@zeroxyz/cli 0.0.42 → 0.0.43

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.
Files changed (2) hide show
  1. package/dist/index.js +70 -16
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { join as join11 } from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@zeroxyz/cli",
10
- version: "0.0.42",
10
+ version: "0.0.43",
11
11
  type: "module",
12
12
  bin: {
13
13
  zero: "dist/index.js",
@@ -587,12 +587,11 @@ var ApiService = class _ApiService {
587
587
  // Mints a one-time onramp URL for the caller's wallet. Two paths, picked by
588
588
  // which identity is available:
589
589
  // • BYO key present (this.account) → /v1/wallet/fund-url, proving ownership
590
- // with an EIP-191 signature. Honors the `provider` choice.
590
+ // with an EIP-191 signature.
591
591
  // • No key but a session (managed/runner) → /v1/users/me/fund-url, which
592
- // resolves the user's managed wallet server-side from the Bearer. Coinbase
593
- // only (the managed onramp doesn't take a provider), so `provider` is
594
- // ignored on this path.
595
- // Returns null on any failure so callers can fall back to manual transfer.
592
+ // resolves the user's managed wallet server-side from the Bearer.
593
+ // Both honor the `provider` choice. Returns null on any failure so callers
594
+ // can fall back to manual transfer.
596
595
  getFundingUrl = async (amount, provider = "coinbase") => {
597
596
  try {
598
597
  if (this.account) {
@@ -607,10 +606,12 @@ var ApiService = class _ApiService {
607
606
  return z.object({ url: z.string() }).parse(json).url;
608
607
  }
609
608
  if (this.credentials.kind === "session") {
610
- const params = new URLSearchParams();
609
+ const params = new URLSearchParams({ provider });
611
610
  if (amount) params.set("amount", amount);
612
- const qs = params.toString() ? `?${params.toString()}` : "";
613
- const json = await this.request("GET", `/v1/users/me/fund-url${qs}`);
611
+ const json = await this.request(
612
+ "GET",
613
+ `/v1/users/me/fund-url?${params.toString()}`
614
+ );
614
615
  return z.object({ url: z.string(), walletAddress: z.string() }).parse(json).url;
615
616
  }
616
617
  return null;
@@ -983,6 +984,61 @@ import {
983
984
  http
984
985
  } from "viem";
985
986
  import { base, baseSepolia, tempo as viemTempoChain } from "viem/chains";
987
+
988
+ // src/services/x402-challenge.ts
989
+ import { encodePaymentRequiredHeader } from "@x402/core/http";
990
+ var looksLikeX402Body = (body) => {
991
+ if (!body || typeof body !== "object") return false;
992
+ const b = body;
993
+ return typeof b.x402Version === "number" && Array.isArray(b.accepts) && b.accepts.length > 0;
994
+ };
995
+ var isV1ShapedAccept = (accept) => {
996
+ if (!accept || typeof accept !== "object") return false;
997
+ const a = accept;
998
+ const network = typeof a.network === "string" ? a.network : "";
999
+ const bareNetwork = network !== "" && !network.includes(":");
1000
+ const v1AmountField = a.maxAmountRequired != null && a.amount == null;
1001
+ return bareNetwork || v1AmountField;
1002
+ };
1003
+ var coerceX402BodyVersion = (challenge) => {
1004
+ const accepts = Array.isArray(challenge.accepts) ? challenge.accepts : [];
1005
+ return { ...challenge, x402Version: accepts.some(isV1ShapedAccept) ? 1 : 2 };
1006
+ };
1007
+ var withSynthesizedX402Header = (baseFetch) => async (input, init) => {
1008
+ const response = await baseFetch(input, init);
1009
+ if (response.status !== 402) return response;
1010
+ if (response.headers.get("payment-required") ?? response.headers.get("x-payment-required")) {
1011
+ return response;
1012
+ }
1013
+ const text = await response.clone().text();
1014
+ let parsed;
1015
+ try {
1016
+ parsed = JSON.parse(text);
1017
+ } catch {
1018
+ return response;
1019
+ }
1020
+ if (!looksLikeX402Body(parsed) || parsed.x402Version === 1) {
1021
+ return response;
1022
+ }
1023
+ const challenge = coerceX402BodyVersion(parsed);
1024
+ const headers = new Headers(response.headers);
1025
+ headers.set(
1026
+ "PAYMENT-REQUIRED",
1027
+ // Validated as an x402 body above; encoder wants the concrete type.
1028
+ encodePaymentRequiredHeader(
1029
+ challenge
1030
+ )
1031
+ );
1032
+ headers.delete("content-length");
1033
+ headers.delete("content-encoding");
1034
+ return new Response(text, {
1035
+ status: response.status,
1036
+ statusText: response.statusText,
1037
+ headers
1038
+ });
1039
+ };
1040
+
1041
+ // src/services/payment-service.ts
986
1042
  var SessionCloseFailedError = class extends Error {
987
1043
  session;
988
1044
  response;
@@ -1226,7 +1282,10 @@ var PaymentService = class {
1226
1282
  const httpClient = new x402HTTPClient(client).onPaymentRequired(
1227
1283
  createSIWxClientHook(this.account)
1228
1284
  );
1229
- const wrappedFetch = wrapFetchWithPayment(fetch, httpClient);
1285
+ const wrappedFetch = wrapFetchWithPayment(
1286
+ withSynthesizedX402Header(fetch),
1287
+ httpClient
1288
+ );
1230
1289
  const response = await wrappedFetch(url, {
1231
1290
  method: request.method,
1232
1291
  headers: request.headers,
@@ -1790,11 +1849,6 @@ var resolveRequestBody = (rawData, readStdin2) => {
1790
1849
  }
1791
1850
  return body;
1792
1851
  };
1793
- var looksLikeX402V1Body = (body) => {
1794
- if (!body || typeof body !== "object") return false;
1795
- const b = body;
1796
- return b.x402Version === 1 && Array.isArray(b.accepts) && b.accepts.length > 0;
1797
- };
1798
1852
  var detectPaymentRequirement = async (response) => {
1799
1853
  if (response.status !== 402) return null;
1800
1854
  const x402Header = response.headers.get("payment-required") ?? response.headers.get("x-payment-required");
@@ -1816,7 +1870,7 @@ var detectPaymentRequirement = async (response) => {
1816
1870
  const text = await response.clone().text();
1817
1871
  if (text) {
1818
1872
  const parsed = JSON.parse(text);
1819
- if (looksLikeX402V1Body(parsed)) {
1873
+ if (looksLikeX402Body(parsed)) {
1820
1874
  return { protocol: "x402", raw: parsed };
1821
1875
  }
1822
1876
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeroxyz/cli",
3
- "version": "0.0.42",
3
+ "version": "0.0.43",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "zero": "dist/index.js",