uvd-x402-sdk 2.107.0 → 2.108.0

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/README.md CHANGED
@@ -10,6 +10,8 @@ Users sign a message or transaction, and the Ultravioleta facilitator handles on
10
10
 
11
11
  ## Features
12
12
 
13
+ **Arras NEAR escrow (v2.108.0):** offline local-key NEP-366 authorization, canonical Rust payment IDs and pull lifecycle helpers through `uvd-x402-sdk/near`. [Guide and agent example](docs/near-escrow.md). As of 2026-11-02 the facilitator advertises escrow only on testnet, and the SDK's escrow contract registry has no mainnet row yet.
14
+
13
15
  - **31 Networks**: EVM (19 including HashKey Chain, Arc, Scroll, SKALE Base, Robinhood Chain), Solana, Fogo, Stellar, NEAR, Algorand, Sui, XRP Ledger, Hedera (mainnet + testnet)
14
16
  - **Multi-Stablecoin**: USDC, EURC, AUSD, PYUSD, USDT, USDG (Robinhood Chain)
15
17
  - **x402 v1 & v2**: Protocol auto-detection; native Hedera supports v2/exact only
@@ -1,5 +1,101 @@
1
1
  import { W as WalletAdapter, C as ChainConfig, P as PaymentInfo, X as X402Version } from '../../index-DARXHuQl.mjs';
2
2
 
3
+ type NearEscrowNetwork = 'near:mainnet' | 'near:testnet';
4
+ /** Numbers must be safe integers; use decimal strings or bigint for nanoseconds and u128. */
5
+ type NearUnsigned = string | bigint | number;
6
+ interface EscrowMsgParams {
7
+ operator_id: string;
8
+ receiver: string;
9
+ release_deadline: NearUnsigned;
10
+ reclaim_after: NearUnsigned;
11
+ fee_bps_max: number;
12
+ terms_hash: string;
13
+ salt: string;
14
+ }
15
+ interface PaymentIdParams extends EscrowMsgParams {
16
+ token: string;
17
+ payer: string;
18
+ amount: NearUnsigned;
19
+ }
20
+ interface NearLocalSigner {
21
+ readonly publicKey: Uint8Array;
22
+ /** Sign the NEP-366 SHA-256 digest directly, without a NEP-413 envelope. */
23
+ sign(digest: Uint8Array): Uint8Array | Promise<Uint8Array>;
24
+ }
25
+ interface NearEscrowDelegateOptions {
26
+ network: NearEscrowNetwork;
27
+ signer: NearLocalSigner;
28
+ senderId: string;
29
+ escrowContract: string;
30
+ /** The next access-key nonce, not the current nonce. */
31
+ nonce: NearUnsigned;
32
+ maxBlockHeight: NearUnsigned;
33
+ /** Gas units (1 TGas = 10^12), not a floating point TGas count. */
34
+ gas?: NearUnsigned;
35
+ }
36
+ interface EscrowAuthorizationOptions extends NearEscrowDelegateOptions {
37
+ token: string;
38
+ amount: NearUnsigned;
39
+ msg: EscrowMsgParams;
40
+ }
41
+ interface NearEscrowPayment {
42
+ x402Version: 2;
43
+ scheme: 'escrow';
44
+ network: NearEscrowNetwork;
45
+ payload: {
46
+ signedDelegateAction: string;
47
+ };
48
+ }
49
+ interface NearEscrowFunctionCall {
50
+ methodName: string;
51
+ args: string;
52
+ gas: NearUnsigned;
53
+ deposit: NearUnsigned;
54
+ }
55
+ interface NearEscrowDelegate {
56
+ senderId: string;
57
+ receiverId: string;
58
+ actions: NearEscrowFunctionCall[];
59
+ nonce: NearUnsigned;
60
+ maxBlockHeight: NearUnsigned;
61
+ }
62
+ declare const NEAR_ESCROW_MIN_GAS = 38000000000000n;
63
+ declare const NEAR_ESCROW_MAX_GAS = 100000000000000n;
64
+ declare const NEAR_ESCROW_TOKENS: Readonly<Record<NearEscrowNetwork, string>>;
65
+ /**
66
+ * The Arras escrow deployments this SDK signs for, per network. Any other escrowContract is refused before the
67
+ * signer is called, for authorization and lifecycle alike: a signed delegate can be relayed by anyone, so a 402
68
+ * server must not be able to point it at its own account. Mainnet stays empty until its contract ships in a release.
69
+ */
70
+ declare const NEAR_ESCROW_CONTRACTS: Readonly<Record<NearEscrowNetwork, readonly string[]>>;
71
+ /** Canonical Arras JSON: field order, decimal-string timestamps, lowercase hex, no spaces. */
72
+ declare function buildEscrowMsg(p: EscrowMsgParams): string;
73
+ /** Exact Rust Borsh preimage, exposed for cross-language conformance. */
74
+ declare function paymentIdPreimage(p: PaymentIdParams): Uint8Array;
75
+ declare function computePaymentId(p: PaymentIdParams): string;
76
+ /** A 32-byte Ed25519 seed, or a NEAR ed25519: base58 secret (seed + public key, 64 bytes). */
77
+ declare function createNearLocalSigner(secret: Uint8Array | string): NearLocalSigner;
78
+ /** Build the one allowed FT action. The contract must be in NEAR_ESCROW_CONTRACTS; the operator comes from trusted /supported configuration. */
79
+ declare function buildEscrowAuthorizationDelegate(o: EscrowAuthorizationOptions): NearEscrowDelegate;
80
+ /** Validate before signing, including strict byte binding to the expected canonical FT arguments. */
81
+ declare function validateEscrowAuthorizationDelegate(d: NearEscrowDelegate, o: EscrowAuthorizationOptions): void;
82
+ declare function signEscrowAuthorization(options: EscrowAuthorizationOptions): Promise<NearEscrowPayment>;
83
+ type NearEscrowLifecycleMethod = 'release' | 'refund' | 'reclaim' | 'withdraw' | 'withdraw_for';
84
+ declare function signEscrowLifecycle(options: NearEscrowDelegateOptions, method: NearEscrowLifecycleMethod, args?: {
85
+ payment_id?: string;
86
+ amount?: NearUnsigned | null;
87
+ account?: string;
88
+ }): Promise<NearEscrowPayment>;
89
+ declare const release: (o: NearEscrowDelegateOptions, paymentId: string, amount?: NearUnsigned | null) => Promise<NearEscrowPayment>;
90
+ declare const refund: (o: NearEscrowDelegateOptions, paymentId: string) => Promise<NearEscrowPayment>;
91
+ declare const reclaim: (o: NearEscrowDelegateOptions, paymentId: string) => Promise<NearEscrowPayment>;
92
+ declare const withdraw: (o: NearEscrowDelegateOptions) => Promise<NearEscrowPayment>;
93
+ declare const withdrawFor: (o: NearEscrowDelegateOptions, account: string) => Promise<NearEscrowPayment>;
94
+ /** v2 boundary only: no budget wire format or signing is defined until Arras v2 supplies its vectors. */
95
+ interface AuthorizeFromBudget {
96
+ authorizeFromBudget(request: unknown): Promise<NearEscrowPayment>;
97
+ }
98
+
3
99
  /**
4
100
  * uvd-x402-sdk - NEAR Provider
5
101
  *
@@ -138,4 +234,4 @@ declare class NEARProvider implements WalletAdapter {
138
234
  private base58Encode;
139
235
  }
140
236
 
141
- export { NEARProvider, type WalletSelectorOptions, NEARProvider as default };
237
+ export { type AuthorizeFromBudget, type EscrowAuthorizationOptions, type EscrowMsgParams, NEARProvider, NEAR_ESCROW_CONTRACTS, NEAR_ESCROW_MAX_GAS, NEAR_ESCROW_MIN_GAS, NEAR_ESCROW_TOKENS, type NearEscrowDelegate, type NearEscrowDelegateOptions, type NearEscrowFunctionCall, type NearEscrowLifecycleMethod, type NearEscrowNetwork, type NearEscrowPayment, type NearLocalSigner, type NearUnsigned, type PaymentIdParams, type WalletSelectorOptions, buildEscrowAuthorizationDelegate, buildEscrowMsg, computePaymentId, createNearLocalSigner, NEARProvider as default, paymentIdPreimage, reclaim, refund, release, signEscrowAuthorization, signEscrowLifecycle, validateEscrowAuthorizationDelegate, withdraw, withdrawFor };
@@ -1,5 +1,101 @@
1
1
  import { W as WalletAdapter, C as ChainConfig, P as PaymentInfo, X as X402Version } from '../../index-DARXHuQl.js';
2
2
 
3
+ type NearEscrowNetwork = 'near:mainnet' | 'near:testnet';
4
+ /** Numbers must be safe integers; use decimal strings or bigint for nanoseconds and u128. */
5
+ type NearUnsigned = string | bigint | number;
6
+ interface EscrowMsgParams {
7
+ operator_id: string;
8
+ receiver: string;
9
+ release_deadline: NearUnsigned;
10
+ reclaim_after: NearUnsigned;
11
+ fee_bps_max: number;
12
+ terms_hash: string;
13
+ salt: string;
14
+ }
15
+ interface PaymentIdParams extends EscrowMsgParams {
16
+ token: string;
17
+ payer: string;
18
+ amount: NearUnsigned;
19
+ }
20
+ interface NearLocalSigner {
21
+ readonly publicKey: Uint8Array;
22
+ /** Sign the NEP-366 SHA-256 digest directly, without a NEP-413 envelope. */
23
+ sign(digest: Uint8Array): Uint8Array | Promise<Uint8Array>;
24
+ }
25
+ interface NearEscrowDelegateOptions {
26
+ network: NearEscrowNetwork;
27
+ signer: NearLocalSigner;
28
+ senderId: string;
29
+ escrowContract: string;
30
+ /** The next access-key nonce, not the current nonce. */
31
+ nonce: NearUnsigned;
32
+ maxBlockHeight: NearUnsigned;
33
+ /** Gas units (1 TGas = 10^12), not a floating point TGas count. */
34
+ gas?: NearUnsigned;
35
+ }
36
+ interface EscrowAuthorizationOptions extends NearEscrowDelegateOptions {
37
+ token: string;
38
+ amount: NearUnsigned;
39
+ msg: EscrowMsgParams;
40
+ }
41
+ interface NearEscrowPayment {
42
+ x402Version: 2;
43
+ scheme: 'escrow';
44
+ network: NearEscrowNetwork;
45
+ payload: {
46
+ signedDelegateAction: string;
47
+ };
48
+ }
49
+ interface NearEscrowFunctionCall {
50
+ methodName: string;
51
+ args: string;
52
+ gas: NearUnsigned;
53
+ deposit: NearUnsigned;
54
+ }
55
+ interface NearEscrowDelegate {
56
+ senderId: string;
57
+ receiverId: string;
58
+ actions: NearEscrowFunctionCall[];
59
+ nonce: NearUnsigned;
60
+ maxBlockHeight: NearUnsigned;
61
+ }
62
+ declare const NEAR_ESCROW_MIN_GAS = 38000000000000n;
63
+ declare const NEAR_ESCROW_MAX_GAS = 100000000000000n;
64
+ declare const NEAR_ESCROW_TOKENS: Readonly<Record<NearEscrowNetwork, string>>;
65
+ /**
66
+ * The Arras escrow deployments this SDK signs for, per network. Any other escrowContract is refused before the
67
+ * signer is called, for authorization and lifecycle alike: a signed delegate can be relayed by anyone, so a 402
68
+ * server must not be able to point it at its own account. Mainnet stays empty until its contract ships in a release.
69
+ */
70
+ declare const NEAR_ESCROW_CONTRACTS: Readonly<Record<NearEscrowNetwork, readonly string[]>>;
71
+ /** Canonical Arras JSON: field order, decimal-string timestamps, lowercase hex, no spaces. */
72
+ declare function buildEscrowMsg(p: EscrowMsgParams): string;
73
+ /** Exact Rust Borsh preimage, exposed for cross-language conformance. */
74
+ declare function paymentIdPreimage(p: PaymentIdParams): Uint8Array;
75
+ declare function computePaymentId(p: PaymentIdParams): string;
76
+ /** A 32-byte Ed25519 seed, or a NEAR ed25519: base58 secret (seed + public key, 64 bytes). */
77
+ declare function createNearLocalSigner(secret: Uint8Array | string): NearLocalSigner;
78
+ /** Build the one allowed FT action. The contract must be in NEAR_ESCROW_CONTRACTS; the operator comes from trusted /supported configuration. */
79
+ declare function buildEscrowAuthorizationDelegate(o: EscrowAuthorizationOptions): NearEscrowDelegate;
80
+ /** Validate before signing, including strict byte binding to the expected canonical FT arguments. */
81
+ declare function validateEscrowAuthorizationDelegate(d: NearEscrowDelegate, o: EscrowAuthorizationOptions): void;
82
+ declare function signEscrowAuthorization(options: EscrowAuthorizationOptions): Promise<NearEscrowPayment>;
83
+ type NearEscrowLifecycleMethod = 'release' | 'refund' | 'reclaim' | 'withdraw' | 'withdraw_for';
84
+ declare function signEscrowLifecycle(options: NearEscrowDelegateOptions, method: NearEscrowLifecycleMethod, args?: {
85
+ payment_id?: string;
86
+ amount?: NearUnsigned | null;
87
+ account?: string;
88
+ }): Promise<NearEscrowPayment>;
89
+ declare const release: (o: NearEscrowDelegateOptions, paymentId: string, amount?: NearUnsigned | null) => Promise<NearEscrowPayment>;
90
+ declare const refund: (o: NearEscrowDelegateOptions, paymentId: string) => Promise<NearEscrowPayment>;
91
+ declare const reclaim: (o: NearEscrowDelegateOptions, paymentId: string) => Promise<NearEscrowPayment>;
92
+ declare const withdraw: (o: NearEscrowDelegateOptions) => Promise<NearEscrowPayment>;
93
+ declare const withdrawFor: (o: NearEscrowDelegateOptions, account: string) => Promise<NearEscrowPayment>;
94
+ /** v2 boundary only: no budget wire format or signing is defined until Arras v2 supplies its vectors. */
95
+ interface AuthorizeFromBudget {
96
+ authorizeFromBudget(request: unknown): Promise<NearEscrowPayment>;
97
+ }
98
+
3
99
  /**
4
100
  * uvd-x402-sdk - NEAR Provider
5
101
  *
@@ -138,4 +234,4 @@ declare class NEARProvider implements WalletAdapter {
138
234
  private base58Encode;
139
235
  }
140
236
 
141
- export { NEARProvider, type WalletSelectorOptions, NEARProvider as default };
237
+ export { type AuthorizeFromBudget, type EscrowAuthorizationOptions, type EscrowMsgParams, NEARProvider, NEAR_ESCROW_CONTRACTS, NEAR_ESCROW_MAX_GAS, NEAR_ESCROW_MIN_GAS, NEAR_ESCROW_TOKENS, type NearEscrowDelegate, type NearEscrowDelegateOptions, type NearEscrowFunctionCall, type NearEscrowLifecycleMethod, type NearEscrowNetwork, type NearEscrowPayment, type NearLocalSigner, type NearUnsigned, type PaymentIdParams, type WalletSelectorOptions, buildEscrowAuthorizationDelegate, buildEscrowMsg, computePaymentId, createNearLocalSigner, NEARProvider as default, paymentIdPreimage, reclaim, refund, release, signEscrowAuthorization, signEscrowLifecycle, validateEscrowAuthorizationDelegate, withdraw, withdrawFor };
@@ -3,6 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var ethers = require('ethers');
6
+ var ed25519 = require('@noble/curves/ed25519');
7
+ var sha256 = require('@noble/hashes/sha256');
6
8
 
7
9
  // src/types/index.ts
8
10
  var CAIP2_IDENTIFIERS = {
@@ -1298,6 +1300,257 @@ function chainToCAIP2(chainName) {
1298
1300
  }
1299
1301
  return chainName;
1300
1302
  }
1303
+ var NEAR_ESCROW_MIN_GAS = 38000000000000n;
1304
+ var NEAR_ESCROW_MAX_GAS = 100000000000000n;
1305
+ var NEAR_ESCROW_TOKENS = Object.freeze({
1306
+ "near:mainnet": "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
1307
+ "near:testnet": "3e2210e1184b45b64c8a434c0a7e7b23cc04ea7eb7a6c3c32520d03d4afcb8af"
1308
+ });
1309
+ var NEAR_ESCROW_CONTRACTS = Object.freeze({
1310
+ "near:testnet": Object.freeze(["arras-v1b-1101.testnet"]),
1311
+ "near:mainnet": Object.freeze([])
1312
+ });
1313
+ var NONCE_RANGE_MULTIPLIER = 1000000n;
1314
+ function fullMatch(pattern, value) {
1315
+ return pattern.exec(value)?.[0] === value;
1316
+ }
1317
+ function uint(value, bits, name) {
1318
+ if (typeof value !== "bigint" && typeof value !== "number" && typeof value !== "string" || typeof value === "number" && !Number.isSafeInteger(value) || typeof value === "string" && !fullMatch(/^(0|[1-9][0-9]*)$/, value)) {
1319
+ throw new Error(`${name}: expected an exact unsigned integer`);
1320
+ }
1321
+ const n = BigInt(value);
1322
+ if (n < 0n || n >= 1n << BigInt(bits)) throw new Error(`${name}: out of u${bits} range`);
1323
+ return n;
1324
+ }
1325
+ function account(value, name) {
1326
+ if (typeof value !== "string" || value.length < 2 || value.length > 64 || !fullMatch(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/, value)) throw new Error(`${name}: invalid NEAR account`);
1327
+ }
1328
+ function hex(value, size, name) {
1329
+ if (typeof value !== "string" || value.length !== size * 2 || !fullMatch(/^[0-9a-f]+$/, value)) {
1330
+ throw new Error(`${name}: expected ${size} bytes of lowercase hex without 0x`);
1331
+ }
1332
+ return Uint8Array.from(value.match(/../g), (v) => parseInt(v, 16));
1333
+ }
1334
+ function concat(...parts) {
1335
+ const out = new Uint8Array(parts.reduce((sum, p) => sum + p.length, 0));
1336
+ let at = 0;
1337
+ for (const part of parts) {
1338
+ out.set(part, at);
1339
+ at += part.length;
1340
+ }
1341
+ return out;
1342
+ }
1343
+ function le(n, size) {
1344
+ return Uint8Array.from({ length: size }, (_, i) => Number(n >> BigInt(i * 8) & 255n));
1345
+ }
1346
+ function str(s) {
1347
+ const bytes = new TextEncoder().encode(s);
1348
+ return concat(le(BigInt(bytes.length), 4), bytes);
1349
+ }
1350
+ function unbase58(value) {
1351
+ const alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
1352
+ if (!value || value.length > 128) throw new Error("Invalid base58 length");
1353
+ let n = 0n;
1354
+ for (const c of value) {
1355
+ const digit = alphabet.indexOf(c);
1356
+ if (digit < 0) throw new Error("Invalid base58 character");
1357
+ n = n * 58n + BigInt(digit);
1358
+ }
1359
+ const bytes = [];
1360
+ while (n > 0n) {
1361
+ bytes.push(Number(n & 255n));
1362
+ n >>= 8n;
1363
+ }
1364
+ const zeros = value.match(/^1*/u)[0].length;
1365
+ return concat(new Uint8Array(zeros), Uint8Array.from(bytes.reverse()));
1366
+ }
1367
+ function msgValues(p) {
1368
+ if (typeof p.operator_id !== "string" || !fullMatch(/^[a-z0-9_-]{1,32}$/, p.operator_id)) {
1369
+ throw new Error("operator_id: expected [a-z0-9_-]{1,32}");
1370
+ }
1371
+ account(p.receiver, "receiver");
1372
+ const release2 = uint(p.release_deadline, 64, "release_deadline");
1373
+ const reclaim2 = uint(p.reclaim_after, 64, "reclaim_after");
1374
+ if (release2 >= reclaim2) throw new Error("release_deadline must precede reclaim_after");
1375
+ if (typeof p.fee_bps_max !== "number") throw new Error("fee_bps_max: expected a number");
1376
+ const fee = uint(p.fee_bps_max, 16, "fee_bps_max");
1377
+ return { release: release2, reclaim: reclaim2, fee, terms: hex(p.terms_hash, 32, "terms_hash"), salt: hex(p.salt, 16, "salt") };
1378
+ }
1379
+ function buildEscrowMsg(p) {
1380
+ const v = msgValues(p);
1381
+ return JSON.stringify({
1382
+ v: 1,
1383
+ action: "authorize",
1384
+ operator_id: p.operator_id,
1385
+ receiver: p.receiver,
1386
+ release_deadline: v.release.toString(),
1387
+ reclaim_after: v.reclaim.toString(),
1388
+ fee_bps_max: Number(v.fee),
1389
+ terms_hash: p.terms_hash,
1390
+ salt: p.salt
1391
+ });
1392
+ }
1393
+ function paymentIdPreimage(p) {
1394
+ const v = msgValues(p);
1395
+ account(p.token, "token");
1396
+ account(p.payer, "payer");
1397
+ return concat(
1398
+ Uint8Array.of(1),
1399
+ str(p.operator_id),
1400
+ str(p.token),
1401
+ str(p.payer),
1402
+ str(p.receiver),
1403
+ le(uint(p.amount, 128, "amount"), 16),
1404
+ le(v.release, 8),
1405
+ le(v.reclaim, 8),
1406
+ le(v.fee, 2),
1407
+ v.terms,
1408
+ v.salt
1409
+ );
1410
+ }
1411
+ function computePaymentId(p) {
1412
+ return ethers.encodeBase58(sha256.sha256(paymentIdPreimage(p)));
1413
+ }
1414
+ function createNearLocalSigner(secret) {
1415
+ let raw;
1416
+ if (typeof secret === "string") {
1417
+ if (!secret.startsWith("ed25519:")) throw new Error("Expected ed25519: secret key");
1418
+ raw = unbase58(secret.slice(8));
1419
+ if (raw.length !== 64) throw new Error("NEAR secret key must contain 64 bytes");
1420
+ } else if (secret instanceof Uint8Array && secret.length === 32) {
1421
+ raw = new Uint8Array(secret);
1422
+ } else throw new Error("Expected a 32-byte seed or NEAR secret key");
1423
+ const seed = raw.slice(0, 32);
1424
+ const publicKey = ed25519.ed25519.getPublicKey(seed);
1425
+ if (raw.length === 64 && !raw.slice(32).every((b, i) => b === publicKey[i])) {
1426
+ throw new Error("NEAR secret key public half does not match seed");
1427
+ }
1428
+ return { get publicKey() {
1429
+ return publicKey.slice();
1430
+ }, sign: (digest) => ed25519.ed25519.sign(digest, seed) };
1431
+ }
1432
+ function delegateOptions(o) {
1433
+ if (o.network !== "near:mainnet" && o.network !== "near:testnet") throw new Error("Unsupported NEAR network");
1434
+ account(o.senderId, "senderId");
1435
+ account(o.escrowContract, "escrowContract");
1436
+ if (!NEAR_ESCROW_CONTRACTS[o.network].includes(o.escrowContract)) {
1437
+ throw new Error(`escrowContract: not a registered Arras escrow for ${o.network}`);
1438
+ }
1439
+ const nonce = uint(o.nonce, 64, "nonce");
1440
+ if (nonce === 0n) throw new Error("nonce must be positive");
1441
+ const height = uint(o.maxBlockHeight, 64, "maxBlockHeight");
1442
+ if (height === 0n) throw new Error("maxBlockHeight must be positive");
1443
+ if (nonce >= height * NONCE_RANGE_MULTIPLIER) throw new Error("nonce must be below maxBlockHeight * 10^6");
1444
+ }
1445
+ function buildEscrowAuthorizationDelegate(o) {
1446
+ delegateOptions(o);
1447
+ if (o.token !== NEAR_ESCROW_TOKENS[o.network]) throw new Error("token does not match network USDC");
1448
+ if (o.msg.receiver === o.senderId || o.msg.receiver === o.escrowContract) throw new Error("receiver equals payer or escrow");
1449
+ const amount = uint(o.amount, 128, "amount");
1450
+ if (amount === 0n) throw new Error("amount must be positive");
1451
+ return {
1452
+ senderId: o.senderId,
1453
+ receiverId: o.token,
1454
+ nonce: o.nonce,
1455
+ maxBlockHeight: o.maxBlockHeight,
1456
+ actions: [{ methodName: "ft_transfer_call", args: JSON.stringify({
1457
+ receiver_id: o.escrowContract,
1458
+ amount: amount.toString(),
1459
+ msg: buildEscrowMsg(o.msg)
1460
+ }), gas: o.gas ?? NEAR_ESCROW_MAX_GAS, deposit: 1n }]
1461
+ };
1462
+ }
1463
+ function validateEscrowAuthorizationDelegate(d, o) {
1464
+ const expected = buildEscrowAuthorizationDelegate(o);
1465
+ if (d.senderId !== expected.senderId || d.receiverId !== expected.receiverId || uint(d.nonce, 64, "nonce") !== uint(expected.nonce, 64, "nonce") || uint(d.maxBlockHeight, 64, "maxBlockHeight") !== uint(expected.maxBlockHeight, 64, "maxBlockHeight")) {
1466
+ throw new Error("Delegate does not match authorization");
1467
+ }
1468
+ if (d.actions.length !== 1) throw new Error("Expected exactly one action");
1469
+ const a = d.actions[0];
1470
+ if (a.methodName !== "ft_transfer_call" || a.args !== expected.actions[0].args) throw new Error("FT method or arguments mismatch");
1471
+ if (uint(a.deposit, 128, "deposit") !== 1n) throw new Error("FT deposit must be 1 yocto");
1472
+ const gas = uint(a.gas, 64, "gas");
1473
+ if (gas < NEAR_ESCROW_MIN_GAS || gas > NEAR_ESCROW_MAX_GAS) throw new Error("FT gas outside 38..100 TGas");
1474
+ }
1475
+ async function signDelegate(o, d) {
1476
+ const network = o.network;
1477
+ const pk = new Uint8Array(o.signer.publicKey);
1478
+ if (pk.length !== 32) throw new Error("Expected 32-byte Ed25519 public key");
1479
+ const a = d.actions[0];
1480
+ const bytes = concat(
1481
+ str(d.senderId),
1482
+ str(d.receiverId),
1483
+ le(1n, 4),
1484
+ Uint8Array.of(2),
1485
+ str(a.methodName),
1486
+ str(a.args),
1487
+ le(uint(a.gas, 64, "gas"), 8),
1488
+ le(uint(a.deposit, 128, "deposit"), 16),
1489
+ le(uint(d.nonce, 64, "nonce"), 8),
1490
+ le(uint(d.maxBlockHeight, 64, "maxBlockHeight"), 8),
1491
+ Uint8Array.of(0),
1492
+ pk
1493
+ );
1494
+ const digest = sha256.sha256(concat(Uint8Array.of(110, 1, 0, 64), bytes));
1495
+ const signature = await o.signer.sign(digest.slice());
1496
+ if (!(signature instanceof Uint8Array) || signature.length !== 64 || !ed25519.ed25519.verify(signature, digest, pk)) {
1497
+ throw new Error("Invalid Ed25519 delegate signature");
1498
+ }
1499
+ const signed = concat(bytes, Uint8Array.of(0), signature);
1500
+ return {
1501
+ x402Version: 2,
1502
+ scheme: "escrow",
1503
+ network,
1504
+ payload: { signedDelegateAction: btoa(Array.from(signed, (b) => String.fromCharCode(b)).join("")) }
1505
+ };
1506
+ }
1507
+ async function signEscrowAuthorization(options) {
1508
+ const o = { ...options };
1509
+ const d = buildEscrowAuthorizationDelegate(o);
1510
+ validateEscrowAuthorizationDelegate(d, o);
1511
+ return signDelegate(o, d);
1512
+ }
1513
+ var lifecycleGas = Object.freeze({
1514
+ release: 30000000000000n,
1515
+ refund: 30000000000000n,
1516
+ reclaim: 30000000000000n,
1517
+ withdraw: 50000000000000n,
1518
+ withdraw_for: 50000000000000n
1519
+ });
1520
+ async function signEscrowLifecycle(options, method, args = {}) {
1521
+ const o = { ...options };
1522
+ delegateOptions(o);
1523
+ if (!Object.hasOwn(lifecycleGas, method)) throw new Error("Escrow method not allowed");
1524
+ const gas = uint(o.gas ?? lifecycleGas[method], 64, "gas");
1525
+ const minGas = method === "withdraw" || method === "withdraw_for" ? 29000000000000n : 3000000000000n;
1526
+ if (gas < minGas || gas > lifecycleGas[method]) throw new Error("Lifecycle gas outside method limit");
1527
+ const allowed = method === "release" ? ["payment_id", "amount"] : method === "withdraw" ? [] : method === "withdraw_for" ? ["account"] : ["payment_id"];
1528
+ if (Object.keys(args).some((k) => !allowed.includes(k))) throw new Error("Unexpected lifecycle argument");
1529
+ const params = {};
1530
+ if (method === "withdraw_for") {
1531
+ account(args.account, "account");
1532
+ params.account = args.account;
1533
+ } else if (method !== "withdraw") {
1534
+ if (typeof args.payment_id !== "string" || args.payment_id.length < 32 || args.payment_id.length > 44 || unbase58(args.payment_id).length !== 32) throw new Error("Invalid payment_id");
1535
+ params.payment_id = args.payment_id;
1536
+ if (method === "release") {
1537
+ params.amount = args.amount == null ? null : uint(args.amount, 128, "amount").toString();
1538
+ if (params.amount === "0") throw new Error("release amount must be positive");
1539
+ }
1540
+ }
1541
+ return signDelegate(o, {
1542
+ senderId: o.senderId,
1543
+ receiverId: o.escrowContract,
1544
+ nonce: o.nonce,
1545
+ maxBlockHeight: o.maxBlockHeight,
1546
+ actions: [{ methodName: method, args: JSON.stringify(params), gas, deposit: 0n }]
1547
+ });
1548
+ }
1549
+ var release = (o, paymentId, amount) => signEscrowLifecycle(o, "release", { payment_id: paymentId, amount });
1550
+ var refund = (o, paymentId) => signEscrowLifecycle(o, "refund", { payment_id: paymentId });
1551
+ var reclaim = (o, paymentId) => signEscrowLifecycle(o, "reclaim", { payment_id: paymentId });
1552
+ var withdraw = (o) => signEscrowLifecycle(o, "withdraw");
1553
+ var withdrawFor = (o, account2) => signEscrowLifecycle(o, "withdraw_for", { account: account2 });
1301
1554
 
1302
1555
  // src/providers/near/index.ts
1303
1556
  var NEAR_CONFIG = {
@@ -1378,7 +1631,7 @@ function serializeSignedDelegateAction(delegateActionBytes, signatureBytes) {
1378
1631
  ser.writeFixedBytes(signatureBytes);
1379
1632
  return ser.getBytes();
1380
1633
  }
1381
- async function sha256(data) {
1634
+ async function sha2562(data) {
1382
1635
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
1383
1636
  return new Uint8Array(hashBuffer);
1384
1637
  }
@@ -1622,7 +1875,7 @@ var NEARProvider = class {
1622
1875
  const hashInput = new Uint8Array(NEP366_PREFIX.length + delegateActionBytes.length);
1623
1876
  hashInput.set(NEP366_PREFIX, 0);
1624
1877
  hashInput.set(delegateActionBytes, NEP366_PREFIX.length);
1625
- const delegateHash = await sha256(hashInput);
1878
+ const delegateHash = await sha2562(hashInput);
1626
1879
  const signature = await this.signMessage(delegateHash);
1627
1880
  const signedDelegateActionBytes = serializeSignedDelegateAction(
1628
1881
  delegateActionBytes,
@@ -1764,17 +2017,17 @@ var NEARProvider = class {
1764
2017
  /**
1765
2018
  * Base58 decode (NEAR style)
1766
2019
  */
1767
- base58Decode(str) {
2020
+ base58Decode(str2) {
1768
2021
  const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
1769
2022
  const ALPHABET_MAP = {};
1770
2023
  for (let i = 0; i < ALPHABET.length; i++) {
1771
2024
  ALPHABET_MAP[ALPHABET[i]] = i;
1772
2025
  }
1773
2026
  let bytes = [0];
1774
- for (let i = 0; i < str.length; i++) {
1775
- const value = ALPHABET_MAP[str[i]];
2027
+ for (let i = 0; i < str2.length; i++) {
2028
+ const value = ALPHABET_MAP[str2[i]];
1776
2029
  if (value === void 0) {
1777
- throw new Error(`Invalid base58 character: ${str[i]}`);
2030
+ throw new Error(`Invalid base58 character: ${str2[i]}`);
1778
2031
  }
1779
2032
  for (let j = 0; j < bytes.length; j++) {
1780
2033
  bytes[j] *= 58;
@@ -1791,7 +2044,7 @@ var NEARProvider = class {
1791
2044
  carry >>= 8;
1792
2045
  }
1793
2046
  }
1794
- for (let i = 0; i < str.length && str[i] === "1"; i++) {
2047
+ for (let i = 0; i < str2.length && str2[i] === "1"; i++) {
1795
2048
  bytes.push(0);
1796
2049
  }
1797
2050
  return new Uint8Array(bytes.reverse());
@@ -1818,19 +2071,36 @@ var NEARProvider = class {
1818
2071
  carry = carry / 58 | 0;
1819
2072
  }
1820
2073
  }
1821
- let str = "";
2074
+ let str2 = "";
1822
2075
  for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
1823
- str += "1";
2076
+ str2 += "1";
1824
2077
  }
1825
2078
  for (let i = digits.length - 1; i >= 0; i--) {
1826
- str += ALPHABET[digits[i]];
2079
+ str2 += ALPHABET[digits[i]];
1827
2080
  }
1828
- return str;
2081
+ return str2;
1829
2082
  }
1830
2083
  };
1831
2084
  var near_default = NEARProvider;
1832
2085
 
1833
2086
  exports.NEARProvider = NEARProvider;
2087
+ exports.NEAR_ESCROW_CONTRACTS = NEAR_ESCROW_CONTRACTS;
2088
+ exports.NEAR_ESCROW_MAX_GAS = NEAR_ESCROW_MAX_GAS;
2089
+ exports.NEAR_ESCROW_MIN_GAS = NEAR_ESCROW_MIN_GAS;
2090
+ exports.NEAR_ESCROW_TOKENS = NEAR_ESCROW_TOKENS;
2091
+ exports.buildEscrowAuthorizationDelegate = buildEscrowAuthorizationDelegate;
2092
+ exports.buildEscrowMsg = buildEscrowMsg;
2093
+ exports.computePaymentId = computePaymentId;
2094
+ exports.createNearLocalSigner = createNearLocalSigner;
1834
2095
  exports.default = near_default;
2096
+ exports.paymentIdPreimage = paymentIdPreimage;
2097
+ exports.reclaim = reclaim;
2098
+ exports.refund = refund;
2099
+ exports.release = release;
2100
+ exports.signEscrowAuthorization = signEscrowAuthorization;
2101
+ exports.signEscrowLifecycle = signEscrowLifecycle;
2102
+ exports.validateEscrowAuthorizationDelegate = validateEscrowAuthorizationDelegate;
2103
+ exports.withdraw = withdraw;
2104
+ exports.withdrawFor = withdrawFor;
1835
2105
  //# sourceMappingURL=index.js.map
1836
2106
  //# sourceMappingURL=index.js.map