@dexterai/x402 5.4.0 → 5.4.2

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.
@@ -0,0 +1,70 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { SessionScope, SessionKey, VoucherPayload, SignedVoucher, AtomicAmount } from '@dexterai/vault/types';
3
+
4
+ /**
5
+ * Session-key lifecycle: generation, voucher signing, in-memory hygiene.
6
+ *
7
+ * A session key is an ed25519 keypair generated in process memory at tab
8
+ * open. The buyer's passkey signs a 180-byte registration message endorsing
9
+ * the session pubkey within a scope (counterparty, max amount, expiry).
10
+ * From that point until tab close, the session key signs every voucher; the
11
+ * passkey is never invoked again for the lifetime of the tab.
12
+ *
13
+ * The session keypair is NEVER persisted to disk. A crashed process
14
+ * forfeits the session; the buyer re-prompts the passkey on the next
15
+ * attempt. This is the right default — a session key on disk is a real
16
+ * attack surface, the cost of re-authorizing is a single prompt.
17
+ *
18
+ * Curve choice: ed25519. It's Solana's native signer, every Solana RPC and
19
+ * wallet knows how to verify it, and `tweetnacl` (already a SDK dep) gives
20
+ * us a deterministic implementation that doesn't pull in heavy crypto.
21
+ */
22
+
23
+ /**
24
+ * Generate a fresh ed25519 keypair to act as the session signer. The
25
+ * caller is responsible for getting this keypair endorsed by a passkey via
26
+ * `register_session_key` before any voucher signed with it is acceptable
27
+ * to a seller.
28
+ */
29
+ declare function generateSessionKeypair(): {
30
+ publicKey: Uint8Array;
31
+ privateKey: Uint8Array;
32
+ };
33
+ /**
34
+ * Construct a complete `SessionKey` once the passkey has produced the
35
+ * registration signature for it. The registration bytes are what the
36
+ * seller verifies the signed voucher against; without them the session
37
+ * keypair is just an unauthorized ed25519 pair.
38
+ */
39
+ declare function makeSessionKey(keypair: {
40
+ publicKey: Uint8Array;
41
+ privateKey: Uint8Array;
42
+ }, scope: SessionScope, registration: Uint8Array): SessionKey;
43
+ /**
44
+ * Sign a voucher payload with a session keypair. Returns a `SignedVoucher`
45
+ * the seller can verify locally:
46
+ * 1. sessionSignature is valid for sessionPublicKey over the payload bytes
47
+ * 2. sessionRegistration is the passkey-endorsed scope for sessionPublicKey
48
+ * 3. payload.cumulativeAmount <= scope.maxAmountAtomic
49
+ * 4. now < scope.expiresAtUnix
50
+ * 5. counterparty matches scope.allowedCounterparty
51
+ *
52
+ * This function does NOT enforce scope locally — that's the seller's job —
53
+ * but it does throw on the cap and expiry checks as a defensive client-side
54
+ * guard so a misbehaving caller can't sign vouchers the seller will reject.
55
+ */
56
+ declare function signVoucher(session: SessionKey, payload: VoucherPayload, channelIdBytes: Uint8Array): SignedVoucher;
57
+ /**
58
+ * Convert a `SessionScope` (which uses string AtomicAmount for JSON
59
+ * portability) to the bigint cap actually needed for signing. Throws on
60
+ * malformed input.
61
+ */
62
+ declare function scopeCapAtomic(scope: SessionScope): bigint;
63
+ declare function parseAtomic(s: AtomicAmount): bigint;
64
+ declare function deriveChannelId(args: {
65
+ vaultPda: PublicKey;
66
+ sellerUrl: string;
67
+ nonce: bigint;
68
+ }): Uint8Array;
69
+
70
+ export { scopeCapAtomic as a, deriveChannelId as d, generateSessionKeypair as g, makeSessionKey as m, parseAtomic as p, signVoucher as s };
@@ -0,0 +1,70 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { SessionScope, SessionKey, VoucherPayload, SignedVoucher, AtomicAmount } from '@dexterai/vault/types';
3
+
4
+ /**
5
+ * Session-key lifecycle: generation, voucher signing, in-memory hygiene.
6
+ *
7
+ * A session key is an ed25519 keypair generated in process memory at tab
8
+ * open. The buyer's passkey signs a 180-byte registration message endorsing
9
+ * the session pubkey within a scope (counterparty, max amount, expiry).
10
+ * From that point until tab close, the session key signs every voucher; the
11
+ * passkey is never invoked again for the lifetime of the tab.
12
+ *
13
+ * The session keypair is NEVER persisted to disk. A crashed process
14
+ * forfeits the session; the buyer re-prompts the passkey on the next
15
+ * attempt. This is the right default — a session key on disk is a real
16
+ * attack surface, the cost of re-authorizing is a single prompt.
17
+ *
18
+ * Curve choice: ed25519. It's Solana's native signer, every Solana RPC and
19
+ * wallet knows how to verify it, and `tweetnacl` (already a SDK dep) gives
20
+ * us a deterministic implementation that doesn't pull in heavy crypto.
21
+ */
22
+
23
+ /**
24
+ * Generate a fresh ed25519 keypair to act as the session signer. The
25
+ * caller is responsible for getting this keypair endorsed by a passkey via
26
+ * `register_session_key` before any voucher signed with it is acceptable
27
+ * to a seller.
28
+ */
29
+ declare function generateSessionKeypair(): {
30
+ publicKey: Uint8Array;
31
+ privateKey: Uint8Array;
32
+ };
33
+ /**
34
+ * Construct a complete `SessionKey` once the passkey has produced the
35
+ * registration signature for it. The registration bytes are what the
36
+ * seller verifies the signed voucher against; without them the session
37
+ * keypair is just an unauthorized ed25519 pair.
38
+ */
39
+ declare function makeSessionKey(keypair: {
40
+ publicKey: Uint8Array;
41
+ privateKey: Uint8Array;
42
+ }, scope: SessionScope, registration: Uint8Array): SessionKey;
43
+ /**
44
+ * Sign a voucher payload with a session keypair. Returns a `SignedVoucher`
45
+ * the seller can verify locally:
46
+ * 1. sessionSignature is valid for sessionPublicKey over the payload bytes
47
+ * 2. sessionRegistration is the passkey-endorsed scope for sessionPublicKey
48
+ * 3. payload.cumulativeAmount <= scope.maxAmountAtomic
49
+ * 4. now < scope.expiresAtUnix
50
+ * 5. counterparty matches scope.allowedCounterparty
51
+ *
52
+ * This function does NOT enforce scope locally — that's the seller's job —
53
+ * but it does throw on the cap and expiry checks as a defensive client-side
54
+ * guard so a misbehaving caller can't sign vouchers the seller will reject.
55
+ */
56
+ declare function signVoucher(session: SessionKey, payload: VoucherPayload, channelIdBytes: Uint8Array): SignedVoucher;
57
+ /**
58
+ * Convert a `SessionScope` (which uses string AtomicAmount for JSON
59
+ * portability) to the bigint cap actually needed for signing. Throws on
60
+ * malformed input.
61
+ */
62
+ declare function scopeCapAtomic(scope: SessionScope): bigint;
63
+ declare function parseAtomic(s: AtomicAmount): bigint;
64
+ declare function deriveChannelId(args: {
65
+ vaultPda: PublicKey;
66
+ sellerUrl: string;
67
+ nonce: bigint;
68
+ }): Uint8Array;
69
+
70
+ export { scopeCapAtomic as a, deriveChannelId as d, generateSessionKeypair as g, makeSessionKey as m, parseAtomic as p, signVoucher as s };
@@ -1,36 +1,12 @@
1
- import { PublicKey, Connection, Signer, Commitment, TransactionInstruction, AddressLookupTableAccount, VersionedTransaction, ConfirmOptions } from '@solana/web3.js';
1
+ import { Connection, Signer, Commitment, TransactionInstruction, PublicKey, AddressLookupTableAccount, VersionedTransaction, ConfirmOptions } from '@solana/web3.js';
2
2
  import { V as VaultAdapter } from '../../../types-CSuISjXA.cjs';
3
3
  export { A as AuthorizeSessionOptions, L as LiveSessionDetails, d as LiveSessionExistsError } from '../../../types-CSuISjXA.cjs';
4
+ export { d as deriveChannelId } from '../../../sessions-BG2OYLBi.cjs';
4
5
  import { fetchSessionAccount, fetchVaultSessionAccounts, resolveVaultUsdcAta, waitForSession } from '@dexterai/vault/session';
5
6
  import { PasskeySignerWithPublicKey } from '@dexterai/vault/signers';
6
7
  export { PasskeySignerWithPublicKey as PasskeySigner } from '@dexterai/vault/signers';
7
8
  import '@dexterai/vault/types';
8
9
 
9
- /**
10
- * Session-key lifecycle: generation, voucher signing, in-memory hygiene.
11
- *
12
- * A session key is an ed25519 keypair generated in process memory at tab
13
- * open. The buyer's passkey signs a 180-byte registration message endorsing
14
- * the session pubkey within a scope (counterparty, max amount, expiry).
15
- * From that point until tab close, the session key signs every voucher; the
16
- * passkey is never invoked again for the lifetime of the tab.
17
- *
18
- * The session keypair is NEVER persisted to disk. A crashed process
19
- * forfeits the session; the buyer re-prompts the passkey on the next
20
- * attempt. This is the right default — a session key on disk is a real
21
- * attack surface, the cost of re-authorizing is a single prompt.
22
- *
23
- * Curve choice: ed25519. It's Solana's native signer, every Solana RPC and
24
- * wallet knows how to verify it, and `tweetnacl` (already a SDK dep) gives
25
- * us a deterministic implementation that doesn't pull in heavy crypto.
26
- */
27
-
28
- declare function deriveChannelId(args: {
29
- vaultPda: PublicKey;
30
- sellerUrl: string;
31
- nonce: bigint;
32
- }): Uint8Array;
33
-
34
10
  /**
35
11
  * CLI / Node passkey signer using @noble/curves/p256.
36
12
  *
@@ -267,4 +243,4 @@ declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): Tr
267
243
  /** Factory entry point. */
268
244
  declare function createSolanaVaultAdapter(opts: CreateSolanaVaultAdapterOptions): VaultAdapter;
269
245
 
270
- export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type SelfPayingComposeSend, type SelfPayingComposeSendOptions, type SolanaAdapterSeams, TX_SIZE_LIMIT_BYTES, buildAdapterRegisterInstruction, collectAltAddresses, compileComposeV0, createSelfPayingComposeSend, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
246
+ export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type SelfPayingComposeSend, type SelfPayingComposeSendOptions, type SolanaAdapterSeams, TX_SIZE_LIMIT_BYTES, buildAdapterRegisterInstruction, collectAltAddresses, compileComposeV0, createSelfPayingComposeSend, createSolanaVaultAdapter, passkeySignerFromP256Keypair };
@@ -1,36 +1,12 @@
1
- import { PublicKey, Connection, Signer, Commitment, TransactionInstruction, AddressLookupTableAccount, VersionedTransaction, ConfirmOptions } from '@solana/web3.js';
1
+ import { Connection, Signer, Commitment, TransactionInstruction, PublicKey, AddressLookupTableAccount, VersionedTransaction, ConfirmOptions } from '@solana/web3.js';
2
2
  import { V as VaultAdapter } from '../../../types-CSuISjXA.js';
3
3
  export { A as AuthorizeSessionOptions, L as LiveSessionDetails, d as LiveSessionExistsError } from '../../../types-CSuISjXA.js';
4
+ export { d as deriveChannelId } from '../../../sessions-BG2OYLBi.js';
4
5
  import { fetchSessionAccount, fetchVaultSessionAccounts, resolveVaultUsdcAta, waitForSession } from '@dexterai/vault/session';
5
6
  import { PasskeySignerWithPublicKey } from '@dexterai/vault/signers';
6
7
  export { PasskeySignerWithPublicKey as PasskeySigner } from '@dexterai/vault/signers';
7
8
  import '@dexterai/vault/types';
8
9
 
9
- /**
10
- * Session-key lifecycle: generation, voucher signing, in-memory hygiene.
11
- *
12
- * A session key is an ed25519 keypair generated in process memory at tab
13
- * open. The buyer's passkey signs a 180-byte registration message endorsing
14
- * the session pubkey within a scope (counterparty, max amount, expiry).
15
- * From that point until tab close, the session key signs every voucher; the
16
- * passkey is never invoked again for the lifetime of the tab.
17
- *
18
- * The session keypair is NEVER persisted to disk. A crashed process
19
- * forfeits the session; the buyer re-prompts the passkey on the next
20
- * attempt. This is the right default — a session key on disk is a real
21
- * attack surface, the cost of re-authorizing is a single prompt.
22
- *
23
- * Curve choice: ed25519. It's Solana's native signer, every Solana RPC and
24
- * wallet knows how to verify it, and `tweetnacl` (already a SDK dep) gives
25
- * us a deterministic implementation that doesn't pull in heavy crypto.
26
- */
27
-
28
- declare function deriveChannelId(args: {
29
- vaultPda: PublicKey;
30
- sellerUrl: string;
31
- nonce: bigint;
32
- }): Uint8Array;
33
-
34
10
  /**
35
11
  * CLI / Node passkey signer using @noble/curves/p256.
36
12
  *
@@ -267,4 +243,4 @@ declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): Tr
267
243
  /** Factory entry point. */
268
244
  declare function createSolanaVaultAdapter(opts: CreateSolanaVaultAdapterOptions): VaultAdapter;
269
245
 
270
- export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type SelfPayingComposeSend, type SelfPayingComposeSendOptions, type SolanaAdapterSeams, TX_SIZE_LIMIT_BYTES, buildAdapterRegisterInstruction, collectAltAddresses, compileComposeV0, createSelfPayingComposeSend, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
246
+ export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type SelfPayingComposeSend, type SelfPayingComposeSendOptions, type SolanaAdapterSeams, TX_SIZE_LIMIT_BYTES, buildAdapterRegisterInstruction, collectAltAddresses, compileComposeV0, createSelfPayingComposeSend, createSolanaVaultAdapter, passkeySignerFromP256Keypair };
@@ -1,6 +1,6 @@
1
- "use strict";var pn=Object.create;var at=Object.defineProperty;var dn=Object.getOwnPropertyDescriptor;var fn=Object.getOwnPropertyNames;var gn=Object.getPrototypeOf,yn=Object.prototype.hasOwnProperty;var hn=(t,e)=>{for(var n in e)at(t,n,{get:e[n],enumerable:!0})},$t=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of fn(e))!yn.call(t,s)&&s!==n&&at(t,s,{get:()=>e[s],enumerable:!(r=dn(e,s))||r.enumerable});return t};var J=(t,e,n)=>(n=t!=null?pn(gn(t)):{},$t(e||!t||!t.__esModule?at(n,"default",{value:t,enumerable:!0}):n,t)),An=t=>$t(at({},"__esModule",{value:!0}),t);var Jn={};hn(Jn,{DEFAULT_FACILITATOR_URL:()=>Re,DEXTER_VAULT_PROGRAM_ID:()=>W.DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID:()=>W.INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError:()=>it,SECP256R1_PROGRAM_ID:()=>W.SECP256R1_PROGRAM_ID,SessionScopeExceededError:()=>ce,TabClosedError:()=>Z,UnsupportedNetworkError:()=>ie,atomicToHuman:()=>le,buildRegisterSessionKeyInstruction:()=>ue.buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction:()=>ue.buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction:()=>_t.buildSecp256r1VerifyInstruction,buildVoucherMessage:()=>B.buildVoucherMessage,humanToAtomic:()=>ee,openTab:()=>ut,payUrlWithTab:()=>un,resolveTabOffer:()=>_e,resolveTabTerms:()=>mn,resumeTab:()=>Ft,sessionRegisterMessage:()=>B.sessionRegisterMessage,sessionRevokeMessage:()=>B.sessionRevokeMessage,tabFromGrant:()=>Gt,voucherPayloadMessage:()=>B.voucherPayloadMessage,voucherToHeader:()=>Ke});module.exports=An(Jn);var ie=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},ce=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Z=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},it=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};var Rt=require("@solana/web3.js"),te=require("@noble/hashes/utils");var Kt=J(require("tweetnacl"),1);var B=require("@dexterai/vault/messages");var Wt=require("@noble/hashes/sha256");function Lt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function Vt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=(0,B.voucherPayloadMessage)({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Kt.default.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function ct(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function lt(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=Wt.sha256.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var bn=3600,Re="https://x402.dexter.cash",Ht=6;function ee(t,e=Ht){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function le(t,e=Ht){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var $e=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:le(this.cumulativeAtomic.toString()),remaining:le(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Z(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new ce("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new ce("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Z(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",Ke(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return xn(o.body)}async close(){if(this.closed)throw new Z(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await wn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:le(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function Ke(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:(0,te.bytesToHex)(t.sessionPublicKey),sessionRegistration:(0,te.bytesToHex)(t.sessionRegistration),sessionSignature:(0,te.bytesToHex)(t.sessionSignature)}),"utf8").toString("base64")}function ve(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function Sn(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=ve(e.attempted_cumulative),s=ve(e.on_chain_spent),o=ve(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function wn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,te.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,te.bytesToHex)(e.sessionSignature),sessionRegistration:(0,te.bytesToHex)(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&Sn(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=ve(i.attemptedCumulative),p=ve(i.onChainSpent),d=ve(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function Pt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function ut(t){if(t.network!==t.vault.network)throw new ie(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ie(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Rt.PublicKey(t.vault.vaultPda),r=lt({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=(0,te.bytesToHex)(r),o=BigInt(ee(t.perUnitCap)),a=BigInt(ee(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(ee(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??bn,c=Math.floor(Date.now()/1e3)+i,u=Tn(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?ee(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await Pt(t.facilitatorUrl??Re,t.vault.swigAddress,a,t.network,u),new $e({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??Re})}async function Ft(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function Tn(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Rt.PublicKey(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*xn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
1
+ "use strict";var fn=Object.create;var lt=Object.defineProperty;var gn=Object.getOwnPropertyDescriptor;var yn=Object.getOwnPropertyNames;var hn=Object.getPrototypeOf,An=Object.prototype.hasOwnProperty;var bn=(t,e)=>{for(var n in e)lt(t,n,{get:e[n],enumerable:!0})},Vt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of yn(e))!An.call(t,s)&&s!==n&&lt(t,s,{get:()=>e[s],enumerable:!(r=gn(e,s))||r.enumerable});return t};var J=(t,e,n)=>(n=t!=null?fn(hn(t)):{},Vt(e||!t||!t.__esModule?lt(n,"default",{value:t,enumerable:!0}):n,t)),Sn=t=>Vt(lt({},"__esModule",{value:!0}),t);var zn={};bn(zn,{DEFAULT_FACILITATOR_URL:()=>_e,DEXTER_VAULT_PROGRAM_ID:()=>W.DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID:()=>W.INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError:()=>ut,SECP256R1_PROGRAM_ID:()=>W.SECP256R1_PROGRAM_ID,SessionScopeExceededError:()=>ce,TabClosedError:()=>Z,UnsupportedNetworkError:()=>ie,armTabOpen:()=>We,atomicToHuman:()=>ue,buildRegisterSessionKeyInstruction:()=>me.buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction:()=>me.buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction:()=>It.buildSecp256r1VerifyInstruction,buildVoucherMessage:()=>B.buildVoucherMessage,deriveChannelId:()=>Re,generateSessionKeypair:()=>Wt,humanToAtomic:()=>ee,makeSessionKey:()=>mt,openTab:()=>dt,parseAtomic:()=>le,payUrlWithTab:()=>pn,resolveTabOffer:()=>ke,resolveTabTerms:()=>dn,resumeTab:()=>jt,scopeCapAtomic:()=>Ht,sessionRegisterMessage:()=>B.sessionRegisterMessage,sessionRevokeMessage:()=>B.sessionRevokeMessage,signVoucher:()=>pt,tabFromGrant:()=>Xt,voucherPayloadMessage:()=>B.voucherPayloadMessage,voucherToHeader:()=>Ve});module.exports=Sn(zn);var ie=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},ce=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Z=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},ut=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};var kt=require("@solana/web3.js"),te=require("@noble/hashes/utils");var Ct=J(require("tweetnacl"),1);var B=require("@dexterai/vault/messages");var Ft=require("@noble/hashes/sha256");function Wt(){let t=Ct.default.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function mt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function pt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=(0,B.voucherPayloadMessage)({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Ct.default.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function Ht(t){return le(t.maxAmountAtomic)}function le(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function Re(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=Ft.sha256.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var wn=3600,_e="https://x402.dexter.cash",qt=6;function ee(t,e=qt){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function ue(t,e=qt){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Le=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:ue(this.cumulativeAtomic.toString()),remaining:ue(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Z(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new ce("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new ce("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Z(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",Ve(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return vn(o.body)}async close(){if(this.closed)throw new Z(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await xn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:ue(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function Ve(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:(0,te.bytesToHex)(t.sessionPublicKey),sessionRegistration:(0,te.bytesToHex)(t.sessionRegistration),sessionSignature:(0,te.bytesToHex)(t.sessionSignature)}),"utf8").toString("base64")}function Pe(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function Tn(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Pe(e.attempted_cumulative),s=Pe(e.on_chain_spent),o=Pe(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function xn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,te.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,te.bytesToHex)(e.sessionSignature),sessionRegistration:(0,te.bytesToHex)(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&Tn(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Pe(i.attemptedCumulative),p=Pe(i.onChainSpent),d=Pe(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function We(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function dt(t){if(t.network!==t.vault.network)throw new ie(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ie(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new kt.PublicKey(t.vault.vaultPda),r=Re({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=(0,te.bytesToHex)(r),o=BigInt(ee(t.perUnitCap)),a=BigInt(ee(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(ee(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??wn,c=Math.floor(Date.now()/1e3)+i,u=En(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?ee(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await We(t.facilitatorUrl??_e,t.vault.swigAddress,a,t.network,u),new Le({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??_e})}async function jt(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function En(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new kt.PublicKey(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*vn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
2
2
 
3
- `))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=En(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
4
- `:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function En(t){let e=null,n=[];for(let r of t.split(`
3
+ `))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=Rn(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
4
+ `:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function Rn(t){let e=null,n=[];for(let r of t.split(`
5
5
  `))r.startsWith("event:")?e=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).trimStart());return{eventName:e,data:n.length?n.join(`
6
- `):null}}var Pe=J(require("tweetnacl"),1),ne=require("@solana/web3.js"),jt=require("@noble/hashes/utils"),mt=require("@dexterai/vault/session"),Jt=require("@dexterai/vault/reader");var ue=require("@dexterai/vault/instructions"),_t=require("@dexterai/vault/precompile"),W=require("@dexterai/vault/constants");var Ct="solana:mainnet";async function Gt(t){let e=t.facilitatorUrl??Re,n=t.programId??W.DEXTER_VAULT_PROGRAM_ID,r=new ne.PublicKey(t.vaultPda),s=new ne.PublicKey(t.params.counterparty),o=ct(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=ct(t.params.maxAmountAtomic),i=ct(t.params.maxRevolvingCapacityAtomic),c=vn(t.sessionSecretKey),u=new ne.PublicKey(t.params.sessionPubkey).toBytes();if(!qt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new ne.PublicKey(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Pe.default.randomBytes(32),d=Pe.default.sign.detached(p,c.secretKey);if(!Pe.default.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=(0,B.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new ne.Connection(t.connection,"confirmed"):t.connection,l=await(0,mt.fetchSessionAccount)(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!(0,mt.isSessionLive)(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!qt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new ne.PublicKey(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=lt({vaultPda:r,sellerUrl:x,nonce:g}),b=(0,jt.bytesToHex)(y),C=t.swigAddress;if(!C){let M=await(0,Jt.readVaultFull)(T,r);if(!M.exists||!M.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=M.swigAddress}await Pt(e,C,a,Ct,t.params.counterparty);let $={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},H=Lt({publicKey:c.publicKey,privateKey:c.secretKey},$,f),V={network:Ct,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(M,K)=>Vt(M,K,y),signOpenTab:async M=>M.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new $e({vault:V,network:Ct,seller:x,counterparty:t.params.counterparty,session:H,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function vn(t){if(t.length===64)return Pe.default.sign.keyPair.fromSecretKey(t);if(t.length===32)return Pe.default.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function qt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}var Xt=require("@solana/web3.js");var zt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],Rn=new Map(zt.map(t=>[t.caip2.toLowerCase(),t])),Pn=new Map(zt.map(t=>[t.bare.toLowerCase(),t]));function Le(t){if(!t)return null;let e=t.toLowerCase(),n=Rn.get(e)||Pn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function kt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function _n(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=Le(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function pt(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=kt(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:_n(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function _e(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await pt(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new Xt.PublicKey(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Ve="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",dt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ft="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",me=Ve,We=dt,He=ft,pe="eip155:8453",Ce="eip155:84532",ke="eip155:42161",Ie="eip155:137",Ne="eip155:10",Oe="eip155:43114",Ue="eip155:56",de="eip155:480",fe="eip155:143",ge="eip155:4663",ye="eip155:1187947933",he="eip155:324705682",De="eip155:1",Ae=pe,gt=Ce,Fe=ke,qe=Ie,je=Ne,Je=Oe,Ge=Ue,ze=de,Xe=fe,Ye=ge,Qe=ye,Ze=he,et=De,tt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Yt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Qt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",It="0x55d398326f99059fF775485246999027B3197955",yt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Nt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",ht={[Ue]:yt,[pe]:Qt,[Ce]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[ke]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Ie]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ne]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Oe]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[de]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[fe]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[ge]:Nt,[ye]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[he]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[De]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},At={[It]:{symbol:"USDT",decimals:18},[yt]:{symbol:"USDC",decimals:18}};var bt={[de]:{name:"USDC",version:"2"},[fe]:{name:"USDC",version:"2"},[ge]:{name:"Global Dollar",version:"1"},[ye]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[he]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},re="0x000000000022D473030F116dDEE9F6B43aC78BA3",nt="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",rt={[Ue]:56,[pe]:8453,[Ce]:84532,[ke]:42161,[Ie]:137,[Ne]:10,[Oe]:43114,[de]:480,[fe]:143,[ge]:4663,[ye]:1187947933,[he]:324705682,[De]:1},be={[Ve]:"https://api.dexter.cash/api/solana/rpc",[dt]:"https://api.devnet.solana.com",[ft]:"https://api.testnet.solana.com"},D={[Ue]:"https://api.dexter.cash/api/evm/bsc/rpc",[pe]:"https://api.dexter.cash/api/base/rpc",[Ce]:"https://sepolia.base.org",[ke]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Ie]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ne]:"https://api.dexter.cash/api/evm/optimism/rpc",[Oe]:"https://api.dexter.cash/api/evm/avalanche/rpc",[de]:"https://worldchain-mainnet.g.alchemy.com/public",[fe]:"https://rpc.monad.xyz",[ge]:"https://rpc.mainnet.chain.robinhood.com",[ye]:"https://skale-base.skalenodes.com/v1/base",[he]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[De]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};var N=require("@solana/web3.js"),O=require("@solana/spl-token");var Cn=12e3,kn=1;function Se(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var St=class{name="Solana";networks=[me,We,He];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:be[e]?be[e]:e==="solana"?be[me]:e==="solana-devnet"?be[We]:e==="solana-testnet"?be[He]:be[me]}getAddress(e){return Se(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return Se(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!Se(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),i=new N.PublicKey(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,p=await(0,O.getAssociatedTokenAddress)(i,a,!1,u),d=await(0,O.getAccount)(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!Se(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new N.PublicKey(u.feePayer),f=new N.PublicKey(c),T=new N.PublicKey(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(N.ComputeBudgetProgram.setComputeUnitLimit({units:Cn})),l.push(N.ComputeBudgetProgram.setComputeUnitPrice({microLamports:kn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,g=await(0,O.getMint)(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await(0,O.getAssociatedTokenAddress)(f,a,!1,x),b=await(0,O.getAssociatedTokenAddress)(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let H=BigInt(p);l.push((0,O.createTransferCheckedInstruction)(y,f,b,a,H,g.decimals,[],x));let{blockhash:V}=await o.getLatestBlockhash("confirmed"),M=new N.TransactionMessage({payerKey:d,recentBlockhash:V,instructions:l}).compileToV0Message(),K=new N.VersionedTransaction(M),h=await n.signTransaction(K);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:V}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new N.Connection(n,"confirmed"),s=new N.PublicKey(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function se(t){return new St(t)}var In={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},Zt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function we(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var wt=class{name="EVM";networks=[Ge,Ae,gt,et,Fe,qe,je,Je,ze,Xe,Ye,Qe,Ze];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:D[e]?D[e]:e==="base"?D[Ae]:e==="bsc"?D[Ge]:e==="ethereum"?D[et]:e==="arbitrum"?D[Fe]:e==="polygon"?D[qe]:e==="optimism"?D[je]:e==="avalanche"?D[Je]:e==="world"?D[ze]:e==="monad"?D[Xe]:e==="robinhood"?D[Ye]:e==="skale-base"?D[Qe]:e==="skale-base-sepolia"?D[Ze]:D[Ae]}getAddress(e){return we(e)?e.address:null}isConnected(e){return we(e)?!!e.address:!1}getChainId(e){if(rt[e])return rt[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!we(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,re,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!we(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=bt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let K=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${K} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,K),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((K,h)=>K*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(K=>K.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},$=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},H={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},V=await n.signTypedData({domain:C,types:$,primaryType:"Payment",message:H});this.log("EIP-712 Payment signature obtained");let M={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:V};return{serialized:JSON.stringify(M),signature:V}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,re),u;if(c<BigInt(a)){let C=this.encodeApprove(re,Zt);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let $=this.getChainId(e.network),H=await this.readGasPrice(i),V=await this.readNonce(i,n.address),M=await n.signTransaction({to:o,data:C,chainId:$,gas:50000n,gasPrice:H,nonce:V});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:re,amount:Zt.toString(),signedTransaction:M,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let $=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${$}`),await this.waitForReceipt(i,$),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,$)=>C*256n+BigInt($),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:re},g={permitted:{token:o,amount:BigInt(a)},spender:nt,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:In,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:nt,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function Be(t){return new wt(t)}function Ot(t){if(t===tt||t===Yt)return!0;let e=t.toLowerCase();for(let n of Object.values(ht))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(At))if(n.toLowerCase()===e)return!0;return!1}function Nn(t){return{[Ve]:"Solana",[dt]:"Solana Devnet",[ft]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[pe]:"Base",[Ce]:"Base Sepolia",[De]:"Ethereum",[ke]:"Arbitrum",[Ie]:"Polygon",[Ne]:"Optimism",[Oe]:"Avalanche",[Ue]:"BSC",[de]:"World Chain",[fe]:"Monad",[ge]:"Robinhood Chain",[ye]:"SKALE Base",[he]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function en(t,e){let n=Nn(t);return n===t?e:n}async function On(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Un=new WeakMap;function tn(t){let{adapters:e=[se({verbose:t.verbose}),Be({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,F=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:F}),l("Access pass cached for",E,"| expires:",new Date(F*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&Se(r)&&(b.solana=r),r&&!b.evm&&we(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function $(h,w){return en(h,w)}function H(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function V(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let F=E.headers.get("PAYMENT-REQUIRED");if(!F)return null;let L;try{L=JSON.parse(atob(F))}catch{return null}let U=C(L.accepts);if(!U)return null;let{accept:k,adapter:j,wallet:Te}=U;if(j.name==="Solana"&&!k.extra?.feePayer)return null;let z=k.extra?.decimals??(Ot(k.asset)?6:void 0);if(typeof z!="number")return null;let Me=k.amount??k.maxAmountRequired;if(!Me)return null;let X=H(k.network,j);try{let m=await j.getBalance(k,Te,X),S=Number(Me)/Math.pow(10,z);if(m<S){let vt=$(k.network,j.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${vt}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let Y=await j.buildTransaction(k,Te,X),xe;j.name==="EVM"?xe=JSON.parse(Y.serialized):xe={transaction:Y.serialized};let oe=typeof h=="string"?h:h instanceof URL?h.href:h.url,Ee=L.resource;if(typeof L.resource=="string")try{let m=new URL(L.resource,oe);["http:","https:"].includes(m.protocol)&&(Ee=m.toString())}catch{}else if(L.resource&&typeof L.resource=="object"&&"url"in L.resource){let m=L.resource;try{let S=new URL(m.url,oe);["http:","https:"].includes(S.protocol)&&(Ee={...m,url:S.toString()})}catch{}}let ot={x402Version:k.x402Version??2,resource:Ee,accepted:k,payload:xe};Y.extensions&&(ot.extensions=Y.extensions);let Q=btoa(JSON.stringify(ot)),ae=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":Q}});if(!ae.ok)return l("Pass purchase failed:",ae.status),null;let q=ae.headers.get("ACCESS-PASS");return q&&(y(v,q),l("Access pass purchased and cached")),ae}async function M(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await V(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let F=A.headers.get("X-Quote-Hash");F&&l("Quote hash received:",F);let L=C(_.accepts);if(!L){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:U,adapter:k,wallet:j}=L;if(l(`Using ${k.name} for ${U.network}`),k.name==="Solana"&&!U.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let Te=U.extra?.decimals??(Ot(U.asset)?6:void 0);if(typeof Te!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let z=U.amount??U.maxAmountRequired;if(!z)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(z)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${z} exceeds maximum ${a}`);let Me=H(U.network,k);l("Checking balance...");try{let m=await k.getBalance(U,j,Me),S=Number(z)/Math.pow(10,Te);if(m<S){let vt=$(U.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${vt}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(U))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let X=await k.buildTransaction(U,j,Me);l("Transaction signed");let Y;k.name==="EVM"?Y=JSON.parse(X.serialized):Y={transaction:X.serialized};let xe=h,oe=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,xe).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),oe=m}catch{oe=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,xe).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),oe={...m,url:S})}catch{}}let Ee={x402Version:U.x402Version??2,resource:oe,accepted:U,payload:Y};X.extensions&&(Ee.extensions=X.extensions);let ot=btoa(JSON.stringify(Ee));if(d)try{d(U,X.settlementProbe)}catch{}l("Retrying request with payment...");let Q=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":ot,...F?{"X-Quote-Hash":F}:{}}});if(l("Retry response status:",Q.status),Q.status===402){let m="unknown";try{let S=await Q.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let ae=Q.headers.get("PAYMENT-RESPONSE"),q;if(ae)try{q=JSON.parse(atob(ae))}catch{}return q??={},q.amountAtomic=z,q.assetDecimals=Te,Un.set(Q,q),q.extensions&&l("Settlement extensions:",Object.keys(q.extensions).join(", ")),Q}async function K(h,w){let[E,A]=await On(h,w);return M(E,A)}return{fetch:K}}function G(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function st(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var Tt="Payment authorization was sent, but the merchant did not respond within the timeout. ",xt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function Et(t,e,n){if(!t)return{confirmed:!1,detail:Tt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+xt};try{if(t.kind==="solana"){let a=se(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return rn();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:nn()}let r=Be(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return rn();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:nn()}catch(r){return{confirmed:!1,detail:Tt+`On-chain confirmation could not be completed (${G(r)}).`+xt}}}function nn(){return{confirmed:!1,detail:Tt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+xt}}function rn(){return{confirmed:!1,detail:Tt+"The chain adapter does not support on-chain confirmation."+xt}}var Dn=new Set(["exact","exact-approval"]);async function Bn(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",Ke(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await st(i)}}var sn={version:2,async parseChallenge(t){return pt(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await Bn(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Dn.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=tn({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await st(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=kt(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await Et(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};var on=require("viem");var Mn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function $n(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function Kn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await $n()},i=rt[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:(0,on.getAddress)(e.asset)},types:Mn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Ut(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await Ln(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Vn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:G(r)}}}async function Ln(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await Kn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Vn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await se().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Wn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=Le(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var an={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Wn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Ut(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:Hn(y)}:{ok:!1,...await st(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await Et(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:G(p)}}finally{o!==void 0&&clearTimeout(o)}}};function Hn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}var ln=J(require("tweetnacl"),1);var Dt=require("@solana/web3.js"),cn=Symbol.for("x402:keypair");function Bt(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[cn];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>ln.sign.detached(s,r.secretKey)}}return null}var Fn=[sn,an];async function qn(t){let e=Bt(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${G(n)}`),fetch}}async function Mt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await qn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:G(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of Fn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function un(t,e={},n){let r=await _e(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(ee(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await ut({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Mt(t,e,{},{tab:a}),tab:a}}function jn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:le(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function mn(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await _e(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==tt)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=jn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}0&&(module.exports={DEFAULT_FACILITATOR_URL,DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError,SECP256R1_PROGRAM_ID,SessionScopeExceededError,TabClosedError,UnsupportedNetworkError,atomicToHuman,buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction,buildVoucherMessage,humanToAtomic,openTab,payUrlWithTab,resolveTabOffer,resolveTabTerms,resumeTab,sessionRegisterMessage,sessionRevokeMessage,tabFromGrant,voucherPayloadMessage,voucherToHeader});
6
+ `):null}}var Ce=J(require("tweetnacl"),1),ne=require("@solana/web3.js"),Gt=require("@noble/hashes/utils"),ft=require("@dexterai/vault/session"),zt=require("@dexterai/vault/reader");var me=require("@dexterai/vault/instructions"),It=require("@dexterai/vault/precompile"),W=require("@dexterai/vault/constants");var Nt="solana:mainnet";async function Xt(t){let e=t.facilitatorUrl??_e,n=t.programId??W.DEXTER_VAULT_PROGRAM_ID,r=new ne.PublicKey(t.vaultPda),s=new ne.PublicKey(t.params.counterparty),o=le(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=le(t.params.maxAmountAtomic),i=le(t.params.maxRevolvingCapacityAtomic),c=Pn(t.sessionSecretKey),u=new ne.PublicKey(t.params.sessionPubkey).toBytes();if(!Jt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new ne.PublicKey(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ce.default.randomBytes(32),d=Ce.default.sign.detached(p,c.secretKey);if(!Ce.default.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=(0,B.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new ne.Connection(t.connection,"confirmed"):t.connection,l=await(0,ft.fetchSessionAccount)(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!(0,ft.isSessionLive)(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Jt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new ne.PublicKey(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=Re({vaultPda:r,sellerUrl:x,nonce:g}),b=(0,Gt.bytesToHex)(y),C=t.swigAddress;if(!C){let M=await(0,zt.readVaultFull)(T,r);if(!M.exists||!M.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=M.swigAddress}await We(e,C,a,Nt,t.params.counterparty);let $={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},H=mt({publicKey:c.publicKey,privateKey:c.secretKey},$,f),V={network:Nt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(M,K)=>pt(M,K,y),signOpenTab:async M=>M.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Le({vault:V,network:Nt,seller:x,counterparty:t.params.counterparty,session:H,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function Pn(t){if(t.length===64)return Ce.default.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ce.default.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Jt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}var Qt=require("@solana/web3.js");var Yt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],_n=new Map(Yt.map(t=>[t.caip2.toLowerCase(),t])),Cn=new Map(Yt.map(t=>[t.bare.toLowerCase(),t]));function He(t){if(!t)return null;let e=t.toLowerCase(),n=_n.get(e)||Cn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Ot(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function kn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=He(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function gt(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Ot(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:kn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function ke(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await gt(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new Qt.PublicKey(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Fe="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",yt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ht="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",pe=Fe,qe=yt,je=ht,de="eip155:8453",Ie="eip155:84532",Ne="eip155:42161",Oe="eip155:137",Ue="eip155:10",De="eip155:43114",Be="eip155:56",fe="eip155:480",ge="eip155:143",ye="eip155:4663",he="eip155:1187947933",Ae="eip155:324705682",Me="eip155:1",be=de,At=Ie,Je=Ne,Ge=Oe,ze=Ue,Xe=De,Ye=Be,Qe=fe,Ze=ge,et=ye,tt=he,nt=Ae,rt=Me,st="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Zt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",en="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Ut="0x55d398326f99059fF775485246999027B3197955",bt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Dt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",St={[Be]:bt,[de]:en,[Ie]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Ne]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Oe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ue]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[De]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[fe]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[ge]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[ye]:Dt,[he]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Ae]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Me]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},wt={[Ut]:{symbol:"USDT",decimals:18},[bt]:{symbol:"USDC",decimals:18}};var Tt={[fe]:{name:"USDC",version:"2"},[ge]:{name:"USDC",version:"2"},[ye]:{name:"Global Dollar",version:"1"},[he]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},re="0x000000000022D473030F116dDEE9F6B43aC78BA3",ot="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",at={[Be]:56,[de]:8453,[Ie]:84532,[Ne]:42161,[Oe]:137,[Ue]:10,[De]:43114,[fe]:480,[ge]:143,[ye]:4663,[he]:1187947933,[Ae]:324705682,[Me]:1},Se={[Fe]:"https://api.dexter.cash/api/solana/rpc",[yt]:"https://api.devnet.solana.com",[ht]:"https://api.testnet.solana.com"},D={[Be]:"https://api.dexter.cash/api/evm/bsc/rpc",[de]:"https://api.dexter.cash/api/base/rpc",[Ie]:"https://sepolia.base.org",[Ne]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Oe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ue]:"https://api.dexter.cash/api/evm/optimism/rpc",[De]:"https://api.dexter.cash/api/evm/avalanche/rpc",[fe]:"https://worldchain-mainnet.g.alchemy.com/public",[ge]:"https://rpc.monad.xyz",[ye]:"https://rpc.mainnet.chain.robinhood.com",[he]:"https://skale-base.skalenodes.com/v1/base",[Ae]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Me]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};var N=require("@solana/web3.js"),O=require("@solana/spl-token");var In=12e3,Nn=1;function we(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var xt=class{name="Solana";networks=[pe,qe,je];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:Se[e]?Se[e]:e==="solana"?Se[pe]:e==="solana-devnet"?Se[qe]:e==="solana-testnet"?Se[je]:Se[pe]}getAddress(e){return we(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return we(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!we(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),i=new N.PublicKey(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,p=await(0,O.getAssociatedTokenAddress)(i,a,!1,u),d=await(0,O.getAccount)(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!we(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new N.PublicKey(u.feePayer),f=new N.PublicKey(c),T=new N.PublicKey(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(N.ComputeBudgetProgram.setComputeUnitLimit({units:In})),l.push(N.ComputeBudgetProgram.setComputeUnitPrice({microLamports:Nn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,g=await(0,O.getMint)(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await(0,O.getAssociatedTokenAddress)(f,a,!1,x),b=await(0,O.getAssociatedTokenAddress)(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let H=BigInt(p);l.push((0,O.createTransferCheckedInstruction)(y,f,b,a,H,g.decimals,[],x));let{blockhash:V}=await o.getLatestBlockhash("confirmed"),M=new N.TransactionMessage({payerKey:d,recentBlockhash:V,instructions:l}).compileToV0Message(),K=new N.VersionedTransaction(M),h=await n.signTransaction(K);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:V}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new N.Connection(n,"confirmed"),s=new N.PublicKey(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function se(t){return new xt(t)}var On={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},tn=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Te(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var Et=class{name="EVM";networks=[Ye,be,At,rt,Je,Ge,ze,Xe,Qe,Ze,et,tt,nt];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:D[e]?D[e]:e==="base"?D[be]:e==="bsc"?D[Ye]:e==="ethereum"?D[rt]:e==="arbitrum"?D[Je]:e==="polygon"?D[Ge]:e==="optimism"?D[ze]:e==="avalanche"?D[Xe]:e==="world"?D[Qe]:e==="monad"?D[Ze]:e==="robinhood"?D[et]:e==="skale-base"?D[tt]:e==="skale-base-sepolia"?D[nt]:D[be]}getAddress(e){return Te(e)?e.address:null}isConnected(e){return Te(e)?!!e.address:!1}getChainId(e){if(at[e])return at[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!Te(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,re,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!Te(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=Tt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let K=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${K} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,K),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((K,h)=>K*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(K=>K.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},$=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},H={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},V=await n.signTypedData({domain:C,types:$,primaryType:"Payment",message:H});this.log("EIP-712 Payment signature obtained");let M={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:V};return{serialized:JSON.stringify(M),signature:V}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,re),u;if(c<BigInt(a)){let C=this.encodeApprove(re,tn);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let $=this.getChainId(e.network),H=await this.readGasPrice(i),V=await this.readNonce(i,n.address),M=await n.signTransaction({to:o,data:C,chainId:$,gas:50000n,gasPrice:H,nonce:V});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:re,amount:tn.toString(),signedTransaction:M,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let $=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${$}`),await this.waitForReceipt(i,$),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,$)=>C*256n+BigInt($),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:re},g={permitted:{token:o,amount:BigInt(a)},spender:ot,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:On,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:ot,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function $e(t){return new Et(t)}function Bt(t){if(t===st||t===Zt)return!0;let e=t.toLowerCase();for(let n of Object.values(St))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(wt))if(n.toLowerCase()===e)return!0;return!1}function Un(t){return{[Fe]:"Solana",[yt]:"Solana Devnet",[ht]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[de]:"Base",[Ie]:"Base Sepolia",[Me]:"Ethereum",[Ne]:"Arbitrum",[Oe]:"Polygon",[Ue]:"Optimism",[De]:"Avalanche",[Be]:"BSC",[fe]:"World Chain",[ge]:"Monad",[ye]:"Robinhood Chain",[he]:"SKALE Base",[Ae]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function nn(t,e){let n=Un(t);return n===t?e:n}async function Dn(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Bn=new WeakMap;function rn(t){let{adapters:e=[se({verbose:t.verbose}),$e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,F=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:F}),l("Access pass cached for",E,"| expires:",new Date(F*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&we(r)&&(b.solana=r),r&&!b.evm&&Te(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function $(h,w){return nn(h,w)}function H(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function V(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let F=E.headers.get("PAYMENT-REQUIRED");if(!F)return null;let L;try{L=JSON.parse(atob(F))}catch{return null}let U=C(L.accepts);if(!U)return null;let{accept:k,adapter:j,wallet:xe}=U;if(j.name==="Solana"&&!k.extra?.feePayer)return null;let z=k.extra?.decimals??(Bt(k.asset)?6:void 0);if(typeof z!="number")return null;let Ke=k.amount??k.maxAmountRequired;if(!Ke)return null;let X=H(k.network,j);try{let m=await j.getBalance(k,xe,X),S=Number(Ke)/Math.pow(10,z);if(m<S){let _t=$(k.network,j.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${_t}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let Y=await j.buildTransaction(k,xe,X),Ee;j.name==="EVM"?Ee=JSON.parse(Y.serialized):Ee={transaction:Y.serialized};let oe=typeof h=="string"?h:h instanceof URL?h.href:h.url,ve=L.resource;if(typeof L.resource=="string")try{let m=new URL(L.resource,oe);["http:","https:"].includes(m.protocol)&&(ve=m.toString())}catch{}else if(L.resource&&typeof L.resource=="object"&&"url"in L.resource){let m=L.resource;try{let S=new URL(m.url,oe);["http:","https:"].includes(S.protocol)&&(ve={...m,url:S.toString()})}catch{}}let ct={x402Version:k.x402Version??2,resource:ve,accepted:k,payload:Ee};Y.extensions&&(ct.extensions=Y.extensions);let Q=btoa(JSON.stringify(ct)),ae=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":Q}});if(!ae.ok)return l("Pass purchase failed:",ae.status),null;let q=ae.headers.get("ACCESS-PASS");return q&&(y(v,q),l("Access pass purchased and cached")),ae}async function M(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await V(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let F=A.headers.get("X-Quote-Hash");F&&l("Quote hash received:",F);let L=C(_.accepts);if(!L){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:U,adapter:k,wallet:j}=L;if(l(`Using ${k.name} for ${U.network}`),k.name==="Solana"&&!U.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let xe=U.extra?.decimals??(Bt(U.asset)?6:void 0);if(typeof xe!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let z=U.amount??U.maxAmountRequired;if(!z)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(z)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${z} exceeds maximum ${a}`);let Ke=H(U.network,k);l("Checking balance...");try{let m=await k.getBalance(U,j,Ke),S=Number(z)/Math.pow(10,xe);if(m<S){let _t=$(U.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${_t}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(U))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let X=await k.buildTransaction(U,j,Ke);l("Transaction signed");let Y;k.name==="EVM"?Y=JSON.parse(X.serialized):Y={transaction:X.serialized};let Ee=h,oe=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,Ee).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),oe=m}catch{oe=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,Ee).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),oe={...m,url:S})}catch{}}let ve={x402Version:U.x402Version??2,resource:oe,accepted:U,payload:Y};X.extensions&&(ve.extensions=X.extensions);let ct=btoa(JSON.stringify(ve));if(d)try{d(U,X.settlementProbe)}catch{}l("Retrying request with payment...");let Q=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":ct,...F?{"X-Quote-Hash":F}:{}}});if(l("Retry response status:",Q.status),Q.status===402){let m="unknown";try{let S=await Q.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let ae=Q.headers.get("PAYMENT-RESPONSE"),q;if(ae)try{q=JSON.parse(atob(ae))}catch{}return q??={},q.amountAtomic=z,q.assetDecimals=xe,Bn.set(Q,q),q.extensions&&l("Settlement extensions:",Object.keys(q.extensions).join(", ")),Q}async function K(h,w){let[E,A]=await Dn(h,w);return M(E,A)}return{fetch:K}}function G(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function it(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var vt="Payment authorization was sent, but the merchant did not respond within the timeout. ",Rt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function Pt(t,e,n){if(!t)return{confirmed:!1,detail:vt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+Rt};try{if(t.kind==="solana"){let a=se(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return on();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:sn()}let r=$e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return on();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:sn()}catch(r){return{confirmed:!1,detail:vt+`On-chain confirmation could not be completed (${G(r)}).`+Rt}}}function sn(){return{confirmed:!1,detail:vt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+Rt}}function on(){return{confirmed:!1,detail:vt+"The chain adapter does not support on-chain confirmation."+Rt}}var Mn=new Set(["exact","exact-approval"]);async function $n(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",Ve(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await it(i)}}var an={version:2,async parseChallenge(t){return gt(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await $n(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Mn.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=rn({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await it(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Ot(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await Pt(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};var cn=require("viem");var Kn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Ln(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function Vn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Ln()},i=at[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:(0,cn.getAddress)(e.asset)},types:Kn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Mt(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await Wn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Hn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:G(r)}}}async function Wn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await Vn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Hn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await se().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Fn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=He(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var ln={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Fn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Mt(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:qn(y)}:{ok:!1,...await it(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await Pt(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:G(p)}}finally{o!==void 0&&clearTimeout(o)}}};function qn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}var mn=J(require("tweetnacl"),1);var $t=require("@solana/web3.js"),un=Symbol.for("x402:keypair");function Kt(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[un];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>mn.sign.detached(s,r.secretKey)}}return null}var jn=[an,ln];async function Jn(t){let e=Kt(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${G(n)}`),fetch}}async function Lt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Jn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:G(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of jn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function pn(t,e={},n){let r=await ke(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(ee(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await dt({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Lt(t,e,{},{tab:a}),tab:a}}function Gn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:ue(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function dn(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await ke(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==st)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Gn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}0&&(module.exports={DEFAULT_FACILITATOR_URL,DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError,SECP256R1_PROGRAM_ID,SessionScopeExceededError,TabClosedError,UnsupportedNetworkError,armTabOpen,atomicToHuman,buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction,buildVoucherMessage,deriveChannelId,generateSessionKeypair,humanToAtomic,makeSessionKey,openTab,parseAtomic,payUrlWithTab,resolveTabOffer,resolveTabTerms,resumeTab,scopeCapAtomic,sessionRegisterMessage,sessionRevokeMessage,signVoucher,tabFromGrant,voucherPayloadMessage,voucherToHeader});
@@ -10,6 +10,7 @@ export { SessionRegisterMessageArgs, SessionRevokeMessageArgs, VoucherPayloadByt
10
10
  export { BuildRegisterSessionKeyArgs, BuildRevokeSessionKeyArgs, buildRegisterSessionKeyInstruction, buildRevokeSessionKeyInstruction } from '@dexterai/vault/instructions';
11
11
  export { buildSecp256r1VerifyInstruction } from '@dexterai/vault/precompile';
12
12
  export { DEXTER_VAULT_PROGRAM_ID, INSTRUCTIONS_SYSVAR_ID, SECP256R1_PROGRAM_ID } from '@dexterai/vault/constants';
13
+ export { d as deriveChannelId, g as generateSessionKeypair, m as makeSessionKey, p as parseAtomic, a as scopeCapAtomic, s as signVoucher } from '../sessions-BG2OYLBi.cjs';
13
14
  import '../types-xQu1U4xk.cjs';
14
15
 
15
16
  /**
@@ -44,6 +45,15 @@ declare function atomicToHuman(atomic: AtomicAmount, decimals?: number): HumanAm
44
45
  * pay a `tab`-scheme accepts entry directly.
45
46
  */
46
47
  declare function voucherToHeader(signed: SignedVoucher): string;
48
+ /**
49
+ * Arm drain-protection for a freshly-registered tab via the facilitator's
50
+ * /tab/open. THROWS if protection cannot be confirmed — a tab that is not
51
+ * drain-protected must never be returned to the caller.
52
+ */
53
+ declare function armTabOpen(facilitatorUrl: string, buyerSwigAddress: string, maxAmountAtomic: bigint, network: string, counterparty: string): Promise<{
54
+ armed: true;
55
+ signature: string;
56
+ }>;
47
57
  declare function openTab(options: OpenTabOptions): Promise<Tab>;
48
58
  declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
49
59
 
@@ -303,4 +313,4 @@ interface ResolveTabTermsOptions {
303
313
  */
304
314
  declare function resolveTabTerms(url: string, init?: RequestInit, opts?: ResolveTabTermsOptions): Promise<TabTermsResult>;
305
315
 
306
- export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
316
+ export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, armTabOpen, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
@@ -10,6 +10,7 @@ export { SessionRegisterMessageArgs, SessionRevokeMessageArgs, VoucherPayloadByt
10
10
  export { BuildRegisterSessionKeyArgs, BuildRevokeSessionKeyArgs, buildRegisterSessionKeyInstruction, buildRevokeSessionKeyInstruction } from '@dexterai/vault/instructions';
11
11
  export { buildSecp256r1VerifyInstruction } from '@dexterai/vault/precompile';
12
12
  export { DEXTER_VAULT_PROGRAM_ID, INSTRUCTIONS_SYSVAR_ID, SECP256R1_PROGRAM_ID } from '@dexterai/vault/constants';
13
+ export { d as deriveChannelId, g as generateSessionKeypair, m as makeSessionKey, p as parseAtomic, a as scopeCapAtomic, s as signVoucher } from '../sessions-BG2OYLBi.js';
13
14
  import '../types-xQu1U4xk.js';
14
15
 
15
16
  /**
@@ -44,6 +45,15 @@ declare function atomicToHuman(atomic: AtomicAmount, decimals?: number): HumanAm
44
45
  * pay a `tab`-scheme accepts entry directly.
45
46
  */
46
47
  declare function voucherToHeader(signed: SignedVoucher): string;
48
+ /**
49
+ * Arm drain-protection for a freshly-registered tab via the facilitator's
50
+ * /tab/open. THROWS if protection cannot be confirmed — a tab that is not
51
+ * drain-protected must never be returned to the caller.
52
+ */
53
+ declare function armTabOpen(facilitatorUrl: string, buyerSwigAddress: string, maxAmountAtomic: bigint, network: string, counterparty: string): Promise<{
54
+ armed: true;
55
+ signature: string;
56
+ }>;
47
57
  declare function openTab(options: OpenTabOptions): Promise<Tab>;
48
58
  declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
49
59
 
@@ -303,4 +313,4 @@ interface ResolveTabTermsOptions {
303
313
  */
304
314
  declare function resolveTabTerms(url: string, init?: RequestInit, opts?: ResolveTabTermsOptions): Promise<TabTermsResult>;
305
315
 
306
- export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
316
+ export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, armTabOpen, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
package/dist/tab/index.js CHANGED
@@ -1,6 +1,6 @@
1
- var ye=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},he=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Q=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},At=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};import{PublicKey as Bt}from"@solana/web3.js";import{bytesToHex as ee}from"@noble/hashes/utils";import tn from"tweetnacl";import{sessionRegisterMessage as bt,sessionRevokeMessage as Zt,voucherPayloadMessage as St,buildVoucherMessage as en}from"@dexterai/vault/messages";import{sha256 as nn}from"@noble/hashes/sha256";function Ut(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function Dt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=St({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=tn.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function et(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function tt(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=nn.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var rn=3600,Ce="https://x402.dexter.cash",Mt=6;function Z(t,e=Mt){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function Ae(t,e=Mt){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var ke=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:Ae(this.cumulativeAtomic.toString()),remaining:Ae(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Q(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new he("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new he("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Q(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",nt(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return ln(o.body)}async close(){if(this.closed)throw new Q(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await on(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:Ae(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function nt(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:ee(t.sessionPublicKey),sessionRegistration:ee(t.sessionRegistration),sessionSignature:ee(t.sessionSignature)}),"utf8").toString("base64")}function be(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function sn(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=be(e.attempted_cumulative),s=be(e.on_chain_spent),o=be(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function on(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:ee(e.sessionPublicKey),sessionSignature:ee(e.sessionSignature),sessionRegistration:ee(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&sn(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=be(i.attemptedCumulative),p=be(i.onChainSpent),d=be(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function wt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function Tt(t){if(t.network!==t.vault.network)throw new ye(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ye(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Bt(t.vault.vaultPda),r=tt({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=ee(r),o=BigInt(Z(t.perUnitCap)),a=BigInt(Z(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(Z(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??rn,c=Math.floor(Date.now()/1e3)+i,u=cn(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?Z(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await wt(t.facilitatorUrl??Ce,t.vault.swigAddress,a,t.network,u),new ke({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??Ce})}async function an(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function cn(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Bt(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*ln(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
1
+ var ye=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},he=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Q=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},bt=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};import{PublicKey as Mt}from"@solana/web3.js";import{bytesToHex as ee}from"@noble/hashes/utils";import Bt from"tweetnacl";import{sessionRegisterMessage as St,sessionRevokeMessage as en,voucherPayloadMessage as wt,buildVoucherMessage as tn}from"@dexterai/vault/messages";import{sha256 as sn}from"@noble/hashes/sha256";function nn(){let t=Bt.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function Tt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function xt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=wt({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Bt.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function rn(t){return Ae(t.maxAmountAtomic)}function Ae(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function ke(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=sn.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var on=3600,Ie="https://x402.dexter.cash",$t=6;function Z(t,e=$t){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function be(t,e=$t){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Ne=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:be(this.cumulativeAtomic.toString()),remaining:be(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Q(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new he("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new he("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Q(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",nt(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return mn(o.body)}async close(){if(this.closed)throw new Q(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await cn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:be(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function nt(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:ee(t.sessionPublicKey),sessionRegistration:ee(t.sessionRegistration),sessionSignature:ee(t.sessionSignature)}),"utf8").toString("base64")}function Se(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function an(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Se(e.attempted_cumulative),s=Se(e.on_chain_spent),o=Se(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function cn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:ee(e.sessionPublicKey),sessionSignature:ee(e.sessionSignature),sessionRegistration:ee(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&an(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Se(i.attemptedCumulative),p=Se(i.onChainSpent),d=Se(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function rt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function Et(t){if(t.network!==t.vault.network)throw new ye(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ye(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Mt(t.vault.vaultPda),r=ke({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=ee(r),o=BigInt(Z(t.perUnitCap)),a=BigInt(Z(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(Z(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??on,c=Math.floor(Date.now()/1e3)+i,u=un(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?Z(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await rt(t.facilitatorUrl??Ie,t.vault.swigAddress,a,t.network,u),new Ne({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??Ie})}async function ln(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function un(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Mt(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*mn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
2
2
 
3
- `))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=un(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
4
- `:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function un(t){let e=null,n=[];for(let r of t.split(`
3
+ `))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=pn(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
4
+ `:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function pn(t){let e=null,n=[];for(let r of t.split(`
5
5
  `))r.startsWith("event:")?e=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).trimStart());return{eventName:e,data:n.length?n.join(`
6
- `):null}}import Ne from"tweetnacl";import{Connection as yn,PublicKey as Ie}from"@solana/web3.js";import{bytesToHex as hn}from"@noble/hashes/utils";import{fetchSessionAccount as An,isSessionLive as bn}from"@dexterai/vault/session";import{readVaultFull as Sn}from"@dexterai/vault/reader";import{buildRegisterSessionKeyInstruction as mn,buildRevokeSessionKeyInstruction as pn,deriveSwigWalletAddress as dr}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as dn}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as xt,SECP256R1_PROGRAM_ID as fn,INSTRUCTIONS_SYSVAR_ID as gn}from"@dexterai/vault/constants";var Et="solana:mainnet";async function wn(t){let e=t.facilitatorUrl??Ce,n=t.programId??xt,r=new Ie(t.vaultPda),s=new Ie(t.params.counterparty),o=et(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=et(t.params.maxAmountAtomic),i=et(t.params.maxRevolvingCapacityAtomic),c=Tn(t.sessionSecretKey),u=new Ie(t.params.sessionPubkey).toBytes();if(!$t(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new Ie(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ne.randomBytes(32),d=Ne.sign.detached(p,c.secretKey);if(!Ne.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=bt({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new yn(t.connection,"confirmed"):t.connection,l=await An(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!bn(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!$t(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new Ie(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=tt({vaultPda:r,sellerUrl:x,nonce:g}),b=hn(y),C=t.swigAddress;if(!C){let U=await Sn(T,r);if(!U.exists||!U.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=U.swigAddress}await wt(e,C,a,Et,t.params.counterparty);let D={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},K=Ut({publicKey:c.publicKey,privateKey:c.secretKey},D,f),$={network:Et,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(U,B)=>Dt(U,B,y),signOpenTab:async U=>U.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new ke({vault:$,network:Et,seller:x,counterparty:t.params.counterparty,session:K,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function Tn(t){if(t.length===64)return Ne.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ne.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function $t(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}import{PublicKey as Rn}from"@solana/web3.js";var Kt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],xn=new Map(Kt.map(t=>[t.caip2.toLowerCase(),t])),En=new Map(Kt.map(t=>[t.bare.toLowerCase(),t]));function Oe(t){if(!t)return null;let e=t.toLowerCase(),n=xn.get(e)||En.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function vt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function vn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=Oe(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function rt(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=vt(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:vn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function Ue(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await rt(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new Rn(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var De="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",st="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ot="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",te=De,Be=st,Me=ot,ne="eip155:8453",Se="eip155:84532",we="eip155:42161",Te="eip155:137",xe="eip155:10",Ee="eip155:43114",ve="eip155:56",re="eip155:480",se="eip155:143",oe="eip155:4663",ae="eip155:1187947933",ie="eip155:324705682",Re="eip155:1",ce=ne,at=Se,$e=we,Ke=Te,Le=xe,Ve=Ee,We=ve,He=re,Fe=se,qe=oe,je=ae,Je=ie,Ge=Re,ze="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Lt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Vt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Rt="0x55d398326f99059fF775485246999027B3197955",it="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Pt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",ct={[ve]:it,[ne]:Vt,[Se]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[we]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Te]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[xe]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Ee]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[re]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[se]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[oe]:Pt,[ae]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ie]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Re]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},lt={[Rt]:{symbol:"USDT",decimals:18},[it]:{symbol:"USDC",decimals:18}};var ut={[re]:{name:"USDC",version:"2"},[se]:{name:"USDC",version:"2"},[oe]:{name:"Global Dollar",version:"1"},[ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[ie]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},G="0x000000000022D473030F116dDEE9F6B43aC78BA3",Xe="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",Ye={[ve]:56,[ne]:8453,[Se]:84532,[we]:42161,[Te]:137,[xe]:10,[Ee]:43114,[re]:480,[se]:143,[oe]:4663,[ae]:1187947933,[ie]:324705682,[Re]:1},le={[De]:"https://api.dexter.cash/api/solana/rpc",[st]:"https://api.devnet.solana.com",[ot]:"https://api.testnet.solana.com"},O={[ve]:"https://api.dexter.cash/api/evm/bsc/rpc",[ne]:"https://api.dexter.cash/api/base/rpc",[Se]:"https://sepolia.base.org",[we]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Te]:"https://api.dexter.cash/api/evm/polygon/rpc",[xe]:"https://api.dexter.cash/api/evm/optimism/rpc",[Ee]:"https://api.dexter.cash/api/evm/avalanche/rpc",[re]:"https://worldchain-mainnet.g.alchemy.com/public",[se]:"https://rpc.monad.xyz",[oe]:"https://rpc.mainnet.chain.robinhood.com",[ae]:"https://skale-base.skalenodes.com/v1/base",[ie]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Re]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};import{PublicKey as ue,Connection as _t,TransactionMessage as Pn,VersionedTransaction as _n,ComputeBudgetProgram as Wt}from"@solana/web3.js";import{getAssociatedTokenAddress as Ct,getAccount as Cn,createTransferCheckedInstruction as kn,getMint as In,TOKEN_PROGRAM_ID as Ht,TOKEN_2022_PROGRAM_ID as mt}from"@solana/spl-token";var Nn=12e3,On=1;function me(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var pt=class{name="Solana";networks=[te,Be,Me];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:le[e]?le[e]:e==="solana"?le[te]:e==="solana-devnet"?le[Be]:e==="solana-testnet"?le[Me]:le[te]}getAddress(e){return me(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return me(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!me(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new _t(s,"confirmed"),a=new ue(n.publicKey.toBase58()),i=new ue(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===mt.toBase58()?mt:Ht,p=await Ct(i,a,!1,u),d=await Cn(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!me(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new _t(s,"confirmed"),a=new ue(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new ue(u.feePayer),f=new ue(c),T=new ue(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(Wt.setComputeUnitLimit({units:Nn})),l.push(Wt.setComputeUnitPrice({microLamports:On}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===mt.toBase58()?mt:Ht,g=await In(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await Ct(f,a,!1,x),b=await Ct(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let K=BigInt(p);l.push(kn(y,f,b,a,K,g.decimals,[],x));let{blockhash:$}=await o.getLatestBlockhash("confirmed"),U=new Pn({payerKey:d,recentBlockhash:$,instructions:l}).compileToV0Message(),B=new _n(U),h=await n.signTransaction(B);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:$}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new _t(n,"confirmed"),s=new ue(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function z(t){return new pt(t)}var Un={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},Ft=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function pe(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var dt=class{name="EVM";networks=[We,ce,at,Ge,$e,Ke,Le,Ve,He,Fe,qe,je,Je];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:O[e]?O[e]:e==="base"?O[ce]:e==="bsc"?O[We]:e==="ethereum"?O[Ge]:e==="arbitrum"?O[$e]:e==="polygon"?O[Ke]:e==="optimism"?O[Le]:e==="avalanche"?O[Ve]:e==="world"?O[He]:e==="monad"?O[Fe]:e==="robinhood"?O[qe]:e==="skale-base"?O[je]:e==="skale-base-sepolia"?O[Je]:O[ce]}getAddress(e){return pe(e)?e.address:null}isConnected(e){return pe(e)?!!e.address:!1}getChainId(e){if(Ye[e])return Ye[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!pe(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,G,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!pe(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=ut[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let B=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${B} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,B),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((B,h)=>B*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(B=>B.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},D=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},K={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},$=await n.signTypedData({domain:C,types:D,primaryType:"Payment",message:K});this.log("EIP-712 Payment signature obtained");let U={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:$};return{serialized:JSON.stringify(U),signature:$}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,G),u;if(c<BigInt(a)){let C=this.encodeApprove(G,Ft);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let D=this.getChainId(e.network),K=await this.readGasPrice(i),$=await this.readNonce(i,n.address),U=await n.signTransaction({to:o,data:C,chainId:D,gas:50000n,gasPrice:K,nonce:$});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:G,amount:Ft.toString(),signedTransaction:U,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let D=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${D}`),await this.waitForReceipt(i,D),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,D)=>C*256n+BigInt(D),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:G},g={permitted:{token:o,amount:BigInt(a)},spender:Xe,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:Un,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:Xe,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function Pe(t){return new dt(t)}function kt(t){if(t===ze||t===Lt)return!0;let e=t.toLowerCase();for(let n of Object.values(ct))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(lt))if(n.toLowerCase()===e)return!0;return!1}function Dn(t){return{[De]:"Solana",[st]:"Solana Devnet",[ot]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[ne]:"Base",[Se]:"Base Sepolia",[Re]:"Ethereum",[we]:"Arbitrum",[Te]:"Polygon",[xe]:"Optimism",[Ee]:"Avalanche",[ve]:"BSC",[re]:"World Chain",[se]:"Monad",[oe]:"Robinhood Chain",[ae]:"SKALE Base",[ie]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function qt(t,e){let n=Dn(t);return n===t?e:n}async function Bn(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Mn=new WeakMap;function jt(t){let{adapters:e=[z({verbose:t.verbose}),Pe({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,L=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:L}),l("Access pass cached for",E,"| expires:",new Date(L*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&me(r)&&(b.solana=r),r&&!b.evm&&pe(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function D(h,w){return qt(h,w)}function K(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function $(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let L=E.headers.get("PAYMENT-REQUIRED");if(!L)return null;let M;try{M=JSON.parse(atob(L))}catch{return null}let N=C(M.accepts);if(!N)return null;let{accept:k,adapter:W,wallet:de}=N;if(W.name==="Solana"&&!k.extra?.feePayer)return null;let F=k.extra?.decimals??(kt(k.asset)?6:void 0);if(typeof F!="number")return null;let _e=k.amount??k.maxAmountRequired;if(!_e)return null;let q=K(k.network,W);try{let m=await W.getBalance(k,de,q),S=Number(_e)/Math.pow(10,F);if(m<S){let ht=D(k.network,W.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${ht}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let j=await W.buildTransaction(k,de,q),fe;W.name==="EVM"?fe=JSON.parse(j.serialized):fe={transaction:j.serialized};let X=typeof h=="string"?h:h instanceof URL?h.href:h.url,ge=M.resource;if(typeof M.resource=="string")try{let m=new URL(M.resource,X);["http:","https:"].includes(m.protocol)&&(ge=m.toString())}catch{}else if(M.resource&&typeof M.resource=="object"&&"url"in M.resource){let m=M.resource;try{let S=new URL(m.url,X);["http:","https:"].includes(S.protocol)&&(ge={...m,url:S.toString()})}catch{}}let Ze={x402Version:k.x402Version??2,resource:ge,accepted:k,payload:fe};j.extensions&&(Ze.extensions=j.extensions);let J=btoa(JSON.stringify(Ze)),Y=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":J}});if(!Y.ok)return l("Pass purchase failed:",Y.status),null;let V=Y.headers.get("ACCESS-PASS");return V&&(y(v,V),l("Access pass purchased and cached")),Y}async function U(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await $(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let L=A.headers.get("X-Quote-Hash");L&&l("Quote hash received:",L);let M=C(_.accepts);if(!M){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:N,adapter:k,wallet:W}=M;if(l(`Using ${k.name} for ${N.network}`),k.name==="Solana"&&!N.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let de=N.extra?.decimals??(kt(N.asset)?6:void 0);if(typeof de!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let F=N.amount??N.maxAmountRequired;if(!F)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(F)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${F} exceeds maximum ${a}`);let _e=K(N.network,k);l("Checking balance...");try{let m=await k.getBalance(N,W,_e),S=Number(F)/Math.pow(10,de);if(m<S){let ht=D(N.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${ht}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(N))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let q=await k.buildTransaction(N,W,_e);l("Transaction signed");let j;k.name==="EVM"?j=JSON.parse(q.serialized):j={transaction:q.serialized};let fe=h,X=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,fe).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),X=m}catch{X=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,fe).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),X={...m,url:S})}catch{}}let ge={x402Version:N.x402Version??2,resource:X,accepted:N,payload:j};q.extensions&&(ge.extensions=q.extensions);let Ze=btoa(JSON.stringify(ge));if(d)try{d(N,q.settlementProbe)}catch{}l("Retrying request with payment...");let J=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":Ze,...L?{"X-Quote-Hash":L}:{}}});if(l("Retry response status:",J.status),J.status===402){let m="unknown";try{let S=await J.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let Y=J.headers.get("PAYMENT-RESPONSE"),V;if(Y)try{V=JSON.parse(atob(Y))}catch{}return V??={},V.amountAtomic=F,V.assetDecimals=de,Mn.set(J,V),V.extensions&&l("Settlement extensions:",Object.keys(V.extensions).join(", ")),J}async function B(h,w){let[E,A]=await Bn(h,w);return U(E,A)}return{fetch:B}}function H(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function Qe(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var ft="Payment authorization was sent, but the merchant did not respond within the timeout. ",gt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function yt(t,e,n){if(!t)return{confirmed:!1,detail:ft+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+gt};try{if(t.kind==="solana"){let a=z(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return Gt();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:Jt()}let r=Pe(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return Gt();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:Jt()}catch(r){return{confirmed:!1,detail:ft+`On-chain confirmation could not be completed (${H(r)}).`+gt}}}function Jt(){return{confirmed:!1,detail:ft+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+gt}}function Gt(){return{confirmed:!1,detail:ft+"The chain adapter does not support on-chain confirmation."+gt}}var $n=new Set(["exact","exact-approval"]);async function Kn(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",nt(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await Qe(i)}}var zt={version:2,async parseChallenge(t){return rt(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await Kn(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>$n.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=jt({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await Qe(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=vt(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await yt(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};import{getAddress as Ln}from"viem";var Vn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Wn(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function Hn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Wn()},i=Ye[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:Ln(e.asset)},types:Vn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function It(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await Fn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await qn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:H(r)}}}async function Fn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await Hn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function qn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await z().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function jn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=Oe(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var Xt={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=jn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await It(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:Jn(y)}:{ok:!1,...await Qe(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await yt(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:H(p)}}finally{o!==void 0&&clearTimeout(o)}}};function Jn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}import*as Qt from"tweetnacl";import{Keypair as Es,VersionedTransaction as vs,Transaction as Rs}from"@solana/web3.js";var Yt=Symbol.for("x402:keypair");function Nt(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[Yt];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>Qt.sign.detached(s,r.secretKey)}}return null}var Gn=[zt,Xt];async function zn(t){let e=Nt(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${H(n)}`),fetch}}async function Ot(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await zn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:H(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of Gn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function Xn(t,e={},n){let r=await Ue(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(Z(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await Tt({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Ot(t,e,{},{tab:a}),tab:a}}function Yn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:Ae(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function Qn(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await Ue(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==ze)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Yn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}export{Ce as DEFAULT_FACILITATOR_URL,xt as DEXTER_VAULT_PROGRAM_ID,gn as INSTRUCTIONS_SYSVAR_ID,At as LiveSessionExistsError,fn as SECP256R1_PROGRAM_ID,he as SessionScopeExceededError,Q as TabClosedError,ye as UnsupportedNetworkError,Ae as atomicToHuman,mn as buildRegisterSessionKeyInstruction,pn as buildRevokeSessionKeyInstruction,dn as buildSecp256r1VerifyInstruction,en as buildVoucherMessage,Z as humanToAtomic,Tt as openTab,Xn as payUrlWithTab,Ue as resolveTabOffer,Qn as resolveTabTerms,an as resumeTab,bt as sessionRegisterMessage,Zt as sessionRevokeMessage,wn as tabFromGrant,St as voucherPayloadMessage,nt as voucherToHeader};
6
+ `):null}}import Ue from"tweetnacl";import{Connection as An,PublicKey as Oe}from"@solana/web3.js";import{bytesToHex as bn}from"@noble/hashes/utils";import{fetchSessionAccount as Sn,isSessionLive as wn}from"@dexterai/vault/session";import{readVaultFull as Tn}from"@dexterai/vault/reader";import{buildRegisterSessionKeyInstruction as dn,buildRevokeSessionKeyInstruction as fn,deriveSwigWalletAddress as gr}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as gn}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as vt,SECP256R1_PROGRAM_ID as yn,INSTRUCTIONS_SYSVAR_ID as hn}from"@dexterai/vault/constants";var Rt="solana:mainnet";async function xn(t){let e=t.facilitatorUrl??Ie,n=t.programId??vt,r=new Oe(t.vaultPda),s=new Oe(t.params.counterparty),o=Ae(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=Ae(t.params.maxAmountAtomic),i=Ae(t.params.maxRevolvingCapacityAtomic),c=En(t.sessionSecretKey),u=new Oe(t.params.sessionPubkey).toBytes();if(!Kt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new Oe(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ue.randomBytes(32),d=Ue.sign.detached(p,c.secretKey);if(!Ue.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=St({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new An(t.connection,"confirmed"):t.connection,l=await Sn(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!wn(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Kt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new Oe(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=ke({vaultPda:r,sellerUrl:x,nonce:g}),b=bn(y),C=t.swigAddress;if(!C){let U=await Tn(T,r);if(!U.exists||!U.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=U.swigAddress}await rt(e,C,a,Rt,t.params.counterparty);let D={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},K=Tt({publicKey:c.publicKey,privateKey:c.secretKey},D,f),$={network:Rt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(U,B)=>xt(U,B,y),signOpenTab:async U=>U.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Ne({vault:$,network:Rt,seller:x,counterparty:t.params.counterparty,session:K,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function En(t){if(t.length===64)return Ue.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ue.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Kt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}import{PublicKey as _n}from"@solana/web3.js";var Lt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],vn=new Map(Lt.map(t=>[t.caip2.toLowerCase(),t])),Rn=new Map(Lt.map(t=>[t.bare.toLowerCase(),t]));function De(t){if(!t)return null;let e=t.toLowerCase(),n=vn.get(e)||Rn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Pt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function Pn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function st(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Pt(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:Pn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function Be(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await st(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new _n(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Me="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ot="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",at="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",te=Me,$e=ot,Ke=at,ne="eip155:8453",we="eip155:84532",Te="eip155:42161",xe="eip155:137",Ee="eip155:10",ve="eip155:43114",Re="eip155:56",re="eip155:480",se="eip155:143",oe="eip155:4663",ae="eip155:1187947933",ie="eip155:324705682",Pe="eip155:1",ce=ne,it=we,Le=Te,Ve=xe,We=Ee,He=ve,Fe=Re,qe=re,je=se,Je=oe,Ge=ae,ze=ie,Xe=Pe,Ye="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Vt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Wt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",_t="0x55d398326f99059fF775485246999027B3197955",ct="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ct="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",lt={[Re]:ct,[ne]:Wt,[we]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Te]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[xe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ee]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[ve]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[re]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[se]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[oe]:Ct,[ae]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ie]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Pe]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ut={[_t]:{symbol:"USDT",decimals:18},[ct]:{symbol:"USDC",decimals:18}};var mt={[re]:{name:"USDC",version:"2"},[se]:{name:"USDC",version:"2"},[oe]:{name:"Global Dollar",version:"1"},[ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[ie]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},G="0x000000000022D473030F116dDEE9F6B43aC78BA3",Qe="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",Ze={[Re]:56,[ne]:8453,[we]:84532,[Te]:42161,[xe]:137,[Ee]:10,[ve]:43114,[re]:480,[se]:143,[oe]:4663,[ae]:1187947933,[ie]:324705682,[Pe]:1},le={[Me]:"https://api.dexter.cash/api/solana/rpc",[ot]:"https://api.devnet.solana.com",[at]:"https://api.testnet.solana.com"},O={[Re]:"https://api.dexter.cash/api/evm/bsc/rpc",[ne]:"https://api.dexter.cash/api/base/rpc",[we]:"https://sepolia.base.org",[Te]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[xe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ee]:"https://api.dexter.cash/api/evm/optimism/rpc",[ve]:"https://api.dexter.cash/api/evm/avalanche/rpc",[re]:"https://worldchain-mainnet.g.alchemy.com/public",[se]:"https://rpc.monad.xyz",[oe]:"https://rpc.mainnet.chain.robinhood.com",[ae]:"https://skale-base.skalenodes.com/v1/base",[ie]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Pe]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};import{PublicKey as ue,Connection as kt,TransactionMessage as Cn,VersionedTransaction as kn,ComputeBudgetProgram as Ht}from"@solana/web3.js";import{getAssociatedTokenAddress as It,getAccount as In,createTransferCheckedInstruction as Nn,getMint as On,TOKEN_PROGRAM_ID as Ft,TOKEN_2022_PROGRAM_ID as pt}from"@solana/spl-token";var Un=12e3,Dn=1;function me(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var dt=class{name="Solana";networks=[te,$e,Ke];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:le[e]?le[e]:e==="solana"?le[te]:e==="solana-devnet"?le[$e]:e==="solana-testnet"?le[Ke]:le[te]}getAddress(e){return me(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return me(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!me(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),i=new ue(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===pt.toBase58()?pt:Ft,p=await It(i,a,!1,u),d=await In(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!me(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new ue(u.feePayer),f=new ue(c),T=new ue(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(Ht.setComputeUnitLimit({units:Un})),l.push(Ht.setComputeUnitPrice({microLamports:Dn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===pt.toBase58()?pt:Ft,g=await On(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await It(f,a,!1,x),b=await It(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let K=BigInt(p);l.push(Nn(y,f,b,a,K,g.decimals,[],x));let{blockhash:$}=await o.getLatestBlockhash("confirmed"),U=new Cn({payerKey:d,recentBlockhash:$,instructions:l}).compileToV0Message(),B=new kn(U),h=await n.signTransaction(B);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:$}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new kt(n,"confirmed"),s=new ue(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function z(t){return new dt(t)}var Bn={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},qt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function pe(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var ft=class{name="EVM";networks=[Fe,ce,it,Xe,Le,Ve,We,He,qe,je,Je,Ge,ze];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:O[e]?O[e]:e==="base"?O[ce]:e==="bsc"?O[Fe]:e==="ethereum"?O[Xe]:e==="arbitrum"?O[Le]:e==="polygon"?O[Ve]:e==="optimism"?O[We]:e==="avalanche"?O[He]:e==="world"?O[qe]:e==="monad"?O[je]:e==="robinhood"?O[Je]:e==="skale-base"?O[Ge]:e==="skale-base-sepolia"?O[ze]:O[ce]}getAddress(e){return pe(e)?e.address:null}isConnected(e){return pe(e)?!!e.address:!1}getChainId(e){if(Ze[e])return Ze[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!pe(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,G,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!pe(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=mt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let B=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${B} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,B),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((B,h)=>B*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(B=>B.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},D=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},K={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},$=await n.signTypedData({domain:C,types:D,primaryType:"Payment",message:K});this.log("EIP-712 Payment signature obtained");let U={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:$};return{serialized:JSON.stringify(U),signature:$}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,G),u;if(c<BigInt(a)){let C=this.encodeApprove(G,qt);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let D=this.getChainId(e.network),K=await this.readGasPrice(i),$=await this.readNonce(i,n.address),U=await n.signTransaction({to:o,data:C,chainId:D,gas:50000n,gasPrice:K,nonce:$});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:G,amount:qt.toString(),signedTransaction:U,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let D=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${D}`),await this.waitForReceipt(i,D),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,D)=>C*256n+BigInt(D),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:G},g={permitted:{token:o,amount:BigInt(a)},spender:Qe,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:Bn,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:Qe,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function _e(t){return new ft(t)}function Nt(t){if(t===Ye||t===Vt)return!0;let e=t.toLowerCase();for(let n of Object.values(lt))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(ut))if(n.toLowerCase()===e)return!0;return!1}function Mn(t){return{[Me]:"Solana",[ot]:"Solana Devnet",[at]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[ne]:"Base",[we]:"Base Sepolia",[Pe]:"Ethereum",[Te]:"Arbitrum",[xe]:"Polygon",[Ee]:"Optimism",[ve]:"Avalanche",[Re]:"BSC",[re]:"World Chain",[se]:"Monad",[oe]:"Robinhood Chain",[ae]:"SKALE Base",[ie]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function jt(t,e){let n=Mn(t);return n===t?e:n}async function $n(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Kn=new WeakMap;function Jt(t){let{adapters:e=[z({verbose:t.verbose}),_e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,L=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:L}),l("Access pass cached for",E,"| expires:",new Date(L*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&me(r)&&(b.solana=r),r&&!b.evm&&pe(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function D(h,w){return jt(h,w)}function K(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function $(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let L=E.headers.get("PAYMENT-REQUIRED");if(!L)return null;let M;try{M=JSON.parse(atob(L))}catch{return null}let N=C(M.accepts);if(!N)return null;let{accept:k,adapter:W,wallet:de}=N;if(W.name==="Solana"&&!k.extra?.feePayer)return null;let F=k.extra?.decimals??(Nt(k.asset)?6:void 0);if(typeof F!="number")return null;let Ce=k.amount??k.maxAmountRequired;if(!Ce)return null;let q=K(k.network,W);try{let m=await W.getBalance(k,de,q),S=Number(Ce)/Math.pow(10,F);if(m<S){let At=D(k.network,W.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${At}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let j=await W.buildTransaction(k,de,q),fe;W.name==="EVM"?fe=JSON.parse(j.serialized):fe={transaction:j.serialized};let X=typeof h=="string"?h:h instanceof URL?h.href:h.url,ge=M.resource;if(typeof M.resource=="string")try{let m=new URL(M.resource,X);["http:","https:"].includes(m.protocol)&&(ge=m.toString())}catch{}else if(M.resource&&typeof M.resource=="object"&&"url"in M.resource){let m=M.resource;try{let S=new URL(m.url,X);["http:","https:"].includes(S.protocol)&&(ge={...m,url:S.toString()})}catch{}}let tt={x402Version:k.x402Version??2,resource:ge,accepted:k,payload:fe};j.extensions&&(tt.extensions=j.extensions);let J=btoa(JSON.stringify(tt)),Y=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":J}});if(!Y.ok)return l("Pass purchase failed:",Y.status),null;let V=Y.headers.get("ACCESS-PASS");return V&&(y(v,V),l("Access pass purchased and cached")),Y}async function U(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await $(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let L=A.headers.get("X-Quote-Hash");L&&l("Quote hash received:",L);let M=C(_.accepts);if(!M){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:N,adapter:k,wallet:W}=M;if(l(`Using ${k.name} for ${N.network}`),k.name==="Solana"&&!N.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let de=N.extra?.decimals??(Nt(N.asset)?6:void 0);if(typeof de!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let F=N.amount??N.maxAmountRequired;if(!F)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(F)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${F} exceeds maximum ${a}`);let Ce=K(N.network,k);l("Checking balance...");try{let m=await k.getBalance(N,W,Ce),S=Number(F)/Math.pow(10,de);if(m<S){let At=D(N.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${At}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(N))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let q=await k.buildTransaction(N,W,Ce);l("Transaction signed");let j;k.name==="EVM"?j=JSON.parse(q.serialized):j={transaction:q.serialized};let fe=h,X=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,fe).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),X=m}catch{X=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,fe).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),X={...m,url:S})}catch{}}let ge={x402Version:N.x402Version??2,resource:X,accepted:N,payload:j};q.extensions&&(ge.extensions=q.extensions);let tt=btoa(JSON.stringify(ge));if(d)try{d(N,q.settlementProbe)}catch{}l("Retrying request with payment...");let J=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":tt,...L?{"X-Quote-Hash":L}:{}}});if(l("Retry response status:",J.status),J.status===402){let m="unknown";try{let S=await J.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let Y=J.headers.get("PAYMENT-RESPONSE"),V;if(Y)try{V=JSON.parse(atob(Y))}catch{}return V??={},V.amountAtomic=F,V.assetDecimals=de,Kn.set(J,V),V.extensions&&l("Settlement extensions:",Object.keys(V.extensions).join(", ")),J}async function B(h,w){let[E,A]=await $n(h,w);return U(E,A)}return{fetch:B}}function H(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function et(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var gt="Payment authorization was sent, but the merchant did not respond within the timeout. ",yt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function ht(t,e,n){if(!t)return{confirmed:!1,detail:gt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+yt};try{if(t.kind==="solana"){let a=z(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return zt();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:Gt()}let r=_e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return zt();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:Gt()}catch(r){return{confirmed:!1,detail:gt+`On-chain confirmation could not be completed (${H(r)}).`+yt}}}function Gt(){return{confirmed:!1,detail:gt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+yt}}function zt(){return{confirmed:!1,detail:gt+"The chain adapter does not support on-chain confirmation."+yt}}var Ln=new Set(["exact","exact-approval"]);async function Vn(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",nt(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await et(i)}}var Xt={version:2,async parseChallenge(t){return st(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await Vn(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Ln.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=Jt({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await et(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Pt(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await ht(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};import{getAddress as Wn}from"viem";var Hn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Fn(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function qn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Fn()},i=Ze[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:Wn(e.asset)},types:Hn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Ot(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await jn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Jn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:H(r)}}}async function jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await qn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await z().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Gn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var Yt={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Gn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Ot(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:zn(y)}:{ok:!1,...await et(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await ht(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:H(p)}}finally{o!==void 0&&clearTimeout(o)}}};function zn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}import*as Zt from"tweetnacl";import{Keypair as Rs,VersionedTransaction as Ps,Transaction as _s}from"@solana/web3.js";var Qt=Symbol.for("x402:keypair");function Ut(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[Qt];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>Zt.sign.detached(s,r.secretKey)}}return null}var Xn=[Xt,Yt];async function Yn(t){let e=Ut(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${H(n)}`),fetch}}async function Dt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Yn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:H(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of Xn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function Qn(t,e={},n){let r=await Be(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(Z(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await Et({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Dt(t,e,{},{tab:a}),tab:a}}function Zn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:be(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function er(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await Be(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==Ye)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Zn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}export{Ie as DEFAULT_FACILITATOR_URL,vt as DEXTER_VAULT_PROGRAM_ID,hn as INSTRUCTIONS_SYSVAR_ID,bt as LiveSessionExistsError,yn as SECP256R1_PROGRAM_ID,he as SessionScopeExceededError,Q as TabClosedError,ye as UnsupportedNetworkError,rt as armTabOpen,be as atomicToHuman,dn as buildRegisterSessionKeyInstruction,fn as buildRevokeSessionKeyInstruction,gn as buildSecp256r1VerifyInstruction,tn as buildVoucherMessage,ke as deriveChannelId,nn as generateSessionKeypair,Z as humanToAtomic,Tt as makeSessionKey,Et as openTab,Ae as parseAtomic,Qn as payUrlWithTab,Be as resolveTabOffer,er as resolveTabTerms,ln as resumeTab,rn as scopeCapAtomic,St as sessionRegisterMessage,en as sessionRevokeMessage,xt as signVoucher,xn as tabFromGrant,wt as voucherPayloadMessage,nt as voucherToHeader};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexterai/x402",
3
- "version": "5.4.0",
3
+ "version": "5.4.2",
4
4
  "description": "Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, World Chain, Monad, Robinhood Chain, SKALE.",
5
5
  "author": "Dexter",
6
6
  "license": "MIT",