githubEdit

Frontend Integration

Wallet Onboarding (AES Key)

Before any encrypted operation, the user must be onboarded to get their AES key. COTI MetaMask Snap provides key management.

import { onboard, ONBOARD_CONTRACT_ADDRESS } from '@coti-io/coti-ethers';

async function onboardWallet(provider: ethers.BrowserProvider) {
    const signer = await provider.getSigner();
    const { aesKey } = await onboard(ONBOARD_CONTRACT_ADDRESS, signer);
    // Store aesKey securely — it's needed for all decrypt operations
    return aesKey;
}

Fetching a Private Balance

import { ethers } from 'ethers';
import { decryptUint256 } from '@coti-io/coti-sdk-typescript';

const BALANCE_ABI = [
    "function balanceOf(address) view returns (tuple(uint256 ciphertextHigh, uint256 ciphertextLow))"
];

async function fetchPrivateBalance(
    tokenAddress: string,
    userAddress: string,
    aesKey: string,       // 32 hex chars, no 0x prefix
    decimals: number = 18
): Promise<string> {
    const provider = new ethers.BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();

    const contract = new ethers.Contract(tokenAddress, BALANCE_ABI, signer);
    const encryptedBalance = await contract.balanceOf(userAddress);

    const { ciphertextHigh, ciphertextLow } = encryptedBalance;

    // Zero check — uninitialized balance
    if (ciphertextHigh === 0n && ciphertextLow === 0n) {
        return '0.00';
    }

    const decrypted = decryptUint256({ ciphertextHigh, ciphertextLow }, aesKey);
    return ethers.formatUnits(decrypted, decimals);
}

React Hook Example

Encrypting a Value for Transactions (itUint256)

All encrypted write operations (transfer, approve, mint, burn) require an itUint256 — a ciphertext + signature pair. This is how you build one in the browser without the Snap:

Sending an Encrypted Transfer

Sending an Encrypted Approve

Last updated

Was this helpful?