x402z-client-web 0.0.9

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 ADDED
@@ -0,0 +1,49 @@
1
+ # x402z-client-web
2
+
3
+ Browser helpers for the erc7984-mind-v1 x402 scheme.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add x402z-client-web x402z-shared-web
9
+ ```
10
+
11
+ ## Folder map
12
+
13
+ - `src/http/`: HTTP client helpers
14
+ - `src/scheme/`: scheme implementation + registration
15
+ - `src/index.ts`: public exports
16
+
17
+ ## Usage (Browser)
18
+
19
+ ```ts
20
+ import { createX402zClient } from "x402z-client-web";
21
+ import { SepoliaConfig } from "x402z-shared-web";
22
+
23
+ const client = await createX402zClient({
24
+ signer: {
25
+ address: "0x...",
26
+ signTypedData: async args =>
27
+ window.ethereum.request({ method: "eth_signTypedData_v4", params: [args] }),
28
+ },
29
+ relayerConfig: { ...SepoliaConfig, network: window.ethereum },
30
+ });
31
+
32
+ const response = await client.pay("https://example.com/demo");
33
+ console.log(response.status);
34
+ ```
35
+
36
+ `createX402zClient` builds the confidential payment input automatically using the
37
+ `confidential.batcherAddress` provided by the server’s payment requirements.
38
+
39
+ ## API
40
+
41
+ - `createX402zClient(config)`
42
+ - `signer` (required): EIP-712 signer for x402 payloads
43
+ - `relayerConfig` (required): relayer instance config (browser)
44
+ - `fetch` (optional): custom fetch implementation
45
+ - `client.pay(url, options?)`: performs the 402 handshake and retries with payment headers
46
+
47
+ ## Notes
48
+
49
+ - Scheme name: `erc7984-mind-v1`
@@ -0,0 +1,48 @@
1
+ import { ConfidentialPaymentInput, RelayerSdkModule, initSDK, RelayerInstance } from 'x402z-shared-web';
2
+ export { ConfidentialRequirementsExtra, RelayerInstance } from 'x402z-shared-web';
3
+ import { x402Client } from '@x402/core/client';
4
+ import { PaymentRequirements, SchemeNetworkClient, PaymentPayload, Network } from '@x402/core/types';
5
+ export * from '@x402/core/types';
6
+ import { ClientEvmSigner } from '@x402/evm';
7
+
8
+ type X402zClientSchemeOptions = {
9
+ signer: ClientEvmSigner;
10
+ buildPayment: (requirements: PaymentRequirements) => ConfidentialPaymentInput | Promise<ConfidentialPaymentInput>;
11
+ eip712?: {
12
+ name: string;
13
+ version: string;
14
+ };
15
+ hashEncryptedAmountInput?: (encryptedAmountInput: `0x${string}`) => `0x${string}`;
16
+ clock?: () => number;
17
+ };
18
+ declare class X402zEvmClientScheme implements SchemeNetworkClient {
19
+ private readonly config;
20
+ readonly scheme = "erc7984-mind-v1";
21
+ private readonly hashFn;
22
+ private readonly clock;
23
+ constructor(config: X402zClientSchemeOptions);
24
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
25
+ }
26
+
27
+ type X402zClientRegistrationOptions = X402zClientSchemeOptions & {
28
+ networks?: Network[];
29
+ };
30
+ declare function registerX402zEvmClientScheme(client: x402Client, config: X402zClientRegistrationOptions): x402Client;
31
+
32
+ type X402zClientOptions = Omit<X402zClientRegistrationOptions, "buildPayment"> & {
33
+ relayerSdk?: RelayerSdkModule;
34
+ relayerConfig: unknown;
35
+ initSdkParams?: Parameters<typeof initSDK>[0];
36
+ fetch?: typeof fetch;
37
+ debug?: boolean;
38
+ };
39
+ type PayOptions = {
40
+ headers?: Record<string, string>;
41
+ };
42
+ type X402zClient = {
43
+ relayer: RelayerInstance;
44
+ pay: (url: string, options?: PayOptions) => Promise<Response>;
45
+ };
46
+ declare function createX402zClient(config: X402zClientOptions): Promise<X402zClient>;
47
+
48
+ export { type PayOptions, type X402zClient, type X402zClientOptions, type X402zClientRegistrationOptions, type X402zClientSchemeOptions, X402zEvmClientScheme, createX402zClient, registerX402zEvmClientScheme };
@@ -0,0 +1,48 @@
1
+ import { ConfidentialPaymentInput, RelayerSdkModule, initSDK, RelayerInstance } from 'x402z-shared-web';
2
+ export { ConfidentialRequirementsExtra, RelayerInstance } from 'x402z-shared-web';
3
+ import { x402Client } from '@x402/core/client';
4
+ import { PaymentRequirements, SchemeNetworkClient, PaymentPayload, Network } from '@x402/core/types';
5
+ export * from '@x402/core/types';
6
+ import { ClientEvmSigner } from '@x402/evm';
7
+
8
+ type X402zClientSchemeOptions = {
9
+ signer: ClientEvmSigner;
10
+ buildPayment: (requirements: PaymentRequirements) => ConfidentialPaymentInput | Promise<ConfidentialPaymentInput>;
11
+ eip712?: {
12
+ name: string;
13
+ version: string;
14
+ };
15
+ hashEncryptedAmountInput?: (encryptedAmountInput: `0x${string}`) => `0x${string}`;
16
+ clock?: () => number;
17
+ };
18
+ declare class X402zEvmClientScheme implements SchemeNetworkClient {
19
+ private readonly config;
20
+ readonly scheme = "erc7984-mind-v1";
21
+ private readonly hashFn;
22
+ private readonly clock;
23
+ constructor(config: X402zClientSchemeOptions);
24
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
25
+ }
26
+
27
+ type X402zClientRegistrationOptions = X402zClientSchemeOptions & {
28
+ networks?: Network[];
29
+ };
30
+ declare function registerX402zEvmClientScheme(client: x402Client, config: X402zClientRegistrationOptions): x402Client;
31
+
32
+ type X402zClientOptions = Omit<X402zClientRegistrationOptions, "buildPayment"> & {
33
+ relayerSdk?: RelayerSdkModule;
34
+ relayerConfig: unknown;
35
+ initSdkParams?: Parameters<typeof initSDK>[0];
36
+ fetch?: typeof fetch;
37
+ debug?: boolean;
38
+ };
39
+ type PayOptions = {
40
+ headers?: Record<string, string>;
41
+ };
42
+ type X402zClient = {
43
+ relayer: RelayerInstance;
44
+ pay: (url: string, options?: PayOptions) => Promise<Response>;
45
+ };
46
+ declare function createX402zClient(config: X402zClientOptions): Promise<X402zClient>;
47
+
48
+ export { type PayOptions, type X402zClient, type X402zClientOptions, type X402zClientRegistrationOptions, type X402zClientSchemeOptions, X402zEvmClientScheme, createX402zClient, registerX402zEvmClientScheme };
package/dist/index.js ADDED
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ X402zEvmClientScheme: () => X402zEvmClientScheme,
24
+ createX402zClient: () => createX402zClient,
25
+ registerX402zEvmClientScheme: () => registerX402zEvmClientScheme
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/http/client.ts
30
+ var import_client = require("@x402/core/client");
31
+ var import_http = require("@x402/core/http");
32
+ var import_viem2 = require("viem");
33
+ var import_x402z_shared_web2 = require("x402z-shared-web");
34
+
35
+ // src/scheme/scheme.ts
36
+ var import_viem = require("viem");
37
+ var import_x402z_shared_web = require("x402z-shared-web");
38
+ var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
39
+ var DECIMAL_POINT = ".";
40
+ function normalizeIntegerAmount(value, fallback) {
41
+ const normalized = (0, import_x402z_shared_web.normalizeAmount)(value);
42
+ if (!normalized.includes(DECIMAL_POINT)) {
43
+ return normalized;
44
+ }
45
+ const fallbackNormalized = (0, import_x402z_shared_web.normalizeAmount)(fallback);
46
+ if (fallbackNormalized.includes(DECIMAL_POINT)) {
47
+ throw new Error(`Invalid amount: ${normalized}`);
48
+ }
49
+ return fallbackNormalized;
50
+ }
51
+ var X402zEvmClientScheme = class {
52
+ constructor(config) {
53
+ this.config = config;
54
+ this.scheme = "erc7984-mind-v1";
55
+ this.hashFn = config.hashEncryptedAmountInput ?? import_x402z_shared_web.hashEncryptedAmountInput;
56
+ this.clock = config.clock ?? (() => Math.floor(Date.now() / 1e3));
57
+ }
58
+ async createPaymentPayload(x402Version, paymentRequirements) {
59
+ const input = await this.config.buildPayment(paymentRequirements);
60
+ const extra = paymentRequirements.extra;
61
+ const eip712 = extra?.eip712 ?? this.config.eip712;
62
+ if (!eip712?.name || !eip712?.version) {
63
+ throw new Error("Missing EIP-712 domain parameters (name, version) in requirements or config");
64
+ }
65
+ const now = this.clock();
66
+ const validAfter = input.validAfter ?? Math.max(0, now - 60);
67
+ const validBefore = input.validBefore ?? now + paymentRequirements.maxTimeoutSeconds;
68
+ const nonce = input.nonce ?? (0, import_x402z_shared_web.createNonce)();
69
+ const maxClearAmount = normalizeIntegerAmount(
70
+ input.maxClearAmount ?? extra?.confidential?.maxClearAmount ?? paymentRequirements.amount,
71
+ paymentRequirements.amount
72
+ );
73
+ const resourceHash = input.resourceHash ?? extra?.confidential?.resourceHash ?? ZERO_BYTES32;
74
+ const authorization = {
75
+ holder: this.config.signer.address,
76
+ payee: (0, import_viem.getAddress)(paymentRequirements.payTo),
77
+ maxClearAmount,
78
+ resourceHash,
79
+ validAfter: (0, import_x402z_shared_web.normalizeAmount)(validAfter),
80
+ validBefore: (0, import_x402z_shared_web.normalizeAmount)(validBefore),
81
+ nonce,
82
+ encryptedAmountHash: this.hashFn(input.encryptedAmountInput)
83
+ };
84
+ const chainId = parseInt(paymentRequirements.network.split(":")[1]);
85
+ const signature = await this.config.signer.signTypedData({
86
+ domain: {
87
+ name: eip712.name,
88
+ version: eip712.version,
89
+ chainId,
90
+ verifyingContract: (0, import_viem.getAddress)(paymentRequirements.asset)
91
+ },
92
+ types: import_x402z_shared_web.confidentialPaymentTypes,
93
+ primaryType: "ConfidentialPayment",
94
+ message: {
95
+ holder: (0, import_viem.getAddress)(authorization.holder),
96
+ payee: (0, import_viem.getAddress)(authorization.payee),
97
+ maxClearAmount: BigInt(authorization.maxClearAmount),
98
+ resourceHash: authorization.resourceHash,
99
+ validAfter: BigInt(authorization.validAfter),
100
+ validBefore: BigInt(authorization.validBefore),
101
+ nonce: authorization.nonce,
102
+ encryptedAmountHash: authorization.encryptedAmountHash
103
+ }
104
+ });
105
+ const payload = {
106
+ authorization,
107
+ signature,
108
+ encryptedAmountInput: input.encryptedAmountInput,
109
+ inputProof: input.inputProof
110
+ };
111
+ return {
112
+ x402Version,
113
+ payload
114
+ };
115
+ }
116
+ };
117
+
118
+ // src/scheme/register.ts
119
+ function registerX402zEvmClientScheme(client, config) {
120
+ if (config.networks && config.networks.length > 0) {
121
+ for (const network of config.networks) {
122
+ client.register(network, new X402zEvmClientScheme(config));
123
+ }
124
+ return client;
125
+ }
126
+ client.register("eip155:*", new X402zEvmClientScheme(config));
127
+ return client;
128
+ }
129
+
130
+ // src/http/client.ts
131
+ async function createX402zClient(config) {
132
+ const { fetch: fetchOverride, ...registerConfig } = config;
133
+ const fetchFn = fetchOverride ?? globalThis.fetch;
134
+ const debugEnabled = config.debug ?? false;
135
+ if (!fetchFn) {
136
+ throw new Error("fetch is not available; provide a fetch implementation");
137
+ }
138
+ if (config.relayerSdk) {
139
+ (0, import_x402z_shared_web2.configureRelayerSdk)(config.relayerSdk);
140
+ }
141
+ await (0, import_x402z_shared_web2.initSDK)(config.initSdkParams);
142
+ const relayer = await (0, import_x402z_shared_web2.createRelayer)(config.relayerConfig);
143
+ const buildPayment = async (requirements) => {
144
+ if (!(0, import_viem2.isAddress)(requirements.asset)) {
145
+ throw new Error(`Invalid TOKEN_ADDRESS from requirements: ${requirements.asset}`);
146
+ }
147
+ const extra = requirements.extra;
148
+ const batcherAddress = extra?.confidential?.batcherAddress;
149
+ if (!batcherAddress) {
150
+ throw new Error("Missing confidential.batcherAddress in payment requirements");
151
+ }
152
+ if (debugEnabled) {
153
+ console.debug("[x402z-client] encrypt input", {
154
+ tokenAddress: requirements.asset,
155
+ batcherAddress,
156
+ amount: requirements.amount
157
+ });
158
+ }
159
+ const encrypted = await (0, import_x402z_shared_web2.createEncryptedAmountInput)(
160
+ relayer,
161
+ requirements.asset,
162
+ batcherAddress,
163
+ Number(requirements.amount)
164
+ );
165
+ return {
166
+ encryptedAmountInput: encrypted.handle,
167
+ inputProof: encrypted.inputProof
168
+ };
169
+ };
170
+ const client = new import_client.x402Client();
171
+ registerX402zEvmClientScheme(client, {
172
+ ...registerConfig,
173
+ buildPayment
174
+ });
175
+ const httpClient = new import_http.x402HTTPClient(client);
176
+ return {
177
+ relayer,
178
+ async pay(url, options) {
179
+ const initial = await fetchFn(url, { headers: options?.headers });
180
+ if (initial.status !== 402) {
181
+ return initial;
182
+ }
183
+ const paymentRequired = httpClient.getPaymentRequiredResponse(
184
+ (name) => initial.headers.get(name),
185
+ await initial.json().catch(() => ({}))
186
+ );
187
+ const payload = await httpClient.createPaymentPayload(paymentRequired);
188
+ const payHeaders = httpClient.encodePaymentSignatureHeader(payload);
189
+ if (debugEnabled) {
190
+ console.debug("[x402z-client] payment payload", payload);
191
+ console.debug("[x402z-client] payment headers", payHeaders);
192
+ }
193
+ const mergedHeaders = { ...options?.headers ?? {}, ...payHeaders };
194
+ const paidResponse = await fetchFn(url, { headers: mergedHeaders });
195
+ if (debugEnabled) {
196
+ try {
197
+ const body = await paidResponse.clone().text();
198
+ console.debug("[x402z-client] response", {
199
+ status: paidResponse.status,
200
+ headers: Object.fromEntries(paidResponse.headers.entries()),
201
+ body
202
+ });
203
+ } catch (error) {
204
+ console.debug("[x402z-client] response", {
205
+ status: paidResponse.status,
206
+ headers: Object.fromEntries(paidResponse.headers.entries()),
207
+ body: "<unavailable>"
208
+ });
209
+ }
210
+ }
211
+ return paidResponse;
212
+ }
213
+ };
214
+ }
215
+ // Annotate the CommonJS export names for ESM import in node:
216
+ 0 && (module.exports = {
217
+ X402zEvmClientScheme,
218
+ createX402zClient,
219
+ registerX402zEvmClientScheme
220
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,201 @@
1
+ // src/http/client.ts
2
+ import { x402Client } from "@x402/core/client";
3
+ import { x402HTTPClient } from "@x402/core/http";
4
+ import { isAddress } from "viem";
5
+ import {
6
+ configureRelayerSdk,
7
+ createEncryptedAmountInput,
8
+ createRelayer,
9
+ initSDK
10
+ } from "x402z-shared-web";
11
+
12
+ // src/scheme/scheme.ts
13
+ import { getAddress } from "viem";
14
+ import {
15
+ confidentialPaymentTypes,
16
+ createNonce,
17
+ hashEncryptedAmountInput,
18
+ normalizeAmount
19
+ } from "x402z-shared-web";
20
+ var ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000";
21
+ var DECIMAL_POINT = ".";
22
+ function normalizeIntegerAmount(value, fallback) {
23
+ const normalized = normalizeAmount(value);
24
+ if (!normalized.includes(DECIMAL_POINT)) {
25
+ return normalized;
26
+ }
27
+ const fallbackNormalized = normalizeAmount(fallback);
28
+ if (fallbackNormalized.includes(DECIMAL_POINT)) {
29
+ throw new Error(`Invalid amount: ${normalized}`);
30
+ }
31
+ return fallbackNormalized;
32
+ }
33
+ var X402zEvmClientScheme = class {
34
+ constructor(config) {
35
+ this.config = config;
36
+ this.scheme = "erc7984-mind-v1";
37
+ this.hashFn = config.hashEncryptedAmountInput ?? hashEncryptedAmountInput;
38
+ this.clock = config.clock ?? (() => Math.floor(Date.now() / 1e3));
39
+ }
40
+ async createPaymentPayload(x402Version, paymentRequirements) {
41
+ const input = await this.config.buildPayment(paymentRequirements);
42
+ const extra = paymentRequirements.extra;
43
+ const eip712 = extra?.eip712 ?? this.config.eip712;
44
+ if (!eip712?.name || !eip712?.version) {
45
+ throw new Error("Missing EIP-712 domain parameters (name, version) in requirements or config");
46
+ }
47
+ const now = this.clock();
48
+ const validAfter = input.validAfter ?? Math.max(0, now - 60);
49
+ const validBefore = input.validBefore ?? now + paymentRequirements.maxTimeoutSeconds;
50
+ const nonce = input.nonce ?? createNonce();
51
+ const maxClearAmount = normalizeIntegerAmount(
52
+ input.maxClearAmount ?? extra?.confidential?.maxClearAmount ?? paymentRequirements.amount,
53
+ paymentRequirements.amount
54
+ );
55
+ const resourceHash = input.resourceHash ?? extra?.confidential?.resourceHash ?? ZERO_BYTES32;
56
+ const authorization = {
57
+ holder: this.config.signer.address,
58
+ payee: getAddress(paymentRequirements.payTo),
59
+ maxClearAmount,
60
+ resourceHash,
61
+ validAfter: normalizeAmount(validAfter),
62
+ validBefore: normalizeAmount(validBefore),
63
+ nonce,
64
+ encryptedAmountHash: this.hashFn(input.encryptedAmountInput)
65
+ };
66
+ const chainId = parseInt(paymentRequirements.network.split(":")[1]);
67
+ const signature = await this.config.signer.signTypedData({
68
+ domain: {
69
+ name: eip712.name,
70
+ version: eip712.version,
71
+ chainId,
72
+ verifyingContract: getAddress(paymentRequirements.asset)
73
+ },
74
+ types: confidentialPaymentTypes,
75
+ primaryType: "ConfidentialPayment",
76
+ message: {
77
+ holder: getAddress(authorization.holder),
78
+ payee: getAddress(authorization.payee),
79
+ maxClearAmount: BigInt(authorization.maxClearAmount),
80
+ resourceHash: authorization.resourceHash,
81
+ validAfter: BigInt(authorization.validAfter),
82
+ validBefore: BigInt(authorization.validBefore),
83
+ nonce: authorization.nonce,
84
+ encryptedAmountHash: authorization.encryptedAmountHash
85
+ }
86
+ });
87
+ const payload = {
88
+ authorization,
89
+ signature,
90
+ encryptedAmountInput: input.encryptedAmountInput,
91
+ inputProof: input.inputProof
92
+ };
93
+ return {
94
+ x402Version,
95
+ payload
96
+ };
97
+ }
98
+ };
99
+
100
+ // src/scheme/register.ts
101
+ function registerX402zEvmClientScheme(client, config) {
102
+ if (config.networks && config.networks.length > 0) {
103
+ for (const network of config.networks) {
104
+ client.register(network, new X402zEvmClientScheme(config));
105
+ }
106
+ return client;
107
+ }
108
+ client.register("eip155:*", new X402zEvmClientScheme(config));
109
+ return client;
110
+ }
111
+
112
+ // src/http/client.ts
113
+ async function createX402zClient(config) {
114
+ const { fetch: fetchOverride, ...registerConfig } = config;
115
+ const fetchFn = fetchOverride ?? globalThis.fetch;
116
+ const debugEnabled = config.debug ?? false;
117
+ if (!fetchFn) {
118
+ throw new Error("fetch is not available; provide a fetch implementation");
119
+ }
120
+ if (config.relayerSdk) {
121
+ configureRelayerSdk(config.relayerSdk);
122
+ }
123
+ await initSDK(config.initSdkParams);
124
+ const relayer = await createRelayer(config.relayerConfig);
125
+ const buildPayment = async (requirements) => {
126
+ if (!isAddress(requirements.asset)) {
127
+ throw new Error(`Invalid TOKEN_ADDRESS from requirements: ${requirements.asset}`);
128
+ }
129
+ const extra = requirements.extra;
130
+ const batcherAddress = extra?.confidential?.batcherAddress;
131
+ if (!batcherAddress) {
132
+ throw new Error("Missing confidential.batcherAddress in payment requirements");
133
+ }
134
+ if (debugEnabled) {
135
+ console.debug("[x402z-client] encrypt input", {
136
+ tokenAddress: requirements.asset,
137
+ batcherAddress,
138
+ amount: requirements.amount
139
+ });
140
+ }
141
+ const encrypted = await createEncryptedAmountInput(
142
+ relayer,
143
+ requirements.asset,
144
+ batcherAddress,
145
+ Number(requirements.amount)
146
+ );
147
+ return {
148
+ encryptedAmountInput: encrypted.handle,
149
+ inputProof: encrypted.inputProof
150
+ };
151
+ };
152
+ const client = new x402Client();
153
+ registerX402zEvmClientScheme(client, {
154
+ ...registerConfig,
155
+ buildPayment
156
+ });
157
+ const httpClient = new x402HTTPClient(client);
158
+ return {
159
+ relayer,
160
+ async pay(url, options) {
161
+ const initial = await fetchFn(url, { headers: options?.headers });
162
+ if (initial.status !== 402) {
163
+ return initial;
164
+ }
165
+ const paymentRequired = httpClient.getPaymentRequiredResponse(
166
+ (name) => initial.headers.get(name),
167
+ await initial.json().catch(() => ({}))
168
+ );
169
+ const payload = await httpClient.createPaymentPayload(paymentRequired);
170
+ const payHeaders = httpClient.encodePaymentSignatureHeader(payload);
171
+ if (debugEnabled) {
172
+ console.debug("[x402z-client] payment payload", payload);
173
+ console.debug("[x402z-client] payment headers", payHeaders);
174
+ }
175
+ const mergedHeaders = { ...options?.headers ?? {}, ...payHeaders };
176
+ const paidResponse = await fetchFn(url, { headers: mergedHeaders });
177
+ if (debugEnabled) {
178
+ try {
179
+ const body = await paidResponse.clone().text();
180
+ console.debug("[x402z-client] response", {
181
+ status: paidResponse.status,
182
+ headers: Object.fromEntries(paidResponse.headers.entries()),
183
+ body
184
+ });
185
+ } catch (error) {
186
+ console.debug("[x402z-client] response", {
187
+ status: paidResponse.status,
188
+ headers: Object.fromEntries(paidResponse.headers.entries()),
189
+ body: "<unavailable>"
190
+ });
191
+ }
192
+ }
193
+ return paidResponse;
194
+ }
195
+ };
196
+ }
197
+ export {
198
+ X402zEvmClientScheme,
199
+ createX402zClient,
200
+ registerX402zEvmClientScheme
201
+ };
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "x402z-client-web",
3
+ "version": "0.0.9",
4
+ "main": "./dist/index.js",
5
+ "module": "./dist/index.mjs",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "dependencies": {
18
+ "@x402/core": "^2.0.0",
19
+ "@x402/evm": "^2.0.0",
20
+ "viem": "^2.39.3",
21
+ "x402z-shared-web": "0.0.9"
22
+ },
23
+ "devDependencies": {
24
+ "jest": "^29.7.0",
25
+ "ts-jest": "^29.2.5",
26
+ "@types/jest": "^29.5.12"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup src/index.ts --format cjs,esm --dts",
30
+ "test": "jest --config jest.config.cjs --passWithNoTests"
31
+ }
32
+ }