@taceo/merces-oft-client
v0.2.0
Published
Client for TACEO:MercesOft
Readme
@taceo/merces-oft-client
Client SDK for the TACEO Merces confidential OFT protocol. Client wraps the on-chain Merces
contract calls (deposit/withdraw/transfer/send/redeem/challenge) together with witness/proof
generation, and drives a viem PublicClient/WalletClient to submit
transactions.
Installation
npm add @taceo/merces-oft-client
# or: pnpm add @taceo/merces-oft-clientQuick Start
import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { Client } from "@taceo/merces-oft-client";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const publicClient = createPublicClient({ transport: http(process.env.RPC_URL) });
const walletClient = createWalletClient({ account, transport: http(process.env.RPC_URL) });
const client = await Client.create({
contractAddress: "0x...",
contractKind: "adapter", // or "oft"
idRegistryAddress: "0x...",
gatewayUrl: process.env.GATEWAY_URL, // required for deposit/withdraw/transfer/send
token: "0x...", // omit to use the native token
walletClient,
publicClient,
});
await client.deposit(1_000_000n);
console.log(await client.balance());Client.create registers the wallet with the ID registry on first use, prompting for signatures
the first time it's called for a given wallet in a session.
ClientConfig
| Field | Description |
| ------------------- | ------------------------------------------------------------------------ |
| contractAddress | Address of the deployed Merces contract. |
| contractKind | "adapter" or "oft" — selects the ABI to use. |
| idRegistryAddress | Address of the chain's IdRegistry contract. |
| gatewayUrl | Base URL of the gateway relay. Optional, but required by deposit/withdraw/transfer/send (not every chain has one, e.g. an OFT chain with no ERC20 token has no gasless deposit equivalent). |
| token | ERC20 token address; omit to use the native token. |
| walletClient | viem WalletClient (must have an account configured). |
| publicClient | viem PublicClient. |
| txReceiptTimeout | Timeout in ms to wait for a transaction receipt (default: 30_000). |
| mpcEventTimeout | Timeout in ms to wait for the ProcessedMPC on-chain event, or for the action queue to drain (default: 330_000). |
Client methods
address()— this signer's wallet address.registryIndex()— this signer's index in the ID registry.deposit(amount, onStep?)— depositsamountinto this signer's own already-registered account. Returns{ queuedTxHash, completedTxHash }.withdraw(amount, onStep?)— withdrawsamountfrom this signer's own already-registered account, toclient.address(). Returns{ queuedTxHash, completedTxHash }.transfer(receiver, amount, onStep?)— transfersamountfrom this signer's own account toreceiver's, on the same chain. Returns{ queuedTxHash, completedTxHash }.send(dstChainId, dstIdRegistryAddress, dstPublicClient, receiver, amount, onStep?)— sendsamountfrom this signer's own account toreceiver's account on a different chain, identified by that chain'sIdRegistryaddress and aPublicClientconnected to it. Returns{ queuedTxHash, completedTxHash }.balance()— scans on-chain notes (newest first) for the latest one addressed to this signer and returns its decrypted balance; returns zero if this signer has no note yet, or if it's already been redeemed.myCurrentNote()— this signer's current on-chain note (the onebalance()/redeemNote()act on), including whether it's already been redeemed;nullif this signer has no note yet. Unlikebalance(), doesn't wait for the action queue to drain.redeemNote(noteIndex)— redeems this signer's own note atnoteIndexvia the escape hatch.challengeNote(noteIndex)— challenges a note atnoteIndex, proving the MPC posted an inconsistent ciphertext; no-op if the local honesty check shows the MPC was actually correct. Returns whether the MPC was found dishonest.escapeHatchStatus()— MPC liveness, for gating theredeemNoteescape hatch in a UI.
deposit/withdraw/transfer/send accept an optional onStep callback, called with 'proving' | 'submitting' | 'confirming' for UI progress display. deposit on an OFT chain can throw DepositConfirmationTimeoutError if the on-chain burn landed but confirmation timed out — callers must not retry, since the burn already happened.
