@dexterai/x402 6.0.0-rc.5 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/README.md +5 -1
- package/REFERENCE.md +33 -3
- package/dist/adapters/index.cjs +1 -1
- package/dist/adapters/index.d.cts +3 -2
- package/dist/adapters/index.d.ts +3 -2
- package/dist/adapters/index.js +1 -1
- package/dist/batch-settlement/index.cjs +1 -1
- package/dist/batch-settlement/index.d.cts +4 -3
- package/dist/batch-settlement/index.d.ts +4 -3
- package/dist/batch-settlement/index.js +1 -1
- package/dist/batch-settlement/seller/index.cjs +1 -1
- package/dist/batch-settlement/seller/index.d.cts +5 -4
- package/dist/batch-settlement/seller/index.d.ts +5 -4
- package/dist/batch-settlement/seller/index.js +1 -1
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +7 -4
- package/dist/client/index.d.ts +7 -4
- package/dist/client/index.js +1 -1
- package/dist/mcp/index.cjs +1 -0
- package/dist/mcp/index.d.cts +183 -0
- package/dist/mcp/index.d.ts +183 -0
- package/dist/mcp/index.js +1 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +4 -4
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +5 -4
- package/dist/server/index.d.ts +5 -4
- package/dist/server/index.js +1 -1
- package/dist/sponsored-access-ByM3apeR.d.cts +69 -0
- package/dist/sponsored-access-ByM3apeR.d.ts +69 -0
- package/dist/tab/adapters/solana/index.cjs +1 -1
- package/dist/tab/adapters/solana/index.js +1 -1
- package/dist/tab/index.cjs +4 -4
- package/dist/tab/index.d.cts +4 -2
- package/dist/tab/index.d.ts +4 -2
- package/dist/tab/index.js +5 -5
- package/dist/tab/seller/index.cjs +7 -7
- package/dist/tab/seller/index.js +1 -1
- package/dist/types-8Q38sHOi.d.cts +237 -0
- package/dist/types-8Q38sHOi.d.ts +237 -0
- package/dist/{types-BvQpNtFw.d.cts → types-B4JCwkHH.d.cts} +2 -236
- package/dist/{types-DwVhPqOZ.d.ts → types-BOEYu6ya.d.cts} +4 -2
- package/dist/{types-CkcNYx1Q.d.ts → types-BdUPQzXu.d.ts} +1 -1
- package/dist/{types-JpkrtFbZ.d.cts → types-CTYEYNZO.d.cts} +1 -1
- package/dist/{types-BbvuPNXl.d.cts → types-DhCxPFgg.d.ts} +4 -2
- package/dist/{types-BvQpNtFw.d.ts → types-Ds9IUnXG.d.ts} +2 -236
- package/dist/{types-CBQKKFxJ.d.cts → types-G6MIMJjK.d.cts} +19 -5
- package/dist/{types-CHQzNDR6.d.ts → types-zImyINj3.d.ts} +19 -5
- package/dist/x402-client-Cil4Tmqy.d.cts +93 -0
- package/dist/x402-client-Cil4Tmqy.d.ts +93 -0
- package/docs/mcp.md +98 -0
- package/examples/mcp-paid-tool.ts +39 -0
- package/package.json +16 -10
- package/dist/x402-client-B8zdDeat.d.cts +0 -146
- package/dist/x402-client-B8zdDeat.d.ts +0 -146
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [6.0.1] - 2026-09-17
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- HTTP buyers reject unsupported payment flows and transfer methods before
|
|
15
|
+
signing. HTTP and MCP buyers refuse required payment identifiers until the
|
|
16
|
+
client can satisfy them.
|
|
17
|
+
- `payAndFetch` keeps pending, missing, malformed or mismatched receipts
|
|
18
|
+
unconfirmed. Failures retain the merchant response, transaction identifier
|
|
19
|
+
and receipt so callers can recover the same purchase. Receipts expose the
|
|
20
|
+
authorized amount as `attemptedAmountAtomic`; `amountAtomic` requires a
|
|
21
|
+
matching successful settlement receipt.
|
|
22
|
+
- Paid HTTP error responses retain their original receipts, including HTTP
|
|
23
|
+
402. `capturePaymentReceipt` lets prepared-purchase clients apply the same
|
|
24
|
+
classification. A settled payment with an unsuccessful merchant response
|
|
25
|
+
returns `delivery_failed`, with its receipt available for result recovery.
|
|
26
|
+
- Bazaar route validation rejects nested percent-encoded traversal and URL
|
|
27
|
+
schemes.
|
|
28
|
+
|
|
29
|
+
## [6.0.0] - 2026-09-16
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- `@dexterai/x402/mcp` provides native x402 v2 MCP challenge, object proof and
|
|
34
|
+
receipt helpers, a seller adapter with required durable admission storage,
|
|
35
|
+
and a buyer helper that dispatches one approved payment while retaining the
|
|
36
|
+
complete tool result. Uncertain outcomes require recovery of the original
|
|
37
|
+
operation. The default processor supports exact authorization payments on
|
|
38
|
+
explicitly configured networks; Tasks and other payment flows require
|
|
39
|
+
application integration. See [the MCP guide](./docs/mcp.md).
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Updates `@x402/core`, `@x402/evm`, and `@x402/extensions` from 2.12.0 to 2.26.0
|
|
44
|
+
and uses the upstream file-storage entrypoints.
|
|
45
|
+
- Batch buyers preserve the exact USDC deposit specified by the caller. Each
|
|
46
|
+
handle uses one channel configuration and refuses automatic top-ups or a
|
|
47
|
+
second initial funding attempt. Requests and cumulative vouchers stay within
|
|
48
|
+
the authorized budget, including when recovering a larger existing escrow.
|
|
49
|
+
- `resumeBatchChannel` accepts `maxAmountPerPayment` in USDC, with a default of
|
|
50
|
+
`"1"`. Resume spends existing escrow and refuses new funding. Deposit and
|
|
51
|
+
per-call amounts exceeding six decimal places are rejected before signing.
|
|
52
|
+
|
|
53
|
+
- Promotes the V2 Tab buyer and seller contracts from the v6 release candidates.
|
|
54
|
+
Install with the exact peer `@dexterai/vault@0.43.4` and Node.js 22 or newer.
|
|
55
|
+
- Fresh grants require a `reserveFinalVoucherV2` provider that returns a confirmed,
|
|
56
|
+
voucher-bound reservation receipt. The SDK verifies the transaction and account
|
|
57
|
+
state before releasing the voucher. Historical V1 buyer grants require migration.
|
|
58
|
+
- Existing seller integrations must adopt the fenced ledger and asynchronous
|
|
59
|
+
metering contracts described under 6.0.0-rc.3 before upgrading from v5.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- Reservation verification accepts the known Swig binding versions, including
|
|
64
|
+
attested V3 and automation V4 identities, using the Vault SDK's identity check.
|
|
65
|
+
Unknown versions remain rejected. This preserves the V3 fix previously used in
|
|
66
|
+
the unpublished 6.0.0-rc.6 artifact.
|
|
67
|
+
- CI now installs the packed release in a fresh consumer and verifies the public
|
|
68
|
+
ESM and CommonJS Tab exports, V2 signatures, reservation checks and retry identity.
|
|
69
|
+
|
|
70
|
+
These checks use local fixtures. Hosted checkout and live settlement require
|
|
71
|
+
their own deployment and transaction verification.
|
|
72
|
+
|
|
10
73
|
## [6.0.0-rc.5] - 2026-08-17
|
|
11
74
|
|
|
12
75
|
### Fixed
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<a href="https://www.npmjs.com/package/@dexterai/x402"><img src="https://img.shields.io/npm/v/@dexterai/x402.svg" alt="npm"></a>
|
|
17
|
-
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E=
|
|
17
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E=22-brightgreen.svg" alt="Node"></a>
|
|
18
18
|
<img src="https://img.shields.io/badge/non--custodial-passkey-brightgreen" alt="Non-custodial">
|
|
19
19
|
<a href="https://dexter.cash/sdk"><img src="https://img.shields.io/badge/Try_it-real_payments-blueviolet" alt="Live Demo"></a>
|
|
20
20
|
</p>
|
|
@@ -176,6 +176,8 @@ The screen is hosted for a structural reason, not a stylistic one: the vault's p
|
|
|
176
176
|
|
|
177
177
|
Tabs are the headline. The same install carries the rest of the x402 surface — each documented in full in [REFERENCE.md](./REFERENCE.md).
|
|
178
178
|
|
|
179
|
+
Paid MCP tools use the `@dexterai/x402/mcp` entrypoint. The [MCP guide](./docs/mcp.md) covers the seller adapter, durable storage contract, and buyer dispatch with complete result preservation.
|
|
180
|
+
|
|
179
181
|
- **One-shot payments** — a single discrete purchase over HTTP `402`, USDC on Solana and the major EVM chains. `payAndFetch` (client), `x402Middleware` (server), `useX402Payment` (React).
|
|
180
182
|
- **Batch settlement (EVM)** — prepay an escrow once, make many paid calls with off-chain vouchers, settle in a handful of transactions to amortize gas. `openBatchChannel`.
|
|
181
183
|
- **Discovery** — make any protected route findable by capability through the x402 bazaar spec. `bazaarExtension()`.
|
|
@@ -205,6 +207,8 @@ Tabs are Solana. One-shot and batch settlement span Solana and the major EVM cha
|
|
|
205
207
|
|
|
206
208
|
## More
|
|
207
209
|
|
|
210
|
+
Release maintainers can follow the [GitHub OIDC publishing workflow](./docs/releases.md).
|
|
211
|
+
|
|
208
212
|
- **[REFERENCE.md](./REFERENCE.md)** — every export, option table, and example: tabs, one-shot, batch settlement, discovery.
|
|
209
213
|
- **Upgrading?** v6 pins the tested Vault `0.43.2` pair, requires voucher-bound V2 reservation receipts, and uses exact-state V3 revocation. Migration from v5/v4/v3: [REFERENCE.md](./REFERENCE.md#migration).
|
|
210
214
|
- **License** — MIT, see [LICENSE](./LICENSE).
|
package/REFERENCE.md
CHANGED
|
@@ -42,7 +42,7 @@ import { createSolanaAdapter, createEvmAdapter } from '@dexterai/x402/adapters';
|
|
|
42
42
|
import { toAtomicUnits, fromAtomicUnits } from '@dexterai/x402/utils';
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
> `@dexterai/vault` is an exact **peer dependency** at `0.43.
|
|
45
|
+
> `@dexterai/vault` is an exact **peer dependency** at `0.43.4`: install it alongside the matching v6 x402 package so the adapter, revocation wire, and your app use one tested Vault contract.
|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
@@ -105,7 +105,7 @@ Builds the `vault` adapter the buyer calls drive through.
|
|
|
105
105
|
| `passkeySigner` | `PasskeySignerWithPublicKey` | A `signOperation(operationMessage)` signer (see below) |
|
|
106
106
|
| `feePayer` | `Signer` | Lamport fee payer |
|
|
107
107
|
|
|
108
|
-
The `passkeySigner` uses Vault 0.43.
|
|
108
|
+
The `passkeySigner` uses Vault 0.43.4's canonical shape: `{ credentialId, publicKey, signOperation(operationMessage) }`. The adapter passes the raw operation bytes. The signer obtains the canonical V7 200-byte challenge binding the fixed program, exact vault, current monotonic authorization nonce, operation hash, and fresh ceremony entropy; the adapter owns only the precompile assembly. Do not substitute a bare `sha256(operationMessage)` challenge for V7 operations.
|
|
109
109
|
|
|
110
110
|
- **Browser:** vault's `DexterApiBrowserPasskeySigner` — drops in with no shim.
|
|
111
111
|
- **CLI / server agent:** `passkeySignerFromP256Keypair(kp, { resolveAuthorizationContext })` from `@dexterai/x402/tab/adapters/solana`, wrapping a locally-held P-256 keypair. The resolver must read the current `PasskeyAuthorization` state immediately before a revoke ceremony; the helper never guesses that nonce.
|
|
@@ -346,7 +346,37 @@ console.log(escrow.state); // { deposited: '0.3', spent: '0.16', remaining: '0.1
|
|
|
346
346
|
await escrow.close();
|
|
347
347
|
```
|
|
348
348
|
|
|
349
|
-
|
|
349
|
+
`deposit` is a fixed USDC budget. Opening with `deposit: '10'` authorizes one
|
|
350
|
+
$10 deposit and purchases within that total, including a single purchase above
|
|
351
|
+
$1. Amounts support at most six decimal places. The handle binds to the first
|
|
352
|
+
channel configuration it uses and rejects a different seller, token, or
|
|
353
|
+
withdrawal delay. Exhaustion stops spending; funding another channel requires a
|
|
354
|
+
new `openBatchChannel` call.
|
|
355
|
+
|
|
356
|
+
Give each channel one owner and persist its salt and channel store. After a
|
|
357
|
+
funding attempt with an uncertain outcome, the handle refuses another deposit
|
|
358
|
+
signature. Reconcile that attempt before resuming the existing channel. Use
|
|
359
|
+
`resumeBatchChannel` after a process restart; it spends existing escrow and
|
|
360
|
+
refuses requests that require more funding. Its default per-call limit is one
|
|
361
|
+
USDC. Set a higher limit explicitly when needed:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { resumeBatchChannel } from '@dexterai/x402/batch-settlement';
|
|
365
|
+
|
|
366
|
+
const resumed = await resumeBatchChannel({
|
|
367
|
+
wallet: evmWallet,
|
|
368
|
+
network: 'eip155:8453',
|
|
369
|
+
salt: savedSalt,
|
|
370
|
+
store: savedChannelStore,
|
|
371
|
+
maxAmountPerPayment: '2.00',
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
If the seller never settles, reclaim unspent escrow with `forceWithdraw()` then
|
|
376
|
+
`finalizeWithdraw()`. The seller mounts `createBatchSettlementSeller(config)` as
|
|
377
|
+
an Express handler; Dexter operates the authorizer, so the seller manages no
|
|
378
|
+
signing key. The returned handler exposes `.stop()`, `.closeAll()`, and
|
|
379
|
+
`.closeChannel(id)`.
|
|
350
380
|
|
|
351
381
|
---
|
|
352
382
|
|
package/dist/adapters/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var Rt=Object.create;var ct=Object.defineProperty;var bt=Object.getOwnPropertyDescriptor;var Ot=Object.getOwnPropertyNames;var Bt=Object.getPrototypeOf,vt=Object.prototype.hasOwnProperty;var Mt=(c,t)=>{for(var e in t)ct(c,e,{get:t[e],enumerable:!0})},Nt=(c,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ot(t))!vt.call(c,r)&&r!==e&&ct(c,r,{get:()=>t[r],enumerable:!(o=bt(t,r))||o.enumerable});return c};var dt=(c,t,e)=>(e=c!=null?Rt(Bt(c)):{},Nt(t||!c||!c.__esModule?ct(e,"default",{value:c,enumerable:!0}):e,c)),Lt=c=>Nt(ct({},"__esModule",{value:!0}),c);var Ht={};Mt(Ht,{ARBITRUM_ONE:()=>v,AVALANCHE:()=>U,BASE_MAINNET:()=>P,BASE_SEPOLIA:()=>et,BSC_MAINNET:()=>W,BSC_STABLECOIN_ADDRESSES:()=>ot,BSC_USDC:()=>nt,BSC_USDT:()=>St,EIP712_DOMAINS:()=>st,ETHEREUM_MAINNET:()=>H,EvmAdapter:()=>it,MONAD_MAINNET:()=>K,OPTIMISM:()=>L,PERMIT2_ADDRESS:()=>_,POLYGON:()=>M,ROBINHOOD_MAINNET:()=>F,ROBINHOOD_USDG:()=>ht,SKALE_BASE:()=>j,SKALE_BASE_SEPOLIA:()=>V,SOLANA_DEVNET:()=>O,SOLANA_MAINNET:()=>w,SOLANA_TESTNET:()=>B,SolanaAdapter:()=>at,USDC_ADDRESSES:()=>rt,WORLD_MAINNET:()=>k,X402_EXACT_PERMIT2_PROXY:()=>$,createDefaultAdapters:()=>jt,createEvmAdapter:()=>yt,createSolanaAdapter:()=>Tt,findAdapter:()=>Vt,isEvmWallet:()=>G,isKnownUSDC:()=>Ft,isSolanaWallet:()=>q});module.exports=Lt(Ht);var m=require("@solana/web3.js"),f=require("@solana/spl-token");var _t="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ct="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",xt="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",w=_t,O=Ct,B=xt,pt="eip155:8453",ut="eip155:84532",mt="eip155:42161",ft="eip155:137",lt="eip155:10",gt="eip155:43114",At="eip155:56",Y="eip155:480",z="eip155:143",Z="eip155:4663",Q="eip155:1187947933",tt="eip155:324705682",Et="eip155:1",P=pt,et=ut,v=mt,M=ft,L=lt,U=gt,W=At,k=Y,K=z,F=Z,j=Q,V=tt,H=Et,Dt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",wt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Ut="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",St="0x55d398326f99059fF775485246999027B3197955",nt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",ht="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",rt={[At]:nt,[pt]:Ut,[ut]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[mt]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[ft]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[lt]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[gt]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[Y]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[z]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[Z]:ht,[Q]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[tt]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Et]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ot={[St]:{symbol:"USDT",decimals:18},[nt]:{symbol:"USDC",decimals:18}};var st={[Y]:{name:"USDC",version:"2"},[z]:{name:"USDC",version:"2"},[Z]:{name:"Global Dollar",version:"1"},[Q]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[tt]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},_="0x000000000022D473030F116dDEE9F6B43aC78BA3",$="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",It={[At]:56,[pt]:8453,[ut]:84532,[mt]:42161,[ft]:137,[lt]:10,[gt]:43114,[Y]:480,[z]:143,[Z]:4663,[Q]:1187947933,[tt]:324705682,[Et]:1},R={[_t]:"https://api.dexter.cash/api/solana/rpc",[Ct]:"https://api.devnet.solana.com",[xt]:"https://api.testnet.solana.com"},g={[At]:"https://api.dexter.cash/api/evm/bsc/rpc",[pt]:"https://api.dexter.cash/api/base/rpc",[ut]:"https://sepolia.base.org",[mt]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[ft]:"https://api.dexter.cash/api/evm/polygon/rpc",[lt]:"https://api.dexter.cash/api/evm/optimism/rpc",[gt]:"https://api.dexter.cash/api/evm/avalanche/rpc",[Y]:"https://worldchain-mainnet.g.alchemy.com/public",[z]:"https://rpc.monad.xyz",[Z]:"https://rpc.mainnet.chain.robinhood.com",[Q]:"https://skale-base.skalenodes.com/v1/base",[tt]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Et]:"https://eth.llamarpc.com"};var Wt=12e3,kt=1;function q(c){if(!c||typeof c!="object")return!1;let t=c;return"publicKey"in t&&"signTransaction"in t&&typeof t.signTransaction=="function"}var at=class{name="Solana";networks=[w,O,B];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="solana"||t==="solana-devnet"||t==="solana-testnet"||t.startsWith("solana:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:R[t]?R[t]:t==="solana"?R[w]:t==="solana-devnet"?R[O]:t==="solana-testnet"?R[B]:R[w]}getAddress(t){return q(t)?t.publicKey?.toBase58()??null:null}isConnected(t){return q(t)?t.publicKey!==null:!1}async getBalance(t,e,o){if(!q(e)||!e.publicKey)return 0;let r=o||this.getDefaultRpcUrl(t.network),n=new m.Connection(r,"confirmed"),i=new m.PublicKey(e.publicKey.toBase58()),a=new m.PublicKey(t.asset);try{let d=(await n.getAccountInfo(a,"confirmed"))?.owner.toBase58()===f.TOKEN_2022_PROGRAM_ID.toBase58()?f.TOKEN_2022_PROGRAM_ID:f.TOKEN_PROGRAM_ID,p=await(0,f.getAssociatedTokenAddress)(a,i,!1,d),A=await(0,f.getAccount)(n,p,void 0,d),u=t.extra?.decimals??6;return Number(A.amount)/Math.pow(10,u)}catch(s){if(s&&typeof s=="object"&&"name"in s&&(s.name==="TokenAccountNotFoundError"||s.name==="TokenInvalidAccountOwnerError"))return 0;throw s}}async buildTransaction(t,e,o){if(!q(e))throw new Error("Invalid Solana wallet");if(!e.publicKey)throw new Error("Wallet not connected");let r=o||this.getDefaultRpcUrl(t.network),n=new m.Connection(r,"confirmed"),i=new m.PublicKey(e.publicKey.toBase58()),{payTo:a,asset:s,extra:d}=t,p=t.amount??t.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!d?.feePayer)throw new Error("Missing feePayer in payment requirements");let A=new m.PublicKey(d.feePayer),u=new m.PublicKey(s),E=new m.PublicKey(a);this.log("Building transaction:",{from:i.toBase58(),to:a,amount:p,asset:s,feePayer:d.feePayer});let l=[];l.push(m.ComputeBudgetProgram.setComputeUnitLimit({units:Wt})),l.push(m.ComputeBudgetProgram.setComputeUnitPrice({microLamports:kt}));let h=await n.getAccountInfo(u,"confirmed");if(!h)throw new Error(`Token mint ${s} not found`);let T=h.owner.toBase58()===f.TOKEN_2022_PROGRAM_ID.toBase58()?f.TOKEN_2022_PROGRAM_ID:f.TOKEN_PROGRAM_ID,y=await(0,f.getMint)(n,u,void 0,T);typeof d?.decimals=="number"&&y.decimals!==d.decimals&&this.log(`Decimals mismatch: requirements say ${d.decimals}, mint says ${y.decimals}`);let I=await(0,f.getAssociatedTokenAddress)(u,i,!1,T),S=await(0,f.getAssociatedTokenAddress)(u,E,!0,T);if(!await n.getAccountInfo(I,"confirmed"))throw new Error(`No token account found for ${s}. Please ensure you have USDC in your wallet.`);if(!await n.getAccountInfo(S,"confirmed"))throw new Error(`Seller token account not found. The seller (${a}) must have a USDC account.`);let X=BigInt(p);l.push((0,f.createTransferCheckedInstruction)(I,u,S,i,X,y.decimals,[],T));let{blockhash:D}=await n.getLatestBlockhash("confirmed"),J=new m.TransactionMessage({payerKey:A,recentBlockhash:D,instructions:l}).compileToV0Message(),C=new m.VersionedTransaction(J),b=await e.signTransaction(C);return this.log("Transaction signed successfully"),{serialized:Buffer.from(b.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:I.toBase58(),destinationAta:S.toBase58(),asset:s,amount:p,blockhash:D}}}async confirmSettlement(t,e){if(t.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`);let o=new m.Connection(e,"confirmed"),r=new m.PublicKey(t.destinationAta),n=await o.getSignaturesForAddress(r,{limit:25});if(n.length===0)return{settled:!1};let i=BigInt(t.amount);for(let a of n){if(a.err)continue;let s=await o.getTransaction(a.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!s?.meta)continue;let d=s.transaction.message.getAccountKeys().keySegments().flat(),p=s.meta.preTokenBalances??[],A=s.meta.postTokenBalances??[];for(let u of A){if(u.mint!==t.asset)continue;let E=d[u.accountIndex];if(!E||!E.equals(r))continue;let l=p.find(y=>y.accountIndex===u.accountIndex),h=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(u.uiTokenAmount.amount??"0")-h===i)return{settled:!0,txSignature:a.signature}}}return{settled:!1}}};function Tt(c){return new at(c)}var Kt={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"}]},Pt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function G(c){if(!c||typeof c!="object")return!1;let t=c;return"address"in t&&typeof t.address=="string"&&t.address.startsWith("0x")}var it=class{name="EVM";networks=[W,P,et,H,v,M,L,U,k,K,F,j,V];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="base"||t==="bsc"||t==="ethereum"||t==="arbitrum"||t==="polygon"||t==="optimism"||t==="avalanche"||t==="world"||t==="monad"||t==="robinhood"||t==="skale-base"||t==="skale-base-sepolia"||t.startsWith("eip155:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:g[t]?g[t]:t==="base"?g[P]:t==="bsc"?g[W]:t==="ethereum"?g[H]:t==="arbitrum"?g[v]:t==="polygon"?g[M]:t==="optimism"?g[L]:t==="avalanche"?g[U]:t==="world"?g[k]:t==="monad"?g[K]:t==="robinhood"?g[F]:t==="skale-base"?g[j]:t==="skale-base-sepolia"?g[V]:g[P]}getAddress(t){return G(t)?t.address:null}isConnected(t){return G(t)?!!t.address:!1}getChainId(t){if(It[t])return It[t];if(t.startsWith("eip155:")){let e=t.split(":")[1];return parseInt(e,10)}return t==="base"?8453:t==="bsc"?56:t==="ethereum"?1:t==="arbitrum"?42161:t==="polygon"?137:t==="optimism"?10:t==="avalanche"?43114:t==="world"?480:t==="monad"?143:t==="robinhood"?4663:t==="skale-base"?1187947933:t==="skale-base-sepolia"?324705682:8453}async getBalance(t,e,o){if(!G(e)||!e.address)return 0;let r=o||this.getDefaultRpcUrl(t.network);try{let n=this.encodeBalanceOf(e.address),i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:t.asset,data:n},"latest"]})});if(!i.ok)throw new Error(`RPC request failed: ${i.status}`);let a=await i.json();if(a.error)throw new Error(`RPC error: ${JSON.stringify(a.error)}`);if(!a.result||a.result==="0x")return 0;let s=BigInt(a.result),d=t.extra?.decimals??6;return Number(s)/Math.pow(10,d)}catch(n){throw n}}encodeBalanceOf(t){let e="0x70a08231",o=t.slice(2).toLowerCase().padStart(64,"0");return e+o}async confirmSettlement(t,e){if(t.kind==="eip3009"){let o="0xe94a0102",r=t.from.slice(2).toLowerCase().padStart(64,"0"),n=t.nonce.slice(2).toLowerCase().padStart(64,"0"),i=o+r+n,a=await this.ethCall(e,t.asset,i);return{settled:BigInt(a)!==0n}}if(t.kind==="permit2"){let o="0x4fe02b44",r=BigInt(t.nonce),n=r>>8n,i=r&0xffn,a=t.from.slice(2).toLowerCase().padStart(64,"0"),s=n.toString(16).padStart(64,"0"),d=o+a+s,p=await this.ethCall(e,_,d);return{settled:(BigInt(p)>>i&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`)}async ethCall(t,e,o){let r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:o},"latest"]})});if(!r.ok)throw new Error(`RPC request failed: ${r.status}`);let n=await r.json();if(n.error)throw new Error(`RPC error: ${JSON.stringify(n.error)}`);if(!n.result||n.result==="0x")throw new Error("RPC returned an empty result");return n.result}async buildTransaction(t,e,o){if(!G(e))throw new Error("Invalid EVM wallet");if(!e.address)throw new Error("Wallet not connected");if(t.scheme==="exact-approval")return this.buildApprovalTransaction(t,e,o);if(t.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(t,e,o);let{payTo:r,asset:n,extra:i}=t,a=t.amount??t.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:e.address,to:r,amount:a,asset:n,network:t.network});let s=this.getChainId(t.network),d=st[`eip155:${s}`],p={name:i?.name??d?.name??"USD Coin",version:i?.version??d?.version??"2",chainId:BigInt(s),verifyingContract:n},A={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"}]},u=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(u);let E="0x"+[...u].map(S=>S.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),h={from:e.address,to:r,value:a,validAfter:String(l-600),validBefore:String(l+(t.maxTimeoutSeconds||60)),nonce:E},T={from:e.address,to:r,value:BigInt(a),validAfter:BigInt(l-600),validBefore:BigInt(l+(t.maxTimeoutSeconds||60)),nonce:E};if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let y=await e.signTypedData({domain:p,types:A,primaryType:"TransferWithAuthorization",message:T});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:h,signature:y}),signature:y,settlementProbe:{kind:"eip3009",from:e.address,nonce:E,asset:n,chainId:s}}}async buildApprovalTransaction(t,e,o){let{payTo:r,asset:n,extra:i}=t,a=t.amount??t.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");let s=i?.facilitatorContract;if(!s)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:e.address,to:r,amount:a,asset:n,network:t.network,facilitatorContract:s});let d=o||this.getDefaultRpcUrl(t.network),p=i?.fee??"0",A=BigInt(a)+BigInt(p),u=await this.readAllowance(d,n,e.address,s);if(u<A){if(!e.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 C=this.calculateApprovalAmount(a,p,i?.approvalStrategy);this.log(`Approving ${C} for ${s} (current allowance: ${u})`);let b=await e.sendTransaction({to:n,data:this.encodeApprove(s,C),value:0n});this.log(`Approval tx sent: ${b}`),await this.waitForReceipt(d,b),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let E=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(E);let l=[...E].reduce((C,b)=>C*256n+BigInt(b),0n).toString(),h=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(h);let T="0x"+[...h].map(C=>C.toString(16).padStart(2,"0")).join(""),I=Math.floor(Date.now()/1e3)+(t.maxTimeoutSeconds||300),S=i?.eip712Domain,x=S?{name:S.name,version:S.version,chainId:BigInt(S.chainId),verifyingContract:S.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(t.network)),verifyingContract:s},N=i?.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"}]},X={from:e.address,to:r,token:n,amount:BigInt(a),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(I),paymentId:T},D=await e.signTypedData({domain:x,types:N,primaryType:"Payment",message:X});this.log("EIP-712 Payment signature obtained");let J={from:e.address,to:r,token:n,amount:a,fee:p,nonce:l,deadline:I,paymentId:T,signature:D};return{serialized:JSON.stringify(J),signature:D}}async buildPermit2Transaction(t,e,o){let{payTo:r,asset:n}=t,i=t.amount??t.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:e.address,to:r,amount:i,asset:n,network:t.network});let a=o||this.getDefaultRpcUrl(t.network),s=await this.readAllowance(a,n,e.address,_),d;if(s<BigInt(i)){let x=this.encodeApprove(_,Pt);if(e.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${s})`);let N=this.getChainId(t.network),X=await this.readGasPrice(a),D=await this.readNonce(a,e.address),J=await e.signTransaction({to:n,data:x,chainId:N,gas:50000n,gasPrice:X,nonce:D});d={erc20ApprovalGasSponsoring:{info:{from:e.address,asset:n,spender:_,amount:Pt.toString(),signedTransaction:J,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(e.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${s})`);let N=await e.sendTransaction({to:n,data:x,value:0n});this.log(`Permit2 approval tx sent: ${N}`),await this.waitForReceipt(a,N),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 A=[...p].reduce((x,N)=>x*256n+BigInt(N),0n),u=Math.floor(Date.now()/1e3),E=u-600,l=u+(t.maxTimeoutSeconds||300),h=this.getChainId(t.network),T={name:"Permit2",chainId:BigInt(h),verifyingContract:_},y={permitted:{token:n,amount:BigInt(i)},spender:$,nonce:A,deadline:BigInt(l),witness:{to:r,validAfter:BigInt(E)}},I=await e.signTypedData({domain:T,types:Kt,primaryType:"PermitWitnessTransferFrom",message:y});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let S={signature:I,permit2Authorization:{from:e.address,permitted:{token:n,amount:i},spender:$,nonce:A.toString(),deadline:String(l),witness:{to:r,validAfter:String(E)}}};return{serialized:JSON.stringify(S),signature:I,extensions:d,settlementProbe:{kind:"permit2",from:e.address,nonce:A.toString(),chainId:h}}}async readAllowance(t,e,o,r){let n="0xdd62ed3e",i=o.slice(2).toLowerCase().padStart(64,"0"),a=r.slice(2).toLowerCase().padStart(64,"0"),s=n+i+a;try{let p=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:s},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(t,e){let o="0x095ea7b3",r=t.slice(2).toLowerCase().padStart(64,"0"),n=e.toString(16).padStart(64,"0");return o+r+n}async waitForReceipt(t,e,o=3e4){let r=Date.now();for(;Date.now()-r<o;){try{let i=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[e]})})).json();if(i.result){if(i.result.status==="0x0")throw new Error(`Approval transaction reverted: ${e}`);return}}catch(n){if(n instanceof Error&&n.message.includes("reverted"))throw n}await new Promise(n=>setTimeout(n,2e3))}throw new Error(`Approval transaction receipt timeout after ${o}ms: ${e}`)}async readGasPrice(t){try{let o=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return o.result?BigInt(o.result):50000000n}catch{return 50000000n}}async readNonce(t,e){try{let r=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[e,"latest"]})})).json();return r.result?parseInt(r.result,16):0}catch{return 0}}calculateApprovalAmount(t,e,o){let r=BigInt(t)+BigInt(e);if(!o||o.mode==="exact")return r;let n=BigInt(o.defaultMultiple??10),i=r*n;if(o.maxCapUsd){let a=this.inferDecimals(t),s=BigInt(Math.floor(o.maxCapUsd*Math.pow(10,a)));if(i>s)return s}if(o.exactAboveUsd){let a=this.inferDecimals(t),s=BigInt(Math.floor(o.exactAboveUsd*Math.pow(10,a)));if(BigInt(t)>s)return r}return i}inferDecimals(t){return t.length>12?18:6}};function yt(c){return new it(c)}function Ft(c){if(c===Dt||c===wt)return!0;let t=c.toLowerCase();for(let e of Object.values(rt))if(e.toLowerCase()===t)return!0;for(let e of Object.keys(ot))if(e.toLowerCase()===t)return!0;return!1}function jt(c=!1){return[Tt({verbose:c}),yt({verbose:c})]}function Vt(c,t){return c.find(e=>e.canHandle(t))}0&&(module.exports={ARBITRUM_ONE,AVALANCHE,BASE_MAINNET,BASE_SEPOLIA,BSC_MAINNET,BSC_STABLECOIN_ADDRESSES,BSC_USDC,BSC_USDT,EIP712_DOMAINS,ETHEREUM_MAINNET,EvmAdapter,MONAD_MAINNET,OPTIMISM,PERMIT2_ADDRESS,POLYGON,ROBINHOOD_MAINNET,ROBINHOOD_USDG,SKALE_BASE,SKALE_BASE_SEPOLIA,SOLANA_DEVNET,SOLANA_MAINNET,SOLANA_TESTNET,SolanaAdapter,USDC_ADDRESSES,WORLD_MAINNET,X402_EXACT_PERMIT2_PROXY,createDefaultAdapters,createEvmAdapter,createSolanaAdapter,findAdapter,isEvmWallet,isKnownUSDC,isSolanaWallet});
|
|
1
|
+
"use strict";var Ot=Object.create;var ct=Object.defineProperty;var vt=Object.getOwnPropertyDescriptor;var Bt=Object.getOwnPropertyNames;var Mt=Object.getPrototypeOf,Lt=Object.prototype.hasOwnProperty;var Ut=(a,t)=>{for(var e in t)ct(a,e,{get:t[e],enumerable:!0})},_t=(a,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Bt(t))!Lt.call(a,n)&&n!==e&&ct(a,n,{get:()=>t[n],enumerable:!(o=vt(t,n))||o.enumerable});return a};var dt=(a,t,e)=>(e=a!=null?Ot(Mt(a)):{},_t(t||!a||!a.__esModule?ct(e,"default",{value:a,enumerable:!0}):e,a)),kt=a=>_t(ct({},"__esModule",{value:!0}),a);var Ht={};Ut(Ht,{ARBITRUM_ONE:()=>M,AVALANCHE:()=>k,BASE_MAINNET:()=>P,BASE_SEPOLIA:()=>tt,BSC_MAINNET:()=>W,BSC_STABLECOIN_ADDRESSES:()=>rt,BSC_USDC:()=>et,BSC_USDT:()=>ht,EIP712_DOMAINS:()=>ot,ETHEREUM_MAINNET:()=>q,EvmAdapter:()=>at,MONAD_MAINNET:()=>F,OPTIMISM:()=>U,PERMIT2_ADDRESS:()=>x,POLYGON:()=>L,ROBINHOOD_MAINNET:()=>j,ROBINHOOD_USDG:()=>Tt,SKALE_BASE:()=>$,SKALE_BASE_SEPOLIA:()=>V,SOLANA_DEVNET:()=>v,SOLANA_MAINNET:()=>w,SOLANA_TESTNET:()=>B,SolanaAdapter:()=>st,USDC_ADDRESSES:()=>nt,WORLD_MAINNET:()=>K,X402_EXACT_PERMIT2_PROXY:()=>H,createDefaultAdapters:()=>Vt,createEvmAdapter:()=>It,createSolanaAdapter:()=>yt,findAdapter:()=>qt,isEvmWallet:()=>X,isKnownUSDC:()=>$t,isSolanaWallet:()=>G});module.exports=kt(Ht);function pt(a,t){let e=a.scheme??"exact";if(e!=="exact"&&!(t==="evm"&&e==="exact-approval"))return`Unsupported payment scheme: ${e}`;let o=a.extra?.paymentFlow;if(o!==void 0&&o!=="authorization")return`Unsupported payment flow: ${String(o)}`;let n=a.extra?.assetTransferMethod;if(n!==void 0&&(typeof n!="string"||!(e==="exact-approval"?[]:t==="evm"?["eip3009","permit2"]:["default"]).includes(n)))return`Unsupported payment asset transfer method: ${String(n)}`}var u=require("@solana/web3.js"),m=require("@solana/spl-token");var xt="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ct="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",wt="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",w=xt,v=Ct,B=wt,ut="eip155:8453",mt="eip155:84532",ft="eip155:42161",lt="eip155:137",gt="eip155:10",At="eip155:43114",Et="eip155:56",J="eip155:480",z="eip155:143",Y="eip155:4663",Z="eip155:1187947933",Q="eip155:324705682",St="eip155:1",P=ut,tt=mt,M=ft,L=lt,U=gt,k=At,W=Et,K=J,F=z,j=Y,$=Z,V=Q,q=St,Pt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Dt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Wt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",ht="0x55d398326f99059fF775485246999027B3197955",et="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Tt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",nt={[Et]:et,[ut]:Wt,[mt]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[ft]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[lt]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[gt]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[At]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[J]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[z]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[Y]:Tt,[Z]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Q]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[St]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},rt={[ht]:{symbol:"USDT",decimals:18},[et]:{symbol:"USDC",decimals:18}};var ot={[J]:{name:"USDC",version:"2"},[z]:{name:"USDC",version:"2"},[Y]:{name:"Global Dollar",version:"1"},[Z]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Q]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},x="0x000000000022D473030F116dDEE9F6B43aC78BA3",H="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",Nt={[Et]:56,[ut]:8453,[mt]:84532,[ft]:42161,[lt]:137,[gt]:10,[At]:43114,[J]:480,[z]:143,[Y]:4663,[Z]:1187947933,[Q]:324705682,[St]:1},D={[xt]:"https://api.dexter.cash/api/solana/rpc",[Ct]:"https://api.devnet.solana.com",[wt]:"https://api.testnet.solana.com"},E={[Et]:"https://api.dexter.cash/api/evm/bsc/rpc",[ut]:"https://api.dexter.cash/api/base/rpc",[mt]:"https://sepolia.base.org",[ft]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[lt]:"https://api.dexter.cash/api/evm/polygon/rpc",[gt]:"https://api.dexter.cash/api/evm/optimism/rpc",[At]:"https://api.dexter.cash/api/evm/avalanche/rpc",[J]:"https://worldchain-mainnet.g.alchemy.com/public",[z]:"https://rpc.monad.xyz",[Y]:"https://rpc.mainnet.chain.robinhood.com",[Z]:"https://skale-base.skalenodes.com/v1/base",[Q]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[St]:"https://eth.llamarpc.com"};var Kt=12e3,Ft=1;function G(a){if(!a||typeof a!="object")return!1;let t=a;return"publicKey"in t&&"signTransaction"in t&&typeof t.signTransaction=="function"}var st=class{name="Solana";networks=[w,v,B];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="solana"||t==="solana-devnet"||t==="solana-testnet"||t.startsWith("solana:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:D[t]?D[t]:t==="solana"?D[w]:t==="solana-devnet"?D[v]:t==="solana-testnet"?D[B]:D[w]}getAddress(t){return G(t)?t.publicKey?.toBase58()??null:null}isConnected(t){return G(t)?t.publicKey!==null:!1}async getBalance(t,e,o){if(!G(e)||!e.publicKey)return 0;let n=o||this.getDefaultRpcUrl(t.network),r=new u.Connection(n,"confirmed"),i=new u.PublicKey(e.publicKey.toBase58()),c=new u.PublicKey(t.asset);try{let p=(await r.getAccountInfo(c,"confirmed"))?.owner.toBase58()===m.TOKEN_2022_PROGRAM_ID.toBase58()?m.TOKEN_2022_PROGRAM_ID:m.TOKEN_PROGRAM_ID,d=await(0,m.getAssociatedTokenAddress)(c,i,!1,p),f=await(0,m.getAccount)(r,d,void 0,p),l=t.extra?.decimals??6;return Number(f.amount)/Math.pow(10,l)}catch(s){if(s&&typeof s=="object"&&"name"in s&&(s.name==="TokenAccountNotFoundError"||s.name==="TokenInvalidAccountOwnerError"))return 0;throw s}}async buildTransaction(t,e,o){let n=pt(t,"svm");if(n)throw new Error(n);if(!G(e))throw new Error("Invalid Solana wallet");if(!e.publicKey)throw new Error("Wallet not connected");let r=o||this.getDefaultRpcUrl(t.network),i=new u.Connection(r,"confirmed"),c=new u.PublicKey(e.publicKey.toBase58()),{payTo:s,asset:p,extra:d}=t,f=t.amount??t.maxAmountRequired;if(!f)throw new Error("Missing amount in payment requirements");if(!d?.feePayer)throw new Error("Missing feePayer in payment requirements");let l=new u.PublicKey(d.feePayer),g=new u.PublicKey(p),S=new u.PublicKey(s);this.log("Building transaction:",{from:c.toBase58(),to:s,amount:f,asset:p,feePayer:d.feePayer});let A=[];A.push(u.ComputeBudgetProgram.setComputeUnitLimit({units:Kt})),A.push(u.ComputeBudgetProgram.setComputeUnitPrice({microLamports:Ft}));let N=await i.getAccountInfo(g,"confirmed");if(!N)throw new Error(`Token mint ${p} not found`);let I=N.owner.toBase58()===m.TOKEN_2022_PROGRAM_ID.toBase58()?m.TOKEN_2022_PROGRAM_ID:m.TOKEN_PROGRAM_ID,h=await(0,m.getMint)(i,g,void 0,I);typeof d?.decimals=="number"&&h.decimals!==d.decimals&&this.log(`Decimals mismatch: requirements say ${d.decimals}, mint says ${h.decimals}`);let T=await(0,m.getAssociatedTokenAddress)(g,c,!1,I),y=await(0,m.getAssociatedTokenAddress)(g,S,!0,I);if(!await i.getAccountInfo(T,"confirmed"))throw new Error(`No token account found for ${p}. Please ensure you have USDC in your wallet.`);if(!await i.getAccountInfo(y,"confirmed"))throw new Error(`Seller token account not found. The seller (${s}) must have a USDC account.`);let b=BigInt(f);A.push((0,m.createTransferCheckedInstruction)(T,g,y,c,b,h.decimals,[],I));let{blockhash:R}=await i.getLatestBlockhash("confirmed"),C=new u.TransactionMessage({payerKey:l,recentBlockhash:R,instructions:A}).compileToV0Message(),O=new u.VersionedTransaction(C),Rt=await e.signTransaction(O);return this.log("Transaction signed successfully"),{serialized:Buffer.from(Rt.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:T.toBase58(),destinationAta:y.toBase58(),asset:p,amount:f,blockhash:R}}}async confirmSettlement(t,e){if(t.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`);let o=new u.Connection(e,"confirmed"),n=new u.PublicKey(t.destinationAta),r=await o.getSignaturesForAddress(n,{limit:25});if(r.length===0)return{settled:!1};let i=BigInt(t.amount);for(let c of r){if(c.err)continue;let s=await o.getTransaction(c.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!s?.meta)continue;let p=s.transaction.message.getAccountKeys().keySegments().flat(),d=s.meta.preTokenBalances??[],f=s.meta.postTokenBalances??[];for(let l of f){if(l.mint!==t.asset)continue;let g=p[l.accountIndex];if(!g||!g.equals(n))continue;let S=d.find(I=>I.accountIndex===l.accountIndex),A=BigInt(S?.uiTokenAmount.amount??"0");if(BigInt(l.uiTokenAmount.amount??"0")-A===i)return{settled:!0,txSignature:c.signature}}}return{settled:!1}}};function yt(a){return new st(a)}var jt={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"}]},bt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function X(a){if(!a||typeof a!="object")return!1;let t=a;return"address"in t&&typeof t.address=="string"&&t.address.startsWith("0x")}var at=class{name="EVM";networks=[W,P,tt,q,M,L,U,k,K,F,j,$,V];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="base"||t==="bsc"||t==="ethereum"||t==="arbitrum"||t==="polygon"||t==="optimism"||t==="avalanche"||t==="world"||t==="monad"||t==="robinhood"||t==="skale-base"||t==="skale-base-sepolia"||t.startsWith("eip155:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:E[t]?E[t]:t==="base"?E[P]:t==="bsc"?E[W]:t==="ethereum"?E[q]:t==="arbitrum"?E[M]:t==="polygon"?E[L]:t==="optimism"?E[U]:t==="avalanche"?E[k]:t==="world"?E[K]:t==="monad"?E[F]:t==="robinhood"?E[j]:t==="skale-base"?E[$]:t==="skale-base-sepolia"?E[V]:E[P]}getAddress(t){return X(t)?t.address:null}isConnected(t){return X(t)?!!t.address:!1}getChainId(t){if(Nt[t])return Nt[t];if(t.startsWith("eip155:")){let e=t.split(":")[1];return parseInt(e,10)}return t==="base"?8453:t==="bsc"?56:t==="ethereum"?1:t==="arbitrum"?42161:t==="polygon"?137:t==="optimism"?10:t==="avalanche"?43114:t==="world"?480:t==="monad"?143:t==="robinhood"?4663:t==="skale-base"?1187947933:t==="skale-base-sepolia"?324705682:8453}async getBalance(t,e,o){if(!X(e)||!e.address)return 0;let n=o||this.getDefaultRpcUrl(t.network);try{let r=this.encodeBalanceOf(e.address),i=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:t.asset,data:r},"latest"]})});if(!i.ok)throw new Error(`RPC request failed: ${i.status}`);let c=await i.json();if(c.error)throw new Error(`RPC error: ${JSON.stringify(c.error)}`);if(!c.result||c.result==="0x")return 0;let s=BigInt(c.result),p=t.extra?.decimals??6;return Number(s)/Math.pow(10,p)}catch(r){throw r}}encodeBalanceOf(t){let e="0x70a08231",o=t.slice(2).toLowerCase().padStart(64,"0");return e+o}async confirmSettlement(t,e){if(t.kind==="eip3009"){let o="0xe94a0102",n=t.from.slice(2).toLowerCase().padStart(64,"0"),r=t.nonce.slice(2).toLowerCase().padStart(64,"0"),i=o+n+r,c=await this.ethCall(e,t.asset,i);return{settled:BigInt(c)!==0n}}if(t.kind==="permit2"){let o="0x4fe02b44",n=BigInt(t.nonce),r=n>>8n,i=n&0xffn,c=t.from.slice(2).toLowerCase().padStart(64,"0"),s=r.toString(16).padStart(64,"0"),p=o+c+s,d=await this.ethCall(e,x,p);return{settled:(BigInt(d)>>i&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`)}async ethCall(t,e,o){let n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:o},"latest"]})});if(!n.ok)throw new Error(`RPC request failed: ${n.status}`);let r=await n.json();if(r.error)throw new Error(`RPC error: ${JSON.stringify(r.error)}`);if(!r.result||r.result==="0x")throw new Error("RPC returned an empty result");return r.result}async buildTransaction(t,e,o){let n=pt(t,"evm");if(n)throw new Error(n);if(!X(e))throw new Error("Invalid EVM wallet");if(!e.address)throw new Error("Wallet not connected");if(t.scheme==="exact-approval")return this.buildApprovalTransaction(t,e,o);if(t.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(t,e,o);let{payTo:r,asset:i,extra:c}=t,s=t.amount??t.maxAmountRequired;if(!s)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:e.address,to:r,amount:s,asset:i,network:t.network});let p=this.getChainId(t.network),d=ot[`eip155:${p}`],f={name:c?.name??d?.name??"USD Coin",version:c?.version??d?.version??"2",chainId:BigInt(p),verifyingContract:i},l={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"}]},g=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(g);let S="0x"+[...g].map(y=>y.toString(16).padStart(2,"0")).join(""),A=Math.floor(Date.now()/1e3),N={from:e.address,to:r,value:s,validAfter:String(A-600),validBefore:String(A+(t.maxTimeoutSeconds||60)),nonce:S},I={from:e.address,to:r,value:BigInt(s),validAfter:BigInt(A-600),validBefore:BigInt(A+(t.maxTimeoutSeconds||60)),nonce:S};if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let h=await e.signTypedData({domain:f,types:l,primaryType:"TransferWithAuthorization",message:I});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:N,signature:h}),signature:h,settlementProbe:{kind:"eip3009",from:e.address,nonce:S,asset:i,chainId:p}}}async buildApprovalTransaction(t,e,o){let{payTo:n,asset:r,extra:i}=t,c=t.amount??t.maxAmountRequired;if(!c)throw new Error("Missing amount in payment requirements");let s=i?.facilitatorContract;if(!s)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:e.address,to:n,amount:c,asset:r,network:t.network,facilitatorContract:s});let p=o||this.getDefaultRpcUrl(t.network),d=i?.fee??"0",f=BigInt(c)+BigInt(d),l=await this.readAllowance(p,r,e.address,s);if(l<f){if(!e.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 C=this.calculateApprovalAmount(c,d,i?.approvalStrategy);this.log(`Approving ${C} for ${s} (current allowance: ${l})`);let O=await e.sendTransaction({to:r,data:this.encodeApprove(s,C),value:0n});this.log(`Approval tx sent: ${O}`),await this.waitForReceipt(p,O),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let g=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(g);let S=[...g].reduce((C,O)=>C*256n+BigInt(O),0n).toString(),A=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(A);let N="0x"+[...A].map(C=>C.toString(16).padStart(2,"0")).join(""),h=Math.floor(Date.now()/1e3)+(t.maxTimeoutSeconds||300),T=i?.eip712Domain,y=T?{name:T.name,version:T.version,chainId:BigInt(T.chainId),verifyingContract:T.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(t.network)),verifyingContract:s},_=i?.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"}]},it={from:e.address,to:n,token:r,amount:BigInt(c),fee:BigInt(d),nonce:BigInt(S),deadline:BigInt(h),paymentId:N},b=await e.signTypedData({domain:y,types:_,primaryType:"Payment",message:it});this.log("EIP-712 Payment signature obtained");let R={from:e.address,to:n,token:r,amount:c,fee:d,nonce:S,deadline:h,paymentId:N,signature:b};return{serialized:JSON.stringify(R),signature:b}}async buildPermit2Transaction(t,e,o){let{payTo:n,asset:r}=t,i=t.amount??t.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:e.address,to:n,amount:i,asset:r,network:t.network});let c=o||this.getDefaultRpcUrl(t.network),s=await this.readAllowance(c,r,e.address,x),p;if(s<BigInt(i)){let y=this.encodeApprove(x,bt);if(e.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${s})`);let _=this.getChainId(t.network),it=await this.readGasPrice(c),b=await this.readNonce(c,e.address),R=await e.signTransaction({to:r,data:y,chainId:_,gas:50000n,gasPrice:it,nonce:b});p={erc20ApprovalGasSponsoring:{info:{from:e.address,asset:r,spender:x,amount:bt.toString(),signedTransaction:R,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(e.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${s})`);let _=await e.sendTransaction({to:r,data:y,value:0n});this.log(`Permit2 approval tx sent: ${_}`),await this.waitForReceipt(c,_),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 d=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(d);let f=[...d].reduce((y,_)=>y*256n+BigInt(_),0n),l=Math.floor(Date.now()/1e3),g=l-600,S=l+(t.maxTimeoutSeconds||300),A=this.getChainId(t.network),N={name:"Permit2",chainId:BigInt(A),verifyingContract:x},I={permitted:{token:r,amount:BigInt(i)},spender:H,nonce:f,deadline:BigInt(S),witness:{to:n,validAfter:BigInt(g)}},h=await e.signTypedData({domain:N,types:jt,primaryType:"PermitWitnessTransferFrom",message:I});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let T={signature:h,permit2Authorization:{from:e.address,permitted:{token:r,amount:i},spender:H,nonce:f.toString(),deadline:String(S),witness:{to:n,validAfter:String(g)}}};return{serialized:JSON.stringify(T),signature:h,extensions:p,settlementProbe:{kind:"permit2",from:e.address,nonce:f.toString(),chainId:A}}}async readAllowance(t,e,o,n){let r="0xdd62ed3e",i=o.slice(2).toLowerCase().padStart(64,"0"),c=n.slice(2).toLowerCase().padStart(64,"0"),s=r+i+c;try{let d=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:s},"latest"]})})).json();return d.error||!d.result||d.result==="0x"?0n:BigInt(d.result)}catch{return 0n}}encodeApprove(t,e){let o="0x095ea7b3",n=t.slice(2).toLowerCase().padStart(64,"0"),r=e.toString(16).padStart(64,"0");return o+n+r}async waitForReceipt(t,e,o=3e4){let n=Date.now();for(;Date.now()-n<o;){try{let i=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[e]})})).json();if(i.result){if(i.result.status==="0x0")throw new Error(`Approval transaction reverted: ${e}`);return}}catch(r){if(r instanceof Error&&r.message.includes("reverted"))throw r}await new Promise(r=>setTimeout(r,2e3))}throw new Error(`Approval transaction receipt timeout after ${o}ms: ${e}`)}async readGasPrice(t){try{let o=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return o.result?BigInt(o.result):50000000n}catch{return 50000000n}}async readNonce(t,e){try{let n=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[e,"latest"]})})).json();return n.result?parseInt(n.result,16):0}catch{return 0}}calculateApprovalAmount(t,e,o){let n=BigInt(t)+BigInt(e);if(!o||o.mode==="exact")return n;let r=BigInt(o.defaultMultiple??10),i=n*r;if(o.maxCapUsd){let c=this.inferDecimals(t),s=BigInt(Math.floor(o.maxCapUsd*Math.pow(10,c)));if(i>s)return s}if(o.exactAboveUsd){let c=this.inferDecimals(t),s=BigInt(Math.floor(o.exactAboveUsd*Math.pow(10,c)));if(BigInt(t)>s)return n}return i}inferDecimals(t){return t.length>12?18:6}};function It(a){return new at(a)}function $t(a){if(a===Pt||a===Dt)return!0;let t=a.toLowerCase();for(let e of Object.values(nt))if(e.toLowerCase()===t)return!0;for(let e of Object.keys(rt))if(e.toLowerCase()===t)return!0;return!1}function Vt(a=!1){return[yt({verbose:a}),It({verbose:a})]}function qt(a,t){return a.find(e=>e.canHandle(t))}0&&(module.exports={ARBITRUM_ONE,AVALANCHE,BASE_MAINNET,BASE_SEPOLIA,BSC_MAINNET,BSC_STABLECOIN_ADDRESSES,BSC_USDC,BSC_USDT,EIP712_DOMAINS,ETHEREUM_MAINNET,EvmAdapter,MONAD_MAINNET,OPTIMISM,PERMIT2_ADDRESS,POLYGON,ROBINHOOD_MAINNET,ROBINHOOD_USDG,SKALE_BASE,SKALE_BASE_SEPOLIA,SOLANA_DEVNET,SOLANA_MAINNET,SOLANA_TESTNET,SolanaAdapter,USDC_ADDRESSES,WORLD_MAINNET,X402_EXACT_PERMIT2_PROXY,createDefaultAdapters,createEvmAdapter,createSolanaAdapter,findAdapter,isEvmWallet,isKnownUSDC,isSolanaWallet});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { S as SolanaAdapter, E as EvmAdapter, C as ChainAdapter } from '../types-
|
|
2
|
-
export { A as AdapterConfig, B as BalanceInfo, a as EvmWallet, G as GenericWallet, b as SignedTransaction, c as SolanaWallet, W as WalletSet, d as createEvmAdapter, e as createSolanaAdapter, i as isEvmWallet, f as isSolanaWallet } from '../types-
|
|
1
|
+
import { S as SolanaAdapter, E as EvmAdapter, C as ChainAdapter } from '../types-B4JCwkHH.cjs';
|
|
2
|
+
export { A as AdapterConfig, B as BalanceInfo, a as EvmWallet, G as GenericWallet, b as SignedTransaction, c as SolanaWallet, W as WalletSet, d as createEvmAdapter, e as createSolanaAdapter, i as isEvmWallet, f as isSolanaWallet } from '../types-B4JCwkHH.cjs';
|
|
3
3
|
export { A as ARBITRUM_ONE, a as AVALANCHE, B as BASE_MAINNET, b as BASE_SEPOLIA, c as BSC_MAINNET, d as BSC_STABLECOIN_ADDRESSES, e as BSC_USDC, f as BSC_USDT, E as EIP712_DOMAINS, g as ETHEREUM_MAINNET, M as MONAD_MAINNET, O as OPTIMISM, P as PERMIT2_ADDRESS, h as POLYGON, R as ROBINHOOD_MAINNET, i as ROBINHOOD_USDG, S as SKALE_BASE, j as SKALE_BASE_SEPOLIA, k as SOLANA_DEVNET, l as SOLANA_MAINNET, m as SOLANA_TESTNET, U as USDC_ADDRESSES, W as WORLD_MAINNET, X as X402_EXACT_PERMIT2_PROXY } from '../constants-BLvApMMl.cjs';
|
|
4
|
+
import '../types-8Q38sHOi.cjs';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Check if an asset address is a known USDC contract (any chain).
|
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { S as SolanaAdapter, E as EvmAdapter, C as ChainAdapter } from '../types-
|
|
2
|
-
export { A as AdapterConfig, B as BalanceInfo, a as EvmWallet, G as GenericWallet, b as SignedTransaction, c as SolanaWallet, W as WalletSet, d as createEvmAdapter, e as createSolanaAdapter, i as isEvmWallet, f as isSolanaWallet } from '../types-
|
|
1
|
+
import { S as SolanaAdapter, E as EvmAdapter, C as ChainAdapter } from '../types-Ds9IUnXG.js';
|
|
2
|
+
export { A as AdapterConfig, B as BalanceInfo, a as EvmWallet, G as GenericWallet, b as SignedTransaction, c as SolanaWallet, W as WalletSet, d as createEvmAdapter, e as createSolanaAdapter, i as isEvmWallet, f as isSolanaWallet } from '../types-Ds9IUnXG.js';
|
|
3
3
|
export { A as ARBITRUM_ONE, a as AVALANCHE, B as BASE_MAINNET, b as BASE_SEPOLIA, c as BSC_MAINNET, d as BSC_STABLECOIN_ADDRESSES, e as BSC_USDC, f as BSC_USDT, E as EIP712_DOMAINS, g as ETHEREUM_MAINNET, M as MONAD_MAINNET, O as OPTIMISM, P as PERMIT2_ADDRESS, h as POLYGON, R as ROBINHOOD_MAINNET, i as ROBINHOOD_USDG, S as SKALE_BASE, j as SKALE_BASE_SEPOLIA, k as SOLANA_DEVNET, l as SOLANA_MAINNET, m as SOLANA_TESTNET, U as USDC_ADDRESSES, W as WORLD_MAINNET, X as X402_EXACT_PERMIT2_PROXY } from '../constants-BLvApMMl.js';
|
|
4
|
+
import '../types-8Q38sHOi.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Check if an asset address is a known USDC contract (any chain).
|
package/dist/adapters/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PublicKey as D,Connection as ht,TransactionMessage as Ot,VersionedTransaction as Bt,ComputeBudgetProgram as wt}from"@solana/web3.js";import{getAssociatedTokenAddress as Tt,getAccount as vt,createTransferCheckedInstruction as Mt,getMint as Lt,TOKEN_PROGRAM_ID as Pt,TOKEN_2022_PROGRAM_ID as ft}from"@solana/spl-token";var Nt="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",_t="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Ct="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",P=Nt,B=_t,v=Ct,tt="eip155:8453",et="eip155:84532",nt="eip155:42161",rt="eip155:137",ot="eip155:10",st="eip155:43114",at="eip155:56",M="eip155:480",L="eip155:143",U="eip155:4663",W="eip155:1187947933",k="eip155:324705682",it="eip155:1",R=tt,ct=et,K=nt,F=rt,j=ot,V=st,H=at,$=M,q=L,G=U,X=W,J=k,Y=it,xt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Dt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",bt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",At="0x55d398326f99059fF775485246999027B3197955",dt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Et="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",pt={[at]:dt,[tt]:bt,[et]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[nt]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[rt]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[ot]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[st]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[M]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[L]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[U]:Et,[W]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[k]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[it]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ut={[At]:{symbol:"USDT",decimals:18},[dt]:{symbol:"USDC",decimals:18}};var mt={[M]:{name:"USDC",version:"2"},[L]:{name:"USDC",version:"2"},[U]:{name:"Global Dollar",version:"1"},[W]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[k]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},N="0x000000000022D473030F116dDEE9F6B43aC78BA3",z="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",St={[at]:56,[tt]:8453,[et]:84532,[nt]:42161,[rt]:137,[ot]:10,[st]:43114,[M]:480,[L]:143,[U]:4663,[W]:1187947933,[k]:324705682,[it]:1},x={[Nt]:"https://api.dexter.cash/api/solana/rpc",[_t]:"https://api.devnet.solana.com",[Ct]:"https://api.testnet.solana.com"},f={[at]:"https://api.dexter.cash/api/evm/bsc/rpc",[tt]:"https://api.dexter.cash/api/base/rpc",[et]:"https://sepolia.base.org",[nt]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[rt]:"https://api.dexter.cash/api/evm/polygon/rpc",[ot]:"https://api.dexter.cash/api/evm/optimism/rpc",[st]:"https://api.dexter.cash/api/evm/avalanche/rpc",[M]:"https://worldchain-mainnet.g.alchemy.com/public",[L]:"https://rpc.monad.xyz",[U]:"https://rpc.mainnet.chain.robinhood.com",[W]:"https://skale-base.skalenodes.com/v1/base",[k]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[it]:"https://eth.llamarpc.com"};var Ut=12e3,Wt=1;function Z(p){if(!p||typeof p!="object")return!1;let t=p;return"publicKey"in t&&"signTransaction"in t&&typeof t.signTransaction=="function"}var lt=class{name="Solana";networks=[P,B,v];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="solana"||t==="solana-devnet"||t==="solana-testnet"||t.startsWith("solana:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:x[t]?x[t]:t==="solana"?x[P]:t==="solana-devnet"?x[B]:t==="solana-testnet"?x[v]:x[P]}getAddress(t){return Z(t)?t.publicKey?.toBase58()??null:null}isConnected(t){return Z(t)?t.publicKey!==null:!1}async getBalance(t,e,s){if(!Z(e)||!e.publicKey)return 0;let a=s||this.getDefaultRpcUrl(t.network),n=new ht(a,"confirmed"),i=new D(e.publicKey.toBase58()),o=new D(t.asset);try{let c=(await n.getAccountInfo(o,"confirmed"))?.owner.toBase58()===ft.toBase58()?ft:Pt,d=await Tt(o,i,!1,c),l=await vt(n,d,void 0,c),u=t.extra?.decimals??6;return Number(l.amount)/Math.pow(10,u)}catch(r){if(r&&typeof r=="object"&&"name"in r&&(r.name==="TokenAccountNotFoundError"||r.name==="TokenInvalidAccountOwnerError"))return 0;throw r}}async buildTransaction(t,e,s){if(!Z(e))throw new Error("Invalid Solana wallet");if(!e.publicKey)throw new Error("Wallet not connected");let a=s||this.getDefaultRpcUrl(t.network),n=new ht(a,"confirmed"),i=new D(e.publicKey.toBase58()),{payTo:o,asset:r,extra:c}=t,d=t.amount??t.maxAmountRequired;if(!d)throw new Error("Missing amount in payment requirements");if(!c?.feePayer)throw new Error("Missing feePayer in payment requirements");let l=new D(c.feePayer),u=new D(r),g=new D(o);this.log("Building transaction:",{from:i.toBase58(),to:o,amount:d,asset:r,feePayer:c.feePayer});let m=[];m.push(wt.setComputeUnitLimit({units:Ut})),m.push(wt.setComputeUnitPrice({microLamports:Wt}));let E=await n.getAccountInfo(u,"confirmed");if(!E)throw new Error(`Token mint ${r} not found`);let S=E.owner.toBase58()===ft.toBase58()?ft:Pt,h=await Lt(n,u,void 0,S);typeof c?.decimals=="number"&&h.decimals!==c.decimals&&this.log(`Decimals mismatch: requirements say ${c.decimals}, mint says ${h.decimals}`);let T=await Tt(u,i,!1,S),A=await Tt(u,g,!0,S);if(!await n.getAccountInfo(T,"confirmed"))throw new Error(`No token account found for ${r}. Please ensure you have USDC in your wallet.`);if(!await n.getAccountInfo(A,"confirmed"))throw new Error(`Seller token account not found. The seller (${o}) must have a USDC account.`);let b=BigInt(d);m.push(Mt(T,u,A,i,b,h.decimals,[],S));let{blockhash:C}=await n.getLatestBlockhash("confirmed"),O=new Ot({payerKey:l,recentBlockhash:C,instructions:m}).compileToV0Message(),I=new Bt(O),w=await e.signTransaction(I);return this.log("Transaction signed successfully"),{serialized:Buffer.from(w.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:T.toBase58(),destinationAta:A.toBase58(),asset:r,amount:d,blockhash:C}}}async confirmSettlement(t,e){if(t.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`);let s=new ht(e,"confirmed"),a=new D(t.destinationAta),n=await s.getSignaturesForAddress(a,{limit:25});if(n.length===0)return{settled:!1};let i=BigInt(t.amount);for(let o of n){if(o.err)continue;let r=await s.getTransaction(o.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!r?.meta)continue;let c=r.transaction.message.getAccountKeys().keySegments().flat(),d=r.meta.preTokenBalances??[],l=r.meta.postTokenBalances??[];for(let u of l){if(u.mint!==t.asset)continue;let g=c[u.accountIndex];if(!g||!g.equals(a))continue;let m=d.find(h=>h.accountIndex===u.accountIndex),E=BigInt(m?.uiTokenAmount.amount??"0");if(BigInt(u.uiTokenAmount.amount??"0")-E===i)return{settled:!0,txSignature:o.signature}}}return{settled:!1}}};function yt(p){return new lt(p)}var kt={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"}]},Rt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Q(p){if(!p||typeof p!="object")return!1;let t=p;return"address"in t&&typeof t.address=="string"&&t.address.startsWith("0x")}var gt=class{name="EVM";networks=[H,R,ct,Y,K,F,j,V,$,q,G,X,J];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="base"||t==="bsc"||t==="ethereum"||t==="arbitrum"||t==="polygon"||t==="optimism"||t==="avalanche"||t==="world"||t==="monad"||t==="robinhood"||t==="skale-base"||t==="skale-base-sepolia"||t.startsWith("eip155:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:f[t]?f[t]:t==="base"?f[R]:t==="bsc"?f[H]:t==="ethereum"?f[Y]:t==="arbitrum"?f[K]:t==="polygon"?f[F]:t==="optimism"?f[j]:t==="avalanche"?f[V]:t==="world"?f[$]:t==="monad"?f[q]:t==="robinhood"?f[G]:t==="skale-base"?f[X]:t==="skale-base-sepolia"?f[J]:f[R]}getAddress(t){return Q(t)?t.address:null}isConnected(t){return Q(t)?!!t.address:!1}getChainId(t){if(St[t])return St[t];if(t.startsWith("eip155:")){let e=t.split(":")[1];return parseInt(e,10)}return t==="base"?8453:t==="bsc"?56:t==="ethereum"?1:t==="arbitrum"?42161:t==="polygon"?137:t==="optimism"?10:t==="avalanche"?43114:t==="world"?480:t==="monad"?143:t==="robinhood"?4663:t==="skale-base"?1187947933:t==="skale-base-sepolia"?324705682:8453}async getBalance(t,e,s){if(!Q(e)||!e.address)return 0;let a=s||this.getDefaultRpcUrl(t.network);try{let n=this.encodeBalanceOf(e.address),i=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:t.asset,data:n},"latest"]})});if(!i.ok)throw new Error(`RPC request failed: ${i.status}`);let o=await i.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")return 0;let r=BigInt(o.result),c=t.extra?.decimals??6;return Number(r)/Math.pow(10,c)}catch(n){throw n}}encodeBalanceOf(t){let e="0x70a08231",s=t.slice(2).toLowerCase().padStart(64,"0");return e+s}async confirmSettlement(t,e){if(t.kind==="eip3009"){let s="0xe94a0102",a=t.from.slice(2).toLowerCase().padStart(64,"0"),n=t.nonce.slice(2).toLowerCase().padStart(64,"0"),i=s+a+n,o=await this.ethCall(e,t.asset,i);return{settled:BigInt(o)!==0n}}if(t.kind==="permit2"){let s="0x4fe02b44",a=BigInt(t.nonce),n=a>>8n,i=a&0xffn,o=t.from.slice(2).toLowerCase().padStart(64,"0"),r=n.toString(16).padStart(64,"0"),c=s+o+r,d=await this.ethCall(e,N,c);return{settled:(BigInt(d)>>i&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`)}async ethCall(t,e,s){let a=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:s},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let n=await a.json();if(n.error)throw new Error(`RPC error: ${JSON.stringify(n.error)}`);if(!n.result||n.result==="0x")throw new Error("RPC returned an empty result");return n.result}async buildTransaction(t,e,s){if(!Q(e))throw new Error("Invalid EVM wallet");if(!e.address)throw new Error("Wallet not connected");if(t.scheme==="exact-approval")return this.buildApprovalTransaction(t,e,s);if(t.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(t,e,s);let{payTo:a,asset:n,extra:i}=t,o=t.amount??t.maxAmountRequired;if(!o)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:e.address,to:a,amount:o,asset:n,network:t.network});let r=this.getChainId(t.network),c=mt[`eip155:${r}`],d={name:i?.name??c?.name??"USD Coin",version:i?.version??c?.version??"2",chainId:BigInt(r),verifyingContract:n},l={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"}]},u=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(u);let g="0x"+[...u].map(A=>A.toString(16).padStart(2,"0")).join(""),m=Math.floor(Date.now()/1e3),E={from:e.address,to:a,value:o,validAfter:String(m-600),validBefore:String(m+(t.maxTimeoutSeconds||60)),nonce:g},S={from:e.address,to:a,value:BigInt(o),validAfter:BigInt(m-600),validBefore:BigInt(m+(t.maxTimeoutSeconds||60)),nonce:g};if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let h=await e.signTypedData({domain:d,types:l,primaryType:"TransferWithAuthorization",message:S});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:E,signature:h}),signature:h,settlementProbe:{kind:"eip3009",from:e.address,nonce:g,asset:n,chainId:r}}}async buildApprovalTransaction(t,e,s){let{payTo:a,asset:n,extra:i}=t,o=t.amount??t.maxAmountRequired;if(!o)throw new Error("Missing amount in payment requirements");let r=i?.facilitatorContract;if(!r)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:e.address,to:a,amount:o,asset:n,network:t.network,facilitatorContract:r});let c=s||this.getDefaultRpcUrl(t.network),d=i?.fee??"0",l=BigInt(o)+BigInt(d),u=await this.readAllowance(c,n,e.address,r);if(u<l){if(!e.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 I=this.calculateApprovalAmount(o,d,i?.approvalStrategy);this.log(`Approving ${I} for ${r} (current allowance: ${u})`);let w=await e.sendTransaction({to:n,data:this.encodeApprove(r,I),value:0n});this.log(`Approval tx sent: ${w}`),await this.waitForReceipt(c,w),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let g=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(g);let m=[...g].reduce((I,w)=>I*256n+BigInt(w),0n).toString(),E=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(E);let S="0x"+[...E].map(I=>I.toString(16).padStart(2,"0")).join(""),T=Math.floor(Date.now()/1e3)+(t.maxTimeoutSeconds||300),A=i?.eip712Domain,_=A?{name:A.name,version:A.version,chainId:BigInt(A.chainId),verifyingContract:A.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(t.network)),verifyingContract:r},y=i?.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"}]},b={from:e.address,to:a,token:n,amount:BigInt(o),fee:BigInt(d),nonce:BigInt(m),deadline:BigInt(T),paymentId:S},C=await e.signTypedData({domain:_,types:y,primaryType:"Payment",message:b});this.log("EIP-712 Payment signature obtained");let O={from:e.address,to:a,token:n,amount:o,fee:d,nonce:m,deadline:T,paymentId:S,signature:C};return{serialized:JSON.stringify(O),signature:C}}async buildPermit2Transaction(t,e,s){let{payTo:a,asset:n}=t,i=t.amount??t.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:e.address,to:a,amount:i,asset:n,network:t.network});let o=s||this.getDefaultRpcUrl(t.network),r=await this.readAllowance(o,n,e.address,N),c;if(r<BigInt(i)){let _=this.encodeApprove(N,Rt);if(e.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${r})`);let y=this.getChainId(t.network),b=await this.readGasPrice(o),C=await this.readNonce(o,e.address),O=await e.signTransaction({to:n,data:_,chainId:y,gas:50000n,gasPrice:b,nonce:C});c={erc20ApprovalGasSponsoring:{info:{from:e.address,asset:n,spender:N,amount:Rt.toString(),signedTransaction:O,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(e.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${r})`);let y=await e.sendTransaction({to:n,data:_,value:0n});this.log(`Permit2 approval tx sent: ${y}`),await this.waitForReceipt(o,y),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 d=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(d);let l=[...d].reduce((_,y)=>_*256n+BigInt(y),0n),u=Math.floor(Date.now()/1e3),g=u-600,m=u+(t.maxTimeoutSeconds||300),E=this.getChainId(t.network),S={name:"Permit2",chainId:BigInt(E),verifyingContract:N},h={permitted:{token:n,amount:BigInt(i)},spender:z,nonce:l,deadline:BigInt(m),witness:{to:a,validAfter:BigInt(g)}},T=await e.signTypedData({domain:S,types:kt,primaryType:"PermitWitnessTransferFrom",message:h});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let A={signature:T,permit2Authorization:{from:e.address,permitted:{token:n,amount:i},spender:z,nonce:l.toString(),deadline:String(m),witness:{to:a,validAfter:String(g)}}};return{serialized:JSON.stringify(A),signature:T,extensions:c,settlementProbe:{kind:"permit2",from:e.address,nonce:l.toString(),chainId:E}}}async readAllowance(t,e,s,a){let n="0xdd62ed3e",i=s.slice(2).toLowerCase().padStart(64,"0"),o=a.slice(2).toLowerCase().padStart(64,"0"),r=n+i+o;try{let d=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:r},"latest"]})})).json();return d.error||!d.result||d.result==="0x"?0n:BigInt(d.result)}catch{return 0n}}encodeApprove(t,e){let s="0x095ea7b3",a=t.slice(2).toLowerCase().padStart(64,"0"),n=e.toString(16).padStart(64,"0");return s+a+n}async waitForReceipt(t,e,s=3e4){let a=Date.now();for(;Date.now()-a<s;){try{let i=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[e]})})).json();if(i.result){if(i.result.status==="0x0")throw new Error(`Approval transaction reverted: ${e}`);return}}catch(n){if(n instanceof Error&&n.message.includes("reverted"))throw n}await new Promise(n=>setTimeout(n,2e3))}throw new Error(`Approval transaction receipt timeout after ${s}ms: ${e}`)}async readGasPrice(t){try{let s=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return s.result?BigInt(s.result):50000000n}catch{return 50000000n}}async readNonce(t,e){try{let a=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[e,"latest"]})})).json();return a.result?parseInt(a.result,16):0}catch{return 0}}calculateApprovalAmount(t,e,s){let a=BigInt(t)+BigInt(e);if(!s||s.mode==="exact")return a;let n=BigInt(s.defaultMultiple??10),i=a*n;if(s.maxCapUsd){let o=this.inferDecimals(t),r=BigInt(Math.floor(s.maxCapUsd*Math.pow(10,o)));if(i>r)return r}if(s.exactAboveUsd){let o=this.inferDecimals(t),r=BigInt(Math.floor(s.exactAboveUsd*Math.pow(10,o)));if(BigInt(t)>r)return a}return i}inferDecimals(t){return t.length>12?18:6}};function It(p){return new gt(p)}function Zt(p){if(p===xt||p===Dt)return!0;let t=p.toLowerCase();for(let e of Object.values(pt))if(e.toLowerCase()===t)return!0;for(let e of Object.keys(ut))if(e.toLowerCase()===t)return!0;return!1}function Qt(p=!1){return[yt({verbose:p}),It({verbose:p})]}function te(p,t){return p.find(e=>e.canHandle(t))}export{K as ARBITRUM_ONE,V as AVALANCHE,R as BASE_MAINNET,ct as BASE_SEPOLIA,H as BSC_MAINNET,ut as BSC_STABLECOIN_ADDRESSES,dt as BSC_USDC,At as BSC_USDT,mt as EIP712_DOMAINS,Y as ETHEREUM_MAINNET,gt as EvmAdapter,q as MONAD_MAINNET,j as OPTIMISM,N as PERMIT2_ADDRESS,F as POLYGON,G as ROBINHOOD_MAINNET,Et as ROBINHOOD_USDG,X as SKALE_BASE,J as SKALE_BASE_SEPOLIA,B as SOLANA_DEVNET,P as SOLANA_MAINNET,v as SOLANA_TESTNET,lt as SolanaAdapter,pt as USDC_ADDRESSES,$ as WORLD_MAINNET,z as X402_EXACT_PERMIT2_PROXY,Qt as createDefaultAdapters,It as createEvmAdapter,yt as createSolanaAdapter,te as findAdapter,Q as isEvmWallet,Zt as isKnownUSDC,Z as isSolanaWallet};
|
|
1
|
+
function tt(d,t){let e=d.scheme??"exact";if(e!=="exact"&&!(t==="evm"&&e==="exact-approval"))return`Unsupported payment scheme: ${e}`;let o=d.extra?.paymentFlow;if(o!==void 0&&o!=="authorization")return`Unsupported payment flow: ${String(o)}`;let r=d.extra?.assetTransferMethod;if(r!==void 0&&(typeof r!="string"||!(e==="exact-approval"?[]:t==="evm"?["eip3009","permit2"]:["default"]).includes(r)))return`Unsupported payment asset transfer method: ${String(r)}`}import{PublicKey as C,Connection as Tt,TransactionMessage as Bt,VersionedTransaction as Mt,ComputeBudgetProgram as Dt}from"@solana/web3.js";import{getAssociatedTokenAddress as yt,getAccount as Lt,createTransferCheckedInstruction as Ut,getMint as kt,TOKEN_PROGRAM_ID as bt,TOKEN_2022_PROGRAM_ID as lt}from"@solana/spl-token";var _t="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",xt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Ct="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",b=_t,O=xt,v=Ct,et="eip155:8453",nt="eip155:84532",rt="eip155:42161",ot="eip155:137",st="eip155:10",at="eip155:43114",it="eip155:56",B="eip155:480",M="eip155:143",L="eip155:4663",U="eip155:1187947933",k="eip155:324705682",ct="eip155:1",R=et,dt=nt,W=rt,K=ot,F=st,j=at,$=it,V=B,q=M,H=L,G=U,X=k,J=ct,wt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Pt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",vt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Et="0x55d398326f99059fF775485246999027B3197955",pt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",St="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",ut={[it]:pt,[et]:vt,[nt]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[rt]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[ot]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[st]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[at]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[B]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[M]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[L]:St,[U]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[k]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[ct]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},mt={[Et]:{symbol:"USDT",decimals:18},[pt]:{symbol:"USDC",decimals:18}};var ft={[B]:{name:"USDC",version:"2"},[M]:{name:"USDC",version:"2"},[L]:{name:"Global Dollar",version:"1"},[U]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[k]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},_="0x000000000022D473030F116dDEE9F6B43aC78BA3",z="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",ht={[it]:56,[et]:8453,[nt]:84532,[rt]:42161,[ot]:137,[st]:10,[at]:43114,[B]:480,[M]:143,[L]:4663,[U]:1187947933,[k]:324705682,[ct]:1},x={[_t]:"https://api.dexter.cash/api/solana/rpc",[xt]:"https://api.devnet.solana.com",[Ct]:"https://api.testnet.solana.com"},g={[it]:"https://api.dexter.cash/api/evm/bsc/rpc",[et]:"https://api.dexter.cash/api/base/rpc",[nt]:"https://sepolia.base.org",[rt]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[ot]:"https://api.dexter.cash/api/evm/polygon/rpc",[st]:"https://api.dexter.cash/api/evm/optimism/rpc",[at]:"https://api.dexter.cash/api/evm/avalanche/rpc",[B]:"https://worldchain-mainnet.g.alchemy.com/public",[M]:"https://rpc.monad.xyz",[L]:"https://rpc.mainnet.chain.robinhood.com",[U]:"https://skale-base.skalenodes.com/v1/base",[k]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[ct]:"https://eth.llamarpc.com"};var Wt=12e3,Kt=1;function Y(d){if(!d||typeof d!="object")return!1;let t=d;return"publicKey"in t&&"signTransaction"in t&&typeof t.signTransaction=="function"}var gt=class{name="Solana";networks=[b,O,v];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="solana"||t==="solana-devnet"||t==="solana-testnet"||t.startsWith("solana:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:x[t]?x[t]:t==="solana"?x[b]:t==="solana-devnet"?x[O]:t==="solana-testnet"?x[v]:x[b]}getAddress(t){return Y(t)?t.publicKey?.toBase58()??null:null}isConnected(t){return Y(t)?t.publicKey!==null:!1}async getBalance(t,e,o){if(!Y(e)||!e.publicKey)return 0;let r=o||this.getDefaultRpcUrl(t.network),n=new Tt(r,"confirmed"),a=new C(e.publicKey.toBase58()),i=new C(t.asset);try{let p=(await n.getAccountInfo(i,"confirmed"))?.owner.toBase58()===lt.toBase58()?lt:bt,c=await yt(i,a,!1,p),u=await Lt(n,c,void 0,p),m=t.extra?.decimals??6;return Number(u.amount)/Math.pow(10,m)}catch(s){if(s&&typeof s=="object"&&"name"in s&&(s.name==="TokenAccountNotFoundError"||s.name==="TokenInvalidAccountOwnerError"))return 0;throw s}}async buildTransaction(t,e,o){let r=tt(t,"svm");if(r)throw new Error(r);if(!Y(e))throw new Error("Invalid Solana wallet");if(!e.publicKey)throw new Error("Wallet not connected");let n=o||this.getDefaultRpcUrl(t.network),a=new Tt(n,"confirmed"),i=new C(e.publicKey.toBase58()),{payTo:s,asset:p,extra:c}=t,u=t.amount??t.maxAmountRequired;if(!u)throw new Error("Missing amount in payment requirements");if(!c?.feePayer)throw new Error("Missing feePayer in payment requirements");let m=new C(c.feePayer),f=new C(p),A=new C(s);this.log("Building transaction:",{from:i.toBase58(),to:s,amount:u,asset:p,feePayer:c.feePayer});let l=[];l.push(Dt.setComputeUnitLimit({units:Wt})),l.push(Dt.setComputeUnitPrice({microLamports:Kt}));let y=await a.getAccountInfo(f,"confirmed");if(!y)throw new Error(`Token mint ${p} not found`);let T=y.owner.toBase58()===lt.toBase58()?lt:bt,E=await kt(a,f,void 0,T);typeof c?.decimals=="number"&&E.decimals!==c.decimals&&this.log(`Decimals mismatch: requirements say ${c.decimals}, mint says ${E.decimals}`);let S=await yt(f,i,!1,T),h=await yt(f,A,!0,T);if(!await a.getAccountInfo(S,"confirmed"))throw new Error(`No token account found for ${p}. Please ensure you have USDC in your wallet.`);if(!await a.getAccountInfo(h,"confirmed"))throw new Error(`Seller token account not found. The seller (${s}) must have a USDC account.`);let w=BigInt(u);l.push(Ut(S,f,h,i,w,E.decimals,[],T));let{blockhash:P}=await a.getLatestBlockhash("confirmed"),N=new Bt({payerKey:m,recentBlockhash:P,instructions:l}).compileToV0Message(),D=new Mt(N),Ot=await e.signTransaction(D);return this.log("Transaction signed successfully"),{serialized:Buffer.from(Ot.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:S.toBase58(),destinationAta:h.toBase58(),asset:p,amount:u,blockhash:P}}}async confirmSettlement(t,e){if(t.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`);let o=new Tt(e,"confirmed"),r=new C(t.destinationAta),n=await o.getSignaturesForAddress(r,{limit:25});if(n.length===0)return{settled:!1};let a=BigInt(t.amount);for(let i of n){if(i.err)continue;let s=await o.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!s?.meta)continue;let p=s.transaction.message.getAccountKeys().keySegments().flat(),c=s.meta.preTokenBalances??[],u=s.meta.postTokenBalances??[];for(let m of u){if(m.mint!==t.asset)continue;let f=p[m.accountIndex];if(!f||!f.equals(r))continue;let A=c.find(T=>T.accountIndex===m.accountIndex),l=BigInt(A?.uiTokenAmount.amount??"0");if(BigInt(m.uiTokenAmount.amount??"0")-l===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function It(d){return new gt(d)}var Ft={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"}]},Rt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Z(d){if(!d||typeof d!="object")return!1;let t=d;return"address"in t&&typeof t.address=="string"&&t.address.startsWith("0x")}var At=class{name="EVM";networks=[$,R,dt,J,W,K,F,j,V,q,H,G,X];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="base"||t==="bsc"||t==="ethereum"||t==="arbitrum"||t==="polygon"||t==="optimism"||t==="avalanche"||t==="world"||t==="monad"||t==="robinhood"||t==="skale-base"||t==="skale-base-sepolia"||t.startsWith("eip155:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:g[t]?g[t]:t==="base"?g[R]:t==="bsc"?g[$]:t==="ethereum"?g[J]:t==="arbitrum"?g[W]:t==="polygon"?g[K]:t==="optimism"?g[F]:t==="avalanche"?g[j]:t==="world"?g[V]:t==="monad"?g[q]:t==="robinhood"?g[H]:t==="skale-base"?g[G]:t==="skale-base-sepolia"?g[X]:g[R]}getAddress(t){return Z(t)?t.address:null}isConnected(t){return Z(t)?!!t.address:!1}getChainId(t){if(ht[t])return ht[t];if(t.startsWith("eip155:")){let e=t.split(":")[1];return parseInt(e,10)}return t==="base"?8453:t==="bsc"?56:t==="ethereum"?1:t==="arbitrum"?42161:t==="polygon"?137:t==="optimism"?10:t==="avalanche"?43114:t==="world"?480:t==="monad"?143:t==="robinhood"?4663:t==="skale-base"?1187947933:t==="skale-base-sepolia"?324705682:8453}async getBalance(t,e,o){if(!Z(e)||!e.address)return 0;let r=o||this.getDefaultRpcUrl(t.network);try{let n=this.encodeBalanceOf(e.address),a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:t.asset,data:n},"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 s=BigInt(i.result),p=t.extra?.decimals??6;return Number(s)/Math.pow(10,p)}catch(n){throw n}}encodeBalanceOf(t){let e="0x70a08231",o=t.slice(2).toLowerCase().padStart(64,"0");return e+o}async confirmSettlement(t,e){if(t.kind==="eip3009"){let o="0xe94a0102",r=t.from.slice(2).toLowerCase().padStart(64,"0"),n=t.nonce.slice(2).toLowerCase().padStart(64,"0"),a=o+r+n,i=await this.ethCall(e,t.asset,a);return{settled:BigInt(i)!==0n}}if(t.kind==="permit2"){let o="0x4fe02b44",r=BigInt(t.nonce),n=r>>8n,a=r&0xffn,i=t.from.slice(2).toLowerCase().padStart(64,"0"),s=n.toString(16).padStart(64,"0"),p=o+i+s,c=await this.ethCall(e,_,p);return{settled:(BigInt(c)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`)}async ethCall(t,e,o){let r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:o},"latest"]})});if(!r.ok)throw new Error(`RPC request failed: ${r.status}`);let n=await r.json();if(n.error)throw new Error(`RPC error: ${JSON.stringify(n.error)}`);if(!n.result||n.result==="0x")throw new Error("RPC returned an empty result");return n.result}async buildTransaction(t,e,o){let r=tt(t,"evm");if(r)throw new Error(r);if(!Z(e))throw new Error("Invalid EVM wallet");if(!e.address)throw new Error("Wallet not connected");if(t.scheme==="exact-approval")return this.buildApprovalTransaction(t,e,o);if(t.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(t,e,o);let{payTo:n,asset:a,extra:i}=t,s=t.amount??t.maxAmountRequired;if(!s)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:e.address,to:n,amount:s,asset:a,network:t.network});let p=this.getChainId(t.network),c=ft[`eip155:${p}`],u={name:i?.name??c?.name??"USD Coin",version:i?.version??c?.version??"2",chainId:BigInt(p),verifyingContract:a},m={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 A="0x"+[...f].map(h=>h.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),y={from:e.address,to:n,value:s,validAfter:String(l-600),validBefore:String(l+(t.maxTimeoutSeconds||60)),nonce:A},T={from:e.address,to:n,value:BigInt(s),validAfter:BigInt(l-600),validBefore:BigInt(l+(t.maxTimeoutSeconds||60)),nonce:A};if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let E=await e.signTypedData({domain:u,types:m,primaryType:"TransferWithAuthorization",message:T});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:y,signature:E}),signature:E,settlementProbe:{kind:"eip3009",from:e.address,nonce:A,asset:a,chainId:p}}}async buildApprovalTransaction(t,e,o){let{payTo:r,asset:n,extra:a}=t,i=t.amount??t.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let s=a?.facilitatorContract;if(!s)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:e.address,to:r,amount:i,asset:n,network:t.network,facilitatorContract:s});let p=o||this.getDefaultRpcUrl(t.network),c=a?.fee??"0",u=BigInt(i)+BigInt(c),m=await this.readAllowance(p,n,e.address,s);if(m<u){if(!e.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 N=this.calculateApprovalAmount(i,c,a?.approvalStrategy);this.log(`Approving ${N} for ${s} (current allowance: ${m})`);let D=await e.sendTransaction({to:n,data:this.encodeApprove(s,N),value:0n});this.log(`Approval tx sent: ${D}`),await this.waitForReceipt(p,D),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let f=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let A=[...f].reduce((N,D)=>N*256n+BigInt(D),0n).toString(),l=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(l);let y="0x"+[...l].map(N=>N.toString(16).padStart(2,"0")).join(""),E=Math.floor(Date.now()/1e3)+(t.maxTimeoutSeconds||300),S=a?.eip712Domain,h=S?{name:S.name,version:S.version,chainId:BigInt(S.chainId),verifyingContract:S.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(t.network)),verifyingContract:s},I=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"}]},Q={from:e.address,to:r,token:n,amount:BigInt(i),fee:BigInt(c),nonce:BigInt(A),deadline:BigInt(E),paymentId:y},w=await e.signTypedData({domain:h,types:I,primaryType:"Payment",message:Q});this.log("EIP-712 Payment signature obtained");let P={from:e.address,to:r,token:n,amount:i,fee:c,nonce:A,deadline:E,paymentId:y,signature:w};return{serialized:JSON.stringify(P),signature:w}}async buildPermit2Transaction(t,e,o){let{payTo:r,asset:n}=t,a=t.amount??t.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!e.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:e.address,to:r,amount:a,asset:n,network:t.network});let i=o||this.getDefaultRpcUrl(t.network),s=await this.readAllowance(i,n,e.address,_),p;if(s<BigInt(a)){let h=this.encodeApprove(_,Rt);if(e.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${s})`);let I=this.getChainId(t.network),Q=await this.readGasPrice(i),w=await this.readNonce(i,e.address),P=await e.signTransaction({to:n,data:h,chainId:I,gas:50000n,gasPrice:Q,nonce:w});p={erc20ApprovalGasSponsoring:{info:{from:e.address,asset:n,spender:_,amount:Rt.toString(),signedTransaction:P,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(e.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${s})`);let I=await e.sendTransaction({to:n,data:h,value:0n});this.log(`Permit2 approval tx sent: ${I}`),await this.waitForReceipt(i,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 c=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(c);let u=[...c].reduce((h,I)=>h*256n+BigInt(I),0n),m=Math.floor(Date.now()/1e3),f=m-600,A=m+(t.maxTimeoutSeconds||300),l=this.getChainId(t.network),y={name:"Permit2",chainId:BigInt(l),verifyingContract:_},T={permitted:{token:n,amount:BigInt(a)},spender:z,nonce:u,deadline:BigInt(A),witness:{to:r,validAfter:BigInt(f)}},E=await e.signTypedData({domain:y,types:Ft,primaryType:"PermitWitnessTransferFrom",message:T});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let S={signature:E,permit2Authorization:{from:e.address,permitted:{token:n,amount:a},spender:z,nonce:u.toString(),deadline:String(A),witness:{to:r,validAfter:String(f)}}};return{serialized:JSON.stringify(S),signature:E,extensions:p,settlementProbe:{kind:"permit2",from:e.address,nonce:u.toString(),chainId:l}}}async readAllowance(t,e,o,r){let n="0xdd62ed3e",a=o.slice(2).toLowerCase().padStart(64,"0"),i=r.slice(2).toLowerCase().padStart(64,"0"),s=n+a+i;try{let c=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e,data:s},"latest"]})})).json();return c.error||!c.result||c.result==="0x"?0n:BigInt(c.result)}catch{return 0n}}encodeApprove(t,e){let o="0x095ea7b3",r=t.slice(2).toLowerCase().padStart(64,"0"),n=e.toString(16).padStart(64,"0");return o+r+n}async waitForReceipt(t,e,o=3e4){let r=Date.now();for(;Date.now()-r<o;){try{let a=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[e]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${e}`);return}}catch(n){if(n instanceof Error&&n.message.includes("reverted"))throw n}await new Promise(n=>setTimeout(n,2e3))}throw new Error(`Approval transaction receipt timeout after ${o}ms: ${e}`)}async readGasPrice(t){try{let o=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return o.result?BigInt(o.result):50000000n}catch{return 50000000n}}async readNonce(t,e){try{let r=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[e,"latest"]})})).json();return r.result?parseInt(r.result,16):0}catch{return 0}}calculateApprovalAmount(t,e,o){let r=BigInt(t)+BigInt(e);if(!o||o.mode==="exact")return r;let n=BigInt(o.defaultMultiple??10),a=r*n;if(o.maxCapUsd){let i=this.inferDecimals(t),s=BigInt(Math.floor(o.maxCapUsd*Math.pow(10,i)));if(a>s)return s}if(o.exactAboveUsd){let i=this.inferDecimals(t),s=BigInt(Math.floor(o.exactAboveUsd*Math.pow(10,i)));if(BigInt(t)>s)return r}return a}inferDecimals(t){return t.length>12?18:6}};function Nt(d){return new At(d)}function re(d){if(d===wt||d===Pt)return!0;let t=d.toLowerCase();for(let e of Object.values(ut))if(e.toLowerCase()===t)return!0;for(let e of Object.keys(mt))if(e.toLowerCase()===t)return!0;return!1}function oe(d=!1){return[It({verbose:d}),Nt({verbose:d})]}function se(d,t){return d.find(e=>e.canHandle(t))}export{W as ARBITRUM_ONE,j as AVALANCHE,R as BASE_MAINNET,dt as BASE_SEPOLIA,$ as BSC_MAINNET,mt as BSC_STABLECOIN_ADDRESSES,pt as BSC_USDC,Et as BSC_USDT,ft as EIP712_DOMAINS,J as ETHEREUM_MAINNET,At as EvmAdapter,q as MONAD_MAINNET,F as OPTIMISM,_ as PERMIT2_ADDRESS,K as POLYGON,H as ROBINHOOD_MAINNET,St as ROBINHOOD_USDG,G as SKALE_BASE,X as SKALE_BASE_SEPOLIA,O as SOLANA_DEVNET,b as SOLANA_MAINNET,v as SOLANA_TESTNET,gt as SolanaAdapter,ut as USDC_ADDRESSES,V as WORLD_MAINNET,z as X402_EXACT_PERMIT2_PROXY,oe as createDefaultAdapters,Nt as createEvmAdapter,It as createSolanaAdapter,se as findAdapter,Z as isEvmWallet,re as isKnownUSDC,Y as isSolanaWallet};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var nt=Object.create;var k=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var it=Object.getPrototypeOf,ot=Object.prototype.hasOwnProperty;var st=(t,e)=>{for(var n in e)k(t,n,{get:e[n],enumerable:!0})},$=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of rt(e))!ot.call(t,r)&&r!==n&&k(t,r,{get:()=>e[r],enumerable:!(a=at(e,r))||a.enumerable});return t};var lt=(t,e,n)=>(n=t!=null?nt(it(t)):{},$(e||!t||!t.__esModule?k(n,"default",{value:t,enumerable:!0}):n,t)),ct=t=>$(k({},"__esModule",{value:!0}),t);var ft={};st(ft,{InsufficientBalanceError:()=>A,UnsupportedNetworkError:()=>f,WithdrawNotReadyError:()=>y,createFileChannelStore:()=>P,createLocalStorageChannelStore:()=>B,getDefaultChannelStore:()=>W,openBatchChannel:()=>Q,resumeBatchChannel:()=>Y});module.exports=ct(ft);var s=require("viem"),C=require("viem/chains"),X=require("@x402/evm"),I=require("@x402/evm/batch-settlement/client"),T=require("@x402/core/client");var O=require("os"),N=require("path"),j=require("@x402/evm/batch-settlement/client");function P(t){return new j.FileClientChannelStorage({directory:t})}var E="dexter-x402-channel:";function B(t){return{async get(e){let n=t.getItem(E+e);return n?JSON.parse(n):void 0},async set(e,n){t.setItem(E+e,JSON.stringify(n))},async delete(e){t.removeItem(E+e)}}}function W(){let t=globalThis.localStorage;return t?B(t):P((0,N.join)((0,O.homedir)(),".dexter-x402","channels"))}var A=class extends Error{constructor(e){super(e),this.name="InsufficientBalanceError"}},f=class extends Error{constructor(e){super(e),this.name="UnsupportedNetworkError"}};var L=require("viem"),z=require("@x402/evm/batch-settlement/client"),g=require("@x402/evm"),y=class extends Error{constructor(e){super(e),this.name="WithdrawNotReadyError"}};function M(t,e){return t===0?0:t+e}var dt=6,H=[{name:"payer",type:"address"},{name:"payerAuthorizer",type:"address"},{name:"receiver",type:"address"},{name:"receiverAuthorizer",type:"address"},{name:"token",type:"address"},{name:"withdrawDelay",type:"uint40"},{name:"salt",type:"bytes32"}],R=[{type:"function",name:"initiateWithdraw",inputs:[{name:"config",type:"tuple",components:H},{name:"amount",type:"uint128"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"finalizeWithdraw",inputs:[{name:"config",type:"tuple",components:H}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"pendingWithdrawals",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"amount",type:"uint128"},{name:"initiatedAt",type:"uint40"}],stateMutability:"view"},{type:"function",name:"channels",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"balance",type:"uint128"},{name:"totalClaimed",type:"uint128"}],stateMutability:"view"}];function ht(t){if(Array.isArray(t))return{balance:BigInt(t[0]),totalClaimed:BigInt(t[1])};let e=t;return{balance:BigInt(e.balance),totalClaimed:BigInt(e.totalClaimed)}}function q(t){if(Array.isArray(t))return{amount:BigInt(t[0]),initiatedAt:Number(t[1])};let e=t;return{amount:BigInt(e.amount),initiatedAt:Number(e.initiatedAt)}}async function _(t){let{config:e,network:n,client:a,withdrawDelaySecs:r}=t,i=(0,z.computeChannelId)(e,n),l=t.amountAtomic;l===void 0&&(l=ht(await a.readContract({address:g.BATCH_SETTLEMENT_ADDRESS,abi:R,functionName:"channels",args:[i]})).balance);let c=await a.writeContract({address:g.BATCH_SETTLEMENT_ADDRESS,abi:R,functionName:"initiateWithdraw",args:[e,l]});await a.waitForTransactionReceipt({hash:c});let d=q(await a.readContract({address:g.BATCH_SETTLEMENT_ADDRESS,abi:R,functionName:"pendingWithdrawals",args:[i]}));return{initiateTx:c,finalizableAt:M(d.initiatedAt,r)}}async function J(t){let{config:e,network:n,client:a,withdrawDelaySecs:r}=t,i=(0,z.computeChannelId)(e,n),l=q(await a.readContract({address:g.BATCH_SETTLEMENT_ADDRESS,abi:R,functionName:"pendingWithdrawals",args:[i]}));if(l.initiatedAt===0)throw new y(`no withdrawal is pending for channel ${i} \u2014 call forceWithdraw first`);let c=M(l.initiatedAt,r),d=Math.floor(Date.now()/1e3);if(d<c)throw new y(`withdrawal for channel ${i} is not finalizable until ${c} (unix seconds) \u2014 ${c-d}s remaining`);let o=await a.writeContract({address:g.BATCH_SETTLEMENT_ADDRESS,abi:R,functionName:"finalizeWithdraw",args:[e]});return await a.waitForTransactionReceipt({hash:o}),{finalizeTx:o,withdrawnAmount:(0,L.formatUnits)(l.amount,dt)}}var V={"eip155:8453":{chain:C.base,defaultRpc:"https://api.dexter.cash/api/evm/base/rpc"},"eip155:42161":{chain:C.arbitrum,defaultRpc:"https://api.dexter.cash/api/evm/arbitrum/rpc"},"eip155:137":{chain:C.polygon,defaultRpc:"https://api.dexter.cash/api/evm/polygon/rpc"}};function G(t){let e=V[t.network];if(!e)throw new f(`batch-settlement is not available on network "${t.network}" \u2014 supported: ${Object.keys(V).join(", ")}`);let n=t.rpcUrl??e.defaultRpc,a=t.wallet.signTypedData;if(typeof a!="function")throw new Error("batch-settlement requires an EvmWallet that supports signTypedData (EIP-712)");let r=(0,s.createWalletClient)({account:{address:t.wallet.address,type:"json-rpc"},chain:e.chain,transport:(0,s.http)(n)}).extend(s.publicActions),i=t.wallet.sendTransaction,l=typeof i=="function",c=async u=>{let b=u.to??void 0;if(!b)throw new Error("batch-settlement escape hatch: transaction is missing a `to` address");let p=u.data??"0x";if(typeof i=="function")return await i.call(t.wallet,{to:b,data:p,value:u.value});throw new Error("batch-settlement: wallet has no sendTransaction")},d=Object.assign(r,{address:t.wallet.address,signTypedData:u=>a.call(t.wallet,u),sendTransaction:c}),o=(0,X.toClientEvmSigner)(d),m=new I.BatchSettlementEvmScheme(o,{storage:t.store,depositPolicy:{depositMultiplier:4},depositStrategy:()=>t.depositAtomic,salt:t.salt}),h=new T.x402Client;h.register(t.network,m);let w=new T.x402HTTPClient(h);return{scheme:m,x402Cli:h,httpClient:w,rpcUrl:n,withdrawClient:d,canSubmitTransactions:l}}var v=6;function ut(t,e){let n=e>t?0n:t-e;return{deposited:(0,s.formatUnits)(t,v),spent:(0,s.formatUnits)(e,v),remaining:(0,s.formatUnits)(n,v)}}function pt(t){let e=t.payload;if(!e||typeof e!="object")return"";let n=e.voucher;if(!n||typeof n!="object")return"";let a=n.channelId;return typeof a=="string"?a:""}function mt(t){let e=t.payload;if(!e||typeof e!="object")return;let n=e.channelConfig;if(!(!n||typeof n!="object"))return n}function K(t){let{stack:e,store:n,network:a}=t,r="",i,l=t.depositedAtomic,c=0n;async function d(){if(!r)return;let o=await(0,I.getChannel)(n,r);o&&(o.chargedCumulativeAmount!==void 0&&(c=BigInt(o.chargedCumulativeAmount)),l===0n&&o.balance!==void 0&&(l=BigInt(o.balance)))}return{get channelId(){return r},get salt(){return t.salt},get network(){return a},get state(){return ut(l,c)},async fetch(o,m){let{httpClient:h}=e,w=await fetch(o,m);if(w.status!==402)return w;let F=h.getPaymentRequiredResponse(p=>w.headers.get(p),await w.clone().json().catch(()=>{})),u=2,b;for(let p=1;p<=u;p+=1){let S=await h.createPaymentPayload(F),D=pt(S);D&&(r=D);let U=mt(S);U&&(i=U);let Z=h.encodePaymentSignatureHeader(S),x=await fetch(o,{...m,headers:{...m?.headers??{},...Z}});b=x;let{recovered:tt}=await h.processPaymentResult(S,et=>x.headers.get(et),x.status);if(await d(),!(x.status===402&&tt&&p<u))return x}return b},async close(){return r&&await n.delete(r.toLowerCase()),{closed:!0}},async forceWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement forceWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!i)throw new Error("forceWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return _({config:i,network:a,client:e.withdrawClient,withdrawDelaySecs:i.withdrawDelay})},async finalizeWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement finalizeWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!i)throw new Error("finalizeWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return J({config:i,network:a,client:e.withdrawClient,withdrawDelaySecs:i.withdrawDelay})}}}async function wt(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),(0,s.toHex)(e)}async function Q(t){let e=t.store??W(),n=t.salt??await wt(),a;try{a=(0,s.parseUnits)(t.deposit,v)}catch{throw new Error(`deposit must be a valid USDC amount in decimal units (e.g. "0.30"), got "${t.deposit}"`)}if(a<=0n)throw new Error(`deposit must be a positive amount, got "${t.deposit}"`);let r=G({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:a.toString(),salt:n});return K({stack:r,store:e,network:t.network,depositedAtomic:a,salt:n})}async function Y(t){let e=t.store??W(),n=G({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:"0",salt:t.salt});return K({stack:n,store:e,network:t.network,depositedAtomic:0n,salt:t.salt})}0&&(module.exports={InsufficientBalanceError,UnsupportedNetworkError,WithdrawNotReadyError,createFileChannelStore,createLocalStorageChannelStore,getDefaultChannelStore,openBatchChannel,resumeBatchChannel});
|
|
1
|
+
"use strict";var Ct=Object.create;var I=Object.defineProperty;var yt=Object.getOwnPropertyDescriptor;var xt=Object.getOwnPropertyNames;var Et=Object.getPrototypeOf,St=Object.prototype.hasOwnProperty;var At=(t,e)=>{for(var n in e)I(t,n,{get:e[n],enumerable:!0})},Q=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of xt(e))!St.call(t,r)&&r!==n&&I(t,r,{get:()=>e[r],enumerable:!(a=yt(e,r))||a.enumerable});return t};var bt=(t,e,n)=>(n=t!=null?Ct(Et(t)):{},Q(e||!t||!t.__esModule?I(n,"default",{value:t,enumerable:!0}):n,t)),Rt=t=>Q(I({},"__esModule",{value:!0}),t);var Ft={};At(Ft,{InsufficientBalanceError:()=>P,UnsupportedNetworkError:()=>x,WithdrawNotReadyError:()=>S,createFileChannelStore:()=>X,createLocalStorageChannelStore:()=>Y,getDefaultChannelStore:()=>T,openBatchChannel:()=>ft,resumeBatchChannel:()=>gt});module.exports=Rt(Ft);var d=require("viem"),A=require("viem/chains"),ht=require("@x402/evm"),U=require("@x402/evm/batch-settlement/client"),F=require("@x402/core/client");var Tt="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Dt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Nt="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var z="eip155:8453",$="eip155:84532",K="eip155:42161",H="eip155:137",q="eip155:10",j="eip155:43114",V="eip155:56",W="eip155:480",_="eip155:143",B="eip155:4663",O="eip155:1187947933",k="eip155:324705682",G="eip155:1";var It="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Wt="0x55d398326f99059fF775485246999027B3197955",tt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",_t="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",et={[V]:tt,[z]:It,[$]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[K]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[H]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[q]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[j]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[W]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[_]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[B]:_t,[O]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[k]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[G]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Lt={[Wt]:{symbol:"USDT",decimals:18},[tt]:{symbol:"USDC",decimals:18}};var zt={[W]:{name:"USDC",version:"2"},[_]:{name:"USDC",version:"2"},[B]:{name:"Global Dollar",version:"1"},[O]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[k]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}};var $t={[V]:56,[z]:8453,[$]:84532,[K]:42161,[H]:137,[q]:10,[j]:43114,[W]:480,[_]:143,[B]:4663,[O]:1187947933,[k]:324705682,[G]:1},Kt={[Tt]:"https://api.dexter.cash/api/solana/rpc",[Dt]:"https://api.devnet.solana.com",[Nt]:"https://api.testnet.solana.com"},Ht={[V]:"https://api.dexter.cash/api/evm/bsc/rpc",[z]:"https://api.dexter.cash/api/base/rpc",[$]:"https://sepolia.base.org",[K]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[H]:"https://api.dexter.cash/api/evm/polygon/rpc",[q]:"https://api.dexter.cash/api/evm/optimism/rpc",[j]:"https://api.dexter.cash/api/evm/avalanche/rpc",[W]:"https://worldchain-mainnet.g.alchemy.com/public",[_]:"https://rpc.monad.xyz",[B]:"https://rpc.mainnet.chain.robinhood.com",[O]:"https://skale-base.skalenodes.com/v1/base",[k]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[G]:"https://eth.llamarpc.com"};var nt=require("os"),at=require("path"),rt=require("@x402/evm/batch-settlement/client/file-storage");function X(t){return new rt.FileClientChannelStorage({directory:t})}var J="dexter-x402-channel:";function Y(t){return{async get(e){let n=t.getItem(J+e);return n?JSON.parse(n):void 0},async set(e,n){t.setItem(J+e,JSON.stringify(n))},async delete(e){t.removeItem(J+e)}}}function T(){let t=globalThis.localStorage;return t?Y(t):X((0,at.join)((0,nt.homedir)(),".dexter-x402","channels"))}var P=class extends Error{constructor(e){super(e),this.name="InsufficientBalanceError"}},x=class extends Error{constructor(e){super(e),this.name="UnsupportedNetworkError"}};var ot=require("viem"),Z=require("@x402/evm/batch-settlement/client"),E=require("@x402/evm"),S=class extends Error{constructor(e){super(e),this.name="WithdrawNotReadyError"}};function st(t,e){return t===0?0:t+e}var Bt=6,it=[{name:"payer",type:"address"},{name:"payerAuthorizer",type:"address"},{name:"receiver",type:"address"},{name:"receiverAuthorizer",type:"address"},{name:"token",type:"address"},{name:"withdrawDelay",type:"uint40"},{name:"salt",type:"bytes32"}],D=[{type:"function",name:"initiateWithdraw",inputs:[{name:"config",type:"tuple",components:it},{name:"amount",type:"uint128"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"finalizeWithdraw",inputs:[{name:"config",type:"tuple",components:it}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"pendingWithdrawals",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"amount",type:"uint128"},{name:"initiatedAt",type:"uint40"}],stateMutability:"view"},{type:"function",name:"channels",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"balance",type:"uint128"},{name:"totalClaimed",type:"uint128"}],stateMutability:"view"}];function Ot(t){if(Array.isArray(t))return{balance:BigInt(t[0]),totalClaimed:BigInt(t[1])};let e=t;return{balance:BigInt(e.balance),totalClaimed:BigInt(e.totalClaimed)}}function ct(t){if(Array.isArray(t))return{amount:BigInt(t[0]),initiatedAt:Number(t[1])};let e=t;return{amount:BigInt(e.amount),initiatedAt:Number(e.initiatedAt)}}async function lt(t){let{config:e,network:n,client:a,withdrawDelaySecs:r}=t,s=(0,Z.computeChannelId)(e,n),l=t.amountAtomic;l===void 0&&(l=Ot(await a.readContract({address:E.BATCH_SETTLEMENT_ADDRESS,abi:D,functionName:"channels",args:[s]})).balance);let p=await a.writeContract({address:E.BATCH_SETTLEMENT_ADDRESS,abi:D,functionName:"initiateWithdraw",args:[e,l]});await a.waitForTransactionReceipt({hash:p});let m=ct(await a.readContract({address:E.BATCH_SETTLEMENT_ADDRESS,abi:D,functionName:"pendingWithdrawals",args:[s]}));return{initiateTx:p,finalizableAt:st(m.initiatedAt,r)}}async function dt(t){let{config:e,network:n,client:a,withdrawDelaySecs:r}=t,s=(0,Z.computeChannelId)(e,n),l=ct(await a.readContract({address:E.BATCH_SETTLEMENT_ADDRESS,abi:D,functionName:"pendingWithdrawals",args:[s]}));if(l.initiatedAt===0)throw new S(`no withdrawal is pending for channel ${s} \u2014 call forceWithdraw first`);let p=st(l.initiatedAt,r),m=Math.floor(Date.now()/1e3);if(m<p)throw new S(`withdrawal for channel ${s} is not finalizable until ${p} (unix seconds) \u2014 ${p-m}s remaining`);let c=await a.writeContract({address:E.BATCH_SETTLEMENT_ADDRESS,abi:D,functionName:"finalizeWithdraw",args:[e]});return await a.waitForTransactionReceipt({hash:c}),{finalizeTx:c,withdrawnAmount:(0,ot.formatUnits)(l.amount,Bt)}}var pt={"eip155:8453":{chain:A.base,defaultRpc:"https://api.dexter.cash/api/evm/base/rpc"},"eip155:42161":{chain:A.arbitrum,defaultRpc:"https://api.dexter.cash/api/evm/arbitrum/rpc"},"eip155:137":{chain:A.polygon,defaultRpc:"https://api.dexter.cash/api/evm/polygon/rpc"}};function mt(t){let e=pt[t.network];if(!e)throw new x(`batch-settlement is not available on network "${t.network}" \u2014 supported: ${Object.keys(pt).join(", ")}`);let n=t.rpcUrl??e.defaultRpc,a=BigInt(t.depositAtomic),r=a===0n,s=r?t.maxPaymentAtomic??"1000000":t.depositAtomic,l=et[t.network],p=t.wallet.signTypedData;if(typeof p!="function")throw new Error("batch-settlement requires an EvmWallet that supports signTypedData (EIP-712)");let m=(0,d.createWalletClient)({account:{address:t.wallet.address,type:"json-rpc"},chain:e.chain,transport:(0,d.http)(n)}).extend(d.publicActions),c=t.wallet.sendTransaction,b=typeof c=="function",C=async i=>{let o=i.to??void 0;if(!o)throw new Error("batch-settlement escape hatch: transaction is missing a `to` address");let g=i.data??"0x";if(typeof c=="function")return await c.call(t.wallet,{to:o,data:g,value:i.value});throw new Error("batch-settlement: wallet has no sendTransaction")},f=Object.assign(m,{address:t.wallet.address,signTypedData:i=>{if(!r&&i.primaryType==="Voucher"&&BigInt(i.message.maxClaimableAmount)>a)throw new Error("batch-settlement voucher exceeds the authorized deposit budget");return p.call(t.wallet,i)},sendTransaction:C}),M=(0,ht.toClientEvmSigner)(f),R=!1,y=new U.BatchSettlementEvmScheme(M,{storage:t.store,depositPolicy:{depositMultiplier:4},depositStrategy:i=>{if(r)throw new Error("batch-settlement resume requires funded escrow; resume never authorizes a deposit");if(BigInt(i.currentBalance)>0n||BigInt(i.clientContext.chargedCumulativeAmount??"0")>0n)throw new Error("batch-settlement escrow is exhausted; automatic top-ups are disabled");if(R)throw new Error("batch-settlement initial funding was already attempted; reconcile its outcome and resume the channel before spending again");let o=i.paymentRequirements.extra?.minDeposit;if(typeof o=="string"&&/^\d+$/.test(o)&&BigInt(o)>a)throw new Error("batch-settlement seller minimum deposit exceeds the authorized deposit budget");if(BigInt(i.minimumDepositAmount)>a||i.maxDeposit!==void 0&&BigInt(i.maxDeposit)<a)throw new Error("batch-settlement cannot fund the exact authorized deposit");return R=!0,t.depositAtomic},salt:t.salt}),h=new F.x402Client;h.register(t.network,y),h.setSpendControls({allowedAssets:[{network:t.network,asset:l,maxAmountPerPayment:s}]}),h.registerPolicy((i,o)=>{let g=o.filter(w=>w.asset.toLowerCase()===l.toLowerCase());if(g.length===0)throw new Error("batch-settlement channels support only USDC on the selected network");return g});let u;h.onBeforePaymentCreation(async({selectedRequirements:i})=>{let o=JSON.stringify(y.buildChannelConfig(i),(g,w)=>typeof w=="string"?w.toLowerCase():w);if(u!==void 0&&o!==u)throw new Error("batch-settlement handle is already bound to a different channel configuration");u=o});let N=new F.x402HTTPClient(h);return{scheme:y,x402Cli:h,httpClient:N,rpcUrl:n,withdrawClient:f,canSubmitTransactions:b}}var v=6;function ut(t,e){let n;try{if(!/^(?:\d+(?:\.\d{0,6})?|\.\d{1,6})$/.test(t))throw new Error("invalid decimal");n=(0,d.parseUnits)(t,v)}catch{throw new Error(`${e} must be a valid USDC amount with at most six decimal places (e.g. "0.30"), got "${t}"`)}if(n<=0n)throw new Error(`${e} must be a positive amount, got "${t}"`);return n}function kt(t,e){let n=e>t?0n:t-e;return{deposited:(0,d.formatUnits)(t,v),spent:(0,d.formatUnits)(e,v),remaining:(0,d.formatUnits)(n,v)}}function Pt(t){let e=t.payload;if(!e||typeof e!="object")return"";let n=e.voucher;if(!n||typeof n!="object")return"";let a=n.channelId;return typeof a=="string"?a:""}function vt(t){let e=t.payload;if(!e||typeof e!="object")return;let n=e.channelConfig;if(!(!n||typeof n!="object"))return n}function wt(t){let{stack:e,store:n,network:a}=t,r="",s,l=t.depositedAtomic,p=0n;async function m(){if(!r)return;let c=await(0,U.getChannel)(n,r);c&&(c.chargedCumulativeAmount!==void 0&&(p=BigInt(c.chargedCumulativeAmount)),l===0n&&c.balance!==void 0&&(l=BigInt(c.balance)))}return{get channelId(){return r},get salt(){return t.salt},get network(){return a},get state(){return kt(l,p)},async fetch(c,b){let{httpClient:C}=e,f=await fetch(c,b);if(f.status!==402)return f;let M=C.getPaymentRequiredResponse(h=>f.headers.get(h),await f.clone().json().catch(()=>{})),R=2,y;for(let h=1;h<=R;h+=1){let u=await C.createPaymentPayload(M),N=Pt(u);N&&(r=N);let L=vt(u);L&&(s=L);let i=C.encodePaymentSignatureHeader(u),o=await fetch(c,{...b,headers:{...b?.headers??{},...i}});y=o;let{recovered:g}=await C.processPaymentResult(u,w=>o.headers.get(w),o.status);if(await m(),!(o.status===402&&g&&h<R))return o}return y},async close(){return r&&await n.delete(r.toLowerCase()),{closed:!0}},async forceWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement forceWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!s)throw new Error("forceWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return lt({config:s,network:a,client:e.withdrawClient,withdrawDelaySecs:s.withdrawDelay})},async finalizeWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement finalizeWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!s)throw new Error("finalizeWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return dt({config:s,network:a,client:e.withdrawClient,withdrawDelaySecs:s.withdrawDelay})}}}async function Ut(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),(0,d.toHex)(e)}async function ft(t){let e=t.store??T(),n=t.salt??await Ut(),a=ut(t.deposit,"deposit"),r=mt({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:a.toString(),salt:n});return wt({stack:r,store:e,network:t.network,depositedAtomic:a,salt:n})}async function gt(t){let e=t.store??T(),n=ut(t.maxAmountPerPayment??"1","maxAmountPerPayment"),a=mt({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:"0",maxPaymentAtomic:n.toString(),salt:t.salt});return wt({stack:a,store:e,network:t.network,depositedAtomic:0n,salt:t.salt})}0&&(module.exports={InsufficientBalanceError,UnsupportedNetworkError,WithdrawNotReadyError,createFileChannelStore,createLocalStorageChannelStore,getDefaultChannelStore,openBatchChannel,resumeBatchChannel});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { O as OpenBatchChannelOptions, B as BatchSettlementChannel, R as ResumeBatchChannelOptions, C as ChannelStore } from '../types-
|
|
2
|
-
export { a as ChannelState, b as CloseReceipt, c as CloseResult, F as FinalizeWithdrawResult, d as ForceWithdrawResult, I as InsufficientBalanceError, U as UnsupportedNetworkError, W as WithdrawNotReadyError } from '../types-
|
|
1
|
+
import { O as OpenBatchChannelOptions, B as BatchSettlementChannel, R as ResumeBatchChannelOptions, C as ChannelStore } from '../types-BOEYu6ya.cjs';
|
|
2
|
+
export { a as ChannelState, b as CloseReceipt, c as CloseResult, F as FinalizeWithdrawResult, d as ForceWithdrawResult, I as InsufficientBalanceError, U as UnsupportedNetworkError, W as WithdrawNotReadyError } from '../types-BOEYu6ya.cjs';
|
|
3
3
|
import '@x402/evm/batch-settlement/client';
|
|
4
|
-
import '../types-
|
|
4
|
+
import '../types-B4JCwkHH.cjs';
|
|
5
|
+
import '../types-8Q38sHOi.cjs';
|
|
5
6
|
|
|
6
7
|
declare function openBatchChannel(options: OpenBatchChannelOptions): Promise<BatchSettlementChannel>;
|
|
7
8
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { O as OpenBatchChannelOptions, B as BatchSettlementChannel, R as ResumeBatchChannelOptions, C as ChannelStore } from '../types-
|
|
2
|
-
export { a as ChannelState, b as CloseReceipt, c as CloseResult, F as FinalizeWithdrawResult, d as ForceWithdrawResult, I as InsufficientBalanceError, U as UnsupportedNetworkError, W as WithdrawNotReadyError } from '../types-
|
|
1
|
+
import { O as OpenBatchChannelOptions, B as BatchSettlementChannel, R as ResumeBatchChannelOptions, C as ChannelStore } from '../types-DhCxPFgg.js';
|
|
2
|
+
export { a as ChannelState, b as CloseReceipt, c as CloseResult, F as FinalizeWithdrawResult, d as ForceWithdrawResult, I as InsufficientBalanceError, U as UnsupportedNetworkError, W as WithdrawNotReadyError } from '../types-DhCxPFgg.js';
|
|
3
3
|
import '@x402/evm/batch-settlement/client';
|
|
4
|
-
import '../types-
|
|
4
|
+
import '../types-Ds9IUnXG.js';
|
|
5
|
+
import '../types-8Q38sHOi.js';
|
|
5
6
|
|
|
6
7
|
declare function openBatchChannel(options: OpenBatchChannelOptions): Promise<BatchSettlementChannel>;
|
|
7
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createWalletClient as K,http as Q,publicActions as Y,parseUnits as Z,formatUnits as A,toHex as tt}from"viem";import{base as et,arbitrum as nt,polygon as at}from"viem/chains";import{toClientEvmSigner as rt}from"@x402/evm";import{BatchSettlementEvmScheme as it,getChannel as ot}from"@x402/evm/batch-settlement/client";import{x402Client as st,x402HTTPClient as lt}from"@x402/core/client";import{homedir as q}from"os";import{join as _}from"path";import{FileClientChannelStorage as J}from"@x402/evm/batch-settlement/client";function E(t){return new J({directory:t})}var R="dexter-x402-channel:";function P(t){return{async get(e){let n=t.getItem(R+e);return n?JSON.parse(n):void 0},async set(e,n){t.setItem(R+e,JSON.stringify(n))},async delete(e){t.removeItem(R+e)}}}function x(){let t=globalThis.localStorage;return t?P(t):E(_(q(),".dexter-x402","channels"))}var k=class extends Error{constructor(e){super(e),this.name="InsufficientBalanceError"}},y=class extends Error{constructor(e){super(e),this.name="UnsupportedNetworkError"}};import{formatUnits as V}from"viem";import{computeChannelId as z}from"@x402/evm/batch-settlement/client";import{BATCH_SETTLEMENT_ADDRESS as C}from"@x402/evm";var S=class extends Error{constructor(e){super(e),this.name="WithdrawNotReadyError"}};function F(t,e){return t===0?0:t+e}var X=6,B=[{name:"payer",type:"address"},{name:"payerAuthorizer",type:"address"},{name:"receiver",type:"address"},{name:"receiverAuthorizer",type:"address"},{name:"token",type:"address"},{name:"withdrawDelay",type:"uint40"},{name:"salt",type:"bytes32"}],b=[{type:"function",name:"initiateWithdraw",inputs:[{name:"config",type:"tuple",components:B},{name:"amount",type:"uint128"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"finalizeWithdraw",inputs:[{name:"config",type:"tuple",components:B}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"pendingWithdrawals",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"amount",type:"uint128"},{name:"initiatedAt",type:"uint40"}],stateMutability:"view"},{type:"function",name:"channels",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"balance",type:"uint128"},{name:"totalClaimed",type:"uint128"}],stateMutability:"view"}];function G(t){if(Array.isArray(t))return{balance:BigInt(t[0]),totalClaimed:BigInt(t[1])};let e=t;return{balance:BigInt(e.balance),totalClaimed:BigInt(e.totalClaimed)}}function D(t){if(Array.isArray(t))return{amount:BigInt(t[0]),initiatedAt:Number(t[1])};let e=t;return{amount:BigInt(e.amount),initiatedAt:Number(e.initiatedAt)}}async function U(t){let{config:e,network:n,client:a,withdrawDelaySecs:i}=t,r=z(e,n),s=t.amountAtomic;s===void 0&&(s=G(await a.readContract({address:C,abi:b,functionName:"channels",args:[r]})).balance);let l=await a.writeContract({address:C,abi:b,functionName:"initiateWithdraw",args:[e,s]});await a.waitForTransactionReceipt({hash:l});let c=D(await a.readContract({address:C,abi:b,functionName:"pendingWithdrawals",args:[r]}));return{initiateTx:l,finalizableAt:F(c.initiatedAt,i)}}async function $(t){let{config:e,network:n,client:a,withdrawDelaySecs:i}=t,r=z(e,n),s=D(await a.readContract({address:C,abi:b,functionName:"pendingWithdrawals",args:[r]}));if(s.initiatedAt===0)throw new S(`no withdrawal is pending for channel ${r} \u2014 call forceWithdraw first`);let l=F(s.initiatedAt,i),c=Math.floor(Date.now()/1e3);if(c<l)throw new S(`withdrawal for channel ${r} is not finalizable until ${l} (unix seconds) \u2014 ${l-c}s remaining`);let o=await a.writeContract({address:C,abi:b,functionName:"finalizeWithdraw",args:[e]});return await a.waitForTransactionReceipt({hash:o}),{finalizeTx:o,withdrawnAmount:V(s.amount,X)}}var O={"eip155:8453":{chain:et,defaultRpc:"https://api.dexter.cash/api/evm/base/rpc"},"eip155:42161":{chain:nt,defaultRpc:"https://api.dexter.cash/api/evm/arbitrum/rpc"},"eip155:137":{chain:at,defaultRpc:"https://api.dexter.cash/api/evm/polygon/rpc"}};function N(t){let e=O[t.network];if(!e)throw new y(`batch-settlement is not available on network "${t.network}" \u2014 supported: ${Object.keys(O).join(", ")}`);let n=t.rpcUrl??e.defaultRpc,a=t.wallet.signTypedData;if(typeof a!="function")throw new Error("batch-settlement requires an EvmWallet that supports signTypedData (EIP-712)");let i=K({account:{address:t.wallet.address,type:"json-rpc"},chain:e.chain,transport:Q(n)}).extend(Y),r=t.wallet.sendTransaction,s=typeof r=="function",l=async h=>{let w=h.to??void 0;if(!w)throw new Error("batch-settlement escape hatch: transaction is missing a `to` address");let u=h.data??"0x";if(typeof r=="function")return await r.call(t.wallet,{to:w,data:u,value:h.value});throw new Error("batch-settlement: wallet has no sendTransaction")},c=Object.assign(i,{address:t.wallet.address,signTypedData:h=>a.call(t.wallet,h),sendTransaction:l}),o=rt(c),p=new it(o,{storage:t.store,depositPolicy:{depositMultiplier:4},depositStrategy:()=>t.depositAtomic,salt:t.salt}),d=new st;d.register(t.network,p);let m=new lt(d);return{scheme:p,x402Cli:d,httpClient:m,rpcUrl:n,withdrawClient:c,canSubmitTransactions:s}}var W=6;function ct(t,e){let n=e>t?0n:t-e;return{deposited:A(t,W),spent:A(e,W),remaining:A(n,W)}}function dt(t){let e=t.payload;if(!e||typeof e!="object")return"";let n=e.voucher;if(!n||typeof n!="object")return"";let a=n.channelId;return typeof a=="string"?a:""}function ht(t){let e=t.payload;if(!e||typeof e!="object")return;let n=e.channelConfig;if(!(!n||typeof n!="object"))return n}function j(t){let{stack:e,store:n,network:a}=t,i="",r,s=t.depositedAtomic,l=0n;async function c(){if(!i)return;let o=await ot(n,i);o&&(o.chargedCumulativeAmount!==void 0&&(l=BigInt(o.chargedCumulativeAmount)),s===0n&&o.balance!==void 0&&(s=BigInt(o.balance)))}return{get channelId(){return i},get salt(){return t.salt},get network(){return a},get state(){return ct(s,l)},async fetch(o,p){let{httpClient:d}=e,m=await fetch(o,p);if(m.status!==402)return m;let v=d.getPaymentRequiredResponse(u=>m.headers.get(u),await m.clone().json().catch(()=>{})),h=2,w;for(let u=1;u<=h;u+=1){let f=await d.createPaymentPayload(v),I=dt(f);I&&(i=I);let T=ht(f);T&&(r=T);let H=d.encodePaymentSignatureHeader(f),g=await fetch(o,{...p,headers:{...p?.headers??{},...H}});w=g;let{recovered:L}=await d.processPaymentResult(f,M=>g.headers.get(M),g.status);if(await c(),!(g.status===402&&L&&u<h))return g}return w},async close(){return i&&await n.delete(i.toLowerCase()),{closed:!0}},async forceWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement forceWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!r)throw new Error("forceWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return U({config:r,network:a,client:e.withdrawClient,withdrawDelaySecs:r.withdrawDelay})},async finalizeWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement finalizeWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!r)throw new Error("finalizeWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return $({config:r,network:a,client:e.withdrawClient,withdrawDelaySecs:r.withdrawDelay})}}}async function ut(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),tt(e)}async function pt(t){let e=t.store??x(),n=t.salt??await ut(),a;try{a=Z(t.deposit,W)}catch{throw new Error(`deposit must be a valid USDC amount in decimal units (e.g. "0.30"), got "${t.deposit}"`)}if(a<=0n)throw new Error(`deposit must be a positive amount, got "${t.deposit}"`);let i=N({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:a.toString(),salt:n});return j({stack:i,store:e,network:t.network,depositedAtomic:a,salt:n})}async function mt(t){let e=t.store??x(),n=N({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:"0",salt:t.salt});return j({stack:n,store:e,network:t.network,depositedAtomic:0n,salt:t.salt})}export{k as InsufficientBalanceError,y as UnsupportedNetworkError,S as WithdrawNotReadyError,E as createFileChannelStore,P as createLocalStorageChannelStore,x as getDefaultChannelStore,pt as openBatchChannel,mt as resumeBatchChannel};
|
|
1
|
+
import{createWalletClient as Ct,http as yt,publicActions as xt,parseUnits as Et,formatUnits as q,toHex as St}from"viem";import{base as At,arbitrum as bt,polygon as Rt}from"viem/chains";import{toClientEvmSigner as Tt}from"@x402/evm";import{BatchSettlementEvmScheme as Dt,getChannel as Nt}from"@x402/evm/batch-settlement/client";import{x402Client as It,x402HTTPClient as Wt}from"@x402/core/client";var ot="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",st="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ct="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var P="eip155:8453",v="eip155:84532",U="eip155:42161",F="eip155:137",M="eip155:10",L="eip155:43114",z="eip155:56",T="eip155:480",D="eip155:143",N="eip155:4663",I="eip155:1187947933",W="eip155:324705682",$="eip155:1";var lt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",dt="0x55d398326f99059fF775485246999027B3197955",j="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",pt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",V={[z]:j,[P]:lt,[v]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[U]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[F]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[M]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[L]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[T]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[D]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[N]:pt,[I]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[W]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[$]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Ut={[dt]:{symbol:"USDT",decimals:18},[j]:{symbol:"USDC",decimals:18}};var Ft={[T]:{name:"USDC",version:"2"},[D]:{name:"USDC",version:"2"},[N]:{name:"Global Dollar",version:"1"},[I]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[W]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}};var Mt={[z]:56,[P]:8453,[v]:84532,[U]:42161,[F]:137,[M]:10,[L]:43114,[T]:480,[D]:143,[N]:4663,[I]:1187947933,[W]:324705682,[$]:1},Lt={[ot]:"https://api.dexter.cash/api/solana/rpc",[st]:"https://api.devnet.solana.com",[ct]:"https://api.testnet.solana.com"},zt={[z]:"https://api.dexter.cash/api/evm/bsc/rpc",[P]:"https://api.dexter.cash/api/base/rpc",[v]:"https://sepolia.base.org",[U]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[F]:"https://api.dexter.cash/api/evm/polygon/rpc",[M]:"https://api.dexter.cash/api/evm/optimism/rpc",[L]:"https://api.dexter.cash/api/evm/avalanche/rpc",[T]:"https://worldchain-mainnet.g.alchemy.com/public",[D]:"https://rpc.monad.xyz",[N]:"https://rpc.mainnet.chain.robinhood.com",[I]:"https://skale-base.skalenodes.com/v1/base",[W]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[$]:"https://eth.llamarpc.com"};import{homedir as ht}from"os";import{join as mt}from"path";import{FileClientChannelStorage as ut}from"@x402/evm/batch-settlement/client/file-storage";function G(t){return new ut({directory:t})}var K="dexter-x402-channel:";function J(t){return{async get(e){let n=t.getItem(K+e);return n?JSON.parse(n):void 0},async set(e,n){t.setItem(K+e,JSON.stringify(n))},async delete(e){t.removeItem(K+e)}}}function _(){let t=globalThis.localStorage;return t?J(t):G(mt(ht(),".dexter-x402","channels"))}var H=class extends Error{constructor(e){super(e),this.name="InsufficientBalanceError"}},E=class extends Error{constructor(e){super(e),this.name="UnsupportedNetworkError"}};import{formatUnits as wt}from"viem";import{computeChannelId as Y}from"@x402/evm/batch-settlement/client";import{BATCH_SETTLEMENT_ADDRESS as S}from"@x402/evm";var b=class extends Error{constructor(e){super(e),this.name="WithdrawNotReadyError"}};function Z(t,e){return t===0?0:t+e}var ft=6,X=[{name:"payer",type:"address"},{name:"payerAuthorizer",type:"address"},{name:"receiver",type:"address"},{name:"receiverAuthorizer",type:"address"},{name:"token",type:"address"},{name:"withdrawDelay",type:"uint40"},{name:"salt",type:"bytes32"}],A=[{type:"function",name:"initiateWithdraw",inputs:[{name:"config",type:"tuple",components:X},{name:"amount",type:"uint128"}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"finalizeWithdraw",inputs:[{name:"config",type:"tuple",components:X}],outputs:[],stateMutability:"nonpayable"},{type:"function",name:"pendingWithdrawals",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"amount",type:"uint128"},{name:"initiatedAt",type:"uint40"}],stateMutability:"view"},{type:"function",name:"channels",inputs:[{name:"channelId",type:"bytes32"}],outputs:[{name:"balance",type:"uint128"},{name:"totalClaimed",type:"uint128"}],stateMutability:"view"}];function gt(t){if(Array.isArray(t))return{balance:BigInt(t[0]),totalClaimed:BigInt(t[1])};let e=t;return{balance:BigInt(e.balance),totalClaimed:BigInt(e.totalClaimed)}}function Q(t){if(Array.isArray(t))return{amount:BigInt(t[0]),initiatedAt:Number(t[1])};let e=t;return{amount:BigInt(e.amount),initiatedAt:Number(e.initiatedAt)}}async function tt(t){let{config:e,network:n,client:a,withdrawDelaySecs:o}=t,s=Y(e,n),l=t.amountAtomic;l===void 0&&(l=gt(await a.readContract({address:S,abi:A,functionName:"channels",args:[s]})).balance);let d=await a.writeContract({address:S,abi:A,functionName:"initiateWithdraw",args:[e,l]});await a.waitForTransactionReceipt({hash:d});let h=Q(await a.readContract({address:S,abi:A,functionName:"pendingWithdrawals",args:[s]}));return{initiateTx:d,finalizableAt:Z(h.initiatedAt,o)}}async function et(t){let{config:e,network:n,client:a,withdrawDelaySecs:o}=t,s=Y(e,n),l=Q(await a.readContract({address:S,abi:A,functionName:"pendingWithdrawals",args:[s]}));if(l.initiatedAt===0)throw new b(`no withdrawal is pending for channel ${s} \u2014 call forceWithdraw first`);let d=Z(l.initiatedAt,o),h=Math.floor(Date.now()/1e3);if(h<d)throw new b(`withdrawal for channel ${s} is not finalizable until ${d} (unix seconds) \u2014 ${d-h}s remaining`);let c=await a.writeContract({address:S,abi:A,functionName:"finalizeWithdraw",args:[e]});return await a.waitForTransactionReceipt({hash:c}),{finalizeTx:c,withdrawnAmount:wt(l.amount,ft)}}var nt={"eip155:8453":{chain:At,defaultRpc:"https://api.dexter.cash/api/evm/base/rpc"},"eip155:42161":{chain:bt,defaultRpc:"https://api.dexter.cash/api/evm/arbitrum/rpc"},"eip155:137":{chain:Rt,defaultRpc:"https://api.dexter.cash/api/evm/polygon/rpc"}};function at(t){let e=nt[t.network];if(!e)throw new E(`batch-settlement is not available on network "${t.network}" \u2014 supported: ${Object.keys(nt).join(", ")}`);let n=t.rpcUrl??e.defaultRpc,a=BigInt(t.depositAtomic),o=a===0n,s=o?t.maxPaymentAtomic??"1000000":t.depositAtomic,l=V[t.network],d=t.wallet.signTypedData;if(typeof d!="function")throw new Error("batch-settlement requires an EvmWallet that supports signTypedData (EIP-712)");let h=Ct({account:{address:t.wallet.address,type:"json-rpc"},chain:e.chain,transport:yt(n)}).extend(xt),c=t.wallet.sendTransaction,y=typeof c=="function",g=async r=>{let i=r.to??void 0;if(!i)throw new Error("batch-settlement escape hatch: transaction is missing a `to` address");let f=r.data??"0x";if(typeof c=="function")return await c.call(t.wallet,{to:i,data:f,value:r.value});throw new Error("batch-settlement: wallet has no sendTransaction")},w=Object.assign(h,{address:t.wallet.address,signTypedData:r=>{if(!o&&r.primaryType==="Voucher"&&BigInt(r.message.maxClaimableAmount)>a)throw new Error("batch-settlement voucher exceeds the authorized deposit budget");return d.call(t.wallet,r)},sendTransaction:g}),O=Tt(w),x=!1,C=new Dt(O,{storage:t.store,depositPolicy:{depositMultiplier:4},depositStrategy:r=>{if(o)throw new Error("batch-settlement resume requires funded escrow; resume never authorizes a deposit");if(BigInt(r.currentBalance)>0n||BigInt(r.clientContext.chargedCumulativeAmount??"0")>0n)throw new Error("batch-settlement escrow is exhausted; automatic top-ups are disabled");if(x)throw new Error("batch-settlement initial funding was already attempted; reconcile its outcome and resume the channel before spending again");let i=r.paymentRequirements.extra?.minDeposit;if(typeof i=="string"&&/^\d+$/.test(i)&&BigInt(i)>a)throw new Error("batch-settlement seller minimum deposit exceeds the authorized deposit budget");if(BigInt(r.minimumDepositAmount)>a||r.maxDeposit!==void 0&&BigInt(r.maxDeposit)<a)throw new Error("batch-settlement cannot fund the exact authorized deposit");return x=!0,t.depositAtomic},salt:t.salt}),p=new It;p.register(t.network,C),p.setSpendControls({allowedAssets:[{network:t.network,asset:l,maxAmountPerPayment:s}]}),p.registerPolicy((r,i)=>{let f=i.filter(u=>u.asset.toLowerCase()===l.toLowerCase());if(f.length===0)throw new Error("batch-settlement channels support only USDC on the selected network");return f});let m;p.onBeforePaymentCreation(async({selectedRequirements:r})=>{let i=JSON.stringify(C.buildChannelConfig(r),(f,u)=>typeof u=="string"?u.toLowerCase():u);if(m!==void 0&&i!==m)throw new Error("batch-settlement handle is already bound to a different channel configuration");m=i});let R=new Wt(p);return{scheme:C,x402Cli:p,httpClient:R,rpcUrl:n,withdrawClient:w,canSubmitTransactions:y}}var B=6;function rt(t,e){let n;try{if(!/^(?:\d+(?:\.\d{0,6})?|\.\d{1,6})$/.test(t))throw new Error("invalid decimal");n=Et(t,B)}catch{throw new Error(`${e} must be a valid USDC amount with at most six decimal places (e.g. "0.30"), got "${t}"`)}if(n<=0n)throw new Error(`${e} must be a positive amount, got "${t}"`);return n}function _t(t,e){let n=e>t?0n:t-e;return{deposited:q(t,B),spent:q(e,B),remaining:q(n,B)}}function Bt(t){let e=t.payload;if(!e||typeof e!="object")return"";let n=e.voucher;if(!n||typeof n!="object")return"";let a=n.channelId;return typeof a=="string"?a:""}function Ot(t){let e=t.payload;if(!e||typeof e!="object")return;let n=e.channelConfig;if(!(!n||typeof n!="object"))return n}function it(t){let{stack:e,store:n,network:a}=t,o="",s,l=t.depositedAtomic,d=0n;async function h(){if(!o)return;let c=await Nt(n,o);c&&(c.chargedCumulativeAmount!==void 0&&(d=BigInt(c.chargedCumulativeAmount)),l===0n&&c.balance!==void 0&&(l=BigInt(c.balance)))}return{get channelId(){return o},get salt(){return t.salt},get network(){return a},get state(){return _t(l,d)},async fetch(c,y){let{httpClient:g}=e,w=await fetch(c,y);if(w.status!==402)return w;let O=g.getPaymentRequiredResponse(p=>w.headers.get(p),await w.clone().json().catch(()=>{})),x=2,C;for(let p=1;p<=x;p+=1){let m=await g.createPaymentPayload(O),R=Bt(m);R&&(o=R);let k=Ot(m);k&&(s=k);let r=g.encodePaymentSignatureHeader(m),i=await fetch(c,{...y,headers:{...y?.headers??{},...r}});C=i;let{recovered:f}=await g.processPaymentResult(m,u=>i.headers.get(u),i.status);if(await h(),!(i.status===402&&f&&p<x))return i}return C},async close(){return o&&await n.delete(o.toLowerCase()),{closed:!0}},async forceWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement forceWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!s)throw new Error("forceWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return tt({config:s,network:a,client:e.withdrawClient,withdrawDelaySecs:s.withdrawDelay})},async finalizeWithdraw(){if(!e.canSubmitTransactions)throw new Error("batch-settlement finalizeWithdraw requires a wallet with a sendTransaction method (the withdrawal escape hatch submits an on-chain transaction and the buyer pays gas; a signature-only wallet cannot use it).");if(!s)throw new Error("finalizeWithdraw is unavailable until the channel has resolved on-chain \u2014 make at least one fetch() against the channel first");return et({config:s,network:a,client:e.withdrawClient,withdrawDelaySecs:s.withdrawDelay})}}}async function kt(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),St(e)}async function Pt(t){let e=t.store??_(),n=t.salt??await kt(),a=rt(t.deposit,"deposit"),o=at({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:a.toString(),salt:n});return it({stack:o,store:e,network:t.network,depositedAtomic:a,salt:n})}async function vt(t){let e=t.store??_(),n=rt(t.maxAmountPerPayment??"1","maxAmountPerPayment"),a=at({wallet:t.wallet,network:t.network,rpcUrl:t.rpcUrl,store:e,depositAtomic:"0",maxPaymentAtomic:n.toString(),salt:t.salt});return it({stack:a,store:e,network:t.network,depositedAtomic:0n,salt:t.salt})}export{H as InsufficientBalanceError,E as UnsupportedNetworkError,b as WithdrawNotReadyError,G as createFileChannelStore,J as createLocalStorageChannelStore,_ as getDefaultChannelStore,Pt as openBatchChannel,vt as resumeBatchChannel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var R=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var D=(e,r)=>{for(var s in r)R(e,s,{get:r[s],enumerable:!0})},z=(e,r,s,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of O(r))!_.call(e,n)&&n!==s&&R(e,n,{get:()=>r[n],enumerable:!(o=N(r,n))||o.enumerable});return e};var Q=e=>z(R({},"__esModule",{value:!0}),e);var W={};D(W,{createBatchSettlementSeller:()=>E});module.exports=Q(W);var B=require("os"),U=require("path"),$=require("@x402/evm/batch-settlement/server");var C=require("@x402/core/server"),
|
|
1
|
+
"use strict";var R=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var D=(e,r)=>{for(var s in r)R(e,s,{get:r[s],enumerable:!0})},z=(e,r,s,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of O(r))!_.call(e,n)&&n!==s&&R(e,n,{get:()=>r[n],enumerable:!(o=N(r,n))||o.enumerable});return e};var Q=e=>z(R({},"__esModule",{value:!0}),e);var W={};D(W,{createBatchSettlementSeller:()=>E});module.exports=Q(W);var B=require("os"),U=require("path"),$=require("@x402/evm/batch-settlement/server/file-storage");var C=require("@x402/core/server"),w=require("@x402/core/http"),A=require("@x402/evm/batch-settlement/server");function b(e){let r=e.verbose?console.log.bind(console,"[batch-settlement:seller]"):()=>{},s=new C.HTTPFacilitatorClient({url:e.facilitatorUrl}),o=new A.BatchSettlementEvmScheme(e.payTo,{storage:e.channelStore}),n=new C.x402ResourceServer(s).register(e.network,o),l=new w.x402HTTPResourceServer(n,{[e.route]:{accepts:{scheme:"batch-settlement",payTo:e.payTo,price:e.price,network:e.network},description:"batch-settlement protected route",mimeType:"application/json"}}),i=null;function u(){if(i)return i;let t=l.initialize();return t.catch(a=>{i===t&&(i=null),e.verbose?r("resource server initialize() failed:",a):console.error("[batch-settlement:seller] resource server initialize() failed:",a)}),i=t,t}let h=u();function d(t,a){if(t.headersSent)return;for(let[g,v]of Object.entries(a.headers))t.setHeader(g,v);t.status(a.status);let{body:m}=a;m==null?t.end():typeof m=="string"?t.send(m):t.json(m)}return{scheme:o,facilitator:s,handler:async(t,a,m)=>{try{await u();let g=t.get("host")??"",v=`${t.baseUrl??""}${t.path}`||"/",M={getHeader:y=>t.headers[y.toLowerCase()],getMethod:()=>t.method,getPath:()=>v,getUrl:()=>`${t.protocol}://${g}${t.originalUrl}`,getAcceptHeader:()=>t.headers.accept??"",getUserAgent:()=>t.headers["user-agent"]??"",getBody:()=>t.body??{},getQueryParams:()=>t.query,getQueryParam:y=>{let f=t.query[y];if(typeof f=="string"||Array.isArray(f))return f}},F=t.headers["payment-signature"]??t.headers["x-payment"],x={adapter:M,path:v,method:t.method,paymentHeader:F},p=await l.processHTTPRequest(x);if(r("processHTTPRequest ->",p.type),p.type==="no-payment-required"){m();return}if(p.type==="payment-error"){d(a,p.response);return}let j={request:x,responseBody:Buffer.alloc(0)},S=await l.processSettlement(p.paymentPayload,p.paymentRequirements,p.declaredExtensions,j);if(r("processSettlement ->",S.success?"success":`failure:${S.errorReason}`),!S.success){d(a,S.response);return}for(let[y,f]of Object.entries(S.headers))a.headersSent||a.setHeader(y,f);m()}catch(g){r("handler error:",g),a.headersSent||a.status(500).json({error:"Payment processing error"})}},ready:h}}var P=require("viem"),k=6;async function T(e){let{manager:r,store:s,channelId:o}=e,n=await s.get(o),l=BigInt(n?.chargedCumulativeAmount??"0"),i=BigInt(n?.balance??"0"),u=i>l?i-l:0n,{claims:h,settle:d}=await r.claimAndSettle(),c=await r.refund([o]),t=c.find(a=>a.channel===o)??c[0];return{claimTx:h[0]?.transaction??"",settleTx:d?.transaction??"",refundTx:t?.transaction??"",settledAmount:(0,P.formatUnits)(l,k),refundedAmount:(0,P.formatUnits)(u,k)}}async function I(e){let r=await e.store.list(),s=[];for(let o of r)try{let n=await T({manager:e.manager,store:e.store,channelId:o.channelId});s.push({channelId:o.channelId,...n})}catch(n){s.push({channelId:o.channelId,error:n instanceof Error?n.message:String(n)})}return s}function L(e){let r=!1,s=async()=>{try{await e.claimAndSettle()}catch(n){e.onError?.(n)}},o=setInterval(()=>{r||s()},e.claimIntervalMs);return typeof o.unref=="function"&&o.unref(),{async stop(){r||(r=!0,clearInterval(o),await s())}}}var q="https://x402.dexter.cash",G="GET /",H=new Set(["eip155:8453","eip155:42161","eip155:137"]);function K(e){return e===!1?null:e===void 0||e===!0?3e5:(e.claimIntervalSecs??300)*1e3}function E(e){if(!H.has(e.network))throw new Error(`batch-settlement is not supported on network "${e.network}" \u2014 supported: ${[...H].join(", ")}`);let r=e.facilitatorUrl??q,s=e.channelStore??new $.FileChannelStorage({directory:(0,U.join)((0,B.homedir)(),".dexter-x402","seller-channels")}),o=b({payTo:e.payTo,network:e.network,price:e.price,route:e.route??G,facilitatorUrl:r,channelStore:s,verbose:e.verbose}),n=o.scheme.createChannelManager(o.facilitator,e.network),l=async()=>{await n.claimAndSettle()},i=K(e.autoSettle),u=null;i!==null&&(u=L({claimAndSettle:l,claimIntervalMs:i,onError:t=>console.error("[batch-settlement:seller] auto-loop claim pass failed",t)}));let h=s,d=(t,a,m)=>{o.handler(t,a,m)},c=d;return c.middleware=()=>d,c.closeChannel=t=>T({manager:n,store:h,channelId:t}),c.closeAll=()=>I({manager:n,store:h}),c.stop=async()=>{u&&await u.stop()},c}0&&(module.exports={createBatchSettlementSeller});
|