SDK

Stabletrust SDK

A TypeScript SDK that abstracts homomorphic encryption and zero-knowledge proofs Stabletrust so you can add confidential transfers to any web or Node.js app in minutes.


Installation

Install via npm or yarn:

npm
npm install @fairblock/stabletrust
yarn
yarn add @fairblock/stabletrust

Prerequisites

Node.js 18 or later
An ethers.js v6 compatible signer (e.g. from Privy, MetaMask, or a server wallet)
Test ETH on your target network for gas fees
An ERC-20 token address on a supported network

Quick start

The full lifecycle Stabletrust account setup, deposit, transfer, balance, and withdrawal:

typescript
import { ConfidentialTransferClient } from '@fairblock/stabletrust';

// 1. Initialize the client
const client = new ConfidentialTransferClient({
  rpcUrl: 'https://base-sepolia.drpc.org',
  chainId: 84532,
});

// 2. One-time account setup (~45s to finalize onchain)
await client.ensureAccount(signer);

// 3. Deposit public ERC-20 tokens into the confidential layer
await client.confidentialDeposit({
  signer,
  tokenAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
  amount: ethers.parseUnits('100', 6), // BigInt
});

// 4. Send a private transfer
await client.confidentialTransfer({
  signer,
  tokenAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
  recipientAddress: '0xRecipientAddress',
  amount: 100, // Number
});

// 5. Check encrypted balance (decrypted client-side)
const balance = await client.getConfidentialBalance({
  signer,
  tokenAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
});
// { total: '100', available: '100', pending: '0' }

// 6. Withdraw back to standard ERC-20
await client.withdraw({
  signer,
  tokenAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
  amount: 50, // Number
});

Amount format: deposit uses BigInt via ethers.parseUnits(). withdraw and transfer use Number.

Method reference

ensureAccount(signer)

One-time account initialization. Generates homomorphic encryption keypairs via wallet signature and registers public keys onchain. Takes approximately 45 seconds to finalize.

Must be called before any deposit, transfer, or withdraw.

confidentialDeposit({ signer, tokenAddress, amount })

Converts public ERC-20 tokens into an encrypted confidential balance. Handles token approvals automatically. Amount must be passed as BigInt (use ethers.parseUnits).

confidentialTransfer({ signer, tokenAddress, recipientAddress, amount })

Sends tokens between confidential accounts. Both the amount and destination remain encrypted onchain. Recipient must have an initialized Stabletrust account. Amount as Number.

withdraw({ signer, tokenAddress, amount })

Converts encrypted tokens back to standard ERC-20 tokens in the public layer. Amount as Number.

getConfidentialBalance({ signer, tokenAddress })

Queries the encrypted balance and decrypts it client-side using the user's private key. Returns { total, available, pending } as strings.

Common errors

ErrorResolution
Account does not existCall ensureAccount(signer) before any operation
Insufficient balanceCheck available balance with getConfidentialBalance()
Account finalization timeoutWait for onchain finalization (~45s) and retry

Supported networks

Ethereum Sepolia11155111
Arbitrum Sepolia421614
Base Sepolia84532
Stable Testnet2201
Arc1244
Tempo42431

Next steps