@wafermapxyz/cli 0.4.3 → 0.4.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.4 (2 Nov 2026)
4
+
5
+ **$WAFERMAP holder tiers.**
6
+
7
+ - **Pro free calls.** A wallet holding 1,000,000 $WAFERMAP on Robinhood Chain gets 10 free calls a day (UTC) to Wafermap resources listed at $0.01 or less. `call()` (CLI `wafermap call`, MCP `wafermap_call`) sends a **holder pass** to Wafermap with each call; when the call is free, the result comes back with `receipt: null` and `free: {left, perDay}`, no payment is signed and nothing is recorded as spending. Otherwise the call is quoted and paid as before.
8
+ - **Holder pass.** A message the wallet signs (`personal_sign`: no transaction, no cost) that proves it holds the wallet, valid for 24 hours and reused until its last 10 minutes (`Wafermap.holderPass()`). It goes to Wafermap only: never with `pay()` to third-party services, and never to marketplace listings (`m/...`). The SDK exports `PASS_HEADER`, `passMessage`, `encodePass`, `decodePass`, `makePass`.
9
+ - **`wafermap holder`** shows what the wallet's $WAFERMAP unlocks: holder price, tier, free calls left today, x402 Tracker Pro. Needs no password (`holderInfo()` in the SDK).
10
+ - **`wafermap pass`** prints a pass for scripts, e.g. the x402 Tracker Pro API (`/api/x402/pro/movers`, `/api/x402/pro/export`, for wallets holding 100,000 $WAFERMAP).
11
+
3
12
  ## 0.4.3 (2 Nov 2026)
4
13
 
5
14
  The two open points from the third public review by @whoiskn0why (8/10), thank you.
package/README.md CHANGED
@@ -82,7 +82,9 @@ Pass `approve: (a) => boolean` to confirm each payment or swap yourself, and `le
82
82
 
83
83
  ## $WAFERMAP holder discount
84
84
 
85
- A wallet that holds at least 100,000 $WAFERMAP on Robinhood Chain pays 50% less for Wafermap's own resources when it pays on an EVM network (Robinhood Chain, Base, Arbitrum, Polygon). Nothing to set up: `wafermap call` names the wallet to Wafermap and the quote comes back discounted; the server re-checks the balance of the wallet that signs. Marketplace listings and Solana payments keep the regular price. Check a wallet: https://wafermap.xyz/api/holder?address=0x…
85
+ A wallet that holds at least 100,000 $WAFERMAP on Robinhood Chain pays 50% less for Wafermap's own resources when it pays on an EVM network (Robinhood Chain, Base, Arbitrum, Polygon). Nothing to set up: `wafermap call` names the wallet to Wafermap and the quote comes back discounted; the server re-checks the balance of the wallet that signs. Marketplace listings and Solana payments keep the regular price. Check a wallet: https://wafermap.xyz/api/holder?address=0x…, or run `wafermap holder`.
86
+
87
+ With 1,000,000 $WAFERMAP the wallet is **Pro**: 10 free calls a day (UTC) to resources listed at $0.01 or less. `wafermap call` sends a holder pass (a signed message, no transaction, valid 24 hours) to Wafermap only; when a call is free, nothing is signed for payment and it prints `✓ Free call`. Holders of 100,000 also unlock x402 Tracker Pro: `wafermap pass` prints a pass for its API. Details: https://wafermap.xyz/docs#holders
86
88
 
87
89
  ## Where the limits live
88
90
 
package/dist/cli.js CHANGED
@@ -437,6 +437,47 @@ var init_x402client = __esm({
437
437
  }
438
438
  });
439
439
 
440
+ // shared/pass.ts
441
+ function passMessage(address, iat, exp) {
442
+ return [
443
+ "wafermap.xyz holder pass",
444
+ "",
445
+ `Wallet: ${address}`,
446
+ `Issued: ${new Date(iat * 1e3).toISOString()}`,
447
+ `Expires: ${new Date(exp * 1e3).toISOString()}`,
448
+ "",
449
+ "Proves you hold this wallet, so Wafermap can apply what your $WAFERMAP unlocks. It costs nothing and moves no funds."
450
+ ].join("\n");
451
+ }
452
+ function decodePass(s) {
453
+ if (!s || s.length > 1e3 || !/^[A-Za-z0-9_-]+$/.test(s)) return null;
454
+ try {
455
+ const p = JSON.parse(unb64url(s));
456
+ if (p?.v !== 1 || typeof p.address !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(p.address)) return null;
457
+ if (!Number.isInteger(p.iat) || !Number.isInteger(p.exp) || typeof p.sig !== "string" || !/^0x[0-9a-fA-F]{130}$/.test(p.sig)) return null;
458
+ return { v: 1, address: p.address, iat: p.iat, exp: p.exp, sig: p.sig };
459
+ } catch {
460
+ return null;
461
+ }
462
+ }
463
+ async function makePass(signer, seconds = PASS_MAX_SECONDS, now = Math.floor(Date.now() / 1e3)) {
464
+ const iat = now;
465
+ const exp = now + Math.min(Math.max(60, seconds), PASS_MAX_SECONDS);
466
+ const sig = await signer.signMessage({ message: passMessage(signer.address, iat, exp) });
467
+ return { v: 1, address: signer.address, iat, exp, sig };
468
+ }
469
+ var PASS_HEADER, PASS_MAX_SECONDS, b64url, unb64url, encodePass;
470
+ var init_pass = __esm({
471
+ "shared/pass.ts"() {
472
+ "use strict";
473
+ PASS_HEADER = "x-wafermap-pass";
474
+ PASS_MAX_SECONDS = 86400;
475
+ b64url = (s) => btoa(unescape(encodeURIComponent(s))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
476
+ unb64url = (s) => decodeURIComponent(escape(atob(s.replace(/-/g, "+").replace(/_/g, "/"))));
477
+ encodePass = (p) => b64url(JSON.stringify(p));
478
+ }
479
+ });
480
+
440
481
  // src/core.ts
441
482
  var core_exports = {};
442
483
  __export(core_exports, {
@@ -446,6 +487,7 @@ __export(core_exports, {
446
487
  Wafermap: () => Wafermap,
447
488
  WafermapError: () => WafermapError,
448
489
  checkPayment: () => checkPayment,
490
+ holderInfo: () => holderInfo,
449
491
  isNet: () => isNet,
450
492
  listResources: () => listResources,
451
493
  mergeLog: () => mergeLog
@@ -473,6 +515,15 @@ async function checkPayment(e, rpc) {
473
515
  return "error";
474
516
  }
475
517
  }
518
+ async function holderInfo(address, baseUrl = "https://wafermap.xyz", timeoutMs = DEFAULT_TIMEOUT_MS) {
519
+ const host = new URL(baseUrl).host;
520
+ const r = await fetch(`${baseUrl.replace(/\/$/, "")}/api/holder?address=${encodeURIComponent(address)}`, { signal: AbortSignal.timeout(timeoutMs) }).catch((e) => {
521
+ throw timedOut(e) ? new WafermapError("timeout", `${host} did not answer within ${Math.round(timeoutMs / 1e3)} s.`) : new WafermapError("network_error", `${host}: ${e?.message ?? "request failed"}`);
522
+ });
523
+ const j = await r.json().catch(() => null);
524
+ if (!r.ok || !j) throw new WafermapError(j?.error?.code ?? "network_error", j?.error?.message ?? `${host} answered HTTP ${r.status}.`);
525
+ return j;
526
+ }
476
527
  async function listResources(baseUrl = "https://wafermap.xyz", timeoutMs = DEFAULT_TIMEOUT_MS) {
477
528
  const host = new URL(baseUrl).host;
478
529
  const gaveUp = () => new WafermapError("timeout", `${host} did not answer within ${Math.round(timeoutMs / 1e3)} s. Nothing was paid.`);
@@ -494,6 +545,7 @@ var init_core = __esm({
494
545
  init_swap();
495
546
  init_solana();
496
547
  init_x402client();
548
+ init_pass();
497
549
  NETS = CHAIN_KEYS;
498
550
  isNet = (v) => NETS.includes(v);
499
551
  isSwapNet = (v) => v === "robinhood" || v === "base";
@@ -649,8 +701,19 @@ var init_core = __esm({
649
701
  async resources() {
650
702
  return listResources(this.baseUrl, this.timeoutMs);
651
703
  }
704
+ passCache = null;
705
+ /** A holder pass (shared/pass.ts) signed by this wallet, valid 24 h and reused until its last 10 minutes. It
706
+ * proves the wallet to Wafermap for what its $WAFERMAP unlocks (Pro free calls, x402 Tracker Pro). Signing
707
+ * a message moves no funds. */
708
+ async holderPass() {
709
+ const p = decodePass(this.passCache);
710
+ if (this.passCache && p && p.exp - 600 > Date.now() / 1e3) return this.passCache;
711
+ this.passCache = encodePass(await makePass({ address: this.account.address, signMessage: (a) => this.account.signMessage(a) }));
712
+ return this.passCache;
713
+ }
652
714
  async call(id, input = {}, o = {}) {
653
- const go = () => this.paidFetch("resource", id, `${this.baseUrl}/v1/${id}`, { method: "POST", headers: { "content-type": "application/json", "x-wafermap-payer": this.address }, body: JSON.stringify(input) }, o.network);
715
+ const pass = id.startsWith("m/") ? null : await this.holderPass();
716
+ const go = () => this.paidFetch("resource", id, `${this.baseUrl}/v1/${id}`, { method: "POST", headers: { "content-type": "application/json", "x-wafermap-payer": this.address, ...pass ? { [PASS_HEADER]: pass } : {} }, body: JSON.stringify(input) }, o.network);
654
717
  const settle = (r2, out2) => {
655
718
  if (!r2.paid || !r2.id) return;
656
719
  const status = r2.res.status === 402 ? "refused" : r2.res.ok ? "ok" : "failed";
@@ -960,7 +1023,7 @@ var VERSION;
960
1023
  var init_version = __esm({
961
1024
  "src/version.ts"() {
962
1025
  "use strict";
963
- VERSION = "0.4.3";
1026
+ VERSION = "0.4.4";
964
1027
  }
965
1028
  });
966
1029
 
@@ -1515,6 +1578,8 @@ Wallet
1515
1578
  Pay
1516
1579
  wafermap resources [words] Wafermap's pay-per-call catalog
1517
1580
  wafermap call <id> [field=value ...] run a resource and pay its price (--json '{...}' for complex input)
1581
+ wafermap holder what this wallet's $WAFERMAP unlocks: holder price, Pro free calls left today
1582
+ wafermap pass print a holder pass (X-Wafermap-Pass) for scripts and x402 Tracker Pro
1518
1583
  wafermap discover <words> search third-party x402 services
1519
1584
  wafermap pay <url> [field=value ...] call any x402 URL and pay it (--post to send a JSON body)
1520
1585
 
@@ -1630,6 +1695,26 @@ async function main() {
1630
1695
  Caps: $0.10 per payment, $1 per day, $25 per swap. Change with \`wafermap limits\`.`);
1631
1696
  return;
1632
1697
  }
1698
+ case "holder": {
1699
+ const addr = keystoreAddress() ?? die("No wallet yet. Run `wafermap init`.");
1700
+ const j = await holderInfo(addr, process.env.WAFERMAP_URL, Number(process.env.WAFERMAP_TIMEOUT_MS) || void 0);
1701
+ if (!j.active) return console.log("The $WAFERMAP holder program is off.");
1702
+ const n = (v) => Math.floor(v).toLocaleString("en-US");
1703
+ const k = j.perks;
1704
+ console.log(`${addr}
1705
+ holds ${n(j.balance)} $WAFERMAP on Robinhood Chain`);
1706
+ console.log(` tier ${j.tier === "pro" ? "Pro" : j.tier === "holder" ? "Holder" : "none"}`);
1707
+ console.log(` price ${j.holder ? `${j.percent}% off Wafermap resources on EVM networks` : `regular (hold ${n(j.minTokens)} for ${j.percent}% off)`}`);
1708
+ if (k) console.log(` free ${j.tier === "pro" ? `${k.freeLeftToday ?? "?"} of ${k.freeCallsPerDay} free calls left today (resources up to $${k.freeMaxUsd}); \`wafermap call\` uses them first` : `hold ${n(k.proMinTokens)} for ${k.freeCallsPerDay} free calls a day`}`);
1709
+ return console.log(` tracker ${j.holder ? "x402 Tracker Pro unlocked: wafermap.xyz/x402 (or `wafermap pass` for the API)" : `x402 Tracker Pro needs ${n(j.minTokens)}`}`);
1710
+ }
1711
+ case "pass": {
1712
+ const wm = openWallet(await password());
1713
+ const v = await wm.holderPass();
1714
+ console.error(`Holder pass for ${wm.address}, valid 24 hours. It proves you hold the wallet and moves no funds; anyone who has it can use your free calls until it expires, so keep it private. Send it as X-Wafermap-Pass:`);
1715
+ console.error(` curl -H "X-Wafermap-Pass: $(wafermap pass)" https://wafermap.xyz/api/x402/pro/movers`);
1716
+ return console.log(v);
1717
+ }
1633
1718
  case "address": {
1634
1719
  const evm = keystoreAddress() ?? die("No wallet yet. Run `wafermap init`.");
1635
1720
  let sol = keystoreSolana();
@@ -1711,6 +1796,7 @@ Total $${total.toFixed(4)} in ${pays.length} payments. From 0.3.3 every payment
1711
1796
  const wm = openWallet(await password(), approver(yes));
1712
1797
  const out = await wm.call(id, inputOf(a, 1), { network: net(a.flags.network) });
1713
1798
  if (out.receipt) console.error(`\u2713 Paid $${out.receipt.amountUsd} ${out.receipt.asset} \xB7 ${EXPLORER(out.receipt.network)}/tx/${out.receipt.tx}`);
1799
+ else if (out.free) console.error(`\u2713 Free call ($WAFERMAP Pro) \xB7 ${out.free.left} of ${out.free.perDay} left today. Nothing was paid.`);
1714
1800
  if (typeof a.flags.out === "string") await saveMedia(out.result, a.flags.out);
1715
1801
  return printResult(out.result);
1716
1802
  }
package/dist/index.js CHANGED
@@ -407,6 +407,41 @@ async function x402fetch(url, init, opts) {
407
407
  return { res, paid: { ...signed, tx: readSettlement(res)?.tx ?? null } };
408
408
  }
409
409
 
410
+ // shared/pass.ts
411
+ var PASS_HEADER = "x-wafermap-pass";
412
+ var PASS_MAX_SECONDS = 86400;
413
+ function passMessage(address, iat, exp) {
414
+ return [
415
+ "wafermap.xyz holder pass",
416
+ "",
417
+ `Wallet: ${address}`,
418
+ `Issued: ${new Date(iat * 1e3).toISOString()}`,
419
+ `Expires: ${new Date(exp * 1e3).toISOString()}`,
420
+ "",
421
+ "Proves you hold this wallet, so Wafermap can apply what your $WAFERMAP unlocks. It costs nothing and moves no funds."
422
+ ].join("\n");
423
+ }
424
+ var b64url = (s) => btoa(unescape(encodeURIComponent(s))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
425
+ var unb64url = (s) => decodeURIComponent(escape(atob(s.replace(/-/g, "+").replace(/_/g, "/"))));
426
+ var encodePass = (p) => b64url(JSON.stringify(p));
427
+ function decodePass(s) {
428
+ if (!s || s.length > 1e3 || !/^[A-Za-z0-9_-]+$/.test(s)) return null;
429
+ try {
430
+ const p = JSON.parse(unb64url(s));
431
+ if (p?.v !== 1 || typeof p.address !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(p.address)) return null;
432
+ if (!Number.isInteger(p.iat) || !Number.isInteger(p.exp) || typeof p.sig !== "string" || !/^0x[0-9a-fA-F]{130}$/.test(p.sig)) return null;
433
+ return { v: 1, address: p.address, iat: p.iat, exp: p.exp, sig: p.sig };
434
+ } catch {
435
+ return null;
436
+ }
437
+ }
438
+ async function makePass(signer, seconds = PASS_MAX_SECONDS, now = Math.floor(Date.now() / 1e3)) {
439
+ const iat = now;
440
+ const exp = now + Math.min(Math.max(60, seconds), PASS_MAX_SECONDS);
441
+ const sig = await signer.signMessage({ message: passMessage(signer.address, iat, exp) });
442
+ return { v: 1, address: signer.address, iat, exp, sig };
443
+ }
444
+
410
445
  // src/core.ts
411
446
  var NETS = CHAIN_KEYS;
412
447
  var isSwapNet = (v) => v === "robinhood" || v === "base";
@@ -442,6 +477,15 @@ async function checkPayment(e, rpc) {
442
477
  var DEFAULT_LIMITS = { perPayment: 0.1, perDay: 1, perSwap: 25 };
443
478
  var DEFAULT_TIMEOUT_MS = 6e4;
444
479
  var timedOut = (e) => e?.name === "TimeoutError" || e?.cause?.name === "TimeoutError";
480
+ async function holderInfo(address, baseUrl = "https://wafermap.xyz", timeoutMs = DEFAULT_TIMEOUT_MS) {
481
+ const host = new URL(baseUrl).host;
482
+ const r = await fetch(`${baseUrl.replace(/\/$/, "")}/api/holder?address=${encodeURIComponent(address)}`, { signal: AbortSignal.timeout(timeoutMs) }).catch((e) => {
483
+ throw timedOut(e) ? new WafermapError("timeout", `${host} did not answer within ${Math.round(timeoutMs / 1e3)} s.`) : new WafermapError("network_error", `${host}: ${e?.message ?? "request failed"}`);
484
+ });
485
+ const j = await r.json().catch(() => null);
486
+ if (!r.ok || !j) throw new WafermapError(j?.error?.code ?? "network_error", j?.error?.message ?? `${host} answered HTTP ${r.status}.`);
487
+ return j;
488
+ }
445
489
  async function listResources(baseUrl = "https://wafermap.xyz", timeoutMs = DEFAULT_TIMEOUT_MS) {
446
490
  const host = new URL(baseUrl).host;
447
491
  const gaveUp = () => new WafermapError("timeout", `${host} did not answer within ${Math.round(timeoutMs / 1e3)} s. Nothing was paid.`);
@@ -596,8 +640,19 @@ var Wafermap = class {
596
640
  async resources() {
597
641
  return listResources(this.baseUrl, this.timeoutMs);
598
642
  }
643
+ passCache = null;
644
+ /** A holder pass (shared/pass.ts) signed by this wallet, valid 24 h and reused until its last 10 minutes. It
645
+ * proves the wallet to Wafermap for what its $WAFERMAP unlocks (Pro free calls, x402 Tracker Pro). Signing
646
+ * a message moves no funds. */
647
+ async holderPass() {
648
+ const p = decodePass(this.passCache);
649
+ if (this.passCache && p && p.exp - 600 > Date.now() / 1e3) return this.passCache;
650
+ this.passCache = encodePass(await makePass({ address: this.account.address, signMessage: (a) => this.account.signMessage(a) }));
651
+ return this.passCache;
652
+ }
599
653
  async call(id, input = {}, o = {}) {
600
- const go = () => this.paidFetch("resource", id, `${this.baseUrl}/v1/${id}`, { method: "POST", headers: { "content-type": "application/json", "x-wafermap-payer": this.address }, body: JSON.stringify(input) }, o.network);
654
+ const pass = id.startsWith("m/") ? null : await this.holderPass();
655
+ const go = () => this.paidFetch("resource", id, `${this.baseUrl}/v1/${id}`, { method: "POST", headers: { "content-type": "application/json", "x-wafermap-payer": this.address, ...pass ? { [PASS_HEADER]: pass } : {} }, body: JSON.stringify(input) }, o.network);
601
656
  const settle = (r2, out2) => {
602
657
  if (!r2.paid || !r2.id) return;
603
658
  const status = r2.res.status === 402 ? "refused" : r2.res.ok ? "ok" : "failed";
@@ -711,6 +766,7 @@ export {
711
766
  DEFAULT_TIMEOUT_MS,
712
767
  KYBER_ROUTER,
713
768
  MAX_VALIDITY_SECONDS,
769
+ PASS_HEADER,
714
770
  PAY_CHAINS,
715
771
  SwapError,
716
772
  Wafermap,
@@ -718,10 +774,15 @@ export {
718
774
  X402Error,
719
775
  checkPayment,
720
776
  choose,
777
+ decodePass,
721
778
  decodeSwap,
779
+ encodePass,
722
780
  executeSwap,
781
+ holderInfo,
723
782
  listResources,
783
+ makePass,
724
784
  mergeLog,
785
+ passMessage,
725
786
  quoteSwap,
726
787
  readQuote,
727
788
  signPayment,
@@ -0,0 +1,21 @@
1
+ export declare const PASS_HEADER = "x-wafermap-pass";
2
+ export declare const PASS_MAX_SECONDS = 86400;
3
+ export type Pass = {
4
+ v: 1;
5
+ address: string;
6
+ iat: number;
7
+ exp: number;
8
+ sig: string;
9
+ };
10
+ /** The exact text the wallet signs. */
11
+ export declare function passMessage(address: string, iat: number, exp: number): string;
12
+ export declare const encodePass: (p: Pass) => string;
13
+ /** The pass's fields, or null when it is not a well-formed pass (the signature is not checked here). */
14
+ export declare function decodePass(s: string | undefined | null): Pass | null;
15
+ /** Signs a new pass with any signer that can personal_sign. Valid for `seconds` (at most a day). */
16
+ export declare function makePass(signer: {
17
+ address: string;
18
+ signMessage: (a: {
19
+ message: string;
20
+ }) => Promise<string>;
21
+ }, seconds?: number, now?: number): Promise<Pass>;
@@ -87,6 +87,8 @@ export declare function mergeLog(entries: SpendEntry[]): SpendEntry[];
87
87
  export declare function checkPayment(e: Pick<SpendEntry, "network" | "payer" | "nonce" | "validBefore">, rpc?: string): Promise<"used" | "unused" | "pending" | "unknown" | "error">;
88
88
  export declare const DEFAULT_LIMITS: Limits;
89
89
  export declare const DEFAULT_TIMEOUT_MS = 60000;
90
+ /** What a wallet's $WAFERMAP unlocks (holder price, Pro free calls left today), from /api/holder. Needs no key. */
91
+ export declare function holderInfo(address: string, baseUrl?: string, timeoutMs?: number): Promise<any>;
90
92
  /** Wafermap's resource catalog. Needs no wallet; gives up after `timeoutMs` like every other request. */
91
93
  export declare function listResources(baseUrl?: string, timeoutMs?: number): Promise<any[]>;
92
94
  export declare class Wafermap {
@@ -126,6 +128,11 @@ export declare class Wafermap {
126
128
  private acquire;
127
129
  private paidFetch;
128
130
  resources(): Promise<any[]>;
131
+ private passCache;
132
+ /** A holder pass (shared/pass.ts) signed by this wallet, valid 24 h and reused until its last 10 minutes. It
133
+ * proves the wallet to Wafermap for what its $WAFERMAP unlocks (Pro free calls, x402 Tracker Pro). Signing
134
+ * a message moves no funds. */
135
+ holderPass(): Promise<string>;
129
136
  call(id: string, input?: Record<string, unknown>, o?: {
130
137
  network?: Net;
131
138
  }): Promise<{
@@ -139,6 +146,11 @@ export declare class Wafermap {
139
146
  tx: string;
140
147
  ms: number;
141
148
  } | null;
149
+ free?: {
150
+ wallet: string;
151
+ left: number;
152
+ perDay: number;
153
+ };
142
154
  }>;
143
155
  discover(query: string, limit?: number): Promise<{
144
156
  url: string;
@@ -1,4 +1,5 @@
1
- export { Wafermap, WafermapError, DEFAULT_LIMITS, DEFAULT_TIMEOUT_MS, checkPayment, listResources, mergeLog } from "./core.js";
1
+ export { Wafermap, WafermapError, DEFAULT_LIMITS, DEFAULT_TIMEOUT_MS, checkPayment, holderInfo, listResources, mergeLog } from "./core.js";
2
+ export { PASS_HEADER, passMessage, encodePass, decodePass, makePass } from "../shared/pass";
2
3
  export type { Approval, Limits, Net, PaymentStatus, SpendEntry, SwapQuote, Token, WafermapOptions } from "./core.js";
3
4
  export { x402fetch, readQuote, choose, signPayment, PAY_CHAINS, MAX_VALIDITY_SECONDS, X402Error } from "../shared/x402client";
4
5
  export { quoteSwap, executeSwap, decodeSwap, KYBER_ROUTER, SwapError } from "../shared/swap";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wafermapxyz/cli",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Wafermap for agents: an encrypted local wallet that pays x402 resources, discovers and pays third-party x402 services (USDG on Robinhood Chain; USDC on Solana, Base, Arbitrum, Polygon), and swaps on Robinhood Chain and Base. CLI, SDK and MCP server.",
5
5
  "type": "module",
6
6
  "bin": {