@nullclear/x402-arbiter 1.0.0 → 1.1.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/dist/index.cjs CHANGED
@@ -38,9 +38,15 @@ async function signX402Payment(signer, option, resourceUrl) {
38
38
  const account = (0, import_accounts.privateKeyToAccount)(signer);
39
39
  accountAddress = account.address;
40
40
  signTypedDataFn = (params) => account.signTypedData(params);
41
- } else if (typeof signer === "object" && signer !== null && "signTypedData" in signer && "account" in signer && signer.account) {
42
- const rawAccount = signer.account;
43
- accountAddress = typeof rawAccount === "string" ? rawAccount : rawAccount.address;
41
+ } else if (typeof signer === "object" && signer !== null && "signTypedData" in signer) {
42
+ if ("account" in signer && signer.account) {
43
+ const rawAccount = signer.account;
44
+ accountAddress = typeof rawAccount === "string" ? rawAccount : rawAccount.address;
45
+ } else if ("address" in signer && signer.address) {
46
+ accountAddress = signer.address;
47
+ } else {
48
+ throw new Error("Signer object missing address");
49
+ }
44
50
  signTypedDataFn = (params) => signer.signTypedData(params);
45
51
  } else {
46
52
  throw new Error("Invalid signer provided to signX402Payment: must be private key or viem account/wallet client");
@@ -79,10 +85,14 @@ async function signX402Payment(signer, option, resourceUrl) {
79
85
  nonce: authorization.nonce
80
86
  }
81
87
  });
88
+ const acceptedOption = {
89
+ ...option,
90
+ extra: option.extra || { name: "USD Coin", version: "2" }
91
+ };
82
92
  const payload = {
83
93
  x402Version: 2,
84
94
  resource: resourceUrl ? { url: resourceUrl } : void 0,
85
- accepted: option,
95
+ accepted: acceptedOption,
86
96
  payload: {
87
97
  signature,
88
98
  authorization
@@ -162,6 +172,8 @@ var NullClearEscrowAbortedError = class extends Error {
162
172
  score;
163
173
  upstreamStatus;
164
174
  reason;
175
+ failoverAttempts;
176
+ failedCandidates;
165
177
  constructor(message, details) {
166
178
  super(message);
167
179
  this.name = "NullClearEscrowAbortedError";
@@ -275,8 +287,12 @@ function createNullClearFetch(config) {
275
287
  expectedStatus: [200],
276
288
  jsonSchema,
277
289
  requiredFields: init?.nullclear?.requiredFields,
278
- sha256Match: init?.nullclear?.sha256Match
279
- }
290
+ sha256Match: init?.nullclear?.sha256Match,
291
+ rejectRefusals: init?.nullclear?.rejectRefusals ?? true,
292
+ invariants: init?.nullclear?.invariants
293
+ },
294
+ fallbacks: init?.nullclear?.fallbacks,
295
+ spendPolicy: init?.nullclear?.spendPolicy
280
296
  };
281
297
  const arbiterRes = await customFetch(`${arbiterUrl}/v1/clear`, {
282
298
  method: "POST",
@@ -305,7 +321,9 @@ function createNullClearFetch(config) {
305
321
  validationErrors: arbiterData.validationErrors || [],
306
322
  score: arbiterData.score,
307
323
  upstreamStatus: arbiterData.upstreamStatus,
308
- reason: arbiterData.reason || arbiterData.error
324
+ reason: arbiterData.reason || arbiterData.error,
325
+ failoverAttempts: arbiterData.failoverAttempts,
326
+ failedCandidates: arbiterData.failedCandidates
309
327
  }
310
328
  );
311
329
  };
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PrivateKeyAccount } from 'viem/accounts';
2
2
  import { WalletClient } from 'viem';
3
- import { X402PaymentOption, KYAMandate } from '@nullclear/shared';
3
+ import { X402PaymentOption, ValidationConfig, FallbackTarget, SpendPolicy, KYAMandate, InvariantRule } from '@nullclear/shared';
4
4
  import { z } from 'zod';
5
5
 
6
6
  type SignerInput = `0x${string}` | PrivateKeyAccount | {
@@ -27,12 +27,10 @@ interface ClearRequest {
27
27
  paymentSignatureHeader: string;
28
28
  sellerAgentId?: string;
29
29
  minTrustScore?: number;
30
- validation?: {
31
- expectedStatus?: number[];
32
- jsonSchema?: Record<string, unknown>;
33
- requiredFields?: string[];
34
- sha256Match?: string;
35
- };
30
+ twoPhaseRelease?: boolean;
31
+ validation?: ValidationConfig;
32
+ fallbacks?: FallbackTarget[];
33
+ spendPolicy?: SpendPolicy;
36
34
  }
37
35
  interface ClearResult<T = unknown> {
38
36
  cleared: boolean;
@@ -40,12 +38,21 @@ interface ClearResult<T = unknown> {
40
38
  clearingId?: string;
41
39
  buyerCharged: string;
42
40
  clearingFee?: string;
41
+ settlementRouting?: string;
43
42
  transaction?: `0x${string}`;
44
43
  attestation?: unknown;
45
44
  data?: T;
46
45
  stage?: string;
47
46
  error?: string;
48
47
  validationErrors?: string[];
48
+ failoverAttempts?: number;
49
+ winningSellerAgentId?: string;
50
+ failedCandidates?: Array<{
51
+ targetUrl: string;
52
+ sellerAgentId?: string;
53
+ stage: string;
54
+ reason: string;
55
+ }>;
49
56
  }
50
57
  declare class NullClearClient {
51
58
  private arbiterUrl;
@@ -65,6 +72,13 @@ declare class NullClearEscrowAbortedError extends Error {
65
72
  score?: number;
66
73
  upstreamStatus?: number;
67
74
  reason?: string;
75
+ failoverAttempts?: number;
76
+ failedCandidates?: Array<{
77
+ targetUrl: string;
78
+ sellerAgentId?: string;
79
+ stage: string;
80
+ reason: string;
81
+ }>;
68
82
  constructor(message: string, details: {
69
83
  stage: string;
70
84
  buyerCharged?: string;
@@ -72,6 +86,13 @@ declare class NullClearEscrowAbortedError extends Error {
72
86
  score?: number;
73
87
  upstreamStatus?: number;
74
88
  reason?: string;
89
+ failoverAttempts?: number;
90
+ failedCandidates?: Array<{
91
+ targetUrl: string;
92
+ sellerAgentId?: string;
93
+ stage: string;
94
+ reason: string;
95
+ }>;
75
96
  });
76
97
  }
77
98
  /**
@@ -84,6 +105,10 @@ interface NullClearOptions {
84
105
  schema?: z.ZodTypeAny | Record<string, unknown>;
85
106
  requiredFields?: string[];
86
107
  sha256Match?: string;
108
+ invariants?: InvariantRule[];
109
+ rejectRefusals?: boolean;
110
+ fallbacks?: FallbackTarget[];
111
+ spendPolicy?: SpendPolicy;
87
112
  }
88
113
  interface NullClearFetchConfig {
89
114
  accountOrPrivateKey: SignerInput;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PrivateKeyAccount } from 'viem/accounts';
2
2
  import { WalletClient } from 'viem';
3
- import { X402PaymentOption, KYAMandate } from '@nullclear/shared';
3
+ import { X402PaymentOption, ValidationConfig, FallbackTarget, SpendPolicy, KYAMandate, InvariantRule } from '@nullclear/shared';
4
4
  import { z } from 'zod';
5
5
 
6
6
  type SignerInput = `0x${string}` | PrivateKeyAccount | {
@@ -27,12 +27,10 @@ interface ClearRequest {
27
27
  paymentSignatureHeader: string;
28
28
  sellerAgentId?: string;
29
29
  minTrustScore?: number;
30
- validation?: {
31
- expectedStatus?: number[];
32
- jsonSchema?: Record<string, unknown>;
33
- requiredFields?: string[];
34
- sha256Match?: string;
35
- };
30
+ twoPhaseRelease?: boolean;
31
+ validation?: ValidationConfig;
32
+ fallbacks?: FallbackTarget[];
33
+ spendPolicy?: SpendPolicy;
36
34
  }
37
35
  interface ClearResult<T = unknown> {
38
36
  cleared: boolean;
@@ -40,12 +38,21 @@ interface ClearResult<T = unknown> {
40
38
  clearingId?: string;
41
39
  buyerCharged: string;
42
40
  clearingFee?: string;
41
+ settlementRouting?: string;
43
42
  transaction?: `0x${string}`;
44
43
  attestation?: unknown;
45
44
  data?: T;
46
45
  stage?: string;
47
46
  error?: string;
48
47
  validationErrors?: string[];
48
+ failoverAttempts?: number;
49
+ winningSellerAgentId?: string;
50
+ failedCandidates?: Array<{
51
+ targetUrl: string;
52
+ sellerAgentId?: string;
53
+ stage: string;
54
+ reason: string;
55
+ }>;
49
56
  }
50
57
  declare class NullClearClient {
51
58
  private arbiterUrl;
@@ -65,6 +72,13 @@ declare class NullClearEscrowAbortedError extends Error {
65
72
  score?: number;
66
73
  upstreamStatus?: number;
67
74
  reason?: string;
75
+ failoverAttempts?: number;
76
+ failedCandidates?: Array<{
77
+ targetUrl: string;
78
+ sellerAgentId?: string;
79
+ stage: string;
80
+ reason: string;
81
+ }>;
68
82
  constructor(message: string, details: {
69
83
  stage: string;
70
84
  buyerCharged?: string;
@@ -72,6 +86,13 @@ declare class NullClearEscrowAbortedError extends Error {
72
86
  score?: number;
73
87
  upstreamStatus?: number;
74
88
  reason?: string;
89
+ failoverAttempts?: number;
90
+ failedCandidates?: Array<{
91
+ targetUrl: string;
92
+ sellerAgentId?: string;
93
+ stage: string;
94
+ reason: string;
95
+ }>;
75
96
  });
76
97
  }
77
98
  /**
@@ -84,6 +105,10 @@ interface NullClearOptions {
84
105
  schema?: z.ZodTypeAny | Record<string, unknown>;
85
106
  requiredFields?: string[];
86
107
  sha256Match?: string;
108
+ invariants?: InvariantRule[];
109
+ rejectRefusals?: boolean;
110
+ fallbacks?: FallbackTarget[];
111
+ spendPolicy?: SpendPolicy;
87
112
  }
88
113
  interface NullClearFetchConfig {
89
114
  accountOrPrivateKey: SignerInput;
package/dist/index.js CHANGED
@@ -12,9 +12,15 @@ async function signX402Payment(signer, option, resourceUrl) {
12
12
  const account = privateKeyToAccount(signer);
13
13
  accountAddress = account.address;
14
14
  signTypedDataFn = (params) => account.signTypedData(params);
15
- } else if (typeof signer === "object" && signer !== null && "signTypedData" in signer && "account" in signer && signer.account) {
16
- const rawAccount = signer.account;
17
- accountAddress = typeof rawAccount === "string" ? rawAccount : rawAccount.address;
15
+ } else if (typeof signer === "object" && signer !== null && "signTypedData" in signer) {
16
+ if ("account" in signer && signer.account) {
17
+ const rawAccount = signer.account;
18
+ accountAddress = typeof rawAccount === "string" ? rawAccount : rawAccount.address;
19
+ } else if ("address" in signer && signer.address) {
20
+ accountAddress = signer.address;
21
+ } else {
22
+ throw new Error("Signer object missing address");
23
+ }
18
24
  signTypedDataFn = (params) => signer.signTypedData(params);
19
25
  } else {
20
26
  throw new Error("Invalid signer provided to signX402Payment: must be private key or viem account/wallet client");
@@ -53,10 +59,14 @@ async function signX402Payment(signer, option, resourceUrl) {
53
59
  nonce: authorization.nonce
54
60
  }
55
61
  });
62
+ const acceptedOption = {
63
+ ...option,
64
+ extra: option.extra || { name: "USD Coin", version: "2" }
65
+ };
56
66
  const payload = {
57
67
  x402Version: 2,
58
68
  resource: resourceUrl ? { url: resourceUrl } : void 0,
59
- accepted: option,
69
+ accepted: acceptedOption,
60
70
  payload: {
61
71
  signature,
62
72
  authorization
@@ -138,6 +148,8 @@ var NullClearEscrowAbortedError = class extends Error {
138
148
  score;
139
149
  upstreamStatus;
140
150
  reason;
151
+ failoverAttempts;
152
+ failedCandidates;
141
153
  constructor(message, details) {
142
154
  super(message);
143
155
  this.name = "NullClearEscrowAbortedError";
@@ -251,8 +263,12 @@ function createNullClearFetch(config) {
251
263
  expectedStatus: [200],
252
264
  jsonSchema,
253
265
  requiredFields: init?.nullclear?.requiredFields,
254
- sha256Match: init?.nullclear?.sha256Match
255
- }
266
+ sha256Match: init?.nullclear?.sha256Match,
267
+ rejectRefusals: init?.nullclear?.rejectRefusals ?? true,
268
+ invariants: init?.nullclear?.invariants
269
+ },
270
+ fallbacks: init?.nullclear?.fallbacks,
271
+ spendPolicy: init?.nullclear?.spendPolicy
256
272
  };
257
273
  const arbiterRes = await customFetch(`${arbiterUrl}/v1/clear`, {
258
274
  method: "POST",
@@ -281,7 +297,9 @@ function createNullClearFetch(config) {
281
297
  validationErrors: arbiterData.validationErrors || [],
282
298
  score: arbiterData.score,
283
299
  upstreamStatus: arbiterData.upstreamStatus,
284
- reason: arbiterData.reason || arbiterData.error
300
+ reason: arbiterData.reason || arbiterData.error,
301
+ failoverAttempts: arbiterData.failoverAttempts,
302
+ failedCandidates: arbiterData.failedCandidates
285
303
  }
286
304
  );
287
305
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nullclear/x402-arbiter",
3
- "version": "1.0.0",
3
+ "version": "1.1.2",
4
4
  "description": "NullClear Developer and Agent SDK for safe x402 calls with deferred schema escrow",
5
5
  "license": "MIT",
6
6
  "homepage": "https://nullclear.dev",
@@ -27,12 +27,12 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@nullclear/shared": "1.0.0",
30
+ "@nullclear/shared": "1.1.2",
31
31
  "viem": "^2.23.0",
32
32
  "zod": "^3.24.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@nullclear/worker-arbiter": "1.0.0",
35
+ "@nullclear/worker-arbiter": "1.1.2",
36
36
  "tsup": "^8.3.6",
37
37
  "typescript": "^5.7.3",
38
38
  "vitest": "^3.0.5"