Skip to content
PortunaPortunaPortunaDocsTestnet

Revoking a delegation

POST /v1/revocations removes the delegate from a deposit address: the address becomes a plain EOA again, without code. Your gas wallet pays the gas, with no fee.

  • Users send the native coin to the address from exchanges that use a fixed 21,000 gas limit. Such transfers fail on an address with code: see Deposits from exchanges.
  • You stop using Portuna Sweep and want your addresses back as they were.

You do not need it to sweep an address into another hot wallet: sign an authorization for that hot wallet’s delegate and send it with the next sweep.

The deposit address signs an authorization of the zero address, 0x0000000000000000000000000000000000000000, with its current nonce. Your gas wallet sends it in a transaction to itself; several revocations go in one transaction.

  • The nonce. Each authorization the chain applies raises the address’s nonce by 1, so after the first sweep it is usually 1. If a first sweep of the address is still queued, the revocation’s nonce must be one more.
  • Order. A revocation waits until the sweeps of the same address requested before it have gone out.
  • Afterwards. Sweeping the address again needs a new authorization of the delegate, like a first sweep.

Sign the authorization as for a sweep (see Signing authorizations), with the zero address and the current nonce, then:

Terminal window
curl -X POST "https://api-testnet.portuna.io/v1/revocations" \
-H "Authorization: Bearer $PORTUNA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "revoke-2c75",
"chain_id": 11155111,
"account": "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23",
"authorization": {
"chain_id": 11155111,
"address": "0x0000000000000000000000000000000000000000",
"nonce": 1,
"y_parity": 1,
"r": "0x04bec751666b1f63d7f4572d81a38642d47517b63b84f6b94a0a494a198c315d",
"s": "0x2a3cc8c27acdae37a0eb652d394ff698ad3910adbfa4d7a393c49a6d4099cabb"
}
}'

The answer is 202 with the revocation in status queued; follow it with GET /v1/revocations/{id}.

In your custody, sign RevocationDigest (revocationDigest) like an authorization digest, and turn the raw signature into the API’s format with RevocationFromSignature (revocationFromSignature).

StatusreasonWhat to do
revokedDone: the address has no code. A revocation.revoked event is sent.
rejectednot_delegatedNothing: the address had no delegation.
rejectedstale_authorizationThe nonce changed. Sign again with the current nonce.
rejectedinvalid_authorizationThe authorization did not pass the check before sending. Sign again.
failednot_appliedThe transaction went through but the chain skipped the authorization: the nonce changed after the check. Sign again.
failedanother codeThe attempts ran out: see causes of a failed attempt, such as insufficient_gas_balance.

Only gas, from your gas wallet, and no fee. One revocation takes about 28,800 gas on Sepolia under the Glamsterdam rules and 36,800 under the earlier rules of Ethereum mainnet and BSC; in a transaction with tens of revocations, about 20,000 per address under the earlier rules. gas and gas_cost in the revocation show its share.