> For the complete documentation index, see [llms.txt](https://docs.intents.aurora.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.intents.aurora.dev/intents-connect/developer-guides/sui/staking-sui.md).

# Staking Sui

A worked, self-contained guide to delegating native **SUI** to a validator through the service. It covers both execution modes — **steps-only**, where your Sui intermediary already holds the SUI, and **bridge-in**, where the SUI arrives from another chain and is staked in the same signed request.

### The venue

|                                    | **Validator staking**                                                                        |
| ---------------------------------- | -------------------------------------------------------------------------------------------- |
| Coin                               | SUI only                                                                                     |
| What you get                       | a `StakedSui` object owned by your intermediary, earning staking rewards from the next epoch |
| Yield source                       | protocol staking rewards                                                                     |
| Minimum                            | **1 SUI** (`1000000000` MIST)                                                                |
| Move call                          | `sui_system::request_add_stake`                                                              |
| Coin is taken                      | by value — the call consumes it                                                              |
| Returns something you must consume | no, it returns nothing                                                                       |

The call takes the coin **by value**, which is what makes it usable on a bridge-in: the coin it consumes can be the action coin itself, and its only other arguments are a shared object and a plain address, so nothing owned needs naming. That matters because a bridge-in signs its bytes before your deposit lands and therefore may not reference an owned object at all.

"Staking" is literal here. A validator stake is a delegation that is withdrawable but only credits rewards per epoch.

### The two execution modes

The steps are nearly identical in both modes. What differs is the endpoint, whether a `quote` and an API key are involved, and how the staked amount is chosen.

|                          | **steps-only**                           | **bridge-in**                                    |
| ------------------------ | ---------------------------------------- | ------------------------------------------------ |
| Endpoint                 | `POST /api/v1/executions/{wallet}/steps` | `POST /api/v1/executions/{wallet}`               |
| Carries a `quote`        | no                                       | yes                                              |
| `x-api-key` header       | not required                             | **required**                                     |
| Precondition             | the intermediary already holds the SUI   | the SUI is bridged in from the origin chain      |
| Staked amount            | a concrete `u64` you compute             | the whole action coin, passed by value           |
| May name an owned object | yes                                      | **no** — shared objects and `{ACTION_COIN}` only |
| Swap type                | not applicable                           | `EXACT_INPUT` or `EXACT_OUTPUT`                  |
| Lifecycle                | create → sign → broadcast                | create → sign → deposit → sweep → broadcast      |

### Addresses (Sui mainnet)

| Thing                                      | Value                                                                |
| ------------------------------------------ | -------------------------------------------------------------------- |
| `0x3` system package, in full              | `0x0000000000000000000000000000000000000000000000000000000000000003` |
| `SuiSystemState` — shared, taken by `&mut` | `0x0000000000000000000000000000000000000000000000000000000000000005` |
| Move call                                  | `sui_system::request_add_stake`                                      |
| Minimum stake                              | `1000000000` MIST (1 SUI)                                            |

**The validator argument is the validator's own SUI address, not its staking-pool object id.** Read it from the active validator set on the system state object (`metadata.sui_address`), and re-source it if a validator leaves the set — staking to an address that is no longer active aborts.

The Move signature is:

```
request_add_stake(
  state:     &mut SuiSystemState,
  stake:     Coin<SUI>,
  validator: address,
  ctx:       &mut TxContext,
)
```

It is an `entry` function that returns nothing: the `StakedSui` it creates is transferred to the intermediary by the call itself, so there is no result for your steps to place anywhere.

#### Coin type and asset id

| Token        | Decimals | Move coin type  |
| ------------ | -------- | --------------- |
| SUI (native) | 9        | `0x2::sui::SUI` |

The shorthand `0x2::sui::SUI` is legal in a type argument, but a `target` package and every `objectId` must be written in full 64-hex form.

`destinationAsset` and `quote.destinationAsset` want the **asset id**, never a Move coin type — the service resolves the id against its own token list and derives the coin type itself. List the ids from `GET /api/v1/supported_tokens`, and note which side Sui appears on: with `?flow=inOperation` (or no flow at all) Sui tokens are in `result.out`, because Sui is a bridge destination and never a bridge source. With `?flow=outOperation` they are in `result.in` instead. Native SUI is listed with an **empty** `contractAddress`, which means the native coin rather than an unknown token.

The listing is not a capability check — it is the upstream token catalogue filtered by chain, and it says nothing about whether this deployment has Sui destinations enabled. The probe for that is `GET /api/v1/executions/{wallet}/intermediary` returning a non-null `sui`; a `null` there means either not enabled or a derivation failure, and either way you cannot build a Sui execution right now.

Amounts everywhere are atomic: 1 SUI is `1000000000` MIST.

***

## Mode 1 — steps-only (the intermediary already holds the SUI)

### Staking the whole action coin

One command, and no sink, because the call consumes the coin by value and returns nothing:

```jsonc
"steps": [
  {
    "metadata": { "name": "request_add_stake", "description": "Stake SUI with a validator" },
    "command": "moveCall",
    "target":  "0x0000000000000000000000000000000000000000000000000000000000000003::sui_system::request_add_stake",
    "arguments": [
      { "kind": "object", "objectId": "0x0000000000000000000000000000000000000000000000000000000000000005",
        "shared": true, "mutable": true },                                 // SuiSystemState, by &mut
      { "kind": "object", "objectId": "{ACTION_COIN}" },                   // Coin<SUI>, by value
      { "kind": "pure",   "type": "address",
        "value": "0xcb7efe4253a0fe58df608d8a2d3c0eea94b4b40a8738c8daae4eb77830c16cd7" }  // the validator's SUI address
      // no argument for the trailing &mut TxContext
    ]
  }
]
```

Two things about that mapping are worth stating explicitly, because each one is a `400` if you get it wrong. **`mutable` belongs on the system state**, which is taken by `&mut`; setting `mutable` without `shared` is a `400`. And **nothing is sent for `&mut TxContext`** — the runtime supplies it.

### Staking an amount and keeping the rest

Split the amount off the action coin. The split output is consumed by the stake call, but `splitCoins` only **borrows** the coin it splits from, so the action coin still needs its trailing sink:

```jsonc
"steps": [
  {
    "metadata": { "name": "Split", "description": "Take the stake amount out of the coin" },
    "command": "splitCoins",
    "coin":    { "kind": "object", "objectId": "{ACTION_COIN}" },
    "amounts": [ { "kind": "pure", "type": "u64", "value": "2000000000" } ]   // 2 SUI (9 decimals)
  },
  {
    "metadata": { "name": "request_add_stake", "description": "Stake SUI with a validator" },
    "command": "moveCall",
    "target":  "0x0000000000000000000000000000000000000000000000000000000000000003::sui_system::request_add_stake",
    "arguments": [
      { "kind": "object", "objectId": "0x0000000000000000000000000000000000000000000000000000000000000005",
        "shared": true, "mutable": true },
      { "kind": "nestedResult", "command": 0, "index": 0 },
      { "kind": "pure", "type": "address", "value": "<validator SUI address>" }
    ]
  },
  {
    "metadata": { "name": "Sink", "description": "Consume the action coin" },
    "command":   "transferObjects",
    "arguments": [ { "kind": "object", "objectId": "{ACTION_COIN}" } ],
    "recipient": { "kind": "pure", "type": "address", "value": "{INTERMEDIARY}" }
  }
]
```

The precise rule behind that last command is worth knowing, because it decides whether the sink is mandatory or merely tidy. What aborts is an unconsumed *result*; an unconsumed *input* coin is simply written back to its owner. So when the action coin resolves to coin objects the trailing transfer is a harmless self-transfer, and when it resolves to a credited balance — the case after every bridge-in — the action coin **is** a result and the transfer is load-bearing. You do not get to choose which: it is decided at build time from what the intermediary happens to hold. Write steps that are correct either way.

**A stake below 1 SUI aborts.** The staking pool enforces a minimum of exactly one SUI so check the amount before you send it rather than letting the user discover it as a simulation failure. On the whole-coin shape that means the action coin itself must be worth at least 1 SUI *after* the service's commission has been split off it.

**Leave something behind on a steps-only stake.** If you stake the whole balance, the intermediary ends up holding zero SUI, and the next steps-only execution over it — including the unstake that gets your stake back — is refused with `the intermediary holds no <coinType>: neither a coin object nor an accumulator balance`. Staking an amount and leaving the remainder keeps the position reachable.

### The create request

```jsonc
POST /api/v1/executions/0xF1a2B3c4D5E6f7089A0b1C2d3E4f5061728394a5/steps
{
  "version": "1.0",
  "type": "sui",
  "destinationAsset": "<asset id for native SUI>",
  "steps": [ /* as above */ ],
  "metadata": { "title": "Stake SUI", "intent": "validator_stake" },
  "dry": false
}
```

`type` may be omitted — the service infers the family from the destination asset — but an omitted `type` is recorded as the literal `"evm"`, and every response for that execution then reports `"type": "evm"` back to you. Always send it explicitly. `metadata` is free-form and never interpreted. No `x-api-key` is needed on this endpoint. A TON origin wallet also sends `publicKey`.

Send `"dry": true` first if you want the fee before committing. A dry run signs nothing and persists nothing, returns `details.networkFee` and omits the signing payload entirely. Its echoed `steps` are your steps back verbatim — note that a **real** create echoes something different, the re-rendered user block of the signed transaction, in which every pure argument comes back as `type: "raw"` carrying its encoded bytes.

One Sui-specific note: a dry run wants real steps. The action-coin check runs before the preview returns, so an explicit `"steps": []` is a `400`. Omitting `steps` altogether is carved out and does return an empty shell, but a preview built that way prices nothing useful — send the steps you intend to execute.

### How much can be staked

The service takes its commission **on chain**, as a split out of the action coin. It is emitted at the first point the action coin is provably funded: one command past the last of your steps that `mergeCoins` another coin **into** `{ACTION_COIN}`, and ahead of every step when none does. Every shape in this guide is the second case — none of them merges into the action coin — so on a steps-only execution the action coin your steps see is already net of the fee, and an amount you split off it must satisfy:

```
amount <= the intermediary's SUI balance - networkFee
```

`networkFee` comes back on both a dry preview and a real create as `result.details.networkFee`, a decimal string in the **action coin's atomic units**. There is no separate `serviceFee` field, and the commission does not appear in the echoed `steps`.

The whole-coin shape avoids the arithmetic entirely: passing `{ACTION_COIN}` by value stakes exactly what is left after the carve, whatever that is. With the 1 SUI minimum in play that is also the shape most likely to abort on a thin balance, so check the net figure, not the gross one.

***

## Mode 2 — bridge-in (bridge the SUI in, then stake it)

A bridge-in brings the SUI from another chain and stakes it in one signed request. It is pre-signed at create: the `201` already carries a populated `details.messageToSign`, so you sign immediately and then send the deposit — there is no deferred-signing round trip to poll for.

### The steps

The single `request_add_stake` command shown above, with `{ACTION_COIN}` as the coin argument and no sink at all — the call consumes the coin by value, which is the whole reason this venue works on a bridge-in.

**Do not carve `{MIN_AMOUNT_OUT}` off the action coin.** By the time your first step runs the commission has already been split off, so the action coin is worth exactly `{MIN_AMOUNT_OUT}` — splitting that amount out of it yields the whole coin plus a live zero-value remainder, and the transaction aborts on the unconsumed result. Pass the coin by value when you mean "all of it". Reserve `{MIN_AMOUNT_OUT}` for a Move call's own amount operand, such as a slippage floor — and leave it as the sentinel. Do not resolve it yourself from a preview: a bridge-in is priced by a probe that cannot draw on a delivery which has not landed, so the service reserves only what its own balance of that coin covers and shrinks the substituted figure to fit. The sentinel shrinks with it; a literal cannot, and the create is refused.

**Every argument must be shared or `{ACTION_COIN}`.** A bridge-in's bytes are signed before the deposit lands and carry no object version that could be refreshed later, so an owned object's version would go stale before they are broadcast; naming one is a `400` (`a pre-signed sui execution may not reference an owned object`). The shape above satisfies this: the system state is shared, the validator is a pure address, and the call needs no owned position object.

The test is "is this an `object` argument without `shared: true`", not "does it look like an address" — so an `{INTERMEDIARY}` sentinel sitting in an `objectId` counts as an owned reference too. `{ACTION_COIN}` is the only exemption.

There is also nothing to set up on a first stake. The venue needs no position object created up front, so a first-time user's steps are byte-identical to a repeat user's. The one first-time cost is fee-side and handled by the service: a wallet's very first Sui deposit carries an extra allowance in the bridge-in fee.

### The create request

```jsonc
POST /api/v1/executions/0xF1a2B3c4D5E6f7089A0b1C2d3E4f5061728394a5
x-api-key: <your key>
{
  "version": "1.0",
  "type": "sui",
  "quote": {
    "originAsset":       "<origin asset id>",
    "amount":            "6600000",
    "destinationAsset":  "<asset id for native SUI>",
    "slippageTolerance": 100,                          // basis points
    "swapType":          "EXACT_INPUT",
    "deadline":          "2026-08-19T12:34:56.000Z"
  },
  "steps": [ /* as above */ ],
  "metadata": { "title": "Stake SUI", "intent": "validator_stake" },
  "dry": false
}
```

`type: "sui"` must agree with the **destination** chain here. A `type` that disagrees with the action chain is a `400` naming the mismatch.

A **missing** `x-api-key` is a flat `401` from the middleware, before any validation runs. An **invalid** one is different: it passes the middleware and is only rejected when the quote is fetched, which happens after your steps have been validated — so a bad key on a bad payload surfaces as the payload's `400` first.

Four fields default if you leave them out: `swapType` to `EXACT_INPUT`, `slippageTolerance` to `100` basis points when zero or absent, `deadline` to ten minutes out, and `version` to `"1.0"`.

#### EXACT\_INPUT vs EXACT\_OUTPUT

* **`EXACT_INPUT`** — `quote.amount` is in the **origin** coin's atomic units. The user fixes what they spend; the staked amount is whatever the bridge delivers, net of slippage and commission.
* **`EXACT_OUTPUT`** — `quote.amount` is in the **destination** (Sui) coin's atomic units. The user fixes the amount that lands on Sui, and the origin side is grossed up to cover it.

Either way the whole-coin shape stakes exactly what arrives, so neither needs the amount wired into a step.

What you should check against the 1 SUI staking threshold is not the amount the user typed. The coin `request_add_stake` receives is the **guaranteed** delivery minus the commission — and on a bridge-in response that is exactly what `quote.minAmountOut` already is. The service nets the commission out of both `quote.minAmountOut` and `quote.amountOut` before echoing them, on the dry path and the real one alike, so the check is simply:

```
quote.minAmountOut >= 1000000000
```

Do not subtract `details.networkFee` from it as well — that charges the fee twice and rejects quotes that would have succeeded. (The gross figure, which the signed transaction reserves, is not exposed; `minAmountOut` in the response is the spendable half.) The one state to guard is a preview that came back **without** `networkFee`: it could not be priced, so its figures are the raw quote with no commission carved out at all. Treat that as no usable quote rather than comparing it against the floor.

On `EXACT_INPUT` the Sui-side figure is not knowable before the quote comes back, so a preview is the only way to check the floor. On `EXACT_OUTPUT` you already know it: the figure is the `amount` you asked for, so the floor check is `amount >= 1000000000` on the value the user typed. The service quotes at `amount + networkFee` and then nets the commission back out before echoing, and an `EXACT_OUTPUT` quote carries no output-side slippage haircut — the service rejects a quote whose `minAmountOut` is anything other than its `amountOut`, because on this swap type the slippage allowance sits on the input side, inside `quote.amountIn`. So do **not** discount the figure by `slippageBps` or by `networkFee`; neither applies.

Two probes, though, not one. On a real create the commission the quote is grossed up by is measured before the quote, and the commission netted back out is measured again while the transaction is assembled. Both price the same transaction shape, so they normally agree, but the echoed figure is `amount` plus however much they differ by — it can land just under the amount you asked for. A dry run uses a single probe for both halves, so a preview always shows exactly `amount` and never reveals that drift. Do not let a request sit exactly on `1000000000`: leave a margin, and re-read `quote.minAmountOut` off the `201` before treating the threshold as cleared.

**A preview is a quote, not a commitment.** The create runs its own fee probe, and on `EXACT_OUTPUT` it re-quotes at an amount grossed up by that freshly measured fee — so `details.networkFee` and `quote.minAmountOut` can both move between the dry round and the signed transaction. Re-read them off the `201` rather than carrying the preview's figures forward into a floor check or a displayed amount.

One thing to carry into step 3 of the lifecycle below: on `EXACT_INPUT` the origin deposit is the amount the user entered, but on `EXACT_OUTPUT` it is `quote.amountIn` from the create response, verbatim and already atomic.

#### Lifecycle

1. **Create.** The `201` carries the quote, `details.networkFee`, and the signing payload under `result.details`.
2. **Sign** `details.payload` with your origin wallet, using the `signingStandard` the response names, and `POST /api/v1/executions/{wallet}/submit`. The reply is `{"status": "SIGNED_PENDING_DEPOSIT"}` while the deposit is still outstanding, or `{"status": "SIGNING"}` if it already settled.
3. **Send the deposit** to `quote.depositAddress` on the origin chain and report it with `POST /api/v1/executions/deposit/submit`.
4. **Poll** `GET /api/v1/executions/{wallet}?id=<executionId>` through `CREATED` → `DEPOSIT_PENDING` → `DEPOSIT_PROCESSING` → `OPERATION_PENDING` → `OPERATION_PROCESSING` → `SUCCESS`.

Two things about a Sui bridge-in specifically. `quote.recipient` is a derived **inbox** address belonging to your intermediary, not the intermediary itself — do not label it as the user's address. And there is one extra hop between "deposit settled" and "transaction broadcast", normally seconds, while the service sweeps the delivery into the intermediary's credited balance. The execution can sit at `OPERATION_PENDING` or `OPERATION_PROCESSING` for that hop; nothing about it needs handling on your side.

**A bridge-in costs materially more than the same steps run steps-only.** Its fee includes an allowance for that sweep — a second, service-funded transaction — plus a further allowance on a wallet's very first Sui deposit. Never present the two fees as comparable, and always quote a bridge-in with a bridge-in preview.

**A surplus stays behind.** The signed transaction reserves exactly the guaranteed `minAmountOut`, so anything the bridge delivers above that stays credited to the intermediary rather than being staked. It is not lost — a later steps-only execution picks it up as the action coin — but a UI that reports "staked" without accounting for it understates the user's balance.

***

### Rules that apply here

* **Name the action coin.** At least one argument must be `{ "kind": "object", "objectId": "{ACTION_COIN}" }`. A pure value carrying the sentinel does not count.
* **Sink the action coin, and sink it last.** Something must consume it by value. A `moveCall` parameter declared `Coin<T>` does, which is why the whole-coin shape needs no extra command; `splitCoins` does **not**, which is why the partial-amount shape does. The command that consumes it has to be the **last** one that mentions it: a PTB value moved by value cannot be named again, so a sink followed by any further reference to `{ACTION_COIN}` aborts with `InvalidValueUsage` instead. That bites hardest where the move is a `moveCall` `Coin<T>` parameter, because appending the trailing `transferObjects` the partial-amount shape ends with is exactly the wrong fix on the whole-coin one. Note that this is the one rule with no create-time field check behind it — it is caught, if at all, by simulation. The fee probe does run your steps on every flow, but on a bridge-in it runs relaxed at a stand-in amount and the assembled transaction itself is never simulated, so treat what it catches as a bonus: a missing sink can still reach the chain and abort there.
* **Consume everything your steps return.** `request_add_stake` returns nothing, so the whole-coin shape has nothing to place — but every `splitCoins` **output** is a result, and Sui aborts on an unconsumed result with `UnusedValueWithoutDrop`, since `Coin<T>` has no `drop` ability. A `makeMoveVec` is not a way out of this: it does move its elements, but the `vector<T>` it produces has no `drop` either, so a vector nobody reads aborts the same way and takes the coins inside it down with the transaction.
* **The intermediary must actually hold the SUI** on a steps-only create, as coin objects, as a credited balance, or both. If it holds more SUI coin objects than the service will fold into one action coin **and** no credited balance, the create is refused rather than spending only some of them. That bound is a deployment setting (default **64**, allowed range 1–511), not a protocol constant, so treat the exact number as deployment-specific — the rejection names the figure in force: `intermediary holds too many sui action coin objects: 0x… holds more than <N> <coinType> objects and no accumulator balance`. It only bites when there is no credited balance to fall back on.
* **One live Sui execution per wallet at a time.** Any non-terminal Sui execution blocks the next one, whichever side Sui is on. A second create is `409`.
* **Never name the sponsor or the service's own entry points.** `0x2::coin::redeem_funds` and everything in `0x2::funds_accumulator` are reserved.
* **Do not add gas, a fee transfer, or a budget.** The service sponsors the transaction and emits its own commission commands ahead of yours. You never pay SUI for gas even when SUI is the coin you are staking.

Steps are validated **and simulated** before anything is signed, on every flow, so a step that would revert is normally a descriptive `400` at create rather than a failure on chain. The simulation you will actually hit is the **fee probe**: it runs first, at a stand-in commission, and fails **closed** — an abort in your steps is `400 sui transaction simulation reverted: fee probe aborted at command N: …`, and a probe that cannot run is a `502 sui fee estimation probe failed: …`. Two qualifications: on a steps-only create the assembled transaction is then simulated a second time with the real commission, and only that second call fails **open** on a transport error; on a bridge-in the assembled transaction is never simulated at all, and the probe below is the only verdict. On a `dry` preview a failed probe does not `400` either — it answers `200` with `networkFee` omitted. One exception: a preview still resolves every object your steps name, at its live version, and a step naming an object that does not exist is a `400` on the preview too, since no version of that payload could ever execute. Any other resolution failure fails open and simply leaves `networkFee` off.

One caveat matters more for a staking flow than for anything else. A bridge-in is priced by simulating the same commands at a **smaller amount** under a different payer, because the real bytes draw on a credited balance that does not exist until the deposit lands. The stand-in amount is capped by what the service itself holds of that coin for pricing, which can be far below a real delivery. So a step that aborts on a small input — the 1 SUI staking minimum being exactly that — can fail the probe even though the real delivery would have satisfied it. The error says so:

```
400 sui transaction simulation reverted: fee probe aborted at command N …
```

That is a service-side sizing matter rather than a defect in your steps: report it, and prove the array with a steps-only execution against the same coin in the meantime.

**That command index is absolute.** On a bridge-in the service emits exactly **three** commands of its own ahead of your step 0 — one `redeem_funds` materialising the delivered balance, then the commission split and its transfer — so your step 0 is command 3. On a steps-only run it is two to four: nothing for a single coin object or one `redeem_funds` for a credited balance, optionally one `mergeCoins` folding the intermediary's other coin objects into it, then the commission pair. Subtract before concluding that a particular step is at fault. The commission pair is only *prepended* when none of your steps merges a coin **into** `{ACTION_COIN}`, which is every shape in this guide; an array that does fund the coin that way sees the pair land one command after that merge instead, displacing every step from there on. Those commands are not in the echoed `steps`, so this error is the one place they are visible to you.

One abort you never have to decode by hand: when the failing command *is* the commission split, the guard says so by name rather than by index — `sui transaction simulation reverted: the <amount> commission split aborted at command N: … (the action coin does not hold the commission at that point in the transaction)`.

### Reading the position afterwards

A stake is not derivable from an address the way a Solana token account is — it is an object created by whichever transaction happened to mint it, so you look it up on chain against the resolved intermediary from `GET /api/v1/executions/{wallet}/intermediary` → `result.sui`.

A validator stake is an owned `0x3::staking_pool::StakedSui`, carrying `principal`, `pool_id` and `stake_activation_epoch`. `principal` **excludes** accrued rewards — those live in the staking pool and only materialise on withdrawal — so summing principal understates what an unstake returns. Computing the accrued figure means reading the pool's exchange-rate table at the activation epoch and at the current one.

Each stake mints its own object, so a position built up over several executions is spread across several `StakedSui` objects rather than growing one.

### Sign and submit

Identical to every other destination. The create response returns `result.details.payload` and `result.details.signingStandard` — the standard is your **origin wallet's** (`erc191` for EVM, `raw_ed25519` for Solana, `nep413` for NEAR, `tip191` for Tron, `sep53` for Stellar, `ton_connect` for TON). Sign that payload and post it:

```
POST /api/v1/executions/{wallet}/submit
{ "signature": "…", "executionId": "…" }
```

An ed25519 origin (Solana, NEAR, Stellar) adds `publicKey`; a TON origin adds both `publicKey` and a `tonConnect` envelope. You never handle the Sui transaction bytes and you never pay SUI for gas — the service sponsors the transaction and recovers the cost through the commission.

Note that a signed Sui transaction is valid for the **current epoch and the next**, roughly one to two days, and is permanently unexecutable after that. Steps-only broadcasts as soon as your signature lands, so it finishes far inside that window; a bridge-in waits for the deposit, and in practice the quote's own `deadline` expires a late bridge-in first. Treat the quote deadline as the deposit deadline you show the user.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.intents.aurora.dev/intents-connect/developer-guides/sui/staking-sui.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
