Operations
Operations are objects that represent Tongo transactions. Each operation encapsulates the cryptographic proofs, encrypted data, and calldata needed for a specific action.
Operation Types
Tongo supports five core operations:
- Fund - Convert ERC20 tokens to encrypted balance
- Transfer - Send encrypted amounts to another account
- Withdraw - Convert encrypted balance back to ERC20
- Rollover - Claim pending incoming transfers
- Ragequit - Emergency withdrawal of entire balance
Operation Workflow
All operations follow a similar pattern:
// 1. Create the operation
const operation = await account.someOperation({...params});
// 2. Convert to calldata
const calldata = operation.toCalldata();
// 3. Execute with Starknet signer
const tx = await signer.execute([calldata]);
// 4. Wait for confirmation
await provider.waitForTransaction(tx.transaction_hash);
Fund Operation
Converts ERC20 tokens into encrypted Tongo balance.
Creating a Fund Operation
const fundOp = await account.fund({ amount: 1000n });
Approving ERC20 Spending
Fund operations require ERC20 approval. The SDK provides a helper:
// Populate the approval transaction
await fundOp.populateApprove();
// Execute both approval and fund
await signer.execute([
fundOp.approve!, // ERC20 approval
fundOp.toCalldata() // Fund operation
]);
What Happens
- Generates ZK proof of funding
- Creates encrypted balance ciphertext
- Optionally creates audit ciphertext (if auditor is set)
- Creates AE hint for faster decryption
Transfer Operation
Sends encrypted amounts between Tongo accounts.
Creating a Transfer Operation
const transferOp = await account.transfer({
to: recipientPublicKey, // Recipient's public key
amount: 100n // Amount to transfer
});
What Happens
- Encrypts transfer amount for recipient
- Encrypts new balance for sender
- Generates ZK proof that:
- Sender knows their private key
- Transfer amount ≤ sender balance
- New balance is correctly computed
- Creates encrypted pending balance for recipient
- Creates AE hints for both parties
Result
- Sender: Balance reduced, nonce incremented
- Recipient: Pending balance increased (must rollover)
Withdraw Operation
Converts encrypted Tongo balance back to ERC20 tokens.
Creating a Withdraw Operation
const withdrawOp = await account.withdraw({
to: starknetAddress, // Destination address (hex string)
amount: 500n // Amount to withdraw
});
What Happens
- Generates ZK proof that:
- User knows their private key
- Withdrawal amount ≤ current balance
- New balance is correctly computed
- Creates encrypted new balance
- Creates AE hint for new balance
- Transfers ERC20 tokens to destination address
Important Notes
- The
toaddress receives actual ERC20 tokens - Amount is converted using the contract's rate
- Balance is reduced immediately
Rollover Operation
Claims pending incoming transfers and moves them to spendable balance.
Creating a Rollover Operation
const rolloverOp = await account.rollover();
What Happens
- Reads current balance and pending balance
- Generates ZK proof of knowledge of private key
- Computes new balance = old balance + pending
- Creates encrypted new balance
- Resets pending to zero
When to Rollover
You must rollover when:
- You've received a transfer (pending > 0)
- You want to spend received funds
- Before withdrawing received funds
Example Flow
// Check state before rollover
const stateBefore = await account.state();
console.log(stateBefore); // { balance: 0n, pending: 500n, nonce: 0n }
// Rollover
const rolloverOp = await account.rollover();
await signer.execute([rolloverOp.toCalldata()]);
// Check state after rollover
const stateAfter = await account.state();
console.log(stateAfter); // { balance: 500n, pending: 0n, nonce: 1n }
Ragequit Operation
Emergency operation to withdraw entire balance at once.
Creating a Ragequit Operation
const ragequitOp = await account.ragequit({
to: starknetAddress // Destination for all funds
});
What Happens
- Withdraws entire balance to specified address
- Zeroes out encrypted balance
- Generates proof of balance ownership
When to Use
- Emergency situations
- Account closure
- When you want to exit Tongo completely
Warning: Ragequit withdraws ALL funds. Use
withdrawfor partial withdrawals.
Operation Objects
Common Interface
All operation objects implement:
interface IOperation {
type: OperationType;
toCalldata(): Call;
}
Converting to Calldata
Every operation can be converted to Starknet calldata:
const operation = await account.transfer({...});
const calldata = operation.toCalldata();
// calldata is a Call object:
// {
// contractAddress: string,
// entrypoint: string,
// calldata: string[]
// }
Executing Operations
With a Starknet signer:
// Single operation
await signer.execute([operation.toCalldata()]);
// Multiple operations (e.g., approve + fund)
await signer.execute([
operation1.toCalldata(),
operation2.toCalldata()
]);
Proofs
Every operation (except rollover in some cases) includes a zero-knowledge proof. The SDK automatically:
- Generates the proof using the SHE library
- Includes it in the operation object
- Serializes it for the contract
You don't need to worry about proof generation—it's all handled internally.
Error Handling
Operations can fail during creation:
try {
const transferOp = await account.transfer({
to: recipientPubKey,
amount: 9999999n // More than balance
});
} catch (error) {
console.error("Operation failed:", error.message);
// "You dont have enough balance"
}
Common errors:
"You dont have enough balance"- Insufficient funds for transfer/withdraw"Your pending ammount is 0"- Trying to rollover with no pending balance"You dont have enought balance"[sic] - Withdraw amount exceeds balance
Gas Costs
Approximate gas costs on Starknet:
| Operation | Cairo Steps | Relative Cost |
|---|---|---|
| Fund | ~50K | Low |
| Transfer | ~120K | Medium |
| Rollover | ~80K | Low |
| Withdraw | ~80K | Low |
| Ragequit | ~80K | Low |
Actual costs vary based on network conditions and transaction complexity.