@x402r/evm 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,25 +13,38 @@ npm install @x402r/evm
13
13
  ### Client — Create payment payloads
14
14
 
15
15
  ```typescript
16
- import { createPaymentPayload } from "@x402r/evm/escrow/client";
16
+ import { EscrowEvmScheme, registerEscrowScheme } from "@x402r/evm/escrow/client";
17
+ import { x402Client } from "@x402/core/client";
17
18
 
18
- const payload = await createPaymentPayload(requirements, walletClient);
19
+ const client = new x402Client();
20
+ registerEscrowScheme(client, { signer, networks: "eip155:84532" });
19
21
  ```
20
22
 
21
23
  ### Server — Register with x402 resource server
22
24
 
23
25
  ```typescript
24
- import { EscrowServerScheme } from "@x402r/evm/escrow/server";
26
+ import { EscrowServerScheme, registerEscrowServerScheme } from "@x402r/evm/escrow/server";
27
+ import { x402ResourceServer } from "@x402/core/server";
25
28
 
26
- const scheme = new EscrowServerScheme();
27
- server.register("eip155:84532", scheme);
29
+ const server = new x402ResourceServer(facilitatorConfig);
30
+ registerEscrowServerScheme(server, { networks: "eip155:84532" });
31
+ ```
32
+
33
+ ### Facilitator — Verify and settle payments
34
+
35
+ ```typescript
36
+ import { EscrowFacilitatorScheme, registerEscrowScheme } from "@x402r/evm/escrow/facilitator";
37
+ import { x402Facilitator } from "@x402/core/facilitator";
38
+
39
+ const facilitator = new x402Facilitator();
40
+ registerEscrowScheme(facilitator, { signer, networks: "eip155:84532" });
28
41
  ```
29
42
 
30
43
  ## Exports
31
44
 
32
- - `@x402r/evm/escrow/client` — `createPaymentPayload()`, `EscrowScheme`
33
- - `@x402r/evm/escrow/server` — `EscrowServerScheme`
34
- - `@x402r/evm/escrow/facilitator` — Settlement and verification
45
+ - `@x402r/evm/escrow/client` — `EscrowEvmScheme`, `registerEscrowScheme()`
46
+ - `@x402r/evm/escrow/server` — `EscrowServerScheme`, `registerEscrowServerScheme()`
47
+ - `@x402r/evm/escrow/facilitator` — `EscrowFacilitatorScheme`, `registerEscrowScheme()`
35
48
  - `@x402r/evm/escrow/types` — `EscrowExtra`, `EscrowPayload`
36
49
 
37
50
  ## Links
@@ -1,24 +1,40 @@
1
1
  /**
2
2
  * Escrow Scheme - Client
3
- * Creates payment payloads for escrow payments
3
+ * Creates payment payloads for escrow payments.
4
+ *
5
+ * Implements x402's SchemeNetworkClient interface so it can be registered
6
+ * on an x402Client via client.register('eip155:84532', new EscrowEvmScheme(signer)).
4
7
  */
5
- import type { WalletClient } from "viem";
6
- import type { EscrowExtra, EscrowPayload } from "../../shared/types.js";
7
- export interface PaymentRequirements {
8
- scheme: string;
9
- network: string;
10
- amount: string;
11
- asset: `0x${string}`;
12
- payTo: `0x${string}`;
13
- extra: EscrowExtra;
8
+ import type { Network, PaymentPayload, PaymentRequirements, SchemeNetworkClient } from "@x402/core/types";
9
+ import type { ClientEvmSigner } from "@x402/evm";
10
+ import { x402Client } from "@x402/core/client";
11
+ /**
12
+ * Escrow Client Scheme - implements x402's SchemeNetworkClient
13
+ */
14
+ export declare class EscrowEvmScheme implements SchemeNetworkClient {
15
+ private readonly signer;
16
+ readonly scheme = "escrow";
17
+ constructor(signer: ClientEvmSigner);
18
+ createPaymentPayload(x402Version: number, requirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
14
19
  }
15
20
  /**
16
- * Create an escrow payment payload from payment requirements
21
+ * Register escrow client scheme with x402Client
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const client = new x402Client();
26
+ * registerEscrowScheme(client, { signer, networks: "eip155:84532" });
27
+ * ```
28
+ */
29
+ export declare function registerEscrowScheme(client: x402Client, config: {
30
+ signer: ClientEvmSigner;
31
+ networks: Network | Network[];
32
+ }): x402Client;
33
+ /**
34
+ * @deprecated Use `new EscrowEvmScheme(signer)` directly
17
35
  */
18
- export declare function createPaymentPayload(requirements: PaymentRequirements, wallet: WalletClient): Promise<EscrowPayload>;
19
36
  export declare const EscrowScheme: {
20
37
  scheme: "escrow";
21
- createPaymentPayload: typeof createPaymentPayload;
22
38
  };
23
39
  export type { EscrowExtra, EscrowPayload } from "../../shared/types.js";
24
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/escrow/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAOzC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,aAAa,CAAC,CAmDxB;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAC;AAEF,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/escrow/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA0B/C;;GAEG;AACH,qBAAa,eAAgB,YAAW,mBAAmB;IAG7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,MAAM,YAAY;gBAEE,MAAM,EAAE,eAAe;IAE9C,oBAAoB,CACxB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;CA4E5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,CAAA;CAAE,GACjE,UAAU,CASZ;AAED;;GAEG;AACH,eAAO,MAAM,YAAY;;CAExB,CAAC;AAEF,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,45 +1,104 @@
1
1
  /**
2
2
  * Escrow Scheme - Client
3
- * Creates payment payloads for escrow payments
3
+ * Creates payment payloads for escrow payments.
4
+ *
5
+ * Implements x402's SchemeNetworkClient interface so it can be registered
6
+ * on an x402Client via client.register('eip155:84532', new EscrowEvmScheme(signer)).
4
7
  */
5
8
  import { computeEscrowNonce, signERC3009, generateSalt, } from "../../shared/nonce.js";
6
9
  import { MAX_UINT48 } from "../../shared/constants.js";
7
10
  /**
8
- * Create an escrow payment payload from payment requirements
11
+ * Parse chainId from CAIP-2 network identifier
9
12
  */
10
- export async function createPaymentPayload(requirements, wallet) {
11
- const { escrowAddress, operatorAddress, tokenCollector, minFeeBps = 0, maxFeeBps = 0, feeReceiver, preApprovalExpirySeconds, refundExpirySeconds, authorizationExpirySeconds, } = requirements.extra;
12
- const chainId = await wallet.getChainId();
13
- const maxAmount = requirements.amount;
14
- const paymentInfo = {
15
- operator: operatorAddress,
16
- receiver: requirements.payTo,
17
- token: requirements.asset,
18
- maxAmount,
19
- preApprovalExpiry: preApprovalExpirySeconds ?? MAX_UINT48,
20
- authorizationExpiry: authorizationExpirySeconds ?? MAX_UINT48,
21
- refundExpiry: refundExpirySeconds ?? MAX_UINT48,
22
- minFeeBps,
23
- maxFeeBps,
24
- feeReceiver: feeReceiver ?? operatorAddress,
25
- salt: generateSalt(),
26
- };
27
- const nonce = computeEscrowNonce(chainId, escrowAddress, paymentInfo);
28
- // ERC-3009 authorization - validBefore MUST match what contract passes to receiveWithAuthorization
29
- // The contract uses paymentInfo.preApprovalExpiry as validBefore
30
- const authorization = {
31
- from: wallet.account.address,
32
- to: tokenCollector,
33
- value: maxAmount,
34
- validAfter: "0",
35
- validBefore: String(paymentInfo.preApprovalExpiry),
36
- nonce,
37
- };
38
- const signature = await signERC3009(wallet, authorization, requirements.extra, requirements.asset);
39
- return { authorization, signature, paymentInfo };
13
+ function parseChainId(network) {
14
+ const parts = network.split(":");
15
+ if (parts.length !== 2 || parts[0] !== "eip155") {
16
+ throw new Error(`Invalid network format: ${network}. Expected 'eip155:<chainId>'`);
17
+ }
18
+ const chainId = parseInt(parts[1], 10);
19
+ if (isNaN(chainId)) {
20
+ throw new Error(`Invalid chainId in network: ${network}`);
21
+ }
22
+ return chainId;
40
23
  }
24
+ /**
25
+ * Escrow Client Scheme - implements x402's SchemeNetworkClient
26
+ */
27
+ export class EscrowEvmScheme {
28
+ signer;
29
+ scheme = "escrow";
30
+ constructor(signer) {
31
+ this.signer = signer;
32
+ }
33
+ async createPaymentPayload(x402Version, requirements) {
34
+ if (x402Version !== 2) {
35
+ throw new Error(`Unsupported x402Version: ${x402Version}. Only version 2 is supported.`);
36
+ }
37
+ const extra = requirements.extra;
38
+ // Validate required EIP-712 domain parameters (M3, M10)
39
+ if (!extra.name) {
40
+ throw new Error(`EIP-712 domain parameter 'name' is required in payment requirements for asset ${requirements.asset}`);
41
+ }
42
+ if (!extra.version) {
43
+ throw new Error(`EIP-712 domain parameter 'version' is required in payment requirements for asset ${requirements.asset}`);
44
+ }
45
+ const { escrowAddress, operatorAddress, tokenCollector, minFeeBps = 0, maxFeeBps = 0, feeReceiver, preApprovalExpirySeconds, refundExpirySeconds, authorizationExpirySeconds, } = extra;
46
+ const chainId = parseChainId(requirements.network);
47
+ const maxAmount = requirements.amount;
48
+ const paymentInfo = {
49
+ operator: operatorAddress,
50
+ receiver: requirements.payTo,
51
+ token: requirements.asset,
52
+ maxAmount,
53
+ preApprovalExpiry: preApprovalExpirySeconds ?? MAX_UINT48,
54
+ authorizationExpiry: authorizationExpirySeconds ?? MAX_UINT48,
55
+ refundExpiry: refundExpirySeconds ?? MAX_UINT48,
56
+ minFeeBps,
57
+ maxFeeBps,
58
+ feeReceiver: feeReceiver ?? operatorAddress,
59
+ salt: generateSalt(),
60
+ };
61
+ const nonce = computeEscrowNonce(chainId, escrowAddress, paymentInfo);
62
+ // ERC-3009 authorization - validBefore MUST match what contract passes to receiveWithAuthorization
63
+ // The contract uses paymentInfo.preApprovalExpiry as validBefore
64
+ const authorization = {
65
+ from: this.signer.address,
66
+ to: tokenCollector,
67
+ value: maxAmount,
68
+ validAfter: "0",
69
+ validBefore: String(paymentInfo.preApprovalExpiry),
70
+ nonce,
71
+ };
72
+ const signature = await signERC3009(this.signer, authorization, extra, requirements.asset, chainId);
73
+ return {
74
+ x402Version,
75
+ payload: { authorization, signature, paymentInfo },
76
+ };
77
+ }
78
+ }
79
+ /**
80
+ * Register escrow client scheme with x402Client
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const client = new x402Client();
85
+ * registerEscrowScheme(client, { signer, networks: "eip155:84532" });
86
+ * ```
87
+ */
88
+ export function registerEscrowScheme(client, config) {
89
+ const scheme = new EscrowEvmScheme(config.signer);
90
+ const networks = Array.isArray(config.networks)
91
+ ? config.networks
92
+ : [config.networks];
93
+ for (const network of networks) {
94
+ client.register(network, scheme);
95
+ }
96
+ return client;
97
+ }
98
+ /**
99
+ * @deprecated Use `new EscrowEvmScheme(signer)` directly
100
+ */
41
101
  export const EscrowScheme = {
42
102
  scheme: "escrow",
43
- createPaymentPayload,
44
103
  };
45
104
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/escrow/client/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAYvD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,YAAiC,EACjC,MAAoB;IAEpB,MAAM,EACJ,aAAa,EACb,eAAe,EACf,cAAc,EACd,SAAS,GAAG,CAAC,EACb,SAAS,GAAG,CAAC,EACb,WAAW,EACX,wBAAwB,EACxB,mBAAmB,EACnB,0BAA0B,GAC3B,GAAG,YAAY,CAAC,KAAK,CAAC;IAEvB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC;IAEtC,MAAM,WAAW,GAAG;QAClB,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,YAAY,CAAC,KAAK;QAC5B,KAAK,EAAE,YAAY,CAAC,KAAK;QACzB,SAAS;QACT,iBAAiB,EAAE,wBAAwB,IAAI,UAAU;QACzD,mBAAmB,EAAE,0BAA0B,IAAI,UAAU;QAC7D,YAAY,EAAE,mBAAmB,IAAI,UAAU;QAC/C,SAAS;QACT,SAAS;QACT,WAAW,EAAE,WAAW,IAAI,eAAe;QAC3C,IAAI,EAAE,YAAY,EAAE;KACrB,CAAC;IAEF,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IAEtE,mGAAmG;IACnG,iEAAiE;IACjE,MAAM,aAAa,GAAG;QACpB,IAAI,EAAE,MAAM,CAAC,OAAQ,CAAC,OAAO;QAC7B,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,GAAG;QACf,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC;QAClD,KAAK;KACN,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,WAAW,CACjC,MAAM,EACN,aAAa,EACb,YAAY,CAAC,KAAK,EAClB,YAAY,CAAC,KAAK,CACnB,CAAC;IAEF,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,MAAM,EAAE,QAAiB;IACzB,oBAAoB;CACrB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/escrow/client/index.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ export declare class EscrowFacilitatorScheme implements SchemeNetworkFacilitator
21
21
  readonly caipFamily = "eip155:*";
22
22
  constructor(signer: FacilitatorEvmSigner);
23
23
  getSigners(_network: string): string[];
24
- getExtra(_network: string): Record<string, unknown>;
24
+ getExtra(_network: string): Record<string, unknown> | undefined;
25
25
  verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
26
26
  settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
27
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/escrow/facilitator/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAwBzD;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,wBAAwB;IAI1D,OAAO,CAAC,MAAM;IAH1B,QAAQ,CAAC,MAAM,YAAY;IAC3B,QAAQ,CAAC,UAAU,cAAc;gBAEb,MAAM,EAAE,oBAAoB;IAEhD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAItC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI7C,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,cAAc,CAAC;IAgDpB,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,cAAc,CAAC;CAuD3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE;IACN,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;CAC/B,GACA,eAAe,CAMjB;AAED,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/escrow/facilitator/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,cAAc,EACd,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAwEzD;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,wBAAwB;IAI1D,OAAO,CAAC,MAAM;IAH1B,QAAQ,CAAC,MAAM,YAAY;IAC3B,QAAQ,CAAC,UAAU,cAAc;gBAEb,MAAM,EAAE,oBAAoB;IAEhD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAMtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAIzD,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,cAAc,CAAC;IAmJpB,MAAM,CACV,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,mBAAmB,GAChC,OAAO,CAAC,cAAc,CAAC;CA0F3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE;IACN,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;CAC/B,GACA,eAAe,CAMjB;AAED,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -5,8 +5,9 @@
5
5
  * Implements x402's SchemeNetworkFacilitator interface so the escrow scheme
6
6
  * is a drop-in for the x402 facilitator, just like ExactEvmScheme.
7
7
  */
8
- import { OPERATOR_ABI } from "../../shared/constants.js";
8
+ import { OPERATOR_ABI, ERC20_BALANCE_OF_ABI, ERC6492_MAGIC_VALUE, } from "../../shared/constants.js";
9
9
  import { verifyERC3009Signature } from "../../shared/nonce.js";
10
+ import { isEscrowPayload, isEscrowExtra, } from "../../shared/types.js";
10
11
  /**
11
12
  * Parse chainId from CAIP-2 network identifier
12
13
  * @param network - CAIP-2 network identifier (e.g., 'eip155:84532')
@@ -23,6 +24,39 @@ function parseChainId(network) {
23
24
  }
24
25
  return chainId;
25
26
  }
27
+ /**
28
+ * Extract inner signature from an EIP-6492 wrapped signature.
29
+ * If the signature is not EIP-6492 wrapped, returns it unchanged.
30
+ *
31
+ * EIP-6492 format: abi.encode(address, bytes, bytes) ++ MAGIC_VALUE
32
+ * The inner signature is the third ABI-encoded bytes field.
33
+ */
34
+ function unwrapERC6492Signature(signature) {
35
+ // EIP-6492 magic is 32 bytes (64 hex chars) at the end
36
+ if (signature.length <= 66)
37
+ return signature; // Too short to be wrapped
38
+ const magicSuffix = `0x${signature.slice(-64)}`;
39
+ if (magicSuffix !== ERC6492_MAGIC_VALUE)
40
+ return signature; // Not wrapped
41
+ // Strip the magic suffix and ABI-decode: (address prepareTarget, bytes prepareData, bytes innerSignature)
42
+ // The wrapped data (without magic) is: 0x + ABI-encoded (address, bytes, bytes)
43
+ const wrappedHex = signature.slice(2, -64); // hex without 0x prefix and magic
44
+ // ABI layout for (address, bytes, bytes):
45
+ // word 0 (0-64): address (padded to 32 bytes)
46
+ // word 1 (64-128): offset to prepareData bytes
47
+ // word 2 (128-192): offset to innerSignature bytes
48
+ // Then the dynamic data follows
49
+ if (wrappedHex.length < 192)
50
+ return signature; // Malformed
51
+ const innerSigOffset = parseInt(wrappedHex.slice(128, 192), 16) * 2; // byte offset → hex offset
52
+ if (innerSigOffset + 64 > wrappedHex.length)
53
+ return signature; // Malformed
54
+ const innerSigLength = parseInt(wrappedHex.slice(innerSigOffset, innerSigOffset + 64), 16) * 2; // bytes → hex chars
55
+ const innerSigStart = innerSigOffset + 64;
56
+ if (innerSigStart + innerSigLength > wrappedHex.length)
57
+ return signature; // Malformed
58
+ return `0x${wrappedHex.slice(innerSigStart, innerSigStart + innerSigLength)}`;
59
+ }
26
60
  /**
27
61
  * Escrow Facilitator Scheme - implements x402's SchemeNetworkFacilitator
28
62
  *
@@ -40,39 +74,143 @@ export class EscrowFacilitatorScheme {
40
74
  getSigners(_network) {
41
75
  return [...this.signer.getAddresses()];
42
76
  }
77
+ // C4: name/version now come from server's parsePrice() via AssetAmount.extra.
78
+ // The facilitator should not hardcode token-specific metadata.
43
79
  getExtra(_network) {
44
- return { name: "USDC", version: "2" };
80
+ return undefined;
45
81
  }
46
82
  async verify(payload, requirements) {
83
+ // M5: Type guard instead of double cast
84
+ if (!isEscrowPayload(payload.payload)) {
85
+ return {
86
+ isValid: false,
87
+ invalidReason: "invalid_payload_format",
88
+ };
89
+ }
47
90
  const escrowPayload = payload.payload;
91
+ const payer = escrowPayload.authorization.from;
92
+ // Validate scheme
93
+ if (requirements.scheme !== "escrow") {
94
+ return {
95
+ isValid: false,
96
+ invalidReason: "unsupported_scheme",
97
+ payer,
98
+ };
99
+ }
100
+ // Validate network format
101
+ const networkParts = requirements.network.split(":");
102
+ if (networkParts.length !== 2 || networkParts[0] !== "eip155") {
103
+ return {
104
+ isValid: false,
105
+ invalidReason: "invalid_network",
106
+ payer,
107
+ };
108
+ }
109
+ // M5: Type guard for extra
110
+ if (!isEscrowExtra(requirements.extra)) {
111
+ return {
112
+ isValid: false,
113
+ invalidReason: "invalid_escrow_extra",
114
+ payer,
115
+ };
116
+ }
48
117
  const extra = requirements.extra;
49
118
  const chainId = parseChainId(requirements.network);
119
+ // Time window validation
120
+ const now = Math.floor(Date.now() / 1000);
121
+ const validBefore = Number(escrowPayload.authorization.validBefore);
122
+ const validAfter = Number(escrowPayload.authorization.validAfter);
123
+ if (validBefore <= now + 6) {
124
+ return {
125
+ isValid: false,
126
+ invalidReason: "authorization_expired",
127
+ payer,
128
+ };
129
+ }
130
+ if (validAfter > now) {
131
+ return {
132
+ isValid: false,
133
+ invalidReason: "authorization_not_yet_valid",
134
+ payer,
135
+ };
136
+ }
137
+ // M4: Extract inner signature for verification if EIP-6492 wrapped.
138
+ // The contract's ERC6492SignatureHandler handles deployment; the facilitator
139
+ // only needs the inner ECDSA signature for ecrecover verification.
140
+ const signatureForVerify = unwrapERC6492Signature(escrowPayload.signature);
50
141
  // Verify ERC-3009 signature
51
- const isValidSignature = await verifyERC3009Signature(this.signer, escrowPayload.authorization, escrowPayload.signature, { ...extra, chainId }, requirements.asset);
142
+ const isValidSignature = await verifyERC3009Signature(this.signer, escrowPayload.authorization, signatureForVerify, { ...extra, chainId }, requirements.asset);
52
143
  if (!isValidSignature) {
53
- return { isValid: false, invalidReason: "Invalid ERC-3009 signature" };
144
+ return {
145
+ isValid: false,
146
+ invalidReason: "invalid_escrow_signature",
147
+ payer,
148
+ };
54
149
  }
55
150
  // Verify amount meets requirements
56
151
  if (BigInt(escrowPayload.authorization.value) <
57
152
  BigInt(requirements.amount)) {
58
- return { isValid: false, invalidReason: "Insufficient payment amount" };
153
+ return {
154
+ isValid: false,
155
+ invalidReason: "insufficient_amount",
156
+ payer,
157
+ };
59
158
  }
60
159
  // Verify token matches
61
160
  if (escrowPayload.paymentInfo.token.toLowerCase() !==
62
161
  requirements.asset.toLowerCase()) {
63
- return { isValid: false, invalidReason: "Token mismatch" };
162
+ return {
163
+ isValid: false,
164
+ invalidReason: "token_mismatch",
165
+ payer,
166
+ };
64
167
  }
65
168
  // Verify receiver matches
66
169
  if (escrowPayload.paymentInfo.receiver.toLowerCase() !==
67
170
  requirements.payTo.toLowerCase()) {
68
- return { isValid: false, invalidReason: "Receiver mismatch" };
171
+ return {
172
+ isValid: false,
173
+ invalidReason: "receiver_mismatch",
174
+ payer,
175
+ };
176
+ }
177
+ // H4: Balance check — verify payer has sufficient token balance
178
+ try {
179
+ const balance = await this.signer.readContract({
180
+ address: requirements.asset,
181
+ abi: ERC20_BALANCE_OF_ABI,
182
+ functionName: "balanceOf",
183
+ args: [payer],
184
+ });
185
+ if (BigInt(balance) < BigInt(requirements.amount)) {
186
+ return {
187
+ isValid: false,
188
+ invalidReason: "insufficient_balance",
189
+ payer,
190
+ };
191
+ }
192
+ }
193
+ catch {
194
+ // If balance check fails (e.g., non-standard token), skip it.
195
+ // The on-chain transaction will fail anyway if balance is insufficient.
69
196
  }
70
197
  return {
71
198
  isValid: true,
72
- payer: escrowPayload.authorization.from,
199
+ payer,
73
200
  };
74
201
  }
75
202
  async settle(payload, requirements) {
203
+ // H2: Re-verify before settling to catch expired/invalid payloads
204
+ const verification = await this.verify(payload, requirements);
205
+ if (!verification.isValid) {
206
+ return {
207
+ success: false,
208
+ errorReason: verification.invalidReason ?? "verification_failed",
209
+ transaction: "",
210
+ network: requirements.network,
211
+ payer: verification.payer,
212
+ };
213
+ }
76
214
  const escrowPayload = payload.payload;
77
215
  const extra = requirements.extra;
78
216
  const { authorizeAddress, operatorAddress, tokenCollector } = extra;
@@ -90,7 +228,8 @@ export class EscrowFacilitatorScheme {
90
228
  feeReceiver: escrowPayload.paymentInfo.feeReceiver,
91
229
  salt: BigInt(escrowPayload.paymentInfo.salt),
92
230
  };
93
- // Pass raw signature - ERC3009PaymentCollector expects raw bytes, not ABI-encoded
231
+ // Pass raw signature ERC3009PaymentCollector/ERC6492SignatureHandler
232
+ // handles EIP-6492 unwrapping and wallet deployment on-chain
94
233
  const collectorData = escrowPayload.signature;
95
234
  const target = authorizeAddress ?? operatorAddress;
96
235
  try {
@@ -105,6 +244,21 @@ export class EscrowFacilitatorScheme {
105
244
  collectorData,
106
245
  ],
107
246
  });
247
+ // Wait for transaction confirmation with 60s timeout to avoid hanging on stuck txs
248
+ const receiptPromise = this.signer.waitForTransactionReceipt({
249
+ hash: txHash,
250
+ });
251
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Transaction receipt timeout after 60s")), 60_000));
252
+ const receipt = await Promise.race([receiptPromise, timeoutPromise]);
253
+ if (receipt.status !== "success") {
254
+ return {
255
+ success: false,
256
+ errorReason: "transaction_reverted",
257
+ transaction: txHash,
258
+ network: requirements.network,
259
+ payer: escrowPayload.authorization.from,
260
+ };
261
+ }
108
262
  return {
109
263
  success: true,
110
264
  transaction: txHash,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/escrow/facilitator/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/escrow/facilitator/index.ts"],"names":[],"mappings":"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"}
@@ -5,47 +5,26 @@
5
5
  * Implements x402's SchemeNetworkServer interface so it can be registered
6
6
  * on an x402ResourceServer via server.register('eip155:84532', new EscrowServerScheme()).
7
7
  */
8
- /**
9
- * x402 PaymentRequirements (matches @x402/core/types PaymentRequirements)
10
- */
11
- export interface PaymentRequirements {
12
- scheme: string;
13
- network: string;
14
- amount: string;
15
- asset: string;
16
- payTo: string;
17
- maxTimeoutSeconds: number;
18
- extra: Record<string, unknown>;
19
- }
20
- export interface SupportedKind {
21
- x402Version: number;
22
- scheme: string;
23
- network: string;
24
- extra?: Record<string, unknown>;
25
- }
26
- /**
27
- * x402 AssetAmount (matches @x402/core/types AssetAmount)
28
- */
29
- export interface AssetAmount {
30
- asset: string;
31
- amount: string;
32
- extra?: Record<string, unknown>;
33
- }
34
- /**
35
- * x402 Price type (matches @x402/core/types Price)
36
- */
37
- export type Price = string | number | AssetAmount;
38
- export type Network = `${string}:${string}`;
8
+ import type { AssetAmount, MoneyParser, Network, PaymentRequirements, Price, SchemeNetworkServer } from "@x402/core/types";
9
+ import { x402ResourceServer } from "@x402/core/server";
39
10
  /**
40
11
  * Server scheme - handles price parsing and requirement enhancement.
41
12
  * Implements x402's SchemeNetworkServer interface.
42
13
  */
43
- export declare class EscrowServerScheme {
14
+ export declare class EscrowServerScheme implements SchemeNetworkServer {
44
15
  readonly scheme = "escrow";
45
- private readonly decimals;
46
- constructor(config?: {
47
- decimals?: number;
48
- });
16
+ private moneyParsers;
17
+ /**
18
+ * Register a custom money parser in the parser chain.
19
+ * Multiple parsers can be registered — they will be tried in registration order.
20
+ * Each parser receives a decimal amount (e.g., 1.50 for $1.50).
21
+ * If a parser returns null, the next parser in the chain will be tried.
22
+ * The default parser (USDC) is always the final fallback.
23
+ *
24
+ * @param parser - Custom function to convert amount to AssetAmount (or null to skip)
25
+ * @returns The server instance for chaining
26
+ */
27
+ registerMoneyParser(parser: MoneyParser): EscrowServerScheme;
49
28
  /**
50
29
  * Parse a price into an x402 AssetAmount.
51
30
  *
@@ -55,6 +34,14 @@ export declare class EscrowServerScheme {
55
34
  * - AssetAmount: { asset: "0x...", amount: "10000" }
56
35
  */
57
36
  parsePrice(price: Price, network: Network): Promise<AssetAmount>;
37
+ /**
38
+ * Parse Money (string | number) to a decimal number.
39
+ */
40
+ private parseMoneyToDecimal;
41
+ /**
42
+ * Default money conversion — converts decimal amount to the default stablecoin on the network.
43
+ */
44
+ private defaultMoneyConversion;
58
45
  /**
59
46
  * Enhance payment requirements with facilitator's extra fields.
60
47
  *
@@ -62,7 +49,24 @@ export declare class EscrowServerScheme {
62
49
  * the requirements, so escrow addresses flow from facilitator → merchant
63
50
  * requirements automatically.
64
51
  */
65
- enhancePaymentRequirements(requirements: PaymentRequirements, supportedKind: SupportedKind, _facilitatorExtensions: string[]): Promise<PaymentRequirements>;
52
+ enhancePaymentRequirements(requirements: PaymentRequirements, supportedKind: {
53
+ x402Version: number;
54
+ scheme: string;
55
+ network: Network;
56
+ extra?: Record<string, unknown>;
57
+ }, _facilitatorExtensions: string[]): Promise<PaymentRequirements>;
66
58
  }
59
+ /**
60
+ * Register escrow server scheme with x402ResourceServer
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const server = new x402ResourceServer(facilitatorConfig);
65
+ * registerEscrowServerScheme(server, { networks: "eip155:84532" });
66
+ * ```
67
+ */
68
+ export declare function registerEscrowServerScheme(server: x402ResourceServer, config: {
69
+ networks: Network | Network[];
70
+ }): x402ResourceServer;
67
71
  export type { EscrowExtra, EscrowPayload } from "../../shared/types.js";
68
72
  //# sourceMappingURL=index.d.ts.map