This guide will walk you through the process of sending transactions from your wallet using the Crossmint transactions API with custodial signers. Custodial signers enable secure transaction signing without managing private keys directly.
Note: This guide currently only works for wallets set up with a custodial admin signer. We will soon update it
to cover all types of signers.
When interacting with smart contracts, you need to encode your function calls as data. Here’s how to do it:
Copy
import { encodeFunctionData } from 'viem';// Example: Encoding a "transfer" function call for an ERC-20 tokenconst recipientAddress = '0x...'; // Address of the recipientconst tokenAmount = 1000000n; // 1 token with 6 decimals// Encode the function callconst data = encodeFunctionData({ abi: [{ name: 'transfer', type: 'function', inputs: [ { name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' } ], outputs: [{ name: '', type: 'bool' }], stateMutability: 'nonpayable' }], args: [recipientAddress, tokenAmount]});console.log(data);// Example output: 0xa9059cbb000000000000000000000000recipientAddressWithout0x00000000000000000000000000000000000000000000000000000000000003e8
For Solana, you’ll need to prepare the transaction first, then send it to the API:
1
Prepare Transaction
Create a transaction with placeholders that Crossmint will replace:
Copy
import { PublicKey, TransactionMessage, VersionedTransaction, SystemProgram, LAMPORTS_PER_SOL} from "@solana/web3.js";import base58 from "bs58";// Your wallet address from the quickstart guideconst fromPublicKey = new PublicKey("your_wallet_address");// Recipient addressconst toPublicKey = new PublicKey("recipient_address");// Create a transaction (example: sending 0.01 SOL)const message = new TransactionMessage({ instructions: [ SystemProgram.transfer({ fromPubkey: fromPublicKey, toPubkey: toPublicKey, lamports: 0.01 * LAMPORTS_PER_SOL, }), // Add more instructions as needed ], // Use placeholder values - Crossmint will replace these recentBlockhash: "11111111111111111111111111111111", payerKey: new PublicKey("11111111111111111111111111111112"),}).compileToV0Message();const transaction = new VersionedTransaction(message);// Serialize and encode the transactionconst serializedTransaction = transaction.serialize();const serializedTransactionBase58 = base58.encode(serializedTransaction);console.log("Base58 Encoded Transaction:", serializedTransactionBase58);
The transaction will be properly configured on Crossmint’s servers with the correct blockhash and payer before execution.
Crossmint will also handle signing the transaction with your wallet’s custodial signer.
2
Send Transaction
Now send the transaction to the Crossmint API:
Copy
const walletLocator = 'your_wallet_address'; // Your Solana wallet address from the quickstart guideconst apiKey = 'sk_staging...';async function sendTransaction(serializedTransactionBase58: string) { const response = await fetch( `https://staging.crossmint.com/api/2022-06-09/wallets/${walletLocator}/transactions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-KEY': apiKey, }, body: JSON.stringify({ params: { transaction: serializedTransactionBase58 } }), } ); const data = await response.json(); console.log(data); return data;}// Call the function with your base58-encoded transactionsendTransaction("your_base58_encoded_transaction").catch(console.error);
For more complex Solana transactions, such as token transfers or interactions with programs, you’d add the appropriate instructions to the transaction message before serializing it.