import { e as StellarNetwork } from './CavosStellar-DxAYL2pU.mjs'; import { Horizon, rpc, Transaction, FeeBumpTransaction, xdr, Account } from '@stellar/stellar-sdk'; import './DeviceUnwrapKey-Ct-JUQrB.mjs'; /** In-memory shape of the account's control-key envelope. */ interface AccountEnvelope { /** Sealed control seed (`sealControlSeed` output). */ ct: Uint8Array; /** Per-device ECIES DEK-wraps, keyed by device slot id. */ deviceWraps: Record; /** Passkey-PRF DEK-wrap, if a passkey factor is enrolled. */ passkeyWrap?: Uint8Array; /** Recovery-code DEK-wrap, if the user set one up. */ recoveryWrap?: Uint8Array; } /** Serialize an envelope into `MANAGE_DATA` name→value entries (raw bytes). */ declare function toDataEntries(env: AccountEnvelope): Record; /** Reconstruct an envelope from an account's data entries (name→bytes). */ declare function fromDataEntries(entries: Record): AccountEnvelope; interface StellarAdapterOptions { network: StellarNetwork; /** Horizon URL override (else the per-network default). */ horizonUrl?: string; /** Soroban RPC URL override (else the per-network default). Only used for * contract invocation; classic account state/pay still goes through Horizon. */ rpcUrl?: string; /** Per-request network timeout (ms) for Horizon/RPC calls. Without this the * Stellar SDK's axios client never aborts, so a slow/stalled Horizon hangs * `loadAccount` forever — which surfaces as the login stuck on "Setting up * your account". Defaults to 20s. */ requestTimeoutMs?: number; } /** * A batch of `MANAGE_DATA` writes. A `null` value DELETES the entry (Stellar's * `manageData` with no value), which is how a revoked device's ECIES wrap is * erased — and which refunds the entry's reserve. */ type DataEntryWrites = Record; /** * Swap the account's weight-1 signer. Used by device revocation: the tx is * signed by `oldControl` (still weight 1 when signatures are checked), and by * the time it has applied only `newControl` can sign. Rotating is what makes a * revocation real — a device that was evicted from the envelope may still have * cached the old control seed, so the old key must stop being a signer. */ interface ControlRotation { newControl?: string; oldControl?: string; } /** * Classic-Stellar (`G…`) multisig account adapter. * * Unlike the Soroban `StellarAdapter` (contract `C…` accounts authorized by a * `__check_auth` device signature) this operates on a *classic* account whose * signing is ordinary ed25519 multisig: * * - the **master** key (deterministic from identity) names the `G…` address and * is set to weight 0 at creation — powerless afterwards; * - the **control** key (random, weight 1, thresholds 1) is the real signer, * recovered by decrypting the on-chain envelope (see `envelope.ts`). * * The adapter builds/read classic transactions and account state via Horizon; it * never holds a secret — callers pass in the `Keypair`s to sign with. Gasless * submission is a fee-bump whose fee source is the relayer (Phase 3). */ declare class StellarAdapter { readonly chain: "stellar"; readonly network: StellarNetwork; readonly passphrase: string; private readonly horizonUrl; private readonly rpcUrl; private readonly requestTimeoutMs; private _server?; private _rpc?; constructor(opts: StellarAdapterOptions); server(): Horizon.Server; /** Soroban RPC server (lazily created). Used for contract simulation + submit. */ rpc(): rpc.Server; /** Whether the classic account already exists on-chain. */ isDeployed(address: string): Promise; /** Read the account's `MANAGE_DATA` entries as raw bytes (name → value). */ loadDataEntries(address: string): Promise>; /** Native XLM balance in stroops. Returns 0n if the account doesn't exist. */ balance(address: string): Promise; signerKeys(address: string): Promise; /** * Build the account-creation transaction (source = funder, the relayer or a * self-funded keypair): * 1. `createAccount` funds the `G…` address — which is the control key, * 2. `manageData` writes the control-key envelope entries. * * The control key is the account's master key at weight 1, so there is no * signer to add and no master to demote. The returned tx must be signed by * BOTH the control keypair (for the account's own ops) and the funder. */ buildCreateTx(params: { funder: string; controlAddress: string; envelope?: AccountEnvelope; extraSigners?: string[]; /** Starting balance in stroops (must cover base reserve + entries). */ startingBalance: bigint; }): Promise; /** * Build a **sponsored** account-creation transaction whose source is the * relayer. Wraps the account setup in `beginSponsoringFutureReserves` / * `endSponsoringFutureReserves`, so the relayer (not the user) pays every * reserve — the account is created with a 0 starting balance and holds no * locked XLM of the user's. Ops: * 0. beginSponsoringFutureReserves(G) source = relayer * 1. createAccount(G, 0) source = relayer * 2. manageData(cv:… envelope) source = G (control-signed) * 3. endSponsoringFutureReserves() source = G * * Signed by the control key (which IS G); the relayer co-signs (source + fee + * sponsorship) before submitting. */ buildSponsoredCreateTx(params: { relayer: string; controlAddress: string; envelope?: AccountEnvelope; extraSigners?: string[]; }): Promise; /** * Build a classic native-XLM payment as an *inner* transaction whose source is * the account itself (`G…`), signed by the control key. Wrap it in a fee-bump * (see `wrapFeeBump`) so the relayer pays the fee — gasless. */ buildPaymentTx(params: { from: string; to: string; /** Amount in stroops. */ amount: bigint; }): Promise; /** * Build a data-entry write (e.g. re-wrapping the DEK for a newly approved * device) as an inner tx sourced by the account, signed by the control key. */ buildDataTx(params: { account: string; entries: DataEntryWrites; /** Rotate the weight-1 signer in the same tx (device revocation). */ rotation?: ControlRotation; }): Promise; /** * Build a **sponsored** data-entry write whose source is the relayer, so the * relayer (not the 0-balance account) pays the reserve of any NEW subentry. * Adding a factor (passkey / recovery) or a device slot creates a data entry * that needs ~0.5 XLM of reserve; a sponsored account holds no XLM, so — like * account creation — the write must be wrapped in begin/endSponsoringFuture * reserves with the relayer as sponsor. Ops: * 0. beginSponsoringFutureReserves(account) source = relayer * 1..n. manageData(cv:…) source = account (control-signed) * last. endSponsoringFutureReserves() source = account * * Signed by the control key (account ops) + the relayer (source + fee + sponsor). */ buildSponsoredDataTx(params: { relayer: string; account: string; entries: DataEntryWrites; /** Rotate the weight-1 signer in the same tx (device revocation). The new * signer is a subentry, so it is created inside the sponsorship window. */ rotation?: ControlRotation; /** The relayer's current sequence, as reported BY the relayer. Prefer this * over reading it here: this Horizon may lag the one that will accept the * submission, and a stale sequence is rejected as `tx_bad_seq`. */ relayerSequence?: string; }): Promise; /** * Build a `changeTrust` inner tx (account-sourced, control-signed) that opens a * trustline to a classic asset like USDC — required before the account can hold * or receive that token (e.g. to fund a Trustless Work escrow in USDC). */ buildChangeTrustTx(params: { account: string; asset: { code: string; issuer: string; }; /** Trustline limit as a 7-dp string; omit for the SDK max. */ limit?: string; }): Promise; /** * Build a **sponsored** `changeTrust`: a trustline adds a subentry (~0.5 XLM * reserve), so a 0-balance sponsored account can't open one via a plain * fee-bump. Wrap it in begin/endSponsoringFutureReserves with the relayer as * sponsor + source, exactly like `buildSponsoredDataTx`. Signed by the control * key (account op) + the relayer (source + fee + sponsor). */ buildSponsoredChangeTrustTx(params: { relayer: string; account: string; asset: { code: string; issuer: string; }; limit?: string; }): Promise; /** A classic token balance (e.g. USDC) in its native decimals as a string, or * "0" if the account holds no trustline to that asset. */ tokenBalance(address: string, asset: { code: string; issuer: string; }): Promise; /** Wrap a control-signed inner tx in a fee-bump whose fee source is `feeSource` * (the relayer). The inner tx pays nothing; the relayer pays all fees. */ wrapFeeBump(inner: Transaction, feeSource: string): FeeBumpTransaction; /** Submit a fully-signed classic transaction and return its hash. Throws with * the Horizon result codes on failure. */ submit(tx: Transaction | FeeBumpTransaction): Promise; /** * Build a Soroban contract-invocation transaction, sourced by the user's `G…`, * and run it through `prepareTransaction` (simulate → assemble footprint + * resource fees + soroban auth entries). The returned tx is UNSIGNED and ready * for the caller to (a) sign the auth entries whose credential address is the * user, then (b) sign the tx envelope. See `CavosStellar.invokeContract`. * * `args` must already be `xdr.ScVal`s (use `nativeToScVal`/`Address.toScVal`). */ buildInvokeTx(params: { from: string; contractId: string; method: string; args: xdr.ScVal[]; }): Promise; /** Submit a fully-signed Soroban tx via the RPC and poll until it leaves * `PENDING`. Returns the tx hash on success; throws on failure. */ submitSoroban(tx: Transaction | FeeBumpTransaction): Promise; /** The current ledger sequence — used to bound Soroban auth-entry validity. */ latestLedger(): Promise; /** * Read-only contract call: simulate `method(args)` and return the decoded * native result. No account, signing, or submission — for view functions like * the escrow's `get_escrow`. `from` only sources the simulation (any funded or * even the deployer address works). */ readContract(params: { from: string; contractId: string; method: string; args?: xdr.ScVal[]; }): Promise; /** Decode the return value of a submitted Soroban tx (e.g. the factory's * deployed escrow address). Polls until the tx is visible. */ transactionResult(hash: string): Promise; /** Build an `Account` handle for a known address + sequence (avoids a Horizon * round-trip when the caller already has the sequence). */ accountAt(address: string, sequence: string): Account; } export { type AccountEnvelope as A, StellarAdapter as S, type StellarAdapterOptions as a, fromDataEntries as f, toDataEntries as t };