x402z-server 0.1.0 → 0.1.12

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.js CHANGED
@@ -161,6 +161,23 @@ async function fetchSupported(facilitatorUrl, fetchFn) {
161
161
  }
162
162
  return response.json();
163
163
  }
164
+ function normalizeExactDefaults(extra) {
165
+ const exact = extra?.exact ?? null;
166
+ if (!exact?.asset) {
167
+ return null;
168
+ }
169
+ const name = exact.eip712?.name ?? exact.name;
170
+ const version = exact.eip712?.version ?? exact.version;
171
+ if (!name || !version) {
172
+ return null;
173
+ }
174
+ return {
175
+ asset: exact.asset,
176
+ decimals: exact.decimals ?? 6,
177
+ name,
178
+ version
179
+ };
180
+ }
164
181
  function normalizeConfidentialDefaults(extra) {
165
182
  const confidential = extra?.confidential ?? null;
166
183
  if (!confidential?.asset || !confidential.eip712?.name || !confidential.eip712?.version) {
@@ -180,6 +197,25 @@ function normalizeConfidentialDefaults(extra) {
180
197
  resourceHash: confidential.resourceHash
181
198
  };
182
199
  }
200
+ function parseMoneyToDecimal(money) {
201
+ if (typeof money === "number") {
202
+ return money;
203
+ }
204
+ if (typeof money !== "string") {
205
+ throw new Error("Invalid price type for exact scheme");
206
+ }
207
+ const clean = money.replace(/^\$/, "").trim();
208
+ const amount = Number.parseFloat(clean);
209
+ if (Number.isNaN(amount)) {
210
+ throw new Error(`Invalid money format: ${money}`);
211
+ }
212
+ return amount;
213
+ }
214
+ function convertToTokenAmount(amount, decimals) {
215
+ const [intPart, decPart = ""] = String(amount).split(".");
216
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
217
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
218
+ }
183
219
  async function createX402zServer(config) {
184
220
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
185
221
  const fetchFn = globalThis.fetch;
@@ -195,6 +231,23 @@ async function createX402zServer(config) {
195
231
  if (wantsConfidential && !confidentialConfig) {
196
232
  throw new Error("confidential config is required when using erc7984-mind-v1 routes");
197
233
  }
234
+ const needsExactDefaults = Object.values(config.routes).some(
235
+ (route) => route.accepts.some((accept) => accept.scheme === "exact" && typeof accept.price !== "object")
236
+ );
237
+ let supportedExactDefaults = {};
238
+ if (wantsExact && needsExactDefaults) {
239
+ if (!fetchFn) {
240
+ throw new Error("fetch is required to load exact defaults from facilitator");
241
+ }
242
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
243
+ for (const kind of supported.kinds ?? []) {
244
+ if (kind.scheme !== "exact") continue;
245
+ const normalized = normalizeExactDefaults(kind.extra);
246
+ if (normalized) {
247
+ supportedExactDefaults[kind.network] = normalized;
248
+ }
249
+ }
250
+ }
198
251
  if (wantsConfidential && confidentialConfig) {
199
252
  let supportedDefaults = {};
200
253
  const needsSupportedDefaults = !confidentialConfig.getNetworkConfig && (!confidentialConfig.asset || !confidentialConfig.eip712 || !confidentialConfig.batcherAddress);
@@ -244,9 +297,34 @@ async function createX402zServer(config) {
244
297
  const rpcUrl = relayer ? getRelayerRpcUrl(relayer) : null;
245
298
  const routes = {};
246
299
  for (const [path, route] of Object.entries(config.routes)) {
300
+ const accepts = route.accepts.map((accept) => {
301
+ if (accept.scheme !== "exact") {
302
+ return accept;
303
+ }
304
+ if (typeof accept.price === "object") {
305
+ return accept;
306
+ }
307
+ const defaults = supportedExactDefaults[accept.network];
308
+ if (!defaults) {
309
+ throw new Error(`Missing exact defaults for network ${accept.network}`);
310
+ }
311
+ const decimalAmount = parseMoneyToDecimal(accept.price);
312
+ const amount = convertToTokenAmount(decimalAmount, defaults.decimals);
313
+ return {
314
+ ...accept,
315
+ price: {
316
+ amount,
317
+ asset: defaults.asset,
318
+ extra: {
319
+ name: defaults.name,
320
+ version: defaults.version
321
+ }
322
+ }
323
+ };
324
+ });
247
325
  routes[path] = {
248
326
  ...route,
249
- accepts: route.accepts
327
+ accepts
250
328
  };
251
329
  }
252
330
  const httpServer = new import_http.x402HTTPResourceServer(resourceServer, routes);
package/dist/index.mjs CHANGED
@@ -134,6 +134,23 @@ async function fetchSupported(facilitatorUrl, fetchFn) {
134
134
  }
135
135
  return response.json();
136
136
  }
137
+ function normalizeExactDefaults(extra) {
138
+ const exact = extra?.exact ?? null;
139
+ if (!exact?.asset) {
140
+ return null;
141
+ }
142
+ const name = exact.eip712?.name ?? exact.name;
143
+ const version = exact.eip712?.version ?? exact.version;
144
+ if (!name || !version) {
145
+ return null;
146
+ }
147
+ return {
148
+ asset: exact.asset,
149
+ decimals: exact.decimals ?? 6,
150
+ name,
151
+ version
152
+ };
153
+ }
137
154
  function normalizeConfidentialDefaults(extra) {
138
155
  const confidential = extra?.confidential ?? null;
139
156
  if (!confidential?.asset || !confidential.eip712?.name || !confidential.eip712?.version) {
@@ -153,6 +170,25 @@ function normalizeConfidentialDefaults(extra) {
153
170
  resourceHash: confidential.resourceHash
154
171
  };
155
172
  }
173
+ function parseMoneyToDecimal(money) {
174
+ if (typeof money === "number") {
175
+ return money;
176
+ }
177
+ if (typeof money !== "string") {
178
+ throw new Error("Invalid price type for exact scheme");
179
+ }
180
+ const clean = money.replace(/^\$/, "").trim();
181
+ const amount = Number.parseFloat(clean);
182
+ if (Number.isNaN(amount)) {
183
+ throw new Error(`Invalid money format: ${money}`);
184
+ }
185
+ return amount;
186
+ }
187
+ function convertToTokenAmount(amount, decimals) {
188
+ const [intPart, decPart = ""] = String(amount).split(".");
189
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
190
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
191
+ }
156
192
  async function createX402zServer(config) {
157
193
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
158
194
  const fetchFn = globalThis.fetch;
@@ -168,6 +204,23 @@ async function createX402zServer(config) {
168
204
  if (wantsConfidential && !confidentialConfig) {
169
205
  throw new Error("confidential config is required when using erc7984-mind-v1 routes");
170
206
  }
207
+ const needsExactDefaults = Object.values(config.routes).some(
208
+ (route) => route.accepts.some((accept) => accept.scheme === "exact" && typeof accept.price !== "object")
209
+ );
210
+ let supportedExactDefaults = {};
211
+ if (wantsExact && needsExactDefaults) {
212
+ if (!fetchFn) {
213
+ throw new Error("fetch is required to load exact defaults from facilitator");
214
+ }
215
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
216
+ for (const kind of supported.kinds ?? []) {
217
+ if (kind.scheme !== "exact") continue;
218
+ const normalized = normalizeExactDefaults(kind.extra);
219
+ if (normalized) {
220
+ supportedExactDefaults[kind.network] = normalized;
221
+ }
222
+ }
223
+ }
171
224
  if (wantsConfidential && confidentialConfig) {
172
225
  let supportedDefaults = {};
173
226
  const needsSupportedDefaults = !confidentialConfig.getNetworkConfig && (!confidentialConfig.asset || !confidentialConfig.eip712 || !confidentialConfig.batcherAddress);
@@ -217,9 +270,34 @@ async function createX402zServer(config) {
217
270
  const rpcUrl = relayer ? getRelayerRpcUrl(relayer) : null;
218
271
  const routes = {};
219
272
  for (const [path, route] of Object.entries(config.routes)) {
273
+ const accepts = route.accepts.map((accept) => {
274
+ if (accept.scheme !== "exact") {
275
+ return accept;
276
+ }
277
+ if (typeof accept.price === "object") {
278
+ return accept;
279
+ }
280
+ const defaults = supportedExactDefaults[accept.network];
281
+ if (!defaults) {
282
+ throw new Error(`Missing exact defaults for network ${accept.network}`);
283
+ }
284
+ const decimalAmount = parseMoneyToDecimal(accept.price);
285
+ const amount = convertToTokenAmount(decimalAmount, defaults.decimals);
286
+ return {
287
+ ...accept,
288
+ price: {
289
+ amount,
290
+ asset: defaults.asset,
291
+ extra: {
292
+ name: defaults.name,
293
+ version: defaults.version
294
+ }
295
+ }
296
+ };
297
+ });
220
298
  routes[path] = {
221
299
  ...route,
222
- accepts: route.accepts
300
+ accepts
223
301
  };
224
302
  }
225
303
  const httpServer = new x402HTTPResourceServer(resourceServer, routes);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402z-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.12",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -8,8 +8,8 @@
8
8
  "dist"
9
9
  ],
10
10
  "dependencies": {
11
- "@x402/core": "^2.0.0",
12
- "@x402/evm": "^2.0.0",
11
+ "@x402/core": "^2.2.0",
12
+ "@x402/evm": "^2.2.0",
13
13
  "viem": "^2.43.3",
14
14
  "x402z-shared": "0.1.0"
15
15
  },