@smoothsend/sdk
v1.1.0
Published
Multi-chain gasless transaction SDK for Aptos & Stellar - Enable gas-free transactions with just 3 lines of code
Readme
SmoothSend SDK
Multi-chain gasless transaction SDK. Enable gas-free transactions with just 3 lines of code. Supports Aptos and Stellar.
🚀 Features
- Gasless Transactions: Users don't need APT or XLM for gas fees
- Multi-Chain: Aptos + Stellar (same 3-line API)
- 3-Line Integration: Works with Aptos Wallet Adapter and Stellar wallets (Freighter, etc.)
- Type-Safe: Full TypeScript support with comprehensive type definitions
- Testnet & Mainnet: Supports both networks on each chain
- Fee-in-Token: On Aptos mainnet, tiny fee deducted from token (not APT)
📦 Installation
npm install @smoothsend/sdk⚡ Quick Start - Wallet Adapter (EASIEST - 3 Lines!)
The easiest way to integrate SmoothSend is using the Wallet Adapter integration. Just add 3 lines of code and ALL your transactions become gasless automatically!
import { SmoothSendTransactionSubmitter } from '@smoothsend/sdk';
import { AptosWalletAdapterProvider } from '@aptos-labs/wallet-adapter-react';
import { Network } from '@aptos-labs/ts-sdk';
// 1. Create the transaction submitter (one line!)
const transactionSubmitter = new SmoothSendTransactionSubmitter({
apiKey: 'pk_nogas_your_api_key_here',
network: 'testnet'
});
// 2. Add to your wallet provider
function App() {
return (
<AptosWalletAdapterProvider
dappConfig={{
network: Network.TESTNET,
transactionSubmitter: transactionSubmitter // <-- That's it!
}}
>
<YourApp />
</AptosWalletAdapterProvider>
);
}
// 3. Use normal wallet functions - they're now gasless!
function TransferButton() {
const { signAndSubmitTransaction } = useWallet();
const handleTransfer = async () => {
// This is now gasless! No code changes needed!
const result = await signAndSubmitTransaction({
data: {
function: "0x1::coin::transfer",
typeArguments: ["0x1::aptos_coin::AptosCoin"],
functionArguments: [recipientAddress, amount],
}
});
console.log('Gasless transaction:', result.hash);
};
return <button onClick={handleTransfer}>Send (Gasless!)</button>;
}That's it! All transactions in your app are now gasless. Users don't need APT for gas fees!
💰 Script Composer - Fee-in-Token Transfers
For mainnet with free tier, use Script Composer to deduct fees from the token being transferred:
import { ScriptComposerClient } from '@smoothsend/sdk';
// Create client for mainnet
const client = new ScriptComposerClient({
apiKey: 'pk_nogas_your_api_key',
network: 'mainnet'
});
// Step 1: Build transfer (fee calculated automatically)
const { transactionBytes, fee, totalAmount } = await client.buildTransfer({
sender: wallet.address,
recipient: '0x123...',
amount: '1000000', // 1 USDC
assetType: '0xf22bede...::usdc::USDC',
decimals: 6,
symbol: 'USDC'
});
console.log(`Sending 1 USDC, fee: ${fee} (deducted from token)`);
// Step 2: Sign with wallet
const signedTx = await wallet.signTransaction(transactionBytes);
// Step 3: Submit
const result = await client.submitSignedTransaction({
transactionBytes: signedTx.transactionBytes,
authenticatorBytes: signedTx.authenticatorBytes
});
console.log('Transaction:', result.txHash);When to Use Each Method
| Scenario | Method | Why | |----------|--------|-----| | Testnet (any tier) | TransactionSubmitter | Always free on testnet | | Mainnet + Free tier | ScriptComposerClient | Fee deducted from token ($0.01/tx) | | Mainnet + Paid tier | TransactionSubmitter | Zero fees included in subscription | | Swaps, NFTs, contracts | TransactionSubmitter | Script Composer only supports transfers | | Token transfers (monetize) | ScriptComposerClient | Pass fee to users |
Script Composer Methods
// Estimate fee without building transaction
const estimate = await client.estimateFee({
sender: '0x...',
recipient: '0x...',
amount: '1000000',
assetType: USDC_ADDRESS,
decimals: 6,
symbol: 'USDC'
});
console.log('Fee:', estimate.estimation.formatted.fee);
console.log('Total:', estimate.estimation.formatted.totalAmount);
// Or use the convenience method for complete flow
const result = await client.transfer(transferParams, wallet);⚠️ Important Security Update
For Aptos transactions, the SDK uses a secure serialized transaction approach that requires proper wallet integration using the Aptos Wallet Standard.
See the Wallet Adapter Integration section for the recommended implementation.
🔑 Authentication
SmoothSend uses API keys for authentication. There are two types of keys:
Public Keys (pk_nogas_*)
- Safe for frontend applications - Can be embedded in client-side code
- CORS-protected - Only work from configured domains
- Use in: React apps, Vue apps, browser extensions, mobile apps
Secret Keys (sk_nogas_*)
- Server-side only - Must never be exposed in client-side code
- No CORS restrictions - Work from any server environment
- Use in: Node.js backends, serverless functions, API servers
Getting Your API Keys
- Sign up at dashboard.smoothsend.xyz
- Create a project
- Generate an API key pair - you'll receive both a public and secret key
- Configure CORS origins for your public key
Security Best Practices
⚠️ Never commit secret keys to version control ⚠️ Never expose secret keys in client-side code ✅ Use public keys for frontend applications ✅ Use secret keys for backend services ✅ Configure CORS origins for production domains
🏁 Classic SDK Usage
If you prefer more control over the transaction flow, you can use the classic SDK approach:
Frontend Example (Public Key)
import { SmoothSendSDK } from '@smoothsend/sdk';
// Initialize with public key (safe for frontend)
const smoothSend = new SmoothSendSDK({
apiKey: 'pk_nogas_your_public_key_here',
network: 'testnet',
timeout: 30000,
retries: 3
});
// Create a transfer request
const transferRequest = {
from: '0x742d35cc6634c0532925a3b8d2d2d2d2d2d2d2d2',
to: '0x742d35cc6634c0532925a3b8d2d2d2d2d2d2d2d3',
token: 'USDC',
amount: '1000000', // 1 USDC (6 decimals)
chain: 'aptos-testnet' as const
};
// Execute transfer (with wallet signer)
try {
const result = await smoothSend.transfer(transferRequest, walletSigner);
console.log('Transfer successful:', result.txHash);
} catch (error) {
console.error('Transfer failed:', error.message);
}Backend Example (Secret Key)
import { SmoothSendSDK } from '@smoothsend/sdk';
// Initialize with secret key (server-side only)
const smoothSend = new SmoothSendSDK({
apiKey: 'sk_nogas_your_secret_key_here',
network: 'mainnet',
timeout: 30000,
retries: 3
});
// Execute Aptos transfer from backend
const result = await smoothSend.executeGaslessTransfer({
transactionBytes: signedTx.transactionBytes,
authenticatorBytes: signedTx.authenticatorBytes,
chain: 'aptos-mainnet',
network: 'mainnet'
});
// Or Stellar - submit signed XDR
const stellarResult = await smoothSend.submitStellarTransaction(signedXdr);
console.log('Transfer successful:', result.txHash);⭐ Stellar - Gasless XLM & USDC
Same 3-line API for Stellar. Use with Freighter, Stellar Wallets Kit, or any Stellar-compatible wallet.
import { SmoothSendSDK } from '@smoothsend/sdk';
const sdk = new SmoothSendSDK({ apiKey: 'pk_nogas_xxx', network: 'testnet' });
// Option 1: Full transfer (build + sign + submit)
const result = await sdk.transfer(
{ from: 'G...', to: 'G...', amount: '100', token: 'XLM', chain: 'stellar-testnet' },
stellarWallet
);
// Option 2: Submit pre-signed XDR
const signedXdr = await wallet.signTransaction(tx);
const result = await sdk.submitStellarTransaction(signedXdr);Stellar wallet interface:
const stellarWallet = {
buildTransaction: (params) => buildPaymentTransaction(params.from, params.to, params.amount, params.token),
signTransaction: (tx) => walletKit.signTransaction(tx.toXDR()).then(r => r.signedTxXdr),
};🔧 Supported Networks
| Network | Status | Features | |---------|--------|----------| | Aptos Testnet | ✅ Active | Gasless transactions, Ed25519 signatures | | Aptos Mainnet | ✅ Active | Gasless transactions, Fee-in-token option | | Stellar Testnet | ✅ Active | Gasless XLM, USDC, EURC via Fee Bump | | Stellar Mainnet | ✅ Active | Gasless XLM, USDC, EURC via Fee Bump |
📚 API Reference
SmoothSendTransactionSubmitter
The recommended way to integrate - works with Aptos Wallet Adapter.
import { SmoothSendTransactionSubmitter } from '@smoothsend/sdk';
const submitter = new SmoothSendTransactionSubmitter({
apiKey: 'pk_nogas_your_api_key',
network: 'testnet' // or 'mainnet'
});
// Pass to AptosWalletAdapterProvider
<AptosWalletAdapterProvider
dappConfig={{
network: Network.TESTNET,
transactionSubmitter: submitter
}}
>ScriptComposerClient
For mainnet transfers with fee-in-token (fee deducted from transferred amount).
import { ScriptComposerClient } from '@smoothsend/sdk';
const client = new ScriptComposerClient({
apiKey: 'pk_nogas_your_api_key',
network: 'mainnet'
});
// Build transfer
const { transactionBytes, fee } = await client.buildTransfer({
sender: '0x...',
recipient: '0x...',
amount: '1000000',
assetType: USDC_ADDRESS,
decimals: 6,
symbol: 'USDC'
});
// Estimate fee
const estimate = await client.estimateFee(transferParams);
// Submit signed transaction
const result = await client.submitSignedTransaction({
transactionBytes,
authenticatorBytes
});SmoothSendSDK (Classic)
Direct SDK usage for more control. Works for both Aptos and Stellar.
import { SmoothSendSDK } from '@smoothsend/sdk';
const smoothSend = new SmoothSendSDK({
apiKey: 'pk_nogas_your_api_key',
network: 'testnet',
timeout: 30000,
retries: 3
});
// Aptos - execute gasless transfer
const result = await smoothSend.executeGaslessTransfer({
transactionBytes: signedTx.transactionBytes,
authenticatorBytes: signedTx.authenticatorBytes,
chain: 'aptos-testnet',
network: 'testnet'
});
// Stellar - submit signed XDR
const stellarResult = await smoothSend.submitStellarTransaction(signedXdr);🔐 Security
- All transactions require user signature approval
- Private keys never leave the client
- Rate limiting and validation on relayer endpoints
- Comprehensive input validation
- Public keys are CORS-protected (safe for frontend)
- Secret keys for backend only
🔗 Links
- Dashboard: dashboard.smoothsend.xyz
- Documentation: docs.smoothsend.xyz
- GitHub: github.com/smoothsend
📄 License
MIT
Built with ❤️ by the SmoothSend team
