CtrlK
BlogDocsLog inGet started
Tessl Logo

ts-sdk-transactions

How to build, sign, submit, and simulate transactions in @aptos-labs/ts-sdk. Covers build.simple(), signAndSubmitTransaction(), waitForTransaction(), simulate, sponsored (fee payer), and multi-agent. Triggers on: 'build.simple', 'signAndSubmitTransaction', 'transaction.build', 'waitForTransaction', 'signAsFeePayer', 'SDK transaction', 'sponsored transaction', 'multi-agent transaction'.

78

Quality

100%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Advisory

Suggest reviewing before use

SKILL.md
Quality
Evals
Security

TypeScript SDK: Transactions

Purpose

Guide building, signing, submitting, and simulating transactions with @aptos-labs/ts-sdk. Use the build → sign → submit → wait pattern; optionally simulate before submit.

ALWAYS

  1. Call aptos.waitForTransaction({ transactionHash }) after submit – do not assume transaction is committed after signAndSubmitTransaction.
  2. Use aptos.transaction.build.simple() for entry function payloads – pass sender and data: { function, functionArguments, typeArguments? }.
  3. Simulate before submit for critical/high-value flows – use aptos.transaction.simulate.simple() and check success and vm_status.
  4. Use the same Account instance for signer that you use for sender address when building (e.g. account.accountAddress as sender, account as signer).

NEVER

  1. Do not skip waitForTransaction – submission returns when the tx is accepted, not when it is committed.
  2. Do not use deprecated scriptComposer (removed in v6) – use separate transactions or batch patterns.
  3. Do not use number for u64/u128/u256 in functionArguments – use bigint where required to avoid precision loss.

Standard flow (simple transaction)

import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));
const MODULE_ADDRESS = "0x...";

// 1. Build
const transaction = await aptos.transaction.build.simple({
  sender: account.accountAddress,
  data: {
    function: `${MODULE_ADDRESS}::counter::increment`,
    functionArguments: [],
  },
});

// 2. Sign and submit
const pendingTx = await aptos.signAndSubmitTransaction({
  signer: account,
  transaction,
});

// 3. Wait for commitment
const committedTx = await aptos.waitForTransaction({
  transactionHash: pendingTx.hash,
});

if (!committedTx.success) {
  throw new Error(`Tx failed: ${committedTx.vm_status}`);
}

Build options

// With type arguments (e.g. coin type)
const transaction = await aptos.transaction.build.simple({
  sender: account.accountAddress,
  data: {
    function: "0x1::coin::transfer",
    typeArguments: ["0x1::aptos_coin::AptosCoin"],
    functionArguments: [recipientAddress, amount],
  },
});

// Optional: max gas, expiry, etc. (see SDK types for full options)
const transactionWithOptions = await aptos.transaction.build.simple({
  sender: account.accountAddress,
  data: { function: "...", functionArguments: [] },
  options: {
    maxGasAmount: 2000n,
    gasUnitPrice: 100n,
    expireTimestamp: BigInt(Math.floor(Date.now() / 1000) + 600),
  },
});

Simulation (before submit)

const transaction = await aptos.transaction.build.simple({
  sender: account.accountAddress,
  data: {
    function: `${MODULE_ADDRESS}::counter::increment`,
    functionArguments: [],
  },
});

const [simResult] = await aptos.transaction.simulate.simple({
  signerPublicKey: account.publicKey,
  transaction,
});

if (!simResult.success) {
  throw new Error(`Simulation failed: ${simResult.vm_status}`);
}
console.log("Gas used:", simResult.gas_used);

Sponsored transactions (fee payer)

// 1. Build with fee payer
const transaction = await aptos.transaction.build.simple({
  sender: sender.accountAddress,
  withFeePayer: true,
  data: {
    function: `${MODULE_ADDRESS}::counter::increment`,
    functionArguments: [],
  },
});

// 2. Sender signs
const senderAuth = aptos.transaction.sign({
  signer: sender,
  transaction,
});

// 3. Fee payer signs (different method)
const feePayerAuth = aptos.transaction.signAsFeePayer({
  signer: feePayer,
  transaction,
});

// 4. Submit with both authenticators
const pendingTx = await aptos.transaction.submit.simple({
  transaction,
  senderAuthenticator: senderAuth,
  feePayerAuthenticator: feePayerAuth,
});

await aptos.waitForTransaction({ transactionHash: pendingTx.hash });

Multi-agent transactions

const transaction = await aptos.transaction.build.multiAgent({
  sender: alice.accountAddress,
  secondarySignerAddresses: [bob.accountAddress],
  data: {
    function: `${MODULE_ADDRESS}::escrow::exchange`,
    functionArguments: [itemAddress, amount],
  },
});

const aliceAuth = aptos.transaction.sign({ signer: alice, transaction });
const bobAuth = aptos.transaction.sign({ signer: bob, transaction });

const pendingTx = await aptos.transaction.submit.multiAgent({
  transaction,
  senderAuthenticator: aliceAuth,
  additionalSignersAuthenticators: [bobAuth],
});

await aptos.waitForTransaction({ transactionHash: pendingTx.hash });

waitForTransaction options

const committed = await aptos.waitForTransaction({
  transactionHash: pendingTx.hash,
  options: {
    timeoutSecs: 60,
    checkSuccess: true, // throw if tx failed
  },
});

Gas profiling

const gasProfile = await aptos.gasProfile({
  sender: account.accountAddress,
  data: {
    function: `${MODULE_ADDRESS}::module::function_name`,
    functionArguments: [],
  },
});
console.log("Gas profile:", gasProfile);

Common mistakes

MistakeCorrect approach
Not calling waitForTransactionAlways wait and check committedTx.success
Using number for large amountsUse bigint for u64/u128/u256 in functionArguments
Wrong signer for submitUse the Account whose address is the sender (or fee payer / additional signer as appropriate)
Assuming scriptComposer existsUse separate transactions or batch; scriptComposer removed in v6

References

  • SDK: src/api/transaction.ts, src/internal/transactionSubmission.ts, src/internal/transaction.ts
  • Pattern: TYPESCRIPT_SDK.md
  • Related: ts-sdk-account, ts-sdk-client, ts-sdk-wallet-adapter, use-ts-sdk
Repository
aave/aptos-aave-v3
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.