@cloak.dev/sdk 0.2.2 → 0.2.3-staging.f2d7f2a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2931,6 +2931,27 @@ interface ExternalFeePayerAdapter {
2931
2931
  */
2932
2932
  getPaymentAccountHints?: () => Promise<PublicKey[]>;
2933
2933
  }
2934
+ /**
2935
+ * Refuse a transaction whose input notes do not agree on a mint, or do not
2936
+ * agree with the mint the caller says it is spending.
2937
+ *
2938
+ * TWO SEPARATE PROPERTIES, and they catch different mistakes:
2939
+ *
2940
+ * 1. HOMOGENEITY, always enforced. Every pool is a single mint, so a set of
2941
+ * inputs spanning two mints cannot be a valid spend of either. There is no
2942
+ * legitimate call that does this, so it needs no opt-in. Zero-amount
2943
+ * padding notes are exempt: they are placeholders, not value.
2944
+ *
2945
+ * 2. INTENT, enforced when `options.expectedMint` is given. Homogeneity alone
2946
+ * cannot catch the dangerous case — ONE note of the wrong mint is a
2947
+ * perfectly homogeneous set. Only the caller knows which asset the user
2948
+ * asked for, so only the caller can supply it, and this is where it is
2949
+ * checked.
2950
+ *
2951
+ * The error names both mints, because the whole failure mode is that the two
2952
+ * were assumed to be the same.
2953
+ */
2954
+ declare function assertInputMints(inputUtxos: Utxo[], expectedMint?: PublicKey): void;
2934
2955
  /**
2935
2956
  * Options for transact operation
2936
2957
  */
@@ -3184,6 +3205,31 @@ interface TransactOptions {
3184
3205
  * transaction. Omit for unchanged default behavior.
3185
3206
  */
3186
3207
  externalFeePayer?: ExternalFeePayerAdapter;
3208
+ /**
3209
+ * The mint the CALLER believes it is spending. When set, the SDK refuses the
3210
+ * transaction if the input notes say otherwise.
3211
+ *
3212
+ * ── Why this exists ────────────────────────────────────────────────────────
3213
+ * Every flow takes the pool from the notes it is handed
3214
+ * (`inputUtxos[0].mintAddress`), which is correct — the notes are the source
3215
+ * of truth for which pool they belong to. But it means the SDK cannot tell a
3216
+ * deliberate USDC withdrawal from a SOL withdrawal that was handed a USDC
3217
+ * note by mistake. Both are well-formed, both prove, and both settle.
3218
+ *
3219
+ * A consumer hit exactly that: its note selector sorted by RAW base units
3220
+ * across a store holding every mint, so with 6-decimal USDC and 9-decimal
3221
+ * SOL a stablecoin note outranked every SOL note whenever
3222
+ * `usdc > 1000 * sol`. A user sending 0.05 SOL moved ~50 USDC to the
3223
+ * recipient instead, and every layer reported SOL.
3224
+ *
3225
+ * Nothing about that is a protocol failure — the proof, the nullifier and the
3226
+ * pool accounting are all correct, and the user spent their own note. It is a
3227
+ * failure of INTENT, and intent is the one thing only the caller knows. So
3228
+ * the caller may now state it, and the SDK will hold it.
3229
+ *
3230
+ * Optional for backward compatibility, but pass it on every flow you can.
3231
+ */
3232
+ expectedMint?: PublicKey;
3187
3233
  }
3188
3234
  /**
3189
3235
  * Switchboard-style response: a pre-built instruction.
@@ -4668,14 +4714,691 @@ declare class SimpleWallet {
4668
4714
  sync(): Promise<void>;
4669
4715
  }
4670
4716
 
4717
+ /**
4718
+ * What a quote option attests, which is NOT the same question as whether the rail worked.
4719
+ *
4720
+ * Mirrors the service's `rails::Attestation` enum field-for-field (`services/api/bridge/src/rails/
4721
+ * mod.rs`) rather than collapsing it into a boolean: 1Click signs the deposit address AND the
4722
+ * recipient, so a substituted address is detectable by the client even if the service substituted
4723
+ * it. Jupiter signs nothing, so on that rail the user is trusting Cloak — and a UI reading this
4724
+ * union is forced to say so, where a UI reading a boolean could quietly treat both the same.
4725
+ */
4726
+ type BridgeRailAttestation = {
4727
+ kind: "ed25519";
4728
+ verified: boolean;
4729
+ signer: string;
4730
+ } | {
4731
+ kind: "none";
4732
+ checks: string[];
4733
+ note: string;
4734
+ };
4735
+ interface BridgeRailQuoteOption {
4736
+ /** `"oneclick" | "jupiter"` today; typed as `string` so a new rail the service adds is not a
4737
+ * compile error here — the attestation union is what a caller must actually branch on. */
4738
+ rail: string;
4739
+ /** False means a mis-sent or under-filled transfer has NO automated recovery on this rail. */
4740
+ refunds: boolean;
4741
+ /** Whether `depositAddress` is reusable, or fresh per order and expiring. */
4742
+ addressLifetime: string;
4743
+ /** What the rail expects to deliver. NOT a promise — never display this alone. */
4744
+ amountOut: bigint;
4745
+ /** The floor the rail commits to. This is the number a UI should lead with. */
4746
+ minAmountOut: bigint;
4747
+ timeEstimateSeconds?: number;
4748
+ /** The rail's own expiry, when it returns one. Do not invent a value it attests to. */
4749
+ expiresAt?: string;
4750
+ /** Where the user sends funds on the origin chain. Absent on a dry quote (`allocate: false`),
4751
+ * where nothing has been reserved and there is nothing to send to yet. */
4752
+ depositAddress?: string;
4753
+ attestation: BridgeRailAttestation;
4754
+ }
4755
+ interface BridgeRailProblem {
4756
+ rail: string;
4757
+ reason: string;
4758
+ }
4759
+ interface BridgeRailQuoteRequest {
4760
+ /** The derived receiving address R. Base58, on Solana. */
4761
+ recipient: string;
4762
+ originChain: string;
4763
+ /** Base units on the origin chain, as a bigint — a JS `number` loses precision above 2^53 and
4764
+ * this can be an arbitrary token amount. */
4765
+ amountBaseUnits: bigint;
4766
+ /** Origin-chain address an unfillable 1Click order refunds to. Required for that rail. */
4767
+ refundTo?: string;
4768
+ rails?: string[];
4769
+ /** False (the default) sends `dry: true` to 1Click and skips GUM's allocation probes: nothing is
4770
+ * reserved and no `depositAddress` comes back. Requesting an allocation for a deposit the quote
4771
+ * gate might still refuse is the wrong order of operations — leave this false until the caller
4772
+ * has already decided to proceed. */
4773
+ allocate?: boolean;
4774
+ }
4775
+ interface BridgeRailQuoteResponse {
4776
+ options: BridgeRailQuoteOption[];
4777
+ /** Errors from rails that failed, so one rail being down does not hide the other's answer. */
4778
+ unavailable: BridgeRailProblem[];
4779
+ }
4780
+ /**
4781
+ * Mirrors the service's `api::status::DeliveryState` (`services/api/bridge/src/api/status.rs`),
4782
+ * `snake_case` on the wire and identical here. `"unknown"` is a real answer, not a parse failure:
4783
+ * Jupiter/GUM hands out permanent deposit addresses and has no per-transfer status API, so on
4784
+ * that rail the service ALWAYS answers `"unknown"` and says so in `detail` — poll the recipient's
4785
+ * on-chain balance instead. `"expired"` is derived by the service from the order deadline, not a
4786
+ * value 1Click returns.
4787
+ */
4788
+ type BridgeDeliveryState = "pending" | "delivered" | "refunded" | "expired" | "unknown";
4789
+ interface BridgeRailStatusResult {
4790
+ /** The rail that answered, echoed from the service. */
4791
+ rail: string;
4792
+ state: BridgeDeliveryState;
4793
+ /** The service's own explanation of `state`, e.g. why a `"jupiter"` query is `"unknown"`. */
4794
+ detail: string;
4795
+ }
4796
+ interface BridgeRail {
4797
+ readonly id: string;
4798
+ quote(req: BridgeRailQuoteRequest): Promise<BridgeRailQuoteResponse>;
4799
+ /**
4800
+ * `rail` is the `rail` of the quote option whose `depositAddress` this is: the service keys its
4801
+ * status lookup on (address, rail) because the two rails have unrelated status surfaces.
4802
+ */
4803
+ status(depositAddress: string, rail: string): Promise<BridgeRailStatusResult>;
4804
+ }
4805
+ /**
4806
+ * The one constructor this package exposes for talking to the bridge rails — always through
4807
+ * Cloak's own service, never through a rail's API or Kora.
4808
+ *
4809
+ * `relayUrl` is checked HERE, at construction, in addition to the check `relayFetch` repeats on
4810
+ * every call: a caller who mistypes a rail's own base URL (or Kora's) finds out immediately rather
4811
+ * than on first use, and `assertAllowedRelayOrigin` in this function's own body is what lets
4812
+ * `relay-origin-lock.test.ts` enumerate this door the same way it enumerates `RelayService`'s
4813
+ * constructor.
4814
+ */
4815
+ declare function cloakBridgeRail(relayUrl: string): BridgeRail;
4816
+
4817
+ /**
4818
+ * The paymaster client — the SOL top-up that lets a bridge receiver R (which arrives holding only
4819
+ * bridged tokens, no SOL) shield without the user's own wallet ever appearing on chain.
4820
+ *
4821
+ * Talks ONLY to Cloak's own bridge service (`api.cloak.ag/bridge/paymaster/*`), never to Kora
4822
+ * directly: under fixed pricing (docs/00-DECISION-STATE.md, PAYMASTER ECONOMICS) the Kora API key is
4823
+ * worth real money to whoever holds it, and a browser bundle is not a place that can keep a secret.
4824
+ *
4825
+ * ── The two-round-trip shape, and why it is not one call ─────────────────────────────────────
4826
+ * `prepare` returns an UNSIGNED transaction the service built and priced, plus a voucher that MACs
4827
+ * the exact message bytes. The client's receiving key R signs it — R never leaves the client, and
4828
+ * this is the only place it signs anything for the paymaster flow — and hands the bytes back
4829
+ * unchanged to `cosign`, which recognises them via the voucher and only THEN asks Kora to co-sign as
4830
+ * fee payer. The paymaster's key never leaves the server; R's key never leaves the client; neither
4831
+ * round trip needs the other's secret. See `services/api/bridge/src/api/paymaster.rs` for the
4832
+ * server half of this contract.
4833
+ *
4834
+ * ── Why the shape check below is not optional ────────────────────────────────────────────────
4835
+ * `cosign` answers exactly one question — "is this the message I built?" — and answers it by MAC,
4836
+ * not by re-deriving policy from an arbitrary transaction. That makes `prepare`'s response the ONLY
4837
+ * point where an unexpected instruction could sneak in (a compromised service, a MITM'd response, a
4838
+ * bug that built the wrong thing), because nothing downstream re-checks it. `validate
4839
+ * PaymasterTopUpTransaction` is that one check, and it runs BEFORE R signs anything: signing is the
4840
+ * one irreversible step in this flow from the client's point of view, so the check that matters has
4841
+ * to sit in front of it, not after.
4842
+ */
4843
+
4844
+ /** What `prepare`'s response is checked against before R ever signs it. */
4845
+ interface PaymasterTopUpExpectation {
4846
+ /** R — the only account this transaction may fund or spend from. */
4847
+ recipient: PublicKey;
4848
+ /** The lamports we asked for. `ix0.lamports` may come in at or under this, never over. */
4849
+ maxGrantLamports: bigint;
4850
+ feeMint: PublicKey;
4851
+ /** The fee Kora actually quoted at `prepare` time. `ix1.amount`, if `ix1` exists, must equal this
4852
+ * exactly — not "at most", because the fee is a quote the service already committed to, not a
4853
+ * ceiling. */
4854
+ feeTokenAmount: bigint;
4855
+ /** The paymaster's own token account owner, from `prepare`'s `payment_address`. `ix1`'s
4856
+ * destination must be exactly THIS address's ATA for `feeMint` — nothing else, and never an ATA
4857
+ * derived from `recipient` or from an address the caller does not already trust. */
4858
+ paymentAddress: PublicKey;
4859
+ }
4860
+ /**
4861
+ * The one check standing between `prepare`'s response and R's signature.
4862
+ *
4863
+ * Two instructions, and the shape IS the security story (`paymaster/topup.rs`'s own words, mirrored
4864
+ * here on the verifying side):
4865
+ *
4866
+ * ix0 System transfer, paymaster -> recipient, <= the lamports we asked for
4867
+ * ix1 (optional) SPL transfer, recipient's fee-mint ATA -> paymaster's fee-mint ATA, authority
4868
+ * = recipient, amount == the quoted fee
4869
+ *
4870
+ * Anything else — a third instruction, a different destination, a different authority, an amount
4871
+ * that does not match the quote — is refused. This function throws rather than returning a verdict:
4872
+ * there is no partial-trust path here, and a caller that wants to keep going after a refusal is a
4873
+ * caller papering over a corrupted or hostile response.
4874
+ */
4875
+ declare function validatePaymasterTopUpTransaction(tx: Transaction, expect: PaymasterTopUpExpectation): void;
4876
+ interface PaymasterTopUpResult {
4877
+ /** Fully signed by both R and the paymaster. The caller submits it — Kora's own
4878
+ * `signAndSendTransaction` is disabled service-side, and the broadcast should not carry the
4879
+ * service's IP any more than the deposit itself should carry R's. */
4880
+ transaction: Transaction;
4881
+ feeTokenAmount: bigint;
4882
+ feeMint: string;
4883
+ paymentAddress: string;
4884
+ }
4885
+ /**
4886
+ * The whole paymaster flow: prepare, verify the shape, sign as R, cosign, return the fully-signed
4887
+ * transaction for the caller to submit.
4888
+ *
4889
+ * `receiver` is the derived bridge receiving key (`deriveBridgeReceiver`). It signs here and only
4890
+ * here in this file's flow, and its secret never leaves this function — nothing above needs it, and
4891
+ * nothing here sends it anywhere.
4892
+ */
4893
+ declare function fundReceiverViaPaymaster(relayUrl: string, receiver: Keypair, grantLamports: bigint): Promise<PaymasterTopUpResult>;
4894
+
4895
+ /**
4896
+ * Deriving a bridge receiving address.
4897
+ *
4898
+ * One single-use address per deposit, from the wallet's own key material. Deterministic, offline,
4899
+ * and stateless — which is what lets every other function here work on a device that has never
4900
+ * seen this deposit before.
4901
+ */
4902
+
4903
+ declare const BRIDGE_ESCROW_LABEL = "cloak_bridge_escrow";
4904
+ /**
4905
+ * The index MUST be a small sequential counter (0, 1, 2, …), never a timestamp.
4906
+ *
4907
+ * This is not a style preference: discovery works by deriving indices 0…N and reading each on
4908
+ * chain. A timestamp index is unreachable by any scan, so a deposit made under one is invisible to
4909
+ * every device except the one that made it — which is precisely the failure that made a resume
4910
+ * link look necessary. The prototype harness used `Date.now()` for test hermeticity and those
4911
+ * deposits are, correctly, undiscoverable.
4912
+ */
4913
+ /**
4914
+ * The largest index discovery could plausibly reach. A scan is one round of on-chain reads per
4915
+ * index, so anything past a few thousand is not recoverable in practice — and a timestamp (~1.8e12)
4916
+ * is not recoverable even in principle. Rejecting it here is the difference between the constraint
4917
+ * being documented and it being enforced.
4918
+ */
4919
+ declare const MAX_RECEIVER_INDEX = 10000;
4920
+ declare function deriveBridgeReceiver(nk: Uint8Array | Buffer, index: number): Keypair;
4921
+
4922
+ /**
4923
+ * Finding a user's bridge deposits from their key material alone.
4924
+ *
4925
+ * THIS IS THE FUNCTION THAT MAKES THE BRIDGE AN SDK CAPABILITY RATHER THAN A WEB FEATURE.
4926
+ *
4927
+ * Derive receivers for index 0…N and read each on chain. No stored state, no link to carry, no
4928
+ * localStorage. It works on a device that has never seen the app, in a CLI, on mobile, after a
4929
+ * browser wipe. An earlier design proposed a shareable URL to carry the deposit index to a second
4930
+ * device; the index does not need carrying, it needs scanning, and the link it replaced was a
4931
+ * packaged correlation between an origin payment and a Solana address about to enter the pool.
4932
+ */
4933
+
4934
+ type BridgeDepositState =
4935
+ /** Nothing ever happened at this index. */
4936
+ "unused"
4937
+ /** Funded for a deposit, but no tokens have arrived. */
4938
+ | "awaiting"
4939
+ /** Tokens are sitting at the receiver, in the open, not yet shielded. */
4940
+ | "arrived"
4941
+ /** Shielded, and the receiver's token account has been closed. */
4942
+ | "complete"
4943
+ /** Shielded, but the token account is still open and holding its rent. */
4944
+ | "needs-cleanup"
4945
+ /**
4946
+ * An RPC read failed while checking this index. This is NOT evidence of absence — it is the
4947
+ * opposite of "unused" in every way that matters to a caller: a rate-limited or dropped read
4948
+ * used to fall back to a zero/empty default, which reported a real deposit's index as nothing-
4949
+ * here, indistinguishable from the index truly never having been touched. A user reading that
4950
+ * concludes their money is gone. `error` on the deposit explains what failed; the fix is to
4951
+ * retry, not to trust this entry's tokenBalance/lamports, which are placeholders.
4952
+ */
4953
+ | "unknown";
4954
+ interface BridgeDeposit {
4955
+ index: number;
4956
+ receiver: PublicKey;
4957
+ tokenAccount: PublicKey;
4958
+ state: BridgeDepositState;
4959
+ /** Placeholder 0n when state is "unknown" — the read that would have set this failed. */
4960
+ tokenBalance: bigint;
4961
+ /** Placeholder 0 when state is "unknown" — the read that would have set this failed. */
4962
+ lamports: number;
4963
+ /** Signature of the shield-pool transaction, when one was found. Most recent, if more than one — see indexReused. */
4964
+ shieldSignature?: string;
4965
+ /**
4966
+ * True when this receiver's own history holds more than one shield-pool transaction: this index
4967
+ * was used for more than one deposit. Two deposits at the same index share one on-chain address,
4968
+ * which links them to each other, and `shieldSignature` alone would silently pick one and hide
4969
+ * that a second one exists. A caller MUST warn the user instead of treating this as a single
4970
+ * ordinary deposit.
4971
+ */
4972
+ indexReused?: boolean;
4973
+ /** Every shield-pool signature found at this receiver, most recent first. Present only when indexReused. */
4974
+ shieldSignatures?: string[];
4975
+ /** Set only when state is "unknown": the failure that made this index's status unconfirmable. */
4976
+ error?: string;
4977
+ }
4978
+ interface DiscoverOptions {
4979
+ /**
4980
+ * How many indices to derive, starting at 0. Discovery is one to a few on-chain reads per index,
4981
+ * so this bounds the cost of a scan — it is NOT a claim about where deposits can live. An index
4982
+ * can be as large as MAX_RECEIVER_INDEX (10,000, see ./derive), and the default of 20 only covers
4983
+ * indices allocated sequentially with the stopAfterUnused gap tolerance below. A caller with
4984
+ * reason to believe a deposit landed further out (a CLI --index flag, a resumed session that
4985
+ * knows its own counter) MUST pass a larger scanDepth explicitly — anything past the configured
4986
+ * depth is simply never read, and reports as neither found nor absent, because it was not looked
4987
+ * at. Clamped to MAX_RECEIVER_INDEX + 1 (the count of valid indices, 0 through MAX_RECEIVER_INDEX
4988
+ * inclusive): deriveBridgeReceiver throws past that ceiling, and without the clamp a caller who
4989
+ * over-estimates scanDepth turns that into a mid-scan crash that discards every deposit already
4990
+ * found in the same call.
4991
+ */
4992
+ scanDepth?: number;
4993
+ /** Stop after this many consecutive unused indices. An "unknown" index (RPC failure) neither
4994
+ * counts toward nor resets this run — it carries no information about presence or absence, so
4995
+ * letting it break a real run of unused indices early would reintroduce the same false-absence
4996
+ * failure this file exists to prevent. */
4997
+ stopAfterUnused?: number;
4998
+ programId: PublicKey;
4999
+ mint: PublicKey;
5000
+ }
5001
+ /**
5002
+ * A terminal state needs TWO conjuncts, never one.
5003
+ *
5004
+ * After the rent cleanup runs, "the receiver's token balance is zero" is indistinguishable from
5005
+ * "nothing ever happened at this address". Deriving completion from balance alone overwrites a
5006
+ * real completion record with an empty one — observed live, and it crashed the view that read it.
5007
+ * Completion therefore requires the shield-pool transaction to be present in the receiver's own
5008
+ * history as well.
5009
+ */
5010
+ declare function listBridgeDeposits(conn: Connection, nk: Uint8Array | Buffer, opts: DiscoverOptions): Promise<BridgeDeposit[]>;
5011
+
5012
+ /**
5013
+ * The client half of a bridge deposit, from "tokens have arrived at R" onwards.
5014
+ *
5015
+ * This module is deliberately RAIL-AGNOSTIC. It is imported unchanged by:
5016
+ * - phase1-deposit.ts, where a seeded account plays the rail with a direct SPL transfer
5017
+ * - phase2-e2e.ts, where the rail stand-in delivers over HTTP
5018
+ * - phase3-e2e.ts, where a real Polygon fork drives the whole thing
5019
+ *
5020
+ * That import graph IS the proof of 11-E2E-PLAN.md Phase 2's pass criterion — "the client code
5021
+ * from Phase 1 runs unchanged against the stand-in" — enforced structurally rather than by
5022
+ * eyeballing two copies.
5023
+ *
5024
+ * It was NOT true when first written: phase1-deposit.ts kept its own inline copy, and so never
5025
+ * received the CLEANUP_FEE_BUDGET fix that landed here and in funder.ts. A reviewer caught both
5026
+ * the stale copy and the false claim. Keep every phase importing this file; do not fork it.
5027
+ */
5028
+
5029
+ interface DepositOutcome {
5030
+ signature: string;
5031
+ noteIndex: number;
5032
+ amount: bigint;
5033
+ txSize: number;
5034
+ rBefore: number;
5035
+ rAfter: number;
5036
+ rentExempt: boolean;
5037
+ /** The proof's two input nullifiers (zero-value padding for a pure deposit, but each one is a
5038
+ * genuine Poseidon hash over a random salt — NOT the literal zero sentinel the program treats
5039
+ * as "no PDA needed". See phase4-adversarial.ts case (c). */
5040
+ inputNullifiers: bigint[];
5041
+ /** The three program accounts the funding seam read off the built tx, and what it sent each —
5042
+ * 0 if the account already held enough. Exposed so a caller can independently verify their
5043
+ * on-chain state afterward, including after a thrown error (see `DepositError` below). */
5044
+ fundedAccounts: {
5045
+ name: string;
5046
+ address: string;
5047
+ lamportsSent: number;
5048
+ }[];
5049
+ }
5050
+ /** Thrown by `depositFromDerivedKey` in place of a bare `Error` whenever the funding seam ran
5051
+ * before the failure, so a caller can see exactly what already landed on chain despite the
5052
+ * overall deposit failing. `fundedAccounts` / `measuredSize` are `undefined` only if the seam
5053
+ * never ran at all (failure before signTransaction was called). */
5054
+ declare class DepositError extends Error {
5055
+ readonly fundedAccounts: DepositOutcome["fundedAccounts"];
5056
+ readonly measuredTxSize: number;
5057
+ constructor(message: string, fundedAccounts: DepositOutcome["fundedAccounts"], measuredTxSize: number);
5058
+ }
5059
+ /**
5060
+ * Fund R minimally, then deposit with R as the only signer.
5061
+ *
5062
+ * The funding seam is the SDK's `signTransaction`: by the time it is called the proof and the
5063
+ * relay's risk quote both exist, so the three program accounts are READ OFF the built
5064
+ * transaction rather than re-derived, and cannot drift from what the program will touch.
5065
+ *
5066
+ * `grantOverride` replaces the computed grant (rent floor + deposit fee + cleanup fee) with an
5067
+ * arbitrary lamport amount. Only phase4-adversarial.ts case (a) passes it, to reproduce the
5068
+ * "funded R with just its fee, not its floor" mistake deliberately; every other caller omits it
5069
+ * and gets the same grant this function has always sent.
5070
+ */
5071
+ declare function depositFromDerivedKey(conn: Connection, R: Keypair, funder: Keypair, amount: bigint, log: ((s: string) => void) | undefined, grantOverride: number | undefined,
5072
+ /**
5073
+ * relayUrl, programId and mint are all REQUIRED — no default, for any of the three, on any
5074
+ * environment. They used to fall back to the module-level RELAY/PROGRAM/MINT constants above,
5075
+ * each evaluated once at import time, and that is exactly how a live mainnet deposit got built
5076
+ * against the local program id while the banner said api.cloak.ag: the default filled the hole
5077
+ * silently instead of the caller having to say so. There is nothing left to fall into.
5078
+ */
5079
+ opts: {
5080
+ relayUrl: string;
5081
+ programId: PublicKey;
5082
+ mint: PublicKey;
5083
+ noteSpendKey: Uint8Array;
5084
+ }): Promise<DepositOutcome>;
5085
+
5086
+ /**
5087
+ * Recover the receiving address's token-account rent, even when someone has dusted it.
5088
+ *
5089
+ * THE PROBLEM (found by testing, docs/11-E2E-PLAN.md Phase 4): the rail creates R's token account
5090
+ * and pays its 2,039,280 rent. After the deposit that account is empty and closing it returns the
5091
+ * rent TO THE USER. But SPL Token refuses to close a non-empty account, and dust below the
5092
+ * program's 1,000,000-base-unit deposit minimum cannot be swept by re-depositing it — the program
5093
+ * correctly rejects it with DepositTooSmall. So one base unit from anyone permanently strands
5094
+ * about forty cents of somebody else's money, for free.
5095
+ *
5096
+ * THE FIX, in two parts. Dust that arrives BEFORE the deposit is not a problem at all: the deposit
5097
+ * shields R's whole balance, so it goes into the pool with everything else. The griefing only bites
5098
+ * when dust lands AFTER the deposit, and then the honest answer is to leave it.
5099
+ *
5100
+ * WHY LEAVE IT — this reverses an earlier decision, deliberately. Sweeping the dust to the user's
5101
+ * own wallet publishes `R -> user` on a public ledger, and R has just deposited into the shielded
5102
+ * pool. Anyone can join those two facts and learn that this user made that deposit. That is the
5103
+ * precise inference the pool exists to prevent, and it is the same leak that funding R from the
5104
+ * user's wallet used to cause at the other end of the flow — moved to the end, not removed. It is
5105
+ * not worth about twenty-two cents of rent. Sweeping to Cloak instead is not an option either:
5106
+ * capturing user funds off-chain is an off-chain fee, which the team rule forbids.
5107
+ *
5108
+ * So the default is privacy-first: close when empty, and when dusted, leave the account open and
5109
+ * say so. `dustDestination` lets a caller sweep anyway, with the linkage stated in its doc comment.
5110
+ * Burning stays out: dust can be up to 999,999 base units, and destroying a dollar to recover
5111
+ * twenty-two cents is a worse outcome than the griefing it answers.
5112
+ */
5113
+
5114
+ interface CleanupResult {
5115
+ closed: boolean;
5116
+ dustSwept: bigint;
5117
+ rentReturned: number;
5118
+ destination: string | null;
5119
+ signature: string | null;
5120
+ note: string;
5121
+ }
5122
+ /**
5123
+ * @param dustDestination where post-deposit dust goes, if the caller wants it swept at all.
5124
+ * LEAVE IT UNDEFINED unless the user has been told the cost: any destination they control
5125
+ * publishes `R -> them` and deanonymises the deposit R just made. It is never Cloak's, because
5126
+ * capturing user funds off-chain would be an off-chain fee, which the team rule forbids.
5127
+ * Undefined means "close if empty, otherwise leave it alone and report it".
5128
+ * @param mint the shielded asset R was funded for. Defaults to mainnet USDC so a caller written
5129
+ * before this parameter existed keeps compiling and keeps recovering the same account it always
5130
+ * has; a bridge for any other asset MUST pass its own mint, since R's token account and the
5131
+ * dust sitting in it both belong to whatever mint the rail actually delivered, not to this
5132
+ * default.
5133
+ */
5134
+ declare function cleanupReceivingAddress(conn: Connection, R: Keypair, dustDestination?: PublicKey, mint?: PublicKey): Promise<CleanupResult>;
5135
+
5136
+ /**
5137
+ * Local deposit funder for the bridge testbed.
5138
+ *
5139
+ * The bridge pays a derived address R that arrives with zero SOL, and the deposit takes its
5140
+ * account rent from R (`transact_spl/mod.rs:92` passes `payer_info` into `create_nullifier_pdas`).
5141
+ * But `create_pda_account_safe` (`utils/pda.rs:30-61`) ADOPTS an already-funded, System-owned,
5142
+ * zero-data account and transfers only the shortfall — so the rent can be paid straight to the
5143
+ * three PDAs in an earlier transaction, and R never touches it.
5144
+ *
5145
+ * That split is the whole point. Lamports parked at the nullifier and risk-nonce PDAs are
5146
+ * unrecoverable by ANYONE (no instruction in the program closes them), so flooding this funder
5147
+ * burns Cloak's SOL and earns an attacker nothing. Sending the same total to R instead would put
5148
+ * all of it in an account the requester can sweep in one instruction.
5149
+ *
5150
+ * WHAT SURVIVED THE PORT: the rent constants, the funding-target derivation, and the live rent
5151
+ * read. Everything that SUBMITTED a transaction stayed behind in the prototype — see the note at
5152
+ * the bottom of this file. The production funder is the paymaster, and it runs on a server.
5153
+ */
5154
+
5155
+ /** Rent for a 0-byte System account. `utils/pda.rs:99` -> `minimum_balance(0)`. */
5156
+ declare const MAINNET_RENT_0 = 890880;
5157
+ /** Rent for a 1-byte account. `state/nullifier.rs:18` says `SIZE = 1`. */
5158
+ declare const MAINNET_RENT_1 = 897840;
5159
+ /**
5160
+ * R must be able to pay its own transaction fee. The SDK hard-codes
5161
+ * setComputeUnitPrice(100_000) over setComputeUnitLimit(1_200_000) with no caller lever
5162
+ * (`sdk/src/flows/transact.ts:2598-2599`), so a deposit that fits costs 5,000 + 120,000.
5163
+ * Funding R with the 20,000 an earlier draft assumed leaves it 105,000 short and every
5164
+ * deposit fails under load.
5165
+ */
5166
+ declare const FEE_BUDGET = 130000;
5167
+ /**
5168
+ * A SECOND fee, for the cleanup transaction in which R closes its own token account and the
5169
+ * rail-paid 2,039,280 goes back to the user.
5170
+ *
5171
+ * MEASURED 2026-09-05: without it the close is impossible. Solana checks the fee payer's
5172
+ * rent-exemption after deducting the fee and BEFORE executing, so an R funded to exactly the
5173
+ * floor fails with "insufficient funds for rent" — even though the very transaction being
5174
+ * rejected would have credited it 2,039,280. Budgeting only the deposit's fee strands the
5175
+ * largest recoverable line in the whole flow.
5176
+ */
5177
+ declare const CLEANUP_FEE_BUDGET = 5000;
5178
+ interface DepositRef {
5179
+ programId: PublicKey;
5180
+ mint: PublicKey;
5181
+ /** The two input nullifiers from the proof's public inputs. */
5182
+ nullifiers: [Uint8Array, Uint8Array];
5183
+ /** bind0 from the relay's signed risk quote; the risk-nonce PDA is derived from it. */
5184
+ bind0: Uint8Array;
5185
+ /** R — the derived receiving address that will sign the deposit. */
5186
+ depositor: PublicKey;
5187
+ }
5188
+ /** Mirrors relay `derive_addresses` (supplemental_alt.rs) and the program's own derivations. */
5189
+ declare function deriveFundingTargets(d: DepositRef): {
5190
+ pool: PublicKey;
5191
+ nullifier0: PublicKey;
5192
+ nullifier1: PublicKey;
5193
+ riskNonce: PublicKey;
5194
+ depositorAta: PublicKey;
5195
+ };
5196
+ interface RentRates {
5197
+ zero: number;
5198
+ one: number;
5199
+ }
5200
+ /** Read rent live. Never hard-code it: a local validator's rent sysvar is not authoritative. */
5201
+ declare function readRent(conn: Connection): Promise<RentRates>;
5202
+ interface FundingPlan {
5203
+ transfers: {
5204
+ to: PublicKey;
5205
+ lamports: number;
5206
+ why: string;
5207
+ }[];
5208
+ total: number;
5209
+ alreadyFunded: string[];
5210
+ rent: RentRates;
5211
+ warnings: string[];
5212
+ }
5213
+
5214
+ declare const ONECLICK_PUBKEY_B58 = "reYaWhvwu8Jzo3WUM3zhn6VrhuMEF4eADL17qtRVifc";
5215
+ /**
5216
+ * The exact string this rail signs over, exported so a second implementation can be checked against
5217
+ * it rather than reasoned about.
5218
+ *
5219
+ * A Rust twin of `stable()` has to reproduce JavaScript's key ordering and number formatting byte
5220
+ * for byte, and the two languages do not agree by default: `Object.keys().sort()` orders by UTF-16
5221
+ * code unit while Rust's `sort()` orders by UTF-8 byte. They coincide for ASCII and diverge above
5222
+ * it. This is the same class of bug as `canonicalJson` versus Rust's `keys.sort_unstable()` in the
5223
+ * relay-auth payload, and it fails in the worst direction: a verifier that rejects HONEST quotes
5224
+ * looks like a rail outage, and teaches whoever is on call to ignore it.
5225
+ *
5226
+ * So the cross-language test compares THIS string, not just the boolean verdict. Two verifiers can
5227
+ * agree on a signature by both being wrong in the same place; they cannot agree on the bytes by
5228
+ * accident.
5229
+ */
5230
+ declare function canonicalPayloadString(resp: any): string;
5231
+ declare function verifyQuoteSignature(resp: any): {
5232
+ valid: boolean;
5233
+ reason?: string;
5234
+ };
5235
+
5236
+ /**
5237
+ * Deciding whether a bridge deposit can be honoured — BEFORE the user sends anything.
5238
+ *
5239
+ * WHY THIS EXISTS. Shielding on arrival is mandatory, not a choice: a user who bridges and then
5240
+ * sweeps unshielded has manufactured exactly the `receiver -> them` link the whole design removes.
5241
+ * But "mandatory" moves every failure from the user's account to ours. If someone sends 3 USDC and
5242
+ * the paymaster fee leaves less than the program's 1,000,000-base-unit floor, the shield CANNOT
5243
+ * happen — and under a mandatory model that is the product breaking its own promise, with the money
5244
+ * stranded unshielded at an address the user has never heard of.
5245
+ *
5246
+ * So the check belongs at quote time. The rule is the one the rail-signature check already
5247
+ * established: NEVER SHOW AN ADDRESS YOU CANNOT HONOUR. An unviable deposit is refused before the
5248
+ * deposit address is displayed, not diagnosed after the money has landed.
5249
+ *
5250
+ * All figures are worst-case, taken from the rail's guaranteed floor (`minAmountOut`), never its
5251
+ * target. A quote that only works at the target is a quote that fails on a bad day.
5252
+ */
5253
+ /** programs/shield-pool/src/constants.rs:126 — enforced at transact_spl/deposit.rs:69. */
5254
+ declare const MIN_DEPOSIT_SPL_BASE_UNITS = 1000000n;
5255
+ /**
5256
+ * Live mainnet USDC PoolConfig at deploy time: a flat fee plus a proportional part, charged on
5257
+ * WITHDRAWAL. These are the program's DEFAULTS, not a live read — quote.ts has no RPC client, so it
5258
+ * cannot see a PoolConfig an admin has since changed. Treat this pair as a fallback only: it is
5259
+ * shown to a user as what it will cost to get their money out, and if the live config has moved,
5260
+ * this UNDERSTATES that cost. A caller that has already fetched PoolConfig should pass the real
5261
+ * figures through `BridgeQuoteInput.liveWithdrawFixedFee` / `liveWithdrawFeeBps` instead.
5262
+ */
5263
+ declare const WITHDRAW_FIXED_FEE = 450000n;
5264
+ declare const WITHDRAW_FEE_BPS = 30n;
5265
+ /**
5266
+ * Below this, the fixed costs dominate: a deposit works, but most of it goes to fees.
5267
+ *
5268
+ * It is ADVISORY. `viable` is the hard gate; this only warns and asks for a second confirmation,
5269
+ * because it is the user's money and their call.
5270
+ *
5271
+ * WAS 20 USDC, derived from a 1.21 round trip when the paymaster charged $0.458 for something that
5272
+ * cost it $0.104. Fixed pricing took that to $0.150 on 2026-09-07 (docs/17-PAYMASTER-ECONOMICS.md),
5273
+ * the round trip fell to ~0.90, and leaving the constant alone would have warned people off
5274
+ * deposits that had become perfectly reasonable. If the paymaster fee moves again, recompute
5275
+ * FIXED_ROUND_TRIP rather than editing this number.
5276
+ *
5277
+ * 0.903 / a + 0.003 = 0.063 -> a = 15.05
5278
+ */
5279
+ declare const ECONOMIC_MINIMUM: bigint;
5280
+ interface BridgeQuoteInput {
5281
+ /** What the user sends on the origin chain, in the destination asset's base units. */
5282
+ sent: bigint;
5283
+ /** The rail's GUARANTEED floor. Assess against this, never `amountOut`. */
5284
+ arrivesMin: bigint;
5285
+ /** The rail's target, for display only. */
5286
+ arrivesTarget: bigint;
5287
+ /** What the paymaster will charge to fund the receiver, buffered, in the same units. */
5288
+ paymasterFee: bigint;
5289
+ /**
5290
+ * Live PoolConfig withdraw-fee figures, when the caller has already fetched them on-chain.
5291
+ * Optional: omitting either falls back to the compile-time WITHDRAW_FIXED_FEE / WITHDRAW_FEE_BPS
5292
+ * constants above, which can be stale. quote.ts never fetches these itself — no RPC call belongs
5293
+ * in a pure quote assessment — so the live figures can only arrive this way.
5294
+ */
5295
+ liveWithdrawFixedFee?: bigint;
5296
+ liveWithdrawFeeBps?: bigint;
5297
+ }
5298
+ interface BridgeQuoteAssessment extends BridgeQuoteInput {
5299
+ /** What actually lands shielded, worst case. This is the number to show the user. */
5300
+ shieldedMin: bigint;
5301
+ shieldedTarget: bigint;
5302
+ /** False means REFUSE: the shield is impossible, so the deposit must not be offered. */
5303
+ viable: boolean;
5304
+ /** False means warn: it will work, but the fixed costs dominate. */
5305
+ economic: boolean;
5306
+ /** What it would cost to take it out again, so "shielded" is not mistaken for "free to exit". */
5307
+ withdrawFee: bigint;
5308
+ /** Origin-to-recipient loss if they shielded and immediately withdrew, worst case. */
5309
+ roundTripCost: bigint;
5310
+ roundTripFraction: number;
5311
+ /** Human-readable, ordered most important first. Empty when everything is fine. */
5312
+ reasons: string[];
5313
+ }
5314
+ declare function withdrawFeeFor(amount: bigint): bigint;
5315
+ declare function assessBridgeQuote(q: BridgeQuoteInput): BridgeQuoteAssessment;
5316
+ /** The quote screen, as the user must see it BEFORE any address is shown. */
5317
+ declare function renderAssessment(a: BridgeQuoteAssessment): string;
5318
+
5319
+ /**
5320
+ * Deciding whether a failed shield attempt may be retried.
5321
+ *
5322
+ * This is the most dangerous decision in the flow and the least observable, because it only runs
5323
+ * when something has already gone wrong. Getting it wrong in either direction costs money:
5324
+ *
5325
+ * retry when the deposit actually landed -> a second proof and a second deposit fee, for a
5326
+ * deposit that already happened
5327
+ * refuse when it did not land -> the user is told their funds are unshielded and has
5328
+ * to re-run, which costs a re-run and nothing else
5329
+ *
5330
+ * The asymmetry is the whole design: an unnecessary stop is cheap, a wrongful retry is not. So
5331
+ * anything the evidence cannot explain resolves to "do not retry".
5332
+ *
5333
+ * It lives in the SDK rather than in a CLI script because the shield service will need exactly this
5334
+ * decision, and a second implementation of it would be a second way to lose track of the same money.
5335
+ * It is pure — no chain, no clock — so it can be tested exhaustively, which the CLI version never was.
5336
+ */
5337
+ /**
5338
+ * Failures where retrying only burns another proof: the deposit cannot succeed as constructed, so
5339
+ * a second attempt fails identically and costs another fee to find out.
5340
+ */
5341
+ declare const TERMINAL_FAILURE: RegExp;
5342
+ declare function isTerminalFailure(message: string): boolean;
5343
+ type PostFailureVerdict =
5344
+ /** The receiver's tokens are gone: the deposit transaction landed despite the error. */
5345
+ "landed"
5346
+ /** The balance is untouched: the deposit demonstrably did not consume it. Safe to retry. */
5347
+ | "did-not-land"
5348
+ /** The balance moved by an amount nothing here explains, or could not be read at all. */
5349
+ | "unknown";
5350
+ /**
5351
+ * What the receiver's token balance says about a deposit attempt that threw.
5352
+ *
5353
+ * The deposit transaction moves the receiver's ENTIRE `attempted` balance atomically with the rest
5354
+ * of its instructions, so the balance is a reliable witness: drained to zero means it landed,
5355
+ * unchanged means it did not. Anything else — a partial move, a fresh delivery mid-flight, an
5356
+ * unreadable account — is not something this can interpret, and guessing is exactly the mistake
5357
+ * this function exists to prevent.
5358
+ *
5359
+ * @param attempted what the receiver held when the attempt started
5360
+ * @param after what it holds now, or null if the balance could not be read
5361
+ */
5362
+ declare function classifyPostFailure(attempted: bigint, after: bigint | null): PostFailureVerdict;
5363
+ /** Whether the loop may go again, given what the evidence says. */
5364
+ declare function mayRetry(verdict: PostFailureVerdict, message: string): boolean;
5365
+ /** Linear backoff. Deliberately not exponential: the failures seen here are relay and blockhash
5366
+ * timing, which clear in seconds, and a long tail just strands the user watching a terminal. */
5367
+ declare function retryDelayMs(attempt: number): number;
5368
+ /** Raised in place of the underlying error when the evidence says the deposit landed, or says
5369
+ * nothing this can interpret. The loop stops on it without claiming the funds are unshielded. */
5370
+ declare class DoNotRetry extends Error {
5371
+ constructor(message: string);
5372
+ }
5373
+ interface RetryHooks {
5374
+ /** Called before each wait, so a CLI can say what it is doing and a service can log it. */
5375
+ onRetry?: (attempt: number, delayMs: number, lastError: string) => void;
5376
+ /** Injectable so tests do not actually wait, and a service can use its own scheduler. */
5377
+ sleep?: (ms: number) => Promise<void>;
5378
+ attempts?: number;
5379
+ }
5380
+ /**
5381
+ * Run `attempt` until it succeeds or the evidence says stop.
5382
+ *
5383
+ * The loop is separated from what it runs so it can be tested against injected failures. Its
5384
+ * previous form lived inside a CLI script wired to mainnet constants, which meant the only way to
5385
+ * exercise it was to cause a real failure during a real deposit — so it never was exercised, across
5386
+ * two rounds of changes to it.
5387
+ *
5388
+ * `attempt` is expected to throw `DoNotRetry` when it has already checked chain state and found the
5389
+ * deposit landed, or found something it cannot explain. Everything else is judged by
5390
+ * `isTerminalFailure`.
5391
+ */
5392
+ declare function withShieldRetries<T>(attempt: (attemptNo: number) => Promise<T>, hooks?: RetryHooks): Promise<T>;
5393
+
4671
5394
  /**
4672
5395
  * Cloak SDK - TypeScript SDK for Private Transactions on Solana
4673
5396
  *
4674
5397
  * @packageDocumentation
4675
5398
  */
4676
5399
 
4677
- declare const VERSION = "0.2.1";
5400
+ declare const VERSION = "0.2.3";
4678
5401
  /** True when scanner supports TransactSwap (tag 1). Check this to verify the correct SDK bundle is loaded. */
4679
5402
  declare const SCANNER_SUPPORTS_TRANSACT_SWAP = true;
4680
5403
 
4681
- export { BUILD_ALLOWS_LOCAL_ENDPOINTS, type BuildRecipientDeliveryNotesParams, CHAIN_NOTE_SALT_BITS, CLOAK_PRODUCTION_RELAY_URL, CLOAK_PROGRAM_ID, type ChainNoteTxType, type CircuitVerificationResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, type CommitmentEntry, type CommitmentsResponse, type CompactChainNote, type ComplianceReport, type ComplianceTxType, type ConfirmSettlementParams, DEFAULT_CIRCUITS_URL, DEFAULT_TRANSACTION_CIRCUITS_URL, DELIVERY_MEMO_TAG, DELIVERY_REGISTRY_SEED, type DeliveredNote, type DepositInstructionParams, type DepositNoteSecrets, type DepositOptions, type DepositResult, type DepositStatus, type DiscoverSwapRefundsOptions, type DiscoveredSwapRefund, EXPECTED_CIRCUIT_HASHES, type EncryptedMetadataBundle, type EncryptedNote$1 as EncryptedNote, type ErrorCategory, type ExpandedSpendKey, type ExternalFeePayerAdapter, FIXED_FEE_LAMPORTS, type Groth16Proof, InsecureRandomnessError, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, MERKLE_TREE_HEIGHT, MIN_DEPOSIT_LAMPORTS, type MasterKey, type MatchChangeNoteParams, type MatchDepositNoteParams, type MatchSwapRefundLeafParams, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, MerkleTree, NATIVE_SOL_MINT, type Network, type NoteData, type OnchainMerkleProof, type ParsedDeliveryCarrier, type PendingDeposit, type PendingWithdrawal, RECIPIENT_DELIVERY_CIPHERTEXT_LEN, RECIPIENT_DELIVERY_EPHEMERAL_PK_LEN, RECIPIENT_DELIVERY_NONCE_LEN, RECIPIENT_DELIVERY_NOTE_BYTES, RECIPIENT_DELIVERY_PLAINTEXT_LEN, RECIPIENT_DELIVERY_TAG_LEN, RELAY_ORIGIN_ALLOWLIST, REQUEST_AUTH_MAX_AGE_SECONDS, REQUEST_AUTH_MAX_FUTURE_SKEW_SECONDS, type RecipientDeliveryNote, type RecoveredChangeNote, type RecoveredChangeNoteRecord, type RecoveredDepositNote, type RecoveredDepositNoteRecord, type RecoveredSwapRefund, type RelayAuthPreimage, type RelayAuthSigner, RelayInternalError, RelayService, type RelaySubmissionResult, type RiskQuoteInstructionResponse, RootNotFoundError, SCANNER_SUPPORTS_TRANSACT_SWAP, SIGN_IN_MESSAGE, SanctionsQuoteError, type ScanOptions, type ScanRecipientDeliveryOptions, type ScanResult, type ScanSummary, type ScannedTransaction, type SettlementConnection, type SettlementContext, type SettlementStatus, type SettlementVerdict, SettlementVerificationError, ShieldPoolErrors, type ShieldPoolPDAs, SimpleWallet, type SpendKey, type StorageAdapter, type SubmitTransactToRelayArgs, type SwapOptions, type SwapParams, type SwapRefundAuthorization, type SwapResult, TRANSACTION_CIRCUITS_VERSION, TRANSACT_AUTH_FIELDS, TRANSACT_SWAP_AUTH_FIELDS, type TransactOptions, type TransactParams, type TransactRequestBodyParams, type TransactResult, type TransactionMetadata, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, type Utxo, UtxoAlreadySpentError, type EncryptedNote as UtxoEncryptedNote, type UtxoKeypair, type UtxoSwapParams, type UtxoSwapResult, UtxoWallet, VARIABLE_FEE_DENOMINATOR, VARIABLE_FEE_NUMERATOR, VARIABLE_FEE_RATE, VERSION, type VerifyUtxosResult, type ViewKey, type ViewingKeyPair, type WalletAdapter, type WalletUtxo, type WithdrawOptions, type WithdrawSubmissionResult, assertDirectSubmissionLanded, assertTransactionCircuitIntegrity, bigintToBytes32$1 as bigintToBytes32, bigintToHex, buildMerkleTree, buildMerkleTreeFromChain, buildMerkleTreeFromRelay, buildRecipientDeliveryNotes, buildRelayAuthPreimage, buildTransactRequestBody, bytesToHex, calculateFee, calculateFeeBigint, calculateRelayFee, canRebuildMerkleTreeFromChain, canonicalJson, chainNoteFromBase64, chainNoteToBase64, classifyRelayError, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, computeChainNoteHash, computeExtDataHash, computeMerkleRoot, computeProofForLatestDeposit, computeProofFromChain, computeSignature, computeSwapRefundCommitment, computeCommitment as computeUtxoCommitment, computeNullifier as computeUtxoNullifier, confirmTransactSettlement, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, createRecoverableChangeUtxo, createRecoverableDepositUtxo, createUtxo, createZeroUtxo, decryptCompactChainNote, decryptComplianceMetadataWithMasterKey, decryptTransactionMetadata, deriveChangeNoteBlinding, deriveDepositNoteSecrets, deriveDiversifiedViewingKey, deriveDiversifier, deriveInputNullifierPdas, derivePublicKey, deriveSpendKey, deriveSwapRefundAuthorization, deriveUserCompliancePublicKey, deriveUserComplianceScalar, deriveUtxoKeypairFromSpendKey, deriveViewKey, deriveViewingKeyFromNk, deriveViewingKeyFromSpendKey, deriveViewingKeyFromUtxoPrivateKey, deserializeUtxo, detectNetworkFromRpcUrl, discoverSwapRefunds, downloadNote, encodeDeliveryCarrierMemo, encodeNoteSimple, encodeRecipientDeliveryNote, encryptCompactChainNote, encryptNoteForRecipient, encryptTransactionMetadata, encryptTransactionMetadataBundle, expandSpendKey, explainRelayAuthRejection, exportKeys, exportNote, exportWalletKeys, fetchCommitments, fetchRiskQuoteInstruction, fetchRiskQuoteIx, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatComplianceCsv, formatErrorForLogging, formatSol, fullWithdraw, generateCloakKeys, generateCommitmentAsync, generateMasterSeed, generateNoteFromWallet, generateUtxoKeypair, generateViewingKeyPair, getAddressExplorerUrl, getChainNoteRegistryPDA, getCircuitsPath, getDeliveryRegistryPDA, getDistributableAmount, getExplorerUrl, getNkFromUtxoPrivateKey, getNullifierPDA, getPendingOperationsSummary, getPoolAuthorityConfigPDA, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, getViewKey, hasPendingOperations, hexToBigint$1 as hexToBigint, hexToBytes, importKeys, importWalletKeys, isBrowser, isBrowserLike, isDebugEnabled, isPlausibleSignature, isReactNative, isRootNotFoundError, isSubmissionOutcomeUnknownResponse, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawAmountSufficient, isWithdrawable, keypairToAdapter, loadPendingDeposits, loadPendingWithdrawals, loadVerifiedCircuitArtifacts, matchChangeNote, matchDepositNote, matchSwapRefundLeaf, openRecipientDeliveryNote, parseAmount, parseDeliveryCarrierMemo, parseError, parseNote, parseRelayErrorResponse, parseRelayErrorSignature, parseTransactionError, partialWithdraw, poseidonHash, preflightCheck, preflightNullifiers, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToFieldElement, pubkeyToLimbs, randomBytes, randomChangeNoteSalt, randomDepositNoteSalt, randomFieldElement, readMerkleTreeState, recipientDeliveryNoteToBase64, registerViewingKey, removePendingDeposit, removePendingWithdrawal, resolveCircuitsBase, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, scanRecipientDeliveryNotes, scanTransactions, sdkLogger, selectUtxos, sendTransaction, serializeNote, serializeUtxo, setCircuitsPath, setDebugMode, signTransaction, splitTo2Limbs, submitTransactToRelay, sumUtxoAmounts, swapUtxo, swapWithChange, toComplianceReport, transact, transfer, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, bigintToBytes32 as utxoBigintToBytes32, utxoEquals, hexToBigint as utxoHexToBigint, validateDepositParams, validateNote, validateOutputsSum, validateRoot, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, verifyUtxos, waitForRoot, withTiming };
5404
+ export { BRIDGE_ESCROW_LABEL, BUILD_ALLOWS_LOCAL_ENDPOINTS, type BridgeDeliveryState, type BridgeDeposit, type BridgeDepositState, type BridgeQuoteAssessment, type BridgeQuoteInput, type BridgeRail, type BridgeRailAttestation, type BridgeRailProblem, type BridgeRailQuoteOption, type BridgeRailQuoteRequest, type BridgeRailQuoteResponse, type BridgeRailStatusResult, type BuildRecipientDeliveryNotesParams, CHAIN_NOTE_SALT_BITS, CLEANUP_FEE_BUDGET, CLOAK_PRODUCTION_RELAY_URL, CLOAK_PROGRAM_ID, type ChainNoteTxType, type CircuitVerificationResult, type CleanupResult, type CloakConfig, CloakError, type CloakKeyPair, type CloakNote, type CommitmentEntry, type CommitmentsResponse, type CompactChainNote, type ComplianceReport, type ComplianceTxType, type ConfirmSettlementParams, DEFAULT_CIRCUITS_URL, DEFAULT_TRANSACTION_CIRCUITS_URL, DELIVERY_MEMO_TAG, DELIVERY_REGISTRY_SEED, type DeliveredNote, DepositError, type DepositInstructionParams, type DepositNoteSecrets, type DepositOptions, type DepositOutcome, type DepositRef, type DepositResult, type DepositStatus, type DiscoverOptions, type DiscoverSwapRefundsOptions, type DiscoveredSwapRefund, DoNotRetry, ECONOMIC_MINIMUM, EXPECTED_CIRCUIT_HASHES, type EncryptedMetadataBundle, type EncryptedNote$1 as EncryptedNote, type ErrorCategory, type ExpandedSpendKey, type ExternalFeePayerAdapter, FEE_BUDGET, FIXED_FEE_LAMPORTS, type FundingPlan, type Groth16Proof, InsecureRandomnessError, LAMPORTS_PER_SOL, LocalStorageAdapter, type LogLevel, type Logger, MAINNET_RENT_0, MAINNET_RENT_1, MAX_RECEIVER_INDEX, MERKLE_TREE_HEIGHT, MIN_DEPOSIT_LAMPORTS, MIN_DEPOSIT_SPL_BASE_UNITS, type MasterKey, type MatchChangeNoteParams, type MatchDepositNoteParams, type MatchSwapRefundLeafParams, type MaxLengthArray, MemoryStorageAdapter, type MerkleProof, type MerkleRootResponse, MerkleTree, NATIVE_SOL_MINT, type Network, type NoteData, ONECLICK_PUBKEY_B58, type OnchainMerkleProof, type ParsedDeliveryCarrier, type PaymasterTopUpExpectation, type PaymasterTopUpResult, type PendingDeposit, type PendingWithdrawal, type PostFailureVerdict, RECIPIENT_DELIVERY_CIPHERTEXT_LEN, RECIPIENT_DELIVERY_EPHEMERAL_PK_LEN, RECIPIENT_DELIVERY_NONCE_LEN, RECIPIENT_DELIVERY_NOTE_BYTES, RECIPIENT_DELIVERY_PLAINTEXT_LEN, RECIPIENT_DELIVERY_TAG_LEN, RELAY_ORIGIN_ALLOWLIST, REQUEST_AUTH_MAX_AGE_SECONDS, REQUEST_AUTH_MAX_FUTURE_SKEW_SECONDS, type RecipientDeliveryNote, type RecoveredChangeNote, type RecoveredChangeNoteRecord, type RecoveredDepositNote, type RecoveredDepositNoteRecord, type RecoveredSwapRefund, type RelayAuthPreimage, type RelayAuthSigner, RelayInternalError, RelayService, type RelaySubmissionResult, type RentRates, type RetryHooks, type RiskQuoteInstructionResponse, RootNotFoundError, SCANNER_SUPPORTS_TRANSACT_SWAP, SIGN_IN_MESSAGE, SanctionsQuoteError, type ScanOptions, type ScanRecipientDeliveryOptions, type ScanResult, type ScanSummary, type ScannedTransaction, type SettlementConnection, type SettlementContext, type SettlementStatus, type SettlementVerdict, SettlementVerificationError, ShieldPoolErrors, type ShieldPoolPDAs, SimpleWallet, type SpendKey, type StorageAdapter, type SubmitTransactToRelayArgs, type SwapOptions, type SwapParams, type SwapRefundAuthorization, type SwapResult, TERMINAL_FAILURE, TRANSACTION_CIRCUITS_VERSION, TRANSACT_AUTH_FIELDS, TRANSACT_SWAP_AUTH_FIELDS, type TransactOptions, type TransactParams, type TransactRequestBodyParams, type TransactResult, type TransactionMetadata, type Transfer, type TransferOptions, type TransferResult, type TxStatus, type UserFriendlyError, type Utxo, UtxoAlreadySpentError, type EncryptedNote as UtxoEncryptedNote, type UtxoKeypair, type UtxoSwapParams, type UtxoSwapResult, UtxoWallet, VARIABLE_FEE_DENOMINATOR, VARIABLE_FEE_NUMERATOR, VARIABLE_FEE_RATE, VERSION, type VerifyUtxosResult, type ViewKey, type ViewingKeyPair, WITHDRAW_FEE_BPS, WITHDRAW_FIXED_FEE, type WalletAdapter, type WalletUtxo, type WithdrawOptions, type WithdrawSubmissionResult, assertDirectSubmissionLanded, assertInputMints, assertTransactionCircuitIntegrity, assessBridgeQuote, bigintToBytes32$1 as bigintToBytes32, bigintToHex, buildMerkleTree, buildMerkleTreeFromChain, buildMerkleTreeFromRelay, buildRecipientDeliveryNotes, buildRelayAuthPreimage, buildTransactRequestBody, bytesToHex, calculateFee, calculateFeeBigint, calculateRelayFee, canRebuildMerkleTreeFromChain, canonicalJson, canonicalPayloadString, chainNoteFromBase64, chainNoteToBase64, classifyPostFailure, classifyRelayError, cleanupReceivingAddress, cleanupStalePendingOperations, clearPendingDeposits, clearPendingWithdrawals, cloakBridgeRail, computeChainNoteHash, computeExtDataHash, computeMerkleRoot, computeProofForLatestDeposit, computeProofFromChain, computeSignature, computeSwapRefundCommitment, computeCommitment as computeUtxoCommitment, computeNullifier as computeUtxoNullifier, confirmTransactSettlement, copyNoteToClipboard, createCloakError, createDepositInstruction, createLogger, createRecoverableChangeUtxo, createRecoverableDepositUtxo, createUtxo, createZeroUtxo, decryptCompactChainNote, decryptComplianceMetadataWithMasterKey, decryptTransactionMetadata, depositFromDerivedKey, deriveBridgeReceiver, deriveChangeNoteBlinding, deriveDepositNoteSecrets, deriveDiversifiedViewingKey, deriveDiversifier, deriveFundingTargets, deriveInputNullifierPdas, derivePublicKey, deriveSpendKey, deriveSwapRefundAuthorization, deriveUserCompliancePublicKey, deriveUserComplianceScalar, deriveUtxoKeypairFromSpendKey, deriveViewKey, deriveViewingKeyFromNk, deriveViewingKeyFromSpendKey, deriveViewingKeyFromUtxoPrivateKey, deserializeUtxo, detectNetworkFromRpcUrl, discoverSwapRefunds, downloadNote, encodeDeliveryCarrierMemo, encodeNoteSimple, encodeRecipientDeliveryNote, encryptCompactChainNote, encryptNoteForRecipient, encryptTransactionMetadata, encryptTransactionMetadataBundle, expandSpendKey, explainRelayAuthRejection, exportKeys, exportNote, exportWalletKeys, fetchCommitments, fetchRiskQuoteInstruction, fetchRiskQuoteIx, filterNotesByNetwork, filterWithdrawableNotes, findNoteByCommitment, formatAmount, formatComplianceCsv, formatErrorForLogging, formatSol, fullWithdraw, fundReceiverViaPaymaster, generateCloakKeys, generateCommitmentAsync, generateMasterSeed, generateNoteFromWallet, generateUtxoKeypair, generateViewingKeyPair, getAddressExplorerUrl, getChainNoteRegistryPDA, getCircuitsPath, getDeliveryRegistryPDA, getDistributableAmount, getExplorerUrl, getNkFromUtxoPrivateKey, getNullifierPDA, getPendingOperationsSummary, getPoolAuthorityConfigPDA, getPublicKey, getPublicViewKey, getRecipientAmount, getRpcUrlForNetwork, getShieldPoolPDAs, getSwapStatePDA, getViewKey, hasPendingOperations, hexToBigint$1 as hexToBigint, hexToBytes, importKeys, importWalletKeys, isBrowser, isBrowserLike, isDebugEnabled, isPlausibleSignature, isReactNative, isRootNotFoundError, isSubmissionOutcomeUnknownResponse, isTerminalFailure, isValidHex, isValidRpcUrl, isValidSolanaAddress, isWithdrawAmountSufficient, isWithdrawable, keypairToAdapter, listBridgeDeposits, loadPendingDeposits, loadPendingWithdrawals, loadVerifiedCircuitArtifacts, matchChangeNote, matchDepositNote, matchSwapRefundLeaf, mayRetry, openRecipientDeliveryNote, parseAmount, parseDeliveryCarrierMemo, parseError, parseNote, parseRelayErrorResponse, parseRelayErrorSignature, parseTransactionError, partialWithdraw, poseidonHash, preflightCheck, preflightNullifiers, prepareEncryptedOutput, prepareEncryptedOutputForRecipient, proofToBytes, pubkeyToFieldElement, pubkeyToLimbs, randomBytes, randomChangeNoteSalt, randomDepositNoteSalt, randomFieldElement, readMerkleTreeState, readRent, recipientDeliveryNoteToBase64, registerViewingKey, removePendingDeposit, removePendingWithdrawal, renderAssessment, resolveCircuitsBase, retryDelayMs, savePendingDeposit, savePendingWithdrawal, scanNotesForWallet, scanRecipientDeliveryNotes, scanTransactions, sdkLogger, selectUtxos, sendTransaction, serializeNote, serializeUtxo, setCircuitsPath, setDebugMode, signTransaction, splitTo2Limbs, submitTransactToRelay, sumUtxoAmounts, swapUtxo, swapWithChange, toComplianceReport, transact, transfer, truncate, tryDecryptNote, updateNoteWithDeposit, updatePendingDeposit, updatePendingWithdrawal, bigintToBytes32 as utxoBigintToBytes32, utxoEquals, hexToBigint as utxoHexToBigint, validateDepositParams, validateNote, validateOutputsSum, validatePaymasterTopUpTransaction, validateRoot, validateTransfers, validateWalletConnected, validateWithdrawableNote, verifyAllCircuits, verifyCircuitIntegrity, verifyQuoteSignature, verifyUtxos, waitForRoot, withShieldRetries, withTiming, withdrawFeeFor };