/** * tx-builder/fund-tx.ts — Deep pool-funding proof (#30). * * The load-bearing rule for liquidity-bonds: "an unspent coin in my name" is not * enough — the funding coin must be SPENT into the pool/channel script by a * transaction signed by the LP. `buildPoolFundTx` constructs that spending * transaction (canonical form + WOTS signature over its digest), and * `verifyPoolFundTx` proves: * * 1. the tx bytes were not tampered with (signedDigest === digest(tx)); * 2. the LP signature is valid over the tx digest; * 3. the signer's public key actually owns lpAddress; * 4. the tx pays the claimed token+amount to the pool/channel script. * * Combined with `chain-provider.verifyDeposit(fundingCoinId, lpAddress)` at * acceptance time (unspent + owned), this forms the deep on-chain deposit proof: * a coin that existed in the LP's name and a tx signed by the LP paying it into * the pool script. Real mining/broadcast of the TxPoW happens downstream; this * module guarantees the signing/binding that makes the proof non-forgeable. */ export declare const POOL_FUND_DOMAIN = "totemsdk/pool-fund/deep-proof/v1"; export interface PoolFundTx { version: 1; domain: string; poolId: string; fundingCoinId: string; tokenId: string; amount: string; lpAddress: string; recipientAddress: string; nonce: string; /** RFC-020 P2-11 (TXB-FUND-001): absolute expiry (epoch ms). */ expiresAt: number; } export interface BuildPoolFundTxParams { poolId: string; fundingCoinId: string; tokenId?: string; amount: string; lpAddress: string; recipientAddress: string; lpSeed: Uint8Array; /** * RFC-020 C1: the WOTS leaf index to sign with. Required — never defaulted — * so a caller must obtain it from a lease/watermark reservation and cannot * silently reuse leaf 0. */ lpKeyIndex: number; /** * RFC-020 P2-11: absolute expiry (epoch ms) after which the intent must be * rejected. Required so an intent cannot be replayed indefinitely. */ expiresAt: number; nonce?: string; } /** * RFC-016 P5: a **signed funding intent** — it proves the LP signed these * claims, but NOT that an on-chain transaction spent `fundingCoinId` into the * pool. Acceptance must be accompanied by independently verified on-chain spend * evidence. Formerly named `DeepFundingProof`, which overclaimed. */ export interface SignedFundingIntent { fundingCoinId: string; tokenId: string; amount: string; lpAddress: string; recipientAddress: string; lpPkDigest: string; signedDigest: string; lpSignature: string; nonce: string; /** RFC-020 P2-11: mirrors `PoolFundTx.expiresAt`. */ expiresAt: number; } /** @deprecated Use {@link SignedFundingIntent} (RFC-016 P5). */ export type DeepFundingProof = SignedFundingIntent; export interface PoolFundBuildResult { tx: PoolFundTx; digest: Uint8Array; signature: Uint8Array; proof: SignedFundingIntent; } export interface PoolFundVerification { valid: boolean; reasons: string[]; } /** * Replicate Minima's SIGNEDBY-address derivation from a 32-byte WOTS pk digest: * script = `RETURN SIGNEDBY(pkDigest)` → MMR leaf → Mx address. Matches the * wasm `wots_address_from_keypair_wasm` path, so a keypair's address here is * the same address a Minima node would report for that key. */ export declare function addressFromPkDigest(pkDigest32: Uint8Array): string; export declare function hashPoolFundTx(tx: PoolFundTx): Uint8Array; /** * Construct the pool-funding spending transaction and the LP's deep proof. * The returned TxPoW-relevant digest is what the LP signs; broadcast/mine is * left to the caller (which then proves the coin spent into the pool script). */ export declare function buildPoolFundTx(params: BuildPoolFundTxParams): PoolFundBuildResult; /** RFC-020 P2-11: acceptance-time replay/expiry inputs. */ export interface PoolFundVerifyOptions { /** Current time (epoch ms) for expiry evaluation. Defaults to `Date.now()`. */ now?: number; /** * Replay guard. Acceptance MUST pass the set of nonces already consumed (or an * on-chain spent check); a nonce present here is rejected. */ seenNonces?: ReadonlySet; } /** * Verify a deep funding proof. `expectedPoolAddress` (the pool/channel script * address) is required to prove the spend target — without it the proof only * proves the LP signed some tx, which is why acceptance must pass it. */ export declare function verifyPoolFundTx(tx: PoolFundTx, proof: SignedFundingIntent, expectedPoolAddress: string, opts?: PoolFundVerifyOptions): PoolFundVerification; export declare function toProofHex(proof: SignedFundingIntent): string;