Send a Transaction
Create, approve, and broadcast a transaction using the Tholos API.
This guide covers the complete transaction flow for Flex vaults — from creating a transfer to confirmation on-chain.
1. Estimate fees
Section titled “1. Estimate fees”Before creating a transaction, estimate the network fee:
curl -X POST https://api.tholos.app/transaction/estimate-fee \ -H "Authorization: Bearer $THOLOS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "vaultId": 123, "chain": "ethereum", "to": "0xRecipient...", "amount": "1000000000000000000" }'const response = await fetch("https://api.tholos.app/transaction/estimate-fee", { method: "POST", headers: { Authorization: `Bearer ${process.env.THOLOS_API_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ vaultId: 123, chain: "ethereum", to: "0xRecipient...", amount: "1000000000000000000", }),});const data = await response.json();console.log("Estimated fee:", data);2. Create the transaction
Section titled “2. Create the transaction”curl -X POST https://api.tholos.app/transaction/transfer \ -H "Authorization: Bearer $THOLOS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "vaultId": 123, "chain": "ethereum", "to": "0xRecipient...", "amount": "1000000000000000000", "tokenAddress": null, "note": "Monthly treasury distribution" }'const response = await fetch("https://api.tholos.app/transaction/transfer", { method: "POST", headers: { Authorization: `Bearer ${process.env.THOLOS_API_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ vaultId: 123, chain: "ethereum", to: "0xRecipient...", amount: "1000000000000000000", tokenAddress: null, note: "Monthly treasury distribution", }),});const data = await response.json();console.log("Transaction ID:", data.id);The response includes the new transaction with state DRAFT or SUBMITTED depending on your vault configuration.
3. Approve the transaction
Section titled “3. Approve the transaction”Vault signers need to approve the transaction. The approval flow uses an MPC challenge-response.
Get a challenge — the signer requests a challenge for the transaction:
curl https://api.tholos.app/transaction/{txId}/challenge \-H "Authorization: Bearer $SIGNER_TOKEN"Approve — the signer submits their approval:
curl -X POST https://api.tholos.app/transaction/{txId}/approve \ -H "Authorization: Bearer $SIGNER_TOKEN"Repeat until the vault’s approval threshold is met.
4. Transaction completes
Section titled “4. Transaction completes”Once the threshold number of approvals is reached:
- The server automatically signs the transaction using MPC
- The signed transaction is broadcast to the blockchain
- The state updates to
SUCCEEDEDwhen confirmed on-chain
5. Check transaction status
Section titled “5. Check transaction status”curl https://api.tholos.app/transaction/{txId} \ -H "Authorization: Bearer $THOLOS_API_TOKEN"const response = await fetch("https://api.tholos.app/transaction/456", { headers: { Authorization: `Bearer ${process.env.THOLOS_API_TOKEN}`, },});const data = await response.json();console.log("State:", data.state);console.log("Hash:", data.txHash);Other transaction types
Section titled “Other transaction types”Sign a message
Section titled “Sign a message”curl -X POST https://api.tholos.app/transaction/message \-H "Authorization: Bearer $THOLOS_API_TOKEN" \-H "Content-Type: application/json" \-d '{ "vaultId": 123, "chain": "ethereum", "message": "Hello from Tholos"}'Smart contract interaction
Section titled “Smart contract interaction”curl -X POST https://api.tholos.app/transaction/contract-interaction \ -H "Authorization: Bearer $THOLOS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "vaultId": 123, "chain": "ethereum", "to": "0xContractAddress...", "data": "0xCalldata...", "value": "0" }'ERC-20 token approval
Section titled “ERC-20 token approval”curl -X POST https://api.tholos.app/transaction/erc20-approve \ -H "Authorization: Bearer $THOLOS_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "vaultId": 123, "chain": "ethereum", "tokenAddress": "0xTokenAddress...", "spender": "0xSpenderAddress...", "amount": "1000000000000000000" }'Rejecting a transaction
Section titled “Rejecting a transaction”Any signer can reject a pending transaction:
curl -X POST https://api.tholos.app/transaction/{txId}/reject \ -H "Authorization: Bearer $SIGNER_TOKEN"Next steps
Section titled “Next steps”- Transaction concepts — understand the full state machine
- Manage Policies — set up spending limits and whitelists
- API Reference — see all transaction endpoints