/** * Transact Operations (Internal Railgun Transfer) * * Creates shielded transfers within Railgun - both outputs stay shielded. * Used for fee split: send fee to b402's zk-address, keep rest for user. * * Flow: * 1. User signs message → derive keys locally * 2. Fetch UTXOs from API (no keys sent) * 3. Generate ZK proof with 01x02 circuit (2 shielded outputs) * 4. User signs and sends transaction * 5. After tx confirms, call backend /unshield API for user's change * * Key difference from unshield: * - unshieldPreimage.npk = 0 (tells contract this is a pure transact) * - Both outputs stay shielded in Railgun merkle tree */ import type { Signer } from 'ethers'; import type { SupportedToken } from './local-config'; import { type ChangeNoteInfo } from './proof-inputs'; export interface TransactOptions { feePercentage?: number; token: SupportedToken; signer: Signer; network?: 'mainnet' | 'testnet'; chainId?: number; onProgress?: (progress: number, status: string) => void; } export interface TransactResult { hash: string; feeAmount: string; changeAmount: string; changeNote: ChangeNoteInfo; feeNote: ChangeNoteInfo; changeNotePosition: string; changeNoteTreeNumber: string; } /** * Transact tokens within Railgun (internal transfer, no unshield) * * Splits user's UTXO into: * - Fee note sent to b402's zk-address (stays shielded) * - Change note back to user's zk-address (stays shielded) * * After this transaction, the user should call backend /unshield API * to have b402 unshield their change note. * * @param options - Transact configuration * @returns Transaction result with both note infos */ export declare function transactTokens(options: TransactOptions): Promise;