@nullclear/x402-arbiter 1.1.2 → 1.2.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/dist/index.cjs CHANGED
@@ -107,7 +107,7 @@ var NullClearClient = class {
107
107
  defaultChainId;
108
108
  customFetch;
109
109
  constructor(config = {}) {
110
- this.arbiterUrl = (config.arbiterUrl || "https://arbiter.nullclear.dev").replace(/\/$/, "");
110
+ this.arbiterUrl = (config.arbiterUrl || "https://api.nullclear.dev").replace(/\/$/, "");
111
111
  this.defaultChainId = config.defaultChainId || 8453;
112
112
  this.customFetch = config.fetch || fetch;
113
113
  }
@@ -122,14 +122,29 @@ var NullClearClient = class {
122
122
  return data.data;
123
123
  }
124
124
  async clear(request) {
125
+ const headers = { "Content-Type": "application/json" };
126
+ if (!request.paymentSignatureHeader || request.paymentSignatureHeader === "free-trial") {
127
+ headers["x-nullclear-free-trial"] = "true";
128
+ }
125
129
  const res = await this.customFetch(`${this.arbiterUrl}/v1/clear`, {
126
130
  method: "POST",
127
- headers: { "Content-Type": "application/json" },
131
+ headers,
128
132
  body: JSON.stringify(request)
129
133
  });
130
134
  const data = await res.json();
131
135
  return data;
132
136
  }
137
+ async safeFetch(targetUrl, init) {
138
+ return this.customFetch(`${this.arbiterUrl}/${targetUrl}`, init);
139
+ }
140
+ async createGateway(params) {
141
+ const res = await this.customFetch(`${this.arbiterUrl}/v1/gateways`, {
142
+ method: "POST",
143
+ headers: { "Content-Type": "application/json" },
144
+ body: JSON.stringify(params)
145
+ });
146
+ return res.json();
147
+ }
133
148
  async getKya(agentId, chainId) {
134
149
  const targetChainId = chainId || this.defaultChainId;
135
150
  const res = await this.customFetch(`${this.arbiterUrl}/v1/kya/${targetChainId}/${agentId}`);
@@ -230,9 +245,9 @@ function zodToJsonSchema(schema) {
230
245
  return {};
231
246
  }
232
247
  }
233
- function createNullClearFetch(config) {
248
+ function createNullClearFetch(config = {}) {
234
249
  const chainId = config.chainId || 8453;
235
- const arbiterUrl = (config.arbiterUrl || "https://arbiter.nullclear.dev").replace(/\/$/, "");
250
+ const arbiterUrl = (config.arbiterUrl || "https://api.nullclear.dev").replace(/\/$/, "");
236
251
  const defaultMinTrustScore = config.defaultMinTrustScore || 50;
237
252
  const customFetch = config.customFetch || fetch;
238
253
  return async function nullclearFetch(input, init) {
@@ -244,29 +259,33 @@ function createNullClearFetch(config) {
244
259
  return initialRes;
245
260
  }
246
261
  const paymentRequiredHeader = initialRes.headers.get("PAYMENT-REQUIRED") || initialRes.headers.get("payment-required");
247
- if (!paymentRequiredHeader) {
248
- return initialRes;
249
- }
250
- let paymentRequired;
251
- try {
252
- paymentRequired = (0, import_shared2.decodeBase64Json)(paymentRequiredHeader);
253
- } catch {
254
- return initialRes;
255
- }
256
- const targetNetwork = `eip155:${chainId}`;
257
- const selectedOption = paymentRequired.accepts.find(
258
- (opt) => opt.network === targetNetwork && opt.scheme === "exact"
259
- );
260
- if (!selectedOption) {
261
- throw new Error(
262
- `Seller does not accept payments on network ${targetNetwork}. Accepted: ${paymentRequired.accepts.map((a) => a.network).join(", ")}`
262
+ let paymentSignatureHeader;
263
+ if (config.accountOrPrivateKey && paymentRequiredHeader) {
264
+ let paymentRequired;
265
+ try {
266
+ paymentRequired = (0, import_shared2.decodeBase64Json)(paymentRequiredHeader);
267
+ } catch {
268
+ return initialRes;
269
+ }
270
+ const targetNetwork = `eip155:${chainId}`;
271
+ const selectedOption = paymentRequired.accepts.find(
272
+ (opt) => opt.network === targetNetwork && opt.scheme === "exact"
273
+ );
274
+ if (!selectedOption) {
275
+ throw new Error(
276
+ `Seller does not accept payments on network ${targetNetwork}. Accepted: ${paymentRequired.accepts.map((a) => a.network).join(", ")}`
277
+ );
278
+ }
279
+ paymentSignatureHeader = await signX402Payment(
280
+ config.accountOrPrivateKey,
281
+ selectedOption,
282
+ targetUrl
263
283
  );
284
+ } else if (!config.accountOrPrivateKey) {
285
+ paymentSignatureHeader = "free-trial";
286
+ } else {
287
+ return initialRes;
264
288
  }
265
- const paymentSignatureHeader = await signX402Payment(
266
- config.accountOrPrivateKey,
267
- selectedOption,
268
- targetUrl
269
- );
270
289
  let jsonSchema;
271
290
  if (init?.nullclear?.schema) {
272
291
  if (init.nullclear.schema instanceof import_zod.z.ZodType) {
@@ -294,9 +313,13 @@ function createNullClearFetch(config) {
294
313
  fallbacks: init?.nullclear?.fallbacks,
295
314
  spendPolicy: init?.nullclear?.spendPolicy
296
315
  };
316
+ const clearHeaders = { "Content-Type": "application/json" };
317
+ if (paymentSignatureHeader === "free-trial") {
318
+ clearHeaders["x-nullclear-free-trial"] = "true";
319
+ }
297
320
  const arbiterRes = await customFetch(`${arbiterUrl}/v1/clear`, {
298
321
  method: "POST",
299
- headers: { "Content-Type": "application/json" },
322
+ headers: clearHeaders,
300
323
  body: JSON.stringify(clearPayload)
301
324
  });
302
325
  const arbiterData = await arbiterRes.json();
package/dist/index.d.cts CHANGED
@@ -24,7 +24,7 @@ interface ClearRequest {
24
24
  method?: "GET" | "POST" | "PUT" | "DELETE";
25
25
  headers?: Record<string, string>;
26
26
  body?: unknown;
27
- paymentSignatureHeader: string;
27
+ paymentSignatureHeader?: string;
28
28
  sellerAgentId?: string;
29
29
  minTrustScore?: number;
30
30
  twoPhaseRelease?: boolean;
@@ -35,12 +35,15 @@ interface ClearRequest {
35
35
  interface ClearResult<T = unknown> {
36
36
  cleared: boolean;
37
37
  settled: boolean;
38
+ tier?: string;
39
+ freeTrialRemaining?: number;
38
40
  clearingId?: string;
39
41
  buyerCharged: string;
40
42
  clearingFee?: string;
41
43
  settlementRouting?: string;
42
44
  transaction?: `0x${string}`;
43
45
  attestation?: unknown;
46
+ executionReceipt?: unknown;
44
47
  data?: T;
45
48
  stage?: string;
46
49
  error?: string;
@@ -61,6 +64,18 @@ declare class NullClearClient {
61
64
  constructor(config?: NullClearClientConfig);
62
65
  getScore(agentId: string, chainId?: number): Promise<any>;
63
66
  clear<T = unknown>(request: ClearRequest): Promise<ClearResult<T>>;
67
+ safeFetch(targetUrl: string, init?: RequestInit): Promise<Response>;
68
+ createGateway(params: {
69
+ upstreamUrl: string;
70
+ sellerAddress: string;
71
+ priceUsdc?: string;
72
+ priceAtomic?: string;
73
+ slug?: string;
74
+ description?: string;
75
+ category?: "data" | "security" | "oracle" | "ai";
76
+ validationPreset?: "DEFAULT_JSON" | "STRICT_NO_REFUSAL" | "CUSTOM";
77
+ customSchema?: Record<string, unknown>;
78
+ }): Promise<any>;
64
79
  getKya(agentId: string, chainId?: number): Promise<any>;
65
80
  attestKya(mandate: KYAMandate, chainId?: number, signature?: string, signerAddress?: `0x${string}`): Promise<any>;
66
81
  }
@@ -111,7 +126,7 @@ interface NullClearOptions {
111
126
  spendPolicy?: SpendPolicy;
112
127
  }
113
128
  interface NullClearFetchConfig {
114
- accountOrPrivateKey: SignerInput;
129
+ accountOrPrivateKey?: SignerInput;
115
130
  chainId?: number;
116
131
  arbiterUrl?: string;
117
132
  defaultMinTrustScore?: number;
@@ -124,6 +139,6 @@ type NullClearRequestInit = RequestInit & {
124
139
  * Creates an enhanced fetch client that autonomously intercepts HTTP 402 Payment Required
125
140
  * and safely wraps the call in NullClear Deferred Non-Custodial Schema Escrow
126
141
  */
127
- declare function createNullClearFetch(config: NullClearFetchConfig): (input: RequestInfo | URL, init?: NullClearRequestInit) => Promise<Response>;
142
+ declare function createNullClearFetch(config?: NullClearFetchConfig): (input: RequestInfo | URL, init?: NullClearRequestInit) => Promise<Response>;
128
143
 
129
144
  export { type ClearRequest, type ClearResult, NullClearClient, type NullClearClientConfig, NullClearEscrowAbortedError, type NullClearFetchConfig, type NullClearOptions, type NullClearRequestInit, type SignerInput, createNullClearFetch, signX402Payment, zodToJsonSchema };
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ interface ClearRequest {
24
24
  method?: "GET" | "POST" | "PUT" | "DELETE";
25
25
  headers?: Record<string, string>;
26
26
  body?: unknown;
27
- paymentSignatureHeader: string;
27
+ paymentSignatureHeader?: string;
28
28
  sellerAgentId?: string;
29
29
  minTrustScore?: number;
30
30
  twoPhaseRelease?: boolean;
@@ -35,12 +35,15 @@ interface ClearRequest {
35
35
  interface ClearResult<T = unknown> {
36
36
  cleared: boolean;
37
37
  settled: boolean;
38
+ tier?: string;
39
+ freeTrialRemaining?: number;
38
40
  clearingId?: string;
39
41
  buyerCharged: string;
40
42
  clearingFee?: string;
41
43
  settlementRouting?: string;
42
44
  transaction?: `0x${string}`;
43
45
  attestation?: unknown;
46
+ executionReceipt?: unknown;
44
47
  data?: T;
45
48
  stage?: string;
46
49
  error?: string;
@@ -61,6 +64,18 @@ declare class NullClearClient {
61
64
  constructor(config?: NullClearClientConfig);
62
65
  getScore(agentId: string, chainId?: number): Promise<any>;
63
66
  clear<T = unknown>(request: ClearRequest): Promise<ClearResult<T>>;
67
+ safeFetch(targetUrl: string, init?: RequestInit): Promise<Response>;
68
+ createGateway(params: {
69
+ upstreamUrl: string;
70
+ sellerAddress: string;
71
+ priceUsdc?: string;
72
+ priceAtomic?: string;
73
+ slug?: string;
74
+ description?: string;
75
+ category?: "data" | "security" | "oracle" | "ai";
76
+ validationPreset?: "DEFAULT_JSON" | "STRICT_NO_REFUSAL" | "CUSTOM";
77
+ customSchema?: Record<string, unknown>;
78
+ }): Promise<any>;
64
79
  getKya(agentId: string, chainId?: number): Promise<any>;
65
80
  attestKya(mandate: KYAMandate, chainId?: number, signature?: string, signerAddress?: `0x${string}`): Promise<any>;
66
81
  }
@@ -111,7 +126,7 @@ interface NullClearOptions {
111
126
  spendPolicy?: SpendPolicy;
112
127
  }
113
128
  interface NullClearFetchConfig {
114
- accountOrPrivateKey: SignerInput;
129
+ accountOrPrivateKey?: SignerInput;
115
130
  chainId?: number;
116
131
  arbiterUrl?: string;
117
132
  defaultMinTrustScore?: number;
@@ -124,6 +139,6 @@ type NullClearRequestInit = RequestInit & {
124
139
  * Creates an enhanced fetch client that autonomously intercepts HTTP 402 Payment Required
125
140
  * and safely wraps the call in NullClear Deferred Non-Custodial Schema Escrow
126
141
  */
127
- declare function createNullClearFetch(config: NullClearFetchConfig): (input: RequestInfo | URL, init?: NullClearRequestInit) => Promise<Response>;
142
+ declare function createNullClearFetch(config?: NullClearFetchConfig): (input: RequestInfo | URL, init?: NullClearRequestInit) => Promise<Response>;
128
143
 
129
144
  export { type ClearRequest, type ClearResult, NullClearClient, type NullClearClientConfig, NullClearEscrowAbortedError, type NullClearFetchConfig, type NullClearOptions, type NullClearRequestInit, type SignerInput, createNullClearFetch, signX402Payment, zodToJsonSchema };
package/dist/index.js CHANGED
@@ -81,7 +81,7 @@ var NullClearClient = class {
81
81
  defaultChainId;
82
82
  customFetch;
83
83
  constructor(config = {}) {
84
- this.arbiterUrl = (config.arbiterUrl || "https://arbiter.nullclear.dev").replace(/\/$/, "");
84
+ this.arbiterUrl = (config.arbiterUrl || "https://api.nullclear.dev").replace(/\/$/, "");
85
85
  this.defaultChainId = config.defaultChainId || 8453;
86
86
  this.customFetch = config.fetch || fetch;
87
87
  }
@@ -96,14 +96,29 @@ var NullClearClient = class {
96
96
  return data.data;
97
97
  }
98
98
  async clear(request) {
99
+ const headers = { "Content-Type": "application/json" };
100
+ if (!request.paymentSignatureHeader || request.paymentSignatureHeader === "free-trial") {
101
+ headers["x-nullclear-free-trial"] = "true";
102
+ }
99
103
  const res = await this.customFetch(`${this.arbiterUrl}/v1/clear`, {
100
104
  method: "POST",
101
- headers: { "Content-Type": "application/json" },
105
+ headers,
102
106
  body: JSON.stringify(request)
103
107
  });
104
108
  const data = await res.json();
105
109
  return data;
106
110
  }
111
+ async safeFetch(targetUrl, init) {
112
+ return this.customFetch(`${this.arbiterUrl}/${targetUrl}`, init);
113
+ }
114
+ async createGateway(params) {
115
+ const res = await this.customFetch(`${this.arbiterUrl}/v1/gateways`, {
116
+ method: "POST",
117
+ headers: { "Content-Type": "application/json" },
118
+ body: JSON.stringify(params)
119
+ });
120
+ return res.json();
121
+ }
107
122
  async getKya(agentId, chainId) {
108
123
  const targetChainId = chainId || this.defaultChainId;
109
124
  const res = await this.customFetch(`${this.arbiterUrl}/v1/kya/${targetChainId}/${agentId}`);
@@ -206,9 +221,9 @@ function zodToJsonSchema(schema) {
206
221
  return {};
207
222
  }
208
223
  }
209
- function createNullClearFetch(config) {
224
+ function createNullClearFetch(config = {}) {
210
225
  const chainId = config.chainId || 8453;
211
- const arbiterUrl = (config.arbiterUrl || "https://arbiter.nullclear.dev").replace(/\/$/, "");
226
+ const arbiterUrl = (config.arbiterUrl || "https://api.nullclear.dev").replace(/\/$/, "");
212
227
  const defaultMinTrustScore = config.defaultMinTrustScore || 50;
213
228
  const customFetch = config.customFetch || fetch;
214
229
  return async function nullclearFetch(input, init) {
@@ -220,29 +235,33 @@ function createNullClearFetch(config) {
220
235
  return initialRes;
221
236
  }
222
237
  const paymentRequiredHeader = initialRes.headers.get("PAYMENT-REQUIRED") || initialRes.headers.get("payment-required");
223
- if (!paymentRequiredHeader) {
224
- return initialRes;
225
- }
226
- let paymentRequired;
227
- try {
228
- paymentRequired = decodeBase64Json(paymentRequiredHeader);
229
- } catch {
230
- return initialRes;
231
- }
232
- const targetNetwork = `eip155:${chainId}`;
233
- const selectedOption = paymentRequired.accepts.find(
234
- (opt) => opt.network === targetNetwork && opt.scheme === "exact"
235
- );
236
- if (!selectedOption) {
237
- throw new Error(
238
- `Seller does not accept payments on network ${targetNetwork}. Accepted: ${paymentRequired.accepts.map((a) => a.network).join(", ")}`
238
+ let paymentSignatureHeader;
239
+ if (config.accountOrPrivateKey && paymentRequiredHeader) {
240
+ let paymentRequired;
241
+ try {
242
+ paymentRequired = decodeBase64Json(paymentRequiredHeader);
243
+ } catch {
244
+ return initialRes;
245
+ }
246
+ const targetNetwork = `eip155:${chainId}`;
247
+ const selectedOption = paymentRequired.accepts.find(
248
+ (opt) => opt.network === targetNetwork && opt.scheme === "exact"
249
+ );
250
+ if (!selectedOption) {
251
+ throw new Error(
252
+ `Seller does not accept payments on network ${targetNetwork}. Accepted: ${paymentRequired.accepts.map((a) => a.network).join(", ")}`
253
+ );
254
+ }
255
+ paymentSignatureHeader = await signX402Payment(
256
+ config.accountOrPrivateKey,
257
+ selectedOption,
258
+ targetUrl
239
259
  );
260
+ } else if (!config.accountOrPrivateKey) {
261
+ paymentSignatureHeader = "free-trial";
262
+ } else {
263
+ return initialRes;
240
264
  }
241
- const paymentSignatureHeader = await signX402Payment(
242
- config.accountOrPrivateKey,
243
- selectedOption,
244
- targetUrl
245
- );
246
265
  let jsonSchema;
247
266
  if (init?.nullclear?.schema) {
248
267
  if (init.nullclear.schema instanceof z.ZodType) {
@@ -270,9 +289,13 @@ function createNullClearFetch(config) {
270
289
  fallbacks: init?.nullclear?.fallbacks,
271
290
  spendPolicy: init?.nullclear?.spendPolicy
272
291
  };
292
+ const clearHeaders = { "Content-Type": "application/json" };
293
+ if (paymentSignatureHeader === "free-trial") {
294
+ clearHeaders["x-nullclear-free-trial"] = "true";
295
+ }
273
296
  const arbiterRes = await customFetch(`${arbiterUrl}/v1/clear`, {
274
297
  method: "POST",
275
- headers: { "Content-Type": "application/json" },
298
+ headers: clearHeaders,
276
299
  body: JSON.stringify(clearPayload)
277
300
  });
278
301
  const arbiterData = await arbiterRes.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nullclear/x402-arbiter",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
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.1.2",
30
+ "@nullclear/shared": "1.2.0",
31
31
  "viem": "^2.23.0",
32
32
  "zod": "^3.24.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@nullclear/worker-arbiter": "1.1.2",
35
+ "@nullclear/worker-arbiter": "1.2.0",
36
36
  "tsup": "^8.3.6",
37
37
  "typescript": "^5.7.3",
38
38
  "vitest": "^3.0.5"