Transaction Signing
After building a Soroban transaction via the backend API, the frontend signs it with the user's wallet.
Deposit Transaction Flow
typescript
import * as StellarSdk from "@stellar/stellar-sdk";
async function executeDeposit(vaultId: string, amount: number) {
const wallet = getConnectedWallet(); // from wallet provider
// 1. Get transaction envelope from backend
const res = await fetch("/api/v1/deposit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
vault_id: vaultId,
amount,
wallet_address: wallet.address,
}),
});
const { data } = await res.json();
// 2. Sign with wallet extension
const { signedTxXdr } = await kit.selectedModule.signTransaction(
data.transaction_xdr,
{
networkPassphrase: StellarSdk.Networks.TESTNET,
}
);
// 3. Submit to Stellar network
const server = new StellarSdk.SorobanRpc.Server(
"https://soroban-testnet.stellar.org"
);
const tx = StellarSdk.TransactionBuilder.fromXDR(
signedTxXdr,
StellarSdk.Networks.TESTNET
);
const result = await server.sendTransaction(tx);
// 4. Poll for confirmation
if (result.status === "PENDING") {
const confirmed = await pollTransaction(server, result.hash);
return confirmed;
}
return result;
}Error Handling
typescript
// StellarWalletsKit throws IKitError objects, not Error instances
interface IKitError {
code: number;
message: string;
}
function extractErrorMessage(err: unknown): string {
if (err && typeof err === "object") {
if ("message" in err) return String((err as IKitError).message);
}
if (err instanceof Error) return err.message;
return "Unknown error";
}