Quick Start
Get gasless transactions working in your Aptos dApp in minutes
Which method should I use?
| Method 1 — Wallet Adapter | Method 2 — Script Composer | |
|---|---|---|
| Transaction types | Any — transfers, contracts, NFTs | Token transfers only |
| Testnet | Always free | Always free |
| Mainnet cost | Credits deducted ($0.01 min) | Fee from the token (~$0.01) |
| Code to add | 3 lines — drop-in replacement | ~30 lines — build, sign, submit |
| Best for | Existing dApps, any transaction | Stablecoin transfers, no credits needed |
How billing works
Testnet is always free. Method 1 on mainnet deducts credits from your dashboard balance — from $0.01 per transaction. Method 2 has no credits — the fee comes from the token being sent.
Method 1 — Wallet Adapter Integration
Drop-in replacement. Works with any transaction type, any wallet.
App.tsx
TypeScript
1import { SmoothSendTransactionSubmitter } from '@smoothsend/sdk';2import { AptosWalletAdapterProvider } from '@aptos-labs/wallet-adapter-react';3import { Network } from '@aptos-labs/ts-sdk';4 5function App() {6 // Step 1 — create the submitter with your API key7 const smoothSend = new SmoothSendTransactionSubmitter({8 apiKey: process.env.NEXT_PUBLIC_SMOOTHSEND_API_KEY!,9 network: 'testnet', // or 'mainnet'10 });11 12 // Step 2 — pass it to the wallet provider (that's it!)13 return (14 <AptosWalletAdapterProvider15 dappConfig={{ network: Network.TESTNET, transactionSubmitter: smoothSend }}16 >17 <YourApp />18 </AptosWalletAdapterProvider>19 );20}21 22// Step 3 — use wallet functions as normal. Now gasless!23const { signAndSubmitTransaction } = useWallet();24const result = await signAndSubmitTransaction({ data: payload });Works for
- • Any transaction type — transfers, contracts, NFT mints, DeFi
- • Testnet: completely free, no setup required
- • Mainnet: credits deducted from your dashboard ($0.01 minimum per tx)
Advanced —
useSmoothSend Hook (Per-Function Routing)Use this when only some functions should be gasless. Each component decides independently — sponsored functions go through SmoothSend, others use the user's own APT.
providers.tsx + TodoList.tsx
TypeScript
1// providers.tsx — plain wallet provider, no transactionSubmitter2import { AptosWalletAdapterProvider } from '@aptos-labs/wallet-adapter-react';3import { Network } from '@aptos-labs/ts-sdk';4 5export function Providers({ children }: { children: React.ReactNode }) {6 return (7 <AptosWalletAdapterProvider dappConfig={{ network: Network.MAINNET }}>8 {children}9 </AptosWalletAdapterProvider>10 );11}12 13// TodoList.tsx — per-component hook14import { useSmoothSend } from '@smoothsend/sdk';15import { SmoothSendTransactionSubmitter } from '@smoothsend/sdk';16 17const submitter = new SmoothSendTransactionSubmitter({18 apiKey: process.env.NEXT_PUBLIC_SMOOTHSEND_API_KEY!,19 network: 'mainnet',20});21 22function TodoList() {23 // signAndSubmitTransaction auto-routes:24 // sponsored functions → fee-payer gasless (user pays 0 APT)25 // non-sponsored → user pays gas normally26 const { signAndSubmitTransaction } = useSmoothSend(submitter);27 28 const handleDelete = async (id: number) => {29 // delete_todo is whitelisted in Sponsorship Rules → gasless30 const result = await signAndSubmitTransaction(buildDeleteTodoPayload(id));31 console.log('Tx hash:', result.hash);32 };33}When to choose useSmoothSend over transactionSubmitter
- • You want specific contract functions sponsored, not all transactions
- • You have user-pays actions (e.g. "create" costs gas) alongside free actions (e.g. "delete" is free)
- • You manage sponsorship via the Sponsorship Rules allowlist in your dashboard
Method 2 — Script Composer (Fee-in-Token)
Mainnet token transfers where the fee is deducted from the token. No credits needed.
transfer.ts
TypeScript
1import { ScriptComposerClient } from '@smoothsend/sdk';2import { Deserializer, SimpleTransaction } from '@aptos-labs/ts-sdk';3import { useWallet } from '@aptos-labs/wallet-adapter-react';4 5const client = new ScriptComposerClient({6 apiKey: process.env.NEXT_PUBLIC_SMOOTHSEND_API_KEY!,7 network: 'mainnet',8});9 10async function transferUSDC(walletAddress: string) {11 const { signTransaction } = useWallet();12 13 // Step 1 — build the transaction (fee shown before signing)14 const build = await client.buildTransfer({15 sender: walletAddress,16 recipient: '0xRecipientAddress',17 amount: '1000000', // 1 USDC (6 decimals)18 assetType: '0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b',19 decimals: 6,20 symbol: 'USDC',21 });22 console.log('Fee:', build.feeBreakdown.formatted.fee); // e.g. "0.01 USDC"23 24 // Step 2 — deserialize and sign with the connected wallet25 const txBytes = new Uint8Array(build.transactionBytes);26 const transaction = SimpleTransaction.deserialize(new Deserializer(txBytes));27 const signedTx = await signTransaction({ transactionOrPayload: transaction });28 29 // Step 3 — submit30 const result = await client.submitSignedTransaction({31 transactionBytes: Array.from(txBytes),32 authenticatorBytes: Array.from(signedTx.authenticator.bcsToBytes()),33 });34 console.log('Tx hash:', result.txHash);35}Works for
- • Mainnet stablecoin transfers: USDT, USDC, WBTC, USDe, USD1
- • No credits needed — tiny fee deducted from the token (~$0.01)
- • Users sign with their wallet; relayer pays the APT gas
Get Your API Key
Free to create. Testnet always free. No credit card required to start.