@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 +49 -26
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +49 -26
- package/package.json +3 -3
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://
|
|
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
|
|
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://
|
|
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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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://
|
|
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
|
|
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://
|
|
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
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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:
|
|
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.
|
|
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.
|
|
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.
|
|
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"
|