Transfer currency
When you use the @moneypot/hub server, this is already handled for you.
However, knowing how it works can help you debug potential issues related to transfers.
One of the core features of the MoneyPot casino API is that you can transfer currency between holders (users and controllers).
Transfer status
Transfers can move between these states:
COMPLETED
: (Terminal) The transfer is settled and money was moved between two holder accounts.PENDING
: (Initial) The transfer hasn’t moved any money yet until the sender callscompleteTransfer(id)
.UNCLAIMED
: (Initial) An expirable transfer. Funds have been deducted from the sender (user), but the receiver (controller) must callclaimTransfer(id)
before expiration or before the user cancels the transfer.EXPIRED
: (Terminal) AnUNCLAIMED
transfer that wasn’t claimed in time by receiver. Funds have been returned to sender.CANCELED
: (Terminal) AnUNCLAIMED
orPENDING
transfer where the sender calledcancelTransfer(id)
.
stateDiagram-v2
[*] --> PENDING: Controller creates transfer to user
[*] --> UNCLAIMED: User creates transfer to experience
PENDING --> COMPLETED: Controller calls completeTransfer()
PENDING --> CANCELED: Controller calls cancelTransfer()
UNCLAIMED --> COMPLETED: Controller calls claimTransfer()
UNCLAIMED --> EXPIRED: Time expires
UNCLAIMED --> CANCELED: User calls cancelTransfer()
Receiving user transfers through an experience
When a user wants to play an experience, they use the transferCurrencyToExperience
mutation which starts a transfer to the experience’s underlying controller.
Here is the process:
- The funds are deducted from the user’s account immediately
- An
UNCLAIMED
transfer is created with a very short expiration (one minute)
Then one of these things can happen:
- The user calls
cancelTransfer(id)
and the transfer state becomesCANCELED
- The transfer expires and its state becomes
EXPIRED
- The receiving Controller calls
claimTransfer(id)
, their balance gets credited, and the transfer state becomesCOMPLETED
The controller is responsible for polling the Casino API to watch for incoming UNCLAIMED
transfers.
You must ensure that the
claimTransfer(id)
request to the origin MoneyPot casino succeeds before crediting users in your own database.Otherwise, you will credit users for money that you never received.
A deeper look at funds movement
Most of the complexity in the MoneyPot ecosystem comes from the decentralized nature of a MoneyPot casino, all the experiences, and any number of hub servers underlying those experiences.
User -> Experience transfers (“Put”)
When a user wants to play an experience, they “put” money into the experience by creating an UNCLAIMED transfer to the experience’s underlying controller.
The user’s balance on MoneyPot is immediately deducted so that they can’t double-spend those funds.
- If the unclaimed transfer expires, the user’s funds are refunded to them.
- If the unclaimed transfer is canceled (by the user), the user’s funds are refunded to them.
- If the unclaimed transfer is claimed (by the controller), then the user’s funds are credited to the controller’s balance.
Experience -> User transfers (“Take”)
When a user wants to take funds out of an experience, they use the “take” form to create a take request.
The hub server scans for take requests and turns them into PENDING transfers on MoneyPot.
When hub creates a PENDING transfer, they deduct the user’s funds in the hub database so that the user cannot double-spend those funds on hub. However, no funds are moved on the MoneyPot side until completeTransfer(id)
is called by the controller.
The transfer will stay in the PENDING state until a successful completeTransfer(id)
is called by the controller or if the controller calls cancelTransfer(id)
.