Skip to main content

Transaction and CLI Cookbook for DeepBook

Build common DeepBook programmable transaction blocks (PTBs) from reusable templates for both the sui client ptb CLI and the TypeScript SDK. The sui client ptb CLI needs @-prefixed object IDs, angle-bracket type arguments, and quoted arrays. These templates start with those syntax rules, which cause the most CLI errors, then cover coin operations, generic Move calls, and DeepBook flows.

CLI examples are verified against sui version 1.62.0. DeepBook Move argument order is verified against the DeepBookV3 sources. Generic TypeScript samples pass compile checks against @mysten/sui version 2.22.1. The DeepBook SDK samples follow the documented DeepBookV3 SDK usage. None are executed in this document, so dry-run each command before you rely on it.

tip

Use sui client ptb --preview to print the PTB commands without executing, and --dry-run to estimate gas and catch errors before you sign. The --gas-budget values in these templates are examples. Use the --dry-run estimate to set your own budget.

How do I avoid common sui client ptb errors?​

Most sui client ptb failures come from 3 formatting rules. Get these right and the rest follows.

The examples use shell variables such as $OBJECT_ID and $RECIPIENT. Set each one in your shell before you run a command, for example export RECIPIENT=0x.... Object ID, address, and package variables such as $OBJECT_ID, $RECIPIENT, and $DEEPBOOK hold 0x-prefixed hex values. Type variables such as $BASE, $QUOTE, and $COIN_TYPE hold full Move types, such as 0x2::sui::SUI. For DeepBook package IDs, pools, and coin types, see Contract Information.

Object IDs need an @ prefix​

The CLI treats a bare 0x... value as a number, not an object. Prefix every object ID, address, and gas coin ID with @.

$ sui client ptb \
--transfer-objects "[@$OBJECT_ID]" @$RECIPIENT \
--gas-budget 10000000

Referencing $OBJECT_ID without @ makes the command fail to resolve the object.

Type arguments go in angle brackets​

Type arguments belong in <...>, comma-delimited for multiple types. Quote the whole value so your shell does not interpret the brackets.

$ sui client ptb \
--move-call "$PACKAGE::vault::deposit" "<0x2::sui::SUI>" @$VAULT @$COIN \
--gas-budget 10000000

For 2 type arguments, use "<0x2::sui::SUI, $QUOTE_TYPE>".

Quote arrays so your shell does not expand them​

In zsh and some other shells, [ ] triggers globbing. Wrap every array in quotes.

$ sui client ptb \
--split-coins gas "[1000, 5000]" \
--assign coins \
--transfer-objects "[coins.0, coins.1]" @$RECIPIENT \
--gas-budget 10000000

Use --assign to name a command result, then index into it with .0, .1, and so on. Later commands in the same PTB refer to the result by that name, as --transfer-objects does with coins.0 and coins.1 above.

How do I split, merge, and transfer coins?​

Split 2 coins from the gas coin and transfer them:

$ sui client ptb \
--split-coins gas "[1000, 5000]" \
--assign coins \
--transfer-objects "[coins.0, coins.1]" @$RECIPIENT \
--gas-budget 10000000

Merge coins into a primary coin:

$ sui client ptb \
--merge-coins @$PRIMARY_COIN "[@$COIN_1, @$COIN_2]" \
--gas-budget 10000000

How do I make a Move call with object and type arguments?​

$ sui client ptb \
--move-call "$PACKAGE::vault::deposit" "<0x2::sui::SUI>" @$VAULT 1000 \
--gas-budget 10000000

How do I deposit and place a DeepBook order in one PTB?​

For compile-checked SDK versions of these compositions, plus a three-legged lend, trade, and stake example, see Composing DeepBook transactions.

Get the DeepBookV3 package ID, pool, and coin types from Contract Information. Set DEEPBOOK to the DeepBookV3 package ID. Do not use the CLI deepbook name alias, which resolves to the legacy DeepBook address, not DeepBookV3.

In the SDK samples, string keys such as 'SUI_DBUSDC', 'DEEP_SUI', and 'DBUSDC' are pool and coin keys. Look them up in Contract Information and the DeepBookV3 SDK constants. 'MANAGER_1' is a balance manager key; see Balance Manager.

Placing an order requires a trade proof and takes 13 typed arguments. The TypeScript SDK generates the proof and encodes the arguments for you, so it is the recommended path. Deposit into the BalanceManager and place the order in the same transaction so both settle atomically.

import { Transaction } from '@mysten/sui/transactions';

// `client` is a Sui client extended with the deepbook() plugin.
// See the DeepBookV3 SDK page for setup.
const tx = new Transaction();

// 1. Deposit into the balance manager.
tx.add(client.deepbook.balanceManager.depositIntoManager('MANAGER_1', 'DBUSDC', 100));

// 2. Place a limit bid in the same PTB.
tx.add(
client.deepbook.placeLimitOrder({
poolKey: 'SUI_DBUSDC',
balanceManagerKey: 'MANAGER_1',
clientOrderId: '1',
price: 2.5,
quantity: 10,
isBid: true,
payWithDeep: true,
}),
);

See Balance Manager and Orders for the full parameter set and cancel and modify calls.

How do I write a DeepBook flash loan PTB?​

A flash loan returns a FlashLoan hot potato: a value that you must pass back to the pool in the same transaction, or the whole transaction aborts. borrow_flashloan_base returns 2 values: the borrowed Coin<Base> and the FlashLoan. In the CLI, --assign names both values together, and you index them as .0 and .1. return_flashloan_base takes the pool, the repaid coin, and the FlashLoan.

import { Transaction } from '@mysten/sui/transactions';

const tx = new Transaction();

// Borrow base asset. `flashLoan` is the hot potato you must return.
const [base, flashLoan] = tx.add(client.deepbook.flashLoans.borrowBaseAsset('DEEP_SUI', 1000));

// ... use `base` here, for example swap it through another pool ...

// Repay in the same PTB. The remaining coin returns to you.
const remainder = tx.add(
client.deepbook.flashLoans.returnBaseAsset('DEEP_SUI', 1000, base, flashLoan),
);
tx.transferObjects([remainder], SENDER);

returnBaseAsset repays the borrowed amount from base. remainder holds whatever is left of base after repayment, and the last line transfers it to SENDER.

See Flash Loans for the quote-asset variants.

caution

The flash loan CLI template above has its flag syntax verified against sui 1.62.0 and its argument order verified against the DeepBookV3 pool.move sources, but this document does not execute it end to end. Dry-run it with --dry-run against a real pool and coin types before you rely on it.

How do I verify a PTB before I execute it?​

  1. Add --preview to any command to print its PTB commands without executing.
  2. Add --dry-run to estimate gas and surface argument or type errors.
  3. For DeepBook object IDs and coin and pool keys, see Contract Information and the DeepBookV3 SDK constants.