/** * Sequence0 Client * * Main entry point for app developers to interact with the Sequence0 * decentralized signing network. Create wallets, sign transactions, * and broadcast to any blockchain. * * @example * ```typescript * import { Sequence0 } from '@sequence0/sdk'; * * const s0 = new Sequence0({ network: 'mainnet' }); * * // Create a new wallet * const wallet = await s0.createWallet({ chain: 'ethereum' }); * console.log('Address:', wallet.address); * * // Sign and send a transaction * const txHash = await wallet.sendTransaction({ * to: '0x...', * value: '1000000000000000000', // 1 ETH * }); * ``` */ import { NetworkConfig, CreateWalletOptions, HealthResponse, StatusResponse, WalletDetail, SignResultResponse, WalletProvisioningStatus } from './types'; import { ProgramDeployOptions, ProgramInfo } from './programmable'; import { AtomicSignOptions, AtomicSignResult } from './atomic'; import { DelegateOptions, SubDelegateOptions, DelegationGrant, DelegationTree, AuthorityStatus } from './delegation'; import { Wallet } from '../wallet/wallet'; import { WsClient } from '../utils/websocket'; import { UnsignedFeeTx } from '../utils/fee'; import { SettlementClient } from '../settlement/settlement'; import { UniversalAccountClient, UniversalAccountInfo, CreateUniversalAccountOptions } from './universal-account'; import { SignetClient } from './signet'; import { AegisClient } from './aegis'; import { NexusClient } from './nexus'; export declare class Sequence0 { private config; private http; private ws; private discovery; private feeManager; private resolvedAgentUrl; private circuitBreaker; /** Map of agent API URL -> timestamp when the agent was marked as failed */ private failedAgents; /** Optional signer for wallet ownership proofs */ private ownerSigner; /** Owner's Ethereum address (derived from private key when provided) */ private ownerAddress; /** Optional delegate signer for AEGIS delegated signing */ private delegateSigner; /** Delegation grant ID for delegated signing */ private delegationId; /** * Create a new Sequence0 SDK client * * On testnet, connects to the Sequence0-operated agent by default. * On mainnet, auto-discovers agents from the on-chain AgentRegistry. * * @example * ```typescript * // Mainnet -- auto-discovers agents from on-chain registry * const s0 = new Sequence0({ network: 'mainnet' }); * * // Or specify a specific agent * const s0 = new Sequence0({ network: 'mainnet', agentUrl: 'http://my-agent:8080' }); * * // With debug logging and custom rate limit * const s0 = new Sequence0({ * network: 'mainnet', * debug: true, * maxRetries: 5, * rateLimiter: { maxRequestsPerSecond: 20 }, * }); * ``` */ constructor(config: NetworkConfig); /** * Resolve an agent URL -- uses direct URL if set, otherwise discovers from registry. * Filters out recently-failed agents during discovery. */ private getHttp; /** * Select a healthy agent from the registry, filtering out * agents that failed within the last AGENT_EXCLUSION_TTL ms. */ private selectAgent; /** * Mark the current agent as failed and switch to a different one. * Called internally when a request to the current agent fails * after exhausting retries or when the circuit breaker trips. */ private failoverToNextAgent; /** * Remove expired entries from the failed agents map. */ private pruneExpiredFailures; /** * Create a new HttpClient with the shared circuit breaker and current config. */ private createHttpClient; /** * Execute an HTTP request with automatic agent failover. * If the current agent's circuit breaker trips or all retries fail, * tries to failover to a different agent (up to 2 failover attempts). */ private withFailover; /** * Create a new threshold wallet via DKG ceremony * * Initiates Distributed Key Generation with the agent network. * The private key is never assembled -- each agent holds a share. * * @example * ```typescript * const wallet = await s0.createWallet({ chain: 'ethereum' }); * console.log(wallet.address); // 0x... * console.log(wallet.threshold); // { t: 16, n: 24 } * ``` */ createWallet(options: CreateWalletOptions): Promise; /** * Get an existing wallet by its wallet ID * * Fetches wallet metadata from the agent network. * * @example * ```typescript * const wallet = await s0.getWallet('my-wallet-id'); * const balance = await wallet.getBalance(); * ``` */ getWallet(walletId: string): Promise; /** * List all wallets managed by the agent network */ listWallets(): Promise; /** * Request a threshold signature from the agent network * * @param walletId - The wallet to sign with * @param message - Hex-encoded message to sign * @returns request ID for polling */ requestSignature(walletId: string, message: string): Promise; /** * Poll for a signature result * * @param requestId - From requestSignature() * @returns The signature when ready, null if still pending */ getSignatureResult(requestId: string): Promise; /** * Request a signature and wait for completion * * @param walletId - Wallet ID * @param message - Hex-encoded message * @param timeoutMs - Timeout in ms (default: 30000) * @returns hex-encoded signature */ signAndWait(walletId: string, message: string, timeoutMs?: number): Promise; /** * Get agent network status */ getStatus(): Promise; /** * Health check */ health(): Promise; /** * Request key refresh for a wallet (proactive security). * Requires ownerSigner or ownerPrivateKey in config. */ refreshKeys(walletId: string): Promise; /** * Discover active agents from the on-chain registry */ discoverAgents(): Promise; /** * Discover all active agents from the on-chain registry (paginated). * Fetches all pages when there are more than 100 agents. */ discoverAllAgents(): Promise; /** * Pin SDK calls to a SPECIFIC operator by their on-chain peerId. * * Resolves the operator's REST API URL from the on-chain * `AgentRegistryV2.httpsEndpoints[peerId]` mapping — the URL the * operator self-published via `setHttpsEndpoint(...)`. The returned * Sequence0 instance dials that URL DIRECTLY: no founder-run * `sequence0.network` proxy in the path, no shared HTTPS ingress to * censor or rate-limit. * * Throws if the operator has not published an endpoint yet — clients * SHOULD fall back to the auto-discovery pool in that case. * * @example * ```typescript * const sdkAny = new Sequence0({ network: 'testnet' }); * const aliceSdk = await sdkAny.forOperator('12D3KooWAlice'); * const status = await aliceSdk.getStatus(); // hits https://node.alice.example/ * ``` */ forOperator(peerId: string): Promise; /** * Read per-wallet DKG provisioning status from a healthy agent. * * The agent fleet's strict-mode sign gate (`v3.17.17+`) requires every * committee member to publish a `WalletProvisionedGossip` attestation * before any `/sign` request for that wallet is accepted. This endpoint * exposes the per-agent view of those attestations so callers can: * * - Wait for `complete=true` before issuing the first `/sign` after DKG * - Detect stuck DKGs (`attesting_peer_count < expected_committee_size`) * - Surface scheme-mismatch failures (`reported_scheme` divergence) * * Returns the local view of the agent that serves the request. Different * agents may briefly disagree during gossip propagation — poll until * `complete=true` (typical convergence: <2s on testnet, <10s on mainnet). * * @param walletId - Sequence0 wallet ID * @returns Provisioning status as reported by a healthy agent * * @example * ```typescript * const status = await s0.getWalletProvisioning('my-wallet'); * if (!status.complete) { * console.log(`${status.attesting_peer_count}/${status.expected_committee_size} attested`); * } * ``` */ getWalletProvisioning(walletId: string): Promise; /** * Get the current per-signature fee from the FeeCollector contract. * * Sequence0 Fee Model: * - Fee = 30% of target chain's estimated gas cost * - Paid in the target chain's native token * - Split: 80% agents, 10% reserve, 1% makers, 9% treasury rewards * - Example: Ethereum ($2 gas) -> $0.60 signing fee * - Example: Solana ($0.00025 gas) -> $0.000075 signing fee * - Example: Bitcoin ($5 gas) -> $1.50 signing fee * * The on-chain FeeCollector returns the fee in wei for the Sequence0 * chain (chain ID 800801). The percentage-based model determines what * agents earn; the on-chain fee is a flat registration/coordination fee. * * Returns 0n on testnet (no fees). * * @returns Fee in wei as bigint * * @example * ```typescript * const fee = await s0.getSignatureFee(); * console.log(`Fee: ${fee} wei`); * ``` */ getSignatureFee(): Promise; /** * Build an unsigned fee-payment transaction for a wallet's signing committee. * * This looks up the wallet's committee from the agent network, resolves * each committee member's Ethereum payment address from the on-chain * AgentRegistry, and builds an unsigned `collectFee()` transaction for * the FeeCollector contract. * * Fee model: 30% of the target chain's estimated gas cost, collected on * the target chain in its native token (ETH on Ethereum, SOL on Solana, * BTC on Bitcoin, etc.). The fee is built into the signed transaction * itself as an extra output/transfer. The on-chain FeeCollector contract * on the Sequence0 chain handles governance (fee rates, split ratios). * * Returns null on testnet (no fees). * * @param walletId - The wallet ID that will be signed with * @returns Unsigned transaction `{ to, data, value }` or null if no fee required * * @example * ```typescript * const feeTx = await s0.buildFeeTx('my-wallet-id'); * if (feeTx) { * // Sign and send with your own wallet on the Sequence0 chain * const tx = await signer.sendTransaction(feeTx); * await tx.wait(); * } * // Now request the signature * const sig = await s0.signAndWait('my-wallet-id', messageHex); * ``` */ buildFeeTx(walletId: string): Promise; /** * Deploy a WASM signing policy program to the Sequence0 chain. * * The WASM bytecode is uploaded to the ProgramRegistry contract and * assigned a unique programId (bytes32). Once deployed, the program * can be attached to any wallet owned by the deployer. * * @param options - Program deployment options (bytecode, metadata, limits) * @returns programId as a bytes32 hex string * * @throws {Sequence0Error} If no ownerSigner is configured * @throws {NetworkError} If the deployment transaction fails * * @example * ```typescript * const programId = await s0.deployProgram({ * bytecode: fs.readFileSync('spending-limit.wasm'), * metadataUri: 'ipfs://Qm.../metadata.json', * gasLimit: 5_000_000, * memoryLimit: 16, * }); * console.log('Deployed program:', programId); * ``` */ deployProgram(options: ProgramDeployOptions): Promise; /** * Attach a WASM program to a wallet. * * Only the wallet owner can attach programs. Once attached, the program * runs on every sign request for this wallet -- the agent evaluates it * in a sandboxed WASM environment and rejects the request if the program * returns "deny". * * @param walletId - The wallet to attach the program to * @param programId - The program ID (bytes32 hex) from deployProgram() * * @throws {Sequence0Error} If no ownerSigner is configured * @throws {NetworkError} If the attach transaction fails * * @example * ```typescript * await s0.attachProgram('my-wallet', programId); * ``` */ attachProgram(walletId: string, programId: string): Promise; /** * Detach a WASM program from a wallet. * * Only the wallet owner can detach programs. The program is no longer * evaluated on sign requests for this wallet after detachment. * * @param walletId - The wallet to detach the program from * @param programId - The program ID (bytes32 hex) to detach * * @throws {Sequence0Error} If no ownerSigner is configured * @throws {NetworkError} If the detach transaction fails * * @example * ```typescript * await s0.detachProgram('my-wallet', programId); * ``` */ detachProgram(walletId: string, programId: string): Promise; /** * Get all WASM programs attached to a wallet. * * @param walletId - The wallet to query * @returns Array of program info objects * * @throws {NetworkError} If the agent is unreachable * * @example * ```typescript * const programs = await s0.getWalletPrograms('my-wallet'); * for (const p of programs) { * console.log(`${p.programId}: active=${p.isActive}, gas=${p.gasLimit}`); * } * ``` */ getWalletPrograms(walletId: string): Promise; /** * Sign multiple transactions across chains atomically (all-or-nothing). * * Submits a batch of signing operations to the agent network. The agents * coordinate via a 2-phase commit protocol: either all operations produce * valid signatures, or the entire batch is aborted and no signatures are * released. * * This is essential for: * - Cross-chain arbitrage (buy on chain A, sell on chain B) * - Bridge transfers (lock on source, mint on destination) * - Multi-leg DeFi strategies * * @param options - Atomic signing options with operations array * @returns Result with all signatures (if committed) or error (if aborted) * * @throws {Sequence0Error} If no ownerSigner is configured or operations are empty * @throws {TimeoutError} If the atomic signing times out * * @example * ```typescript * const result = await s0.signAtomic({ * operations: [ * { walletId: 'eth-wallet', chain: 'ethereum', message: '0x...' }, * { walletId: 'arb-wallet', chain: 'arbitrum', message: '0x...' }, * ], * timeout: 60000, * }); * * if (result.status === 'committed') { * for (const [reqId, sig] of result.signatures) { * console.log(`${reqId}: ${sig}`); * } * } else { * console.error('Atomic signing aborted:', result.error); * } * ``` */ signAtomic(options: AtomicSignOptions): Promise; /** * Get a SettlementClient for MERIDIAN Universal Settlement Network operations. * * The settlement client provides methods to submit payment intents, * query cycle status, and retrieve settlement history. Intents are * batched and netted off-chain, then settled atomically via NEXUS. * * @returns A SettlementClient instance bound to the current agent * * @example * ```typescript * const settlement = s0.getSettlementClient(); * * const { intentHash, cycleId } = await settlement.submitIntent( * { * senderWalletId: 'alice-wallet', * recipientWalletId: 'bob-wallet', * chain: 'ethereum', * amount: '1000000000000000000', * }, * ownerSignature, * timestamp, * ); * * const cycle = await settlement.getCurrentCycle(); * console.log(`Cycle ${cycle.cycleId}: ${cycle.status}`); * ``` */ getSettlementClient(): Promise; /** * Get a UniversalAccountClient bound to a healthy agent. * * The client communicates directly with the agent's `/universal/*` * endpoints for account creation, balance queries, and sends. * * @returns A UniversalAccountClient instance * * @example * ```typescript * const ua = await s0.getUniversalAccountClient(); * * const balance = await ua.getUnifiedBalance('ua-abc123'); * console.log('Chains:', balance.totalChains); * * const route = await ua.previewRoute({ * accountId: 'ua-abc123', * to: '0x...', * amount: '1.0', * token: 'ETH', * }); * console.log(`Route: ${route.sourceChain} -> ${route.destinationChain}`); * ``` */ getUniversalAccountClient(): Promise; /** * Create a new universal account — one identity across all 94 chains. * * This is a convenience method that discovers a healthy agent, * creates a UniversalAccountClient, and calls createAccount. * For repeated operations, prefer `getUniversalAccountClient()` * and reuse the client. * * @param options - Account creation options * @returns The created account info with all chain addresses * * @example * ```typescript * const account = await s0.createUniversalAccount({ * ownerSignature: '0x...', * timestamp: Date.now(), * }); * * console.log('Account ID:', account.accountId); * console.log('Ethereum:', account.chainAddresses.ethereum.address); * console.log('Bitcoin:', account.chainAddresses.bitcoin.address); * console.log('Solana:', account.chainAddresses.solana.address); * ``` * * @throws {Sequence0Error} If the creation parameters are invalid * @throws {NetworkError} If no healthy agent is available */ createUniversalAccount(options: CreateUniversalAccountOptions): Promise; /** * Get a SignetClient for SIGNET Programmable Signing operations. * * The client provides methods to deploy WASM signing policy programs, * attach/detach them to wallets, and query program information. * * @returns A SignetClient instance bound to the current agent * * @example * ```typescript * const signet = await s0.getSignetClient(); * * const { programId } = await signet.deployProgram({ * bytecode: wasmHex, * name: 'spending-limit', * description: 'Enforces a 1 ETH per-tx limit', * }); * * await signet.attachProgram('my-wallet', programId); * ``` */ getSignetClient(): Promise; /** * Get an AegisClient for AEGIS Sovereign Agency Protocol operations. * * The client provides methods to create, manage, and revoke * delegation grants, query delegation trees, and send heartbeats * for dead-man's switch scenarios. * * @returns An AegisClient instance bound to the current agent * * @example * ```typescript * const aegis = await s0.getAegisClient(); * * const grant = await aegis.createDelegation('my-wallet', { * to: '0xAiAgent...', * chains: ['ethereum', 'arbitrum'], * constraints: { maxPerTransaction: '1000000000000000000' }, * }); * * const tree = await aegis.getDelegationTree('my-wallet'); * ``` */ getAegisClient(): Promise; /** * Get a NexusClient for NEXUS Atomic Composability operations. * * The client provides methods to submit multi-wallet, multi-chain * atomic signing manifests, poll manifest status, and wait for * completion with automatic polling. * * @returns A NexusClient instance bound to the current agent * * @example * ```typescript * const nexus = await s0.getNexusClient(); * * const result = await nexus.signAtomic({ * operations: [ * { walletId: 'eth-wallet', chain: 'ethereum', message: '0xabc...' }, * { walletId: 'arb-wallet', chain: 'arbitrum', message: '0xdef...' }, * ], * }); * * if (result.status === 'committed') { * for (const [reqId, sig] of result.signatures) { * console.log(reqId, sig); * } * } * ``` */ getNexusClient(): Promise; /** * Subscribe to real-time events from the agent network * * @example * ```typescript * const ws = await s0.subscribe(); * ws.on('SigningComplete', (e) => console.log('Signed:', e)); * ws.on('FeeCollected', (e) => console.log('Fee:', e)); * ``` */ subscribe(walletId?: string): Promise; /** * Clean up all resources (HTTP client, rate limiter, WebSocket, circuit breaker). * Call this when you are done using the SDK. */ destroy(): void; private getWsClient; private getRpcUrl; /** True when the chain uses Ethereum-style 0x... addresses (EVM-compatible). */ private isEvmChain; private getCurveForChain; /** * Build an ownership proof for a sign request using EIP-712 typed structured data. * * EIP-712 domain: { name: "Sequence0", version: "1", chainId, verifyingContract: WalletFactory } * EIP-712 type: Sequence0Auth(string walletId, string action, uint256 timestamp) * * The digest is: keccak256("\x19\x01" || domainSeparator || hashStruct) * * Returns null when no ownerSigner is configured (backwards compatible). */ private signOwnershipProof; /** * Weighted random sampling without replacement. * Agents with higher reputation scores are more likely to be selected. * All agents have a minimum weight of 1 so new agents still have a chance. */ private weightedRandomSample; /** * Emit a one-time warning if the agent URL uses plain HTTP. */ private warnIfHttp; private generateWalletId; /** * Create a delegation grant for a wallet (owner only). */ createDelegation(walletId: string, options: DelegateOptions): Promise; /** * Create a sub-delegation from an existing delegation grant. */ createSubDelegation(walletId: string, options: SubDelegateOptions): Promise; /** * Revoke a delegation grant (cascading to all sub-grants). */ revokeDelegation(walletId: string, delegationId: string): Promise; /** * List all delegation grants for a wallet. */ listDelegations(walletId: string): Promise; /** * Get the delegation tree for a wallet. */ getDelegationTree(walletId: string): Promise; /** * Send heartbeat for dead-man's switch delegation grants. */ heartbeat(walletId: string): Promise; /** * Check remaining authority status of a delegation. */ checkAuthority(delegationId: string): Promise; } //# sourceMappingURL=client.d.ts.map