Introducing Sui Payment Transaction Types

Our latest Sui release introduces three new native transaction types and deprecates three existing methods: Pay, PaySui, and PayAllSui.

Introducing Sui Payment Transaction Types

Our latest Sui release introduces three new native transaction types and deprecates three existing methods. The new APIs—Pay, PaySui, and PayAllSui—effectively replace TransferSui, SplitCoin, and MergeCoin. The three older methods remain functional for the time being, and we will provide advanced notice to the community before removing them.

These Payment methods provide greater ease-of-use and can support a variety of scenarios with less coin management overhead. Our hope is that developers will find more flexibility for supporting a broader set of use cases, as well as stronger API guarantees that are generally expected of payment use cases.

Pay, PaySui, and PayAllSui have been released as part of Sui 0.14.0.

The new Pay* Transaction Types

Pay transactions take multiple coins and send to multiple addresses following the specified amount list. Pay transactions take any type of coin, including SUI. A separate SUI object will be used for gas payment, and the protocol will pick one for the transaction if needed.

  • If the recipient and sender are the same, Pay is effectively a generalized version of splitCoin and mergeCoin.

PaySui transactions take multiple SUI coins and send to multiple addresses following the specified amount list. PaySui only takes SUI coins and does not require a gas coin object.

  • The first SUI coin object input will be used for gas payment, so the balance of this SUI coin has to be equal to or greater than the gas budget.
  • The total SUI coin balance input must be sufficient to cover both the gas budget and the amounts to be transferred.

PayAllSui transactions take multiple SUI coins and sends them to one recipient, after gas payment deduction. After the transaction, strictly zero of the SUI coins input will be left under the sender’s address.

  • The first SUI coin object input will be used for gas payment, so the balance of this SUI coin has to be equal or greater than the gas budget.
  • A sender can transfer all their SUI coins to another address with strictly zero SUI left in one transaction via this transaction type.

Migration Guide

Below are migration code examples based on the Typescript SDK. These changes are very similar to what would be used for Rust SDK and RPC endpoints.

  • TransferSui with a specified amount will migrate to PaySui
// pre-migration codes in TS
const txn = {
    suiObjectId: id,
    gasBudget: GAS_BUDGET,
    recipient: recipient_addr,
    amount: amount,
};
await signer.transferSuiWithRequestType(txn);


// post-migration codes in TS
const txn = {
    inputCoins: [id],
	// length of recipients need to be the same as amounts
    recipients: [recipient_addr],
    amounts: [amount],
    gasBudget: GAS_BUDGET,
};
await signer.paySuiWithRequestType(txn);
  • TransferSui without a specified amount will migrate to PayAllSui
// pre-migration codes in TS
const txn = {
    suiObjectId: id,
    gasBudget: GAS_BUDGET,
    recipient: recipient_addr,
    amount: null,
};
await signer.transferSuiWithRequestType(txn);


// post-migration codes in TS
const txn = {
    inputCoins: [id],
    recipient: recipient_addr,
    gasBudget: GAS_BUDGET,
};
await signer.payAllSuiWithRequestType(txn);
  • SplitCoin and MergeCoin will migrate to Pay
// pre-migration split coin
const txn = {
  coinObjectId: id;
  splitAmounts: [amount0, amount1],
  gasPayment: gas_obj_id,
  gasBudget: GAS_BUDGET,
};
await signer.SplitCoinWithRequestType(txn);
// post-migration pay txn for splitting
const txn = {
  inputCoins: [id],
// length of recipients need to be the same as amounts
  recipients: [sender_addr, sender_addr],
  amounts: [amount0, amount1],
  gasPayment: gas_obj_id,
  gasBudget: GAS_BUDGET,
};
await signer.PayWithRequestType(txn);


// pre-migration merge coin
const txn = {
  primaryCoin: primary_coin_id,
  coinToMerge: coin_to_merge,
  gasPayment?: gas_obj_id,
  gasBudget: GAS_BUDGET,
};
await signer.MergeCoinWithRequestType(txn);
// post-migration pay txn for merging
const txn = {
  inputCoins: [primary_coin_id, coin_to_merge],
  recipients: [sender_addr],
  amounts: [primary_coin_amount + coin_to_merge_amount],
  gasPayment: gas_obj_id,
  gasBudget: GAS_BUDGET,
};
await signer.PayWithRequestType(txn);

Our team will continue working to further improve the developer experience and velocity related to payments. Other initiatives we are working on include:

  • Implement similar util functions like Pay in Move modules.
  • Introduce gas estimation for better gas budget and total gas cost estimations.
  • Further improve coin selection APIs for various use cases.