Skip to content
On this page

7. Withdraw bonds ​

What is a withdrawal? ​

A withdrawal lets you take bonds outside of a channel.

Withdrawal process ​

The withdrawal is a three-step process:

Bonds can be withdrawn if one of the following conditions is met:

  • The other parties don’t respond withdraw_delay seconds after a call to the withdraw entrypoint.
  • You can prove that your channel bonds exceeds your running game bonds - your_withdraw.

Step 1: Call the withdraw request entrypoint ​

Notice that you can't make a withdraw request if you already have one opened in the same channel.

python
@sp.entrypoint
def withdraw_request(self, channel_id, tokens):
    sp.set_type(channel_id, sp.TBytes)
    # Map of token_id => amount you want to withdraw
    sp.set_type(tokens, sp.TMap(nat, nat))
python
platform.withdraw_request(
    channel_id = channel_id,
    tokens = sp.map({0: 10})
).run(sender = player1)

Step 2: Withdraw Challenge ​

withdraw_challenge is first called by the other player.

If he agrees that you can withdraw, he leaves an empty challenge.
Otherwise, he gives a set of non-settled game_id that reference more bonds than your channel bonds - your_withdraw.

WARNING

After the other player has called withdraw_challenge

To answer a challenge, you can push the states not already pushed onchain and settle the non-settled games.
Then, call the withdraw_challenge entrypoint with the set of game_id that are now settled.

If your channel bonds exceeds your running game bonds - your_withdraw you can finalize the withdraw.

python
@sp.entrypoint
def withdraw_challenge(self, channel_id, withdrawer, game_ids):
    sp.set_type(channel_id, sp.TBytes)
    # Address of the player who want to withdraw
    sp.set_type(withdrawer, sp.TAddress)
    # Ids of games you want the entrypoint to take into account to update the challenge.
    sp.set_type(game_ids, sp.TSet(sp.TBytes))
python
game_ids = ... # Set of game ids
platform.withdraw_challenge(
    channel_id  = channel_id,
    withdrawer  = player1.address,
    game_ids    = game_ids
).run(sender = player2.address)
python
# ... update state / settle on games listed in game_ids
game_ids = ... # Set of game ids
platform.withdraw_challenge(
    channel_id  = channel_id,
    withdrawer  = player1.address,
    game_ids    = game_ids
).run(sender = player1.address)

Step 3: Finalize withdraw ​

Finalize the withdraw of the sender.

python
@sp.entrypoint
def withdraw_finalise(self, channel_id):
    sp.set_type(channel_id, sp.TBytes)
python
platform.withdraw_finalise(
    channel_id = channel_id,
).run(sender = player1)

Cancel a request ​

Cancel cannot be completed before the withdraw_delay.

python
@sp.entrypoint
def withdraw_cancel(self, channel_id):
    sp.set_type(channel_id, sp.TBytes)
python
platform.withdraw_cancel(
    channel_id = channel_id,
).run(sender = player1)