@xona-labs/xpay 0.2.24 → 0.2.25

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 (114) hide show
  1. package/CHANGELOG.md +101 -78
  2. package/README.md +71 -69
  3. package/SKILL.md +22 -22
  4. package/dist/agenc/api.d.ts +8 -8
  5. package/dist/agenc/api.js +11 -11
  6. package/dist/agenc/hire.d.ts +4 -4
  7. package/dist/agenc/hire.js +17 -17
  8. package/dist/agenc/price.d.ts +1 -1
  9. package/dist/agenc/price.js +1 -1
  10. package/dist/biometric/index.d.ts +3 -3
  11. package/dist/biometric/index.js +6 -6
  12. package/dist/cli/accounts.d.ts +1 -1
  13. package/dist/cli/accounts.js +1 -1
  14. package/dist/cli/agenc.d.ts +2 -2
  15. package/dist/cli/agenc.js +4 -4
  16. package/dist/cli/balance.d.ts +1 -1
  17. package/dist/cli/balance.js +4 -4
  18. package/dist/cli/bento.d.ts +3 -3
  19. package/dist/cli/bento.js +8 -8
  20. package/dist/cli/bento.js.map +1 -1
  21. package/dist/cli/biometric.d.ts +1 -1
  22. package/dist/cli/biometric.js +8 -8
  23. package/dist/cli/common.js +6 -6
  24. package/dist/cli/common.js.map +1 -1
  25. package/dist/cli/discover.d.ts +2 -2
  26. package/dist/cli/discover.js +4 -4
  27. package/dist/cli/guardrail.d.ts +1 -1
  28. package/dist/cli/guardrail.js +3 -3
  29. package/dist/cli/index.d.ts +2 -2
  30. package/dist/cli/index.js +12 -12
  31. package/dist/cli/init.d.ts +1 -1
  32. package/dist/cli/init.js +2 -2
  33. package/dist/cli/magicblock.d.ts +1 -1
  34. package/dist/cli/magicblock.js +4 -4
  35. package/dist/cli/mcp-server.d.ts +2 -2
  36. package/dist/cli/mcp-server.js +21 -21
  37. package/dist/cli/pay.d.ts +1 -1
  38. package/dist/cli/pay.js +1 -1
  39. package/dist/cli/report.d.ts +2 -2
  40. package/dist/cli/report.js +4 -4
  41. package/dist/cli/report.js.map +1 -1
  42. package/dist/cli/sana.d.ts +1 -1
  43. package/dist/cli/sana.js +3 -3
  44. package/dist/cli/shop.d.ts +1 -1
  45. package/dist/cli/shop.js +1 -1
  46. package/dist/cli/swap.d.ts +1 -1
  47. package/dist/cli/swap.js +3 -3
  48. package/dist/cli/token.d.ts +2 -2
  49. package/dist/cli/token.js +2 -2
  50. package/dist/cli/trade.d.ts +2 -2
  51. package/dist/cli/trade.js +8 -8
  52. package/dist/cli/trade.js.map +1 -1
  53. package/dist/cli/transfer.d.ts +1 -1
  54. package/dist/cli/transfer.js +1 -1
  55. package/dist/cli/x.d.ts +1 -1
  56. package/dist/cli/x.js +1 -1
  57. package/dist/cli/zauth.d.ts +1 -1
  58. package/dist/cli/zauth.js +5 -5
  59. package/dist/discover/cache.js +1 -1
  60. package/dist/discover/index.d.ts +2 -2
  61. package/dist/discover/index.js +6 -6
  62. package/dist/discover/orbitx402.d.ts +2 -2
  63. package/dist/discover/orbitx402.js +1 -1
  64. package/dist/discover/payai.js +1 -1
  65. package/dist/do/index.d.ts +2 -2
  66. package/dist/do/index.js +1 -1
  67. package/dist/guardrail/index.d.ts +4 -4
  68. package/dist/guardrail/index.js +14 -14
  69. package/dist/guardrail/index.js.map +1 -1
  70. package/dist/index.d.ts +7 -7
  71. package/dist/index.js +2 -2
  72. package/dist/magicblock/client.d.ts +2 -2
  73. package/dist/magicblock/client.js +4 -4
  74. package/dist/profile/index.d.ts +3 -3
  75. package/dist/profile/index.js +3 -3
  76. package/dist/profile/storage.d.ts +1 -1
  77. package/dist/profile/storage.js +4 -4
  78. package/dist/profile/types.d.ts +6 -6
  79. package/dist/profile/types.js +1 -1
  80. package/dist/report/index.d.ts +1 -1
  81. package/dist/report/index.js +2 -2
  82. package/dist/sana/tools.js +8 -8
  83. package/dist/signers/raw-evm.d.ts +1 -1
  84. package/dist/signers/raw-evm.js +5 -5
  85. package/dist/signers/raw-solana.d.ts +1 -1
  86. package/dist/signers/raw-solana.js +4 -4
  87. package/dist/swap/index.d.ts +6 -6
  88. package/dist/swap/index.js +12 -12
  89. package/dist/token/index.d.ts +8 -8
  90. package/dist/token/index.js +14 -14
  91. package/dist/token/rwa.d.ts +3 -3
  92. package/dist/token/rwa.js +3 -3
  93. package/dist/tools/index.d.ts +1 -1
  94. package/dist/tools/index.js +31 -31
  95. package/dist/trading/discovery.d.ts +6 -6
  96. package/dist/trading/discovery.js +7 -7
  97. package/dist/trading/index.d.ts +6 -6
  98. package/dist/trading/index.js +13 -13
  99. package/dist/transfer/index.d.ts +4 -4
  100. package/dist/transfer/index.js +8 -8
  101. package/dist/types.d.ts +7 -7
  102. package/dist/use/index.d.ts +5 -5
  103. package/dist/use/index.js +20 -20
  104. package/dist/wallet/index.d.ts +2 -2
  105. package/dist/wallet/index.js +3 -3
  106. package/dist/x402/evm-payment.d.ts +4 -4
  107. package/dist/x402/evm-payment.js +6 -6
  108. package/dist/x402/extract.d.ts +1 -1
  109. package/dist/x402/extract.js +1 -1
  110. package/dist/x402/svm-payment.d.ts +2 -2
  111. package/dist/x402/svm-payment.js +2 -2
  112. package/dist/zauth/index.d.ts +4 -4
  113. package/dist/zauth/index.js +5 -5
  114. package/package.json +4 -3
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Solana token discovery Jupiter Token API v2.
2
+ * Solana token discovery - Jupiter Token API v2.
3
3
  *
4
4
  * Keyless read-only search by ticker, name, or mint address. Returns live
5
- * market data (price, mcap, liquidity) plus Jupiter's verification flag
5
+ * market data (price, mcap, liquidity) plus Jupiter's verification flag -
6
6
  * the main scam signal agents must check before swapping (anyone can mint a
7
7
  * token reusing a real project's ticker).
8
8
  */
@@ -10,23 +10,23 @@ import { Connection, PublicKey } from "@solana/web3.js";
10
10
  import { getMint } from "@solana/spl-token";
11
11
  import { SOLANA_TOKENS } from "../transfer/index.js";
12
12
  const DEFAULT_ENDPOINT = "https://api.jup.ag";
13
- /** Wrapped-SOL mint Jupiter's sentinel for native SOL (wraps/unwraps automatically). */
13
+ /** Wrapped-SOL mint - Jupiter's sentinel for native SOL (wraps/unwraps automatically). */
14
14
  export const NATIVE_SOL_MINT = "So11111111111111111111111111111111111111112";
15
- /** Thrown when a bare ticker matches several plausible tokens retry with the exact mint. */
15
+ /** Thrown when a bare ticker matches several plausible tokens - retry with the exact mint. */
16
16
  export class AmbiguousTokenError extends Error {
17
17
  candidates;
18
18
  constructor(input, candidates) {
19
19
  const list = candidates
20
20
  .map((c) => ` ${c.symbol} (${c.name}) mint ${c.mint}${c.verified ? " [verified]" : " [UNVERIFIED]"} liquidity $${Math.round(c.liquidity ?? 0).toLocaleString()}`)
21
21
  .join("\n");
22
- super(`Token "${input}" is ambiguous pass the exact mint address of the one you mean:\n${list}`);
22
+ super(`Token "${input}" is ambiguous - pass the exact mint address of the one you mean:\n${list}`);
23
23
  this.name = "AmbiguousTokenError";
24
24
  this.candidates = candidates;
25
25
  }
26
26
  }
27
27
  /**
28
28
  * Search tokens by ticker, name, or mint. Ranked verified-first, then by
29
- * liquidity. Read-only no wallet, no signing.
29
+ * liquidity. Read-only - no wallet, no signing.
30
30
  */
31
31
  export async function findTokens(query, opts = {}) {
32
32
  const raw = await searchJupiter(query, opts);
@@ -46,7 +46,7 @@ export async function findTokens(query, opts = {}) {
46
46
  }
47
47
  /**
48
48
  * Deterministic single-token resolution for trading. Accepts a symbol or a
49
- * mint address; never silently picks between plausible candidates throws
49
+ * mint address; never silently picks between plausible candidates - throws
50
50
  * {@link AmbiguousTokenError} instead so the caller can pass the exact mint.
51
51
  */
52
52
  export async function resolveTradeToken(input, opts = {}) {
@@ -57,7 +57,7 @@ export async function resolveTradeToken(input, opts = {}) {
57
57
  return { ...(info ?? fallbackToken(NATIVE_SOL_MINT, 9)), symbol: "SOL", verified: true };
58
58
  }
59
59
  // Well-known symbols pin to a canonical mint (avoids the ~20 lookalike
60
- // "BONK"s Jupiter returns) then still fetch live data by that mint.
60
+ // "BONK"s Jupiter returns) - then still fetch live data by that mint.
61
61
  const pinned = SOLANA_TOKENS[key] ?? Object.values(SOLANA_TOKENS).find((t) => t.symbol.toUpperCase() === key);
62
62
  if (pinned) {
63
63
  const [info] = await searchJupiter(pinned.mint, opts);
@@ -87,16 +87,16 @@ export async function resolveTradeToken(input, opts = {}) {
87
87
  throw new AmbiguousTokenError(input, sorted.slice(0, 5));
88
88
  }
89
89
  if (symbolMatches.length > 0) {
90
- // Only unverified candidates never auto-trade those by ticker.
90
+ // Only unverified candidates - never auto-trade those by ticker.
91
91
  throw new AmbiguousTokenError(input, symbolMatches.sort((a, b) => (b.liquidity ?? 0) - (a.liquidity ?? 0)).slice(0, 5));
92
92
  }
93
- throw new Error(`Unknown token "${input}" no exact ticker match on Jupiter. ` +
93
+ throw new Error(`Unknown token "${input}" - no exact ticker match on Jupiter. ` +
94
94
  `Try \`xpay token find ${input}\` to search, or pass the mint address directly.`);
95
95
  }
96
96
  /**
97
97
  * Label and price wallet balances via one batched Jupiter lookup (comma-
98
98
  * separated mints, max 100). Unknown mints get their real symbol/name; every
99
- * priceable token gets `usdPrice`/`usdValue`. Never throws on any Jupiter
99
+ * priceable token gets `usdPrice`/`usdValue`. Never throws - on any Jupiter
100
100
  * failure the input balances are returned unchanged (a balance display must
101
101
  * not break because a market-data API hiccuped).
102
102
  */
@@ -186,7 +186,7 @@ export async function jupiterFetch(url, apiKey, init) {
186
186
  reason = body?.error ?? body?.errorMessage ?? "";
187
187
  }
188
188
  catch { /* no body */ }
189
- throw new Error(`Jupiter API ${res.status} ${res.statusText}${reason ? ` ${reason}` : ""}` +
189
+ throw new Error(`Jupiter API ${res.status} ${res.statusText}${reason ? ` - ${reason}` : ""}` +
190
190
  (res.status === 429 ? " (rate-limited; set JUPITER_API_KEY for higher limits)" : ""));
191
191
  }
192
192
  return res.json();
@@ -198,7 +198,7 @@ function numOrUndef(v) {
198
198
  function fallbackToken(mint, decimals) {
199
199
  return { mint, symbol: mint.slice(0, 6) + "…", name: "", decimals, verified: false };
200
200
  }
201
- /** Last resort for mints Jupiter has never indexed decimals from chain, no price. */
201
+ /** Last resort for mints Jupiter has never indexed - decimals from chain, no price. */
202
202
  async function onChainToken(mint) {
203
203
  const rpc = process.env.XPAY_SOLANA_RPC ?? "https://solana-mainnet.g.alchemy.com/v2/Ug5mqBVIbSHoa8ZHgTUSJ";
204
204
  try {
@@ -207,7 +207,7 @@ async function onChainToken(mint) {
207
207
  return fallbackToken(mint, info.decimals);
208
208
  }
209
209
  catch {
210
- throw new Error(`Token mint ${mint} not found on Jupiter or on-chain check the address.`);
210
+ throw new Error(`Token mint ${mint} not found on Jupiter or on-chain - check the address.`);
211
211
  }
212
212
  }
213
213
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RWA (real-world asset) discovery on Solana Jupiter Token API v2.
2
+ * RWA (real-world asset) discovery on Solana - Jupiter Token API v2.
3
3
  *
4
4
  * "RWA" covers every tokenized off-chain asset: equities, ETFs, treasuries,
5
5
  * commodities, private credit. What is actually TRADABLE on Solana DEXes
@@ -12,7 +12,7 @@
12
12
  * so it is pinned here explicitly).
13
13
  *
14
14
  * Permissioned funds (BlackRock BUIDL, Ondo OUSG) exist on Solana but are
15
- * KYC-gated: unverified on Jupiter, zero DEX liquidity, not swappable they
15
+ * KYC-gated: unverified on Jupiter, zero DEX liquidity, not swappable - they
16
16
  * are deliberately excluded.
17
17
  *
18
18
  * Jupiter's tag ENDPOINT rejects `rwa`/`stocks`/`xstocks` as queries (only
@@ -34,7 +34,7 @@ export interface RwaFindOptions extends TokenApiOptions {
34
34
  category?: RwaCategory;
35
35
  /** Max results. Default 20. */
36
36
  limit?: number;
37
- /** Include unverified tokens (excluded by default same scam caveat as any ticker). */
37
+ /** Include unverified tokens (excluded by default - same scam caveat as any ticker). */
38
38
  includeUnverified?: boolean;
39
39
  }
40
40
  /**
package/dist/token/rwa.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * RWA (real-world asset) discovery on Solana Jupiter Token API v2.
2
+ * RWA (real-world asset) discovery on Solana - Jupiter Token API v2.
3
3
  *
4
4
  * "RWA" covers every tokenized off-chain asset: equities, ETFs, treasuries,
5
5
  * commodities, private credit. What is actually TRADABLE on Solana DEXes
@@ -12,7 +12,7 @@
12
12
  * so it is pinned here explicitly).
13
13
  *
14
14
  * Permissioned funds (BlackRock BUIDL, Ondo OUSG) exist on Solana but are
15
- * KYC-gated: unverified on Jupiter, zero DEX liquidity, not swappable they
15
+ * KYC-gated: unverified on Jupiter, zero DEX liquidity, not swappable - they
16
16
  * are deliberately excluded.
17
17
  *
18
18
  * Jupiter's tag ENDPOINT rejects `rwa`/`stocks`/`xstocks` as queries (only
@@ -28,7 +28,7 @@ import { searchTokens } from "./index.js";
28
28
  * its top-100 between runs.
29
29
  */
30
30
  const SWEEP_QUERIES = ["xstock", "Ondo Tokenized", "tokenized", "treasury", "remora"];
31
- /** Ondo USDY treasury-backed yieldcoin, tagged yield/yb on Jupiter rather than rwa. */
31
+ /** Ondo USDY - treasury-backed yieldcoin, tagged yield/yb on Jupiter rather than rwa. */
32
32
  const USDY_MINT = "A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6";
33
33
  const CACHE_TTL_MS = 5 * 60_000;
34
34
  let sweepCache;
@@ -21,7 +21,7 @@ export interface ClaudeToolDef {
21
21
  input_schema: Record<string, unknown>;
22
22
  }
23
23
  export interface ToolOptions {
24
- /** Sana API key when present, registers sana_* tools alongside xpay_* tools. */
24
+ /** Sana API key - when present, registers sana_* tools alongside xpay_* tools. */
25
25
  sanaApiKey?: string;
26
26
  }
27
27
  /** Anthropic Claude tool definitions. */
@@ -27,7 +27,7 @@ export function forClaude(xpay, opts = {}) {
27
27
  name: "xpay_discover",
28
28
  description: "Find paid HTTP services across the agentic-commerce catalog (PayAI + others). " +
29
29
  "Returns ranked candidates with price, network, and payment recipient. " +
30
- "Results may include AgenC marketplace agent listings (metadata.source === 'agenc') " +
30
+ "Results may include AgenC marketplace agent listings (metadata.source === 'agenc') - " +
31
31
  "those are priced in SOL lamports and execute as on-chain escrow hires, not HTTP calls. " +
32
32
  "When the user asks specifically about the AgenC marketplace, pass sources: ['agenc'] " +
33
33
  "(optionally with no query) to list ALL its listings instead of the few slots it gets " +
@@ -49,12 +49,12 @@ export function forClaude(xpay, opts = {}) {
49
49
  {
50
50
  name: "xpay_use",
51
51
  description: "Call a specific resource from the catalog. Handles x402 payment automatically. " +
52
- "Prefer passing the full `resource` object returned by xpay_discover it includes " +
52
+ "Prefer passing the full `resource` object returned by xpay_discover - it includes " +
53
53
  "pre-fetched payment requirements so payment goes through without a probe round-trip. " +
54
54
  "Fall back to `resourceUrl` only when you have a URL but no catalog entry. " +
55
55
  "If the resource is an AgenC marketplace listing it executes as a Solana escrow hire " +
56
56
  "instead: SOL is escrowed on-chain and the result is a hire receipt (task PDA + tx " +
57
- "signature), NOT an HTTP response the provider works asynchronously; poll progress " +
57
+ "signature), NOT an HTTP response - the provider works asynchronously; poll progress " +
58
58
  "with xpay_agenc_status.",
59
59
  input_schema: {
60
60
  type: "object",
@@ -119,7 +119,7 @@ export function forClaude(xpay, opts = {}) {
119
119
  },
120
120
  {
121
121
  name: "xpay_report",
122
- description: "Comprehensive USDC activity report for the wallet totals, net flow, daily timeline, top counterparties, and biggest transactions. " +
122
+ description: "Comprehensive USDC activity report for the wallet - totals, net flow, daily timeline, top counterparties, and biggest transactions. " +
123
123
  "Powered by OrbitX402 (on-chain data fetched server-side, no RPC exposed). " +
124
124
  "Use this instead of history for a full picture of spending and income.",
125
125
  input_schema: {
@@ -144,10 +144,10 @@ export function forClaude(xpay, opts = {}) {
144
144
  },
145
145
  {
146
146
  name: "xpay_token_find",
147
- description: "Find Solana tokens by ticker, name, or mint address (Jupiter registry). Read-only no " +
147
+ description: "Find Solana tokens by ticker, name, or mint address (Jupiter registry). Read-only - no " +
148
148
  "wallet, no spending. Returns mint, price, market cap, liquidity, and a `verified` flag. " +
149
149
  "ALWAYS check `verified` before suggesting a swap: unverified tokens can be scams reusing a " +
150
- "real token's ticker. This tool alone answers price/info questions only proceed to a swap " +
150
+ "real token's ticker. This tool alone answers price/info questions - only proceed to a swap " +
151
151
  "if the user explicitly asked to trade, and then use the xpay_swap tool with the chosen mint " +
152
152
  "(do NOT write code or call DEX APIs yourself).",
153
153
  input_schema: {
@@ -161,17 +161,17 @@ export function forClaude(xpay, opts = {}) {
161
161
  },
162
162
  {
163
163
  name: "xpay_swap",
164
- description: "THE ONLY way to swap tokens a single tool call that quotes, signs, and executes inside the " +
164
+ description: "THE ONLY way to swap tokens - a single tool call that quotes, signs, and executes inside the " +
165
165
  "user's own xpay wallet via Jupiter (Solana only). NEVER write code or scripts (Python/JS/curl) " +
166
166
  "to swap, and never call Jupiter or DEX APIs directly: custom code bypasses the user's guardrail " +
167
167
  "caps and token-verification safety, and has no access to the wallet key anyway. When the user " +
168
- "actually wants to swap, this one tool call does everything (quote + sign + execute) but " +
168
+ "actually wants to swap, this one tool call does everything (quote + sign + execute) - but " +
169
169
  "xpay_token_find alone answers informational questions; do NOT follow it with a swap unless the " +
170
170
  "user asked to trade. Swaps are irreversible and guardrail caps are enforced before signing. Before calling, show the " +
171
171
  "user: the input amount + USD value, the expected output amount, and the output token's mint + " +
172
- "verification status and get their explicit approval. Never swap unprompted, and never swap " +
172
+ "verification status - and get their explicit approval. Never swap unprompted, and never swap " +
173
173
  "into an unverified token without the user confirming the exact mint. Ambiguous tickers return " +
174
- "an error listing candidate mints pass the exact mint to disambiguate.",
174
+ "an error listing candidate mints - pass the exact mint to disambiguate.",
175
175
  input_schema: {
176
176
  type: "object",
177
177
  properties: {
@@ -189,7 +189,7 @@ export function forClaude(xpay, opts = {}) {
189
189
  "fun.noxa.fi memecoin scene) right now, with price, market cap, 24h volume, and the token's " +
190
190
  "contract address. FREE, read-only, no wallet. Use this to answer 'what's hot on Robinhood " +
191
191
  "Chain' and to get the exact contract address to pass to xpay_trade. Pass newOnly:true for " +
192
- "the freshest launches (higher risk). This is Robinhood *Chain* on-chain data unrelated to " +
192
+ "the freshest launches (higher risk). This is Robinhood *Chain* on-chain data - unrelated to " +
193
193
  "the Robinhood brokerage app or stock trading.",
194
194
  input_schema: {
195
195
  type: "object",
@@ -201,7 +201,7 @@ export function forClaude(xpay, opts = {}) {
201
201
  },
202
202
  {
203
203
  name: "xpay_trade_quote",
204
- description: "Quote a Robinhood Chain trade WITHOUT executing no signing, no funds moved, no guardrail. " +
204
+ description: "Quote a Robinhood Chain trade WITHOUT executing - no signing, no funds moved, no guardrail. " +
205
205
  "Buy a token with native ETH or sell it back to ETH, routed through Uniswap V3 (NOXA Fun " +
206
206
  "pools). Returns expected output, min output after slippage, pool fee, USD estimate, and " +
207
207
  "whether the token is a verified NOXA launch. Use this to preview a trade before calling " +
@@ -220,16 +220,16 @@ export function forClaude(xpay, opts = {}) {
220
220
  },
221
221
  {
222
222
  name: "xpay_trade",
223
- description: "Trade tokens on Robinhood Chain (Arbitrum L2) via Uniswap V3 quotes, signs, and executes " +
223
+ description: "Trade tokens on Robinhood Chain (Arbitrum L2) via Uniswap V3 - quotes, signs, and executes " +
224
224
  "in ONE call from the user's own xpay wallet. Buy a memecoin with native ETH, or sell it back " +
225
225
  "to ETH (v1 supports ETH↔token only). This is distinct from xpay_swap, which is Solana/Jupiter. " +
226
- "NEVER write code or call DEX/router contracts yourself custom code bypasses the guardrail and " +
226
+ "NEVER write code or call DEX/router contracts yourself - custom code bypasses the guardrail and " +
227
227
  "has no wallet key. Trades are IRREVERSIBLE; guardrail caps are enforced before signing. Before " +
228
228
  "calling: show the user the input amount + USD value, expected output, the token's contract " +
229
229
  "address, and whether it's a verified NOXA launch (unverified tokens can be scams reusing a " +
230
- "ticker) and get explicit approval. Prefer passing the exact contract address from " +
230
+ "ticker) - and get explicit approval. Prefer passing the exact contract address from " +
231
231
  "xpay_trending_tokens over a symbol (memecoin tickers aren't unique). Fund the wallet with ETH " +
232
- "on Robinhood Chain first (bridge via Across or Uniswap) the wallet pays its own gas here.",
232
+ "on Robinhood Chain first (bridge via Across or Uniswap) - the wallet pays its own gas here.",
233
233
  input_schema: {
234
234
  type: "object",
235
235
  properties: {
@@ -243,8 +243,8 @@ export function forClaude(xpay, opts = {}) {
243
243
  },
244
244
  {
245
245
  name: "xpay_x_user",
246
- description: "Realtime X (Twitter) profile lookup followers, bio, verification status. This is a PAID " +
247
- "call (~$0.01 USDC from the wallet via x402, at cost no markup); guardrail caps apply. " +
246
+ description: "Realtime X (Twitter) profile lookup - followers, bio, verification status. This is a PAID " +
247
+ "call (~$0.01 USDC from the wallet via x402, at cost - no markup); guardrail caps apply. " +
248
248
  "Great for due diligence on a token's or project's X account before a swap. Don't spam it: " +
249
249
  "results barely change minute to minute, so one call per account per conversation is enough.",
250
250
  input_schema: {
@@ -258,7 +258,7 @@ export function forClaude(xpay, opts = {}) {
258
258
  {
259
259
  name: "xpay_x_posts",
260
260
  description: "Recent posts from an X (Twitter) account (up to 10, excludes retweets/replies) with " +
261
- "engagement metrics. PAID call (~$0.06 USDC from the wallet via x402, at cost no markup); " +
261
+ "engagement metrics. PAID call (~$0.06 USDC from the wallet via x402, at cost - no markup); " +
262
262
  "guardrail caps apply. Use for checking what a project/account is actually saying right now " +
263
263
  "(e.g. before swapping into their token). One call per account per conversation is enough.",
264
264
  input_schema: {
@@ -272,11 +272,11 @@ export function forClaude(xpay, opts = {}) {
272
272
  },
273
273
  {
274
274
  name: "xpay_zauth_reposcan",
275
- description: "Repository security scan via zauth (partner) scans a git repo for code provenance and " +
275
+ description: "Repository security scan via zauth (partner) - scans a git repo for code provenance and " +
276
276
  "vulnerabilities. PAID call (~$0.05 USDC from the wallet via x402; guardrail caps apply). " +
277
277
  "Scans can take a while: if the response still says status \"scanning\", check later with " +
278
278
  "xpay_zauth_scan_status using the returned sessionToken (the long JWT string, NOT the short " +
279
- "scanId the token is valid ~1 hour). Do NOT call this tool again for the same repo, that " +
279
+ "scanId - the token is valid ~1 hour). Do NOT call this tool again for the same repo, that " +
280
280
  "pays for a second scan. Results are informational: report them to the user, never " +
281
281
  "auto-remediate or trigger further payments based on findings.",
282
282
  input_schema: {
@@ -290,15 +290,15 @@ export function forClaude(xpay, opts = {}) {
290
290
  {
291
291
  name: "xpay_zauth_scan_status",
292
292
  description: "Check a running zauth repo scan by sessionToken (returned by xpay_zauth_reposcan). " +
293
- "FREE, read-only, no wallet always use this to follow up on a pending scan instead of " +
293
+ "FREE, read-only, no wallet - always use this to follow up on a pending scan instead of " +
294
294
  "re-calling xpay_zauth_reposcan, which would pay again. Pass the sessionToken (the long " +
295
- "JWT starting with \"eyJ\"), NOT the scanId the scanId is rejected with a 401.",
295
+ "JWT starting with \"eyJ\"), NOT the scanId - the scanId is rejected with a 401.",
296
296
  input_schema: {
297
297
  type: "object",
298
298
  properties: {
299
299
  sessionToken: {
300
300
  type: "string",
301
- description: "sessionToken from a pending xpay_zauth_reposcan result the long JWT string " +
301
+ description: "sessionToken from a pending xpay_zauth_reposcan result - the long JWT string " +
302
302
  "(starts with \"eyJ\"), not the scanId. Valid ~1 hour after the scan started.",
303
303
  },
304
304
  },
@@ -497,7 +497,7 @@ export function forClaude(xpay, opts = {}) {
497
497
  const sources = input.sources;
498
498
  return xpay.discover({
499
499
  query: input.query,
500
- // Browsing a single catalog implies "show me what's there" don't
500
+ // Browsing a single catalog implies "show me what's there" - don't
501
501
  // truncate to the mixed-results default.
502
502
  limit: input.limit ?? (sources?.length === 1 ? 50 : 5),
503
503
  networks: input.network ? [input.network] : undefined,
@@ -505,7 +505,7 @@ export function forClaude(xpay, opts = {}) {
505
505
  });
506
506
  },
507
507
  xpay_use: async (input) => {
508
- // Prefer the full resource object from xpay_discover it carries
508
+ // Prefer the full resource object from xpay_discover - it carries
509
509
  // pre-fetched accepts[] so we take the catalog path (no probe round-trip).
510
510
  if (input.resource && typeof input.resource === "object") {
511
511
  const parsed = ResourceSchema.safeParse(input.resource);
@@ -513,7 +513,7 @@ export function forClaude(xpay, opts = {}) {
513
513
  return xpay.use(parsed.data, { body: input.body });
514
514
  }
515
515
  }
516
- // Fallback: only a URL was provided probe the resource for a 402 challenge.
516
+ // Fallback: only a URL was provided - probe the resource for a 402 challenge.
517
517
  const url = input.resourceUrl;
518
518
  if (!url)
519
519
  throw new Error("xpay_use: provide either `resource` (full object from xpay_discover) or `resourceUrl`");
@@ -544,13 +544,13 @@ export function forClaude(xpay, opts = {}) {
544
544
  continue;
545
545
  const signer = xpay.wallet.signer(n);
546
546
  if (typeof signer.tokenBalances === "function") {
547
- // Full token breakdown same path as the CLI. Solana balances are
547
+ // Full token breakdown - same path as the CLI. Solana balances are
548
548
  // enriched via Jupiter: unknown mints get real symbols/names, and
549
549
  // priceable tokens carry usdPrice/usdValue.
550
550
  const raw = await signer.tokenBalances().catch(() => []);
551
551
  let tokens = n === "solana" ? await enrichTokenBalances(raw) : raw;
552
552
  // Robinhood Chain: the signer only knows a hardcoded token list, so
553
- // pull the wallet's full ERC-20 holdings from the chain explorer
553
+ // pull the wallet's full ERC-20 holdings from the chain explorer -
554
554
  // this is how memecoins bought via xpay_trade show up. Native ETH
555
555
  // still comes from the signer.
556
556
  if (n === "robinhood") {
@@ -635,7 +635,7 @@ export function forClaude(xpay, opts = {}) {
635
635
  });
636
636
  if (!isScanPending(result.data))
637
637
  return { ...result, data: compactScanReport(result.data) };
638
- // Paid + scan kicked off poll the free status endpoint for a while.
638
+ // Paid + scan kicked off - poll the free status endpoint for a while.
639
639
  // Poll responses don't echo the sessionToken, so keep the kickoff's
640
640
  // copy and re-attach it if the scan outlives our window.
641
641
  const sessionToken = result.data.sessionToken;
@@ -646,7 +646,7 @@ export function forClaude(xpay, opts = {}) {
646
646
  data: {
647
647
  ...data,
648
648
  sessionToken,
649
- note: "Scan still running check later with xpay_zauth_scan_status, passing this " +
649
+ note: "Scan still running - check later with xpay_zauth_scan_status, passing this " +
650
650
  "sessionToken (the long JWT, NOT the scanId). Do not re-run xpay_zauth_reposcan " +
651
651
  "for this repo; that pays again.",
652
652
  },
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Robinhood Chain token discovery GeckoTerminal public API.
2
+ * Robinhood Chain token discovery - GeckoTerminal public API.
3
3
  *
4
4
  * GeckoTerminal indexes Robinhood Chain under the network id "robinhood"
5
5
  * (keyless, ~30 req/min). Used for the trending/new token tools and for the
6
- * USD pricing attached to trade quotes. Discovery is read-only market data
6
+ * USD pricing attached to trade quotes. Discovery is read-only market data -
7
7
  * the trade path itself never depends on it.
8
8
  */
9
9
  export interface DiscoveredToken {
@@ -18,7 +18,7 @@ export interface DiscoveredToken {
18
18
  priceChange24hPct?: number;
19
19
  /** Liquidity pool: 20-byte address (Uniswap v3) or 32-byte id (v4). */
20
20
  pool: string;
21
- /** True for v4 pool ids xpay_trade only routes v3 pools today. */
21
+ /** True for v4 pool ids - xpay_trade only routes v3 pools today. */
22
22
  poolIsV4: boolean;
23
23
  dex?: string;
24
24
  poolCreatedAt?: string;
@@ -27,7 +27,7 @@ export interface DiscoveredToken {
27
27
  export declare function trendingTokens(opts?: {
28
28
  limit?: number;
29
29
  }): Promise<DiscoveredToken[]>;
30
- /** Tokens from the most recently created pools (fresh launches high risk). */
30
+ /** Tokens from the most recently created pools (fresh launches - high risk). */
31
31
  export declare function newTokens(opts?: {
32
32
  limit?: number;
33
33
  }): Promise<DiscoveredToken[]>;
@@ -44,14 +44,14 @@ export interface TokenHolding {
44
44
  /**
45
45
  * All ERC-20 balances a wallet holds on Robinhood Chain, via the chain's
46
46
  * Blockscout explorer API (keyless). This is what surfaces memecoins bought
47
- * through `xpay trade` the on-chain signer only knows a hardcoded token list.
47
+ * through `xpay trade` - the on-chain signer only knows a hardcoded token list.
48
48
  * Best-effort: returns [] if the explorer is unreachable.
49
49
  */
50
50
  export declare function robinhoodHoldings(address: string): Promise<TokenHolding[]>;
51
51
  /**
52
52
  * Resolve a token symbol to its contract address via trending + new pools.
53
53
  * Throws when the symbol is unknown or matches several distinct contracts
54
- * (memecoin symbols are not unique pass the address instead).
54
+ * (memecoin symbols are not unique - pass the address instead).
55
55
  */
56
56
  export declare function resolveTokenBySymbol(symbol: string): Promise<DiscoveredToken>;
57
57
  //# sourceMappingURL=discovery.d.ts.map
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Robinhood Chain token discovery GeckoTerminal public API.
2
+ * Robinhood Chain token discovery - GeckoTerminal public API.
3
3
  *
4
4
  * GeckoTerminal indexes Robinhood Chain under the network id "robinhood"
5
5
  * (keyless, ~30 req/min). Used for the trending/new token tools and for the
6
- * USD pricing attached to trade quotes. Discovery is read-only market data
6
+ * USD pricing attached to trade quotes. Discovery is read-only market data -
7
7
  * the trade path itself never depends on it.
8
8
  */
9
9
  const DEFAULT_ENDPOINT = "https://api.geckoterminal.com/api/v2";
@@ -31,7 +31,7 @@ function poolsToTokens(payload, limit) {
31
31
  const out = [];
32
32
  for (const pool of data) {
33
33
  const attrs = pool.attributes ?? {};
34
- // base_token id looks like "robinhood_0x020b…" address after the prefix.
34
+ // base_token id looks like "robinhood_0x020b…" - address after the prefix.
35
35
  const baseId = pool.relationships?.base_token?.data?.id ?? "";
36
36
  const address = baseId.includes("_") ? baseId.slice(baseId.indexOf("_") + 1) : "";
37
37
  if (!address.startsWith("0x"))
@@ -64,7 +64,7 @@ export async function trendingTokens(opts = {}) {
64
64
  const payload = await gtFetch(`/networks/${GT_NETWORK}/trending_pools?page=1`);
65
65
  return poolsToTokens(payload, opts.limit ?? 10);
66
66
  }
67
- /** Tokens from the most recently created pools (fresh launches high risk). */
67
+ /** Tokens from the most recently created pools (fresh launches - high risk). */
68
68
  export async function newTokens(opts = {}) {
69
69
  const payload = await gtFetch(`/networks/${GT_NETWORK}/new_pools?page=1`);
70
70
  return poolsToTokens(payload, opts.limit ?? 10);
@@ -83,7 +83,7 @@ export async function tokenPriceUsd(address) {
83
83
  /**
84
84
  * All ERC-20 balances a wallet holds on Robinhood Chain, via the chain's
85
85
  * Blockscout explorer API (keyless). This is what surfaces memecoins bought
86
- * through `xpay trade` the on-chain signer only knows a hardcoded token list.
86
+ * through `xpay trade` - the on-chain signer only knows a hardcoded token list.
87
87
  * Best-effort: returns [] if the explorer is unreachable.
88
88
  */
89
89
  export async function robinhoodHoldings(address) {
@@ -132,7 +132,7 @@ function atomsToHuman(atoms, decimals) {
132
132
  /**
133
133
  * Resolve a token symbol to its contract address via trending + new pools.
134
134
  * Throws when the symbol is unknown or matches several distinct contracts
135
- * (memecoin symbols are not unique pass the address instead).
135
+ * (memecoin symbols are not unique - pass the address instead).
136
136
  */
137
137
  export async function resolveTokenBySymbol(symbol) {
138
138
  const wanted = symbol.trim().toUpperCase();
@@ -146,7 +146,7 @@ export async function resolveTokenBySymbol(symbol) {
146
146
  matches.set(t.address.toLowerCase(), t);
147
147
  }
148
148
  if (matches.size === 0) {
149
- throw new Error(`xpay.trade: unknown token "${symbol}" not in Robinhood Chain trending/new pools. ` +
149
+ throw new Error(`xpay.trade: unknown token "${symbol}" - not in Robinhood Chain trending/new pools. ` +
150
150
  "Pass the token's contract address instead.");
151
151
  }
152
152
  if (matches.size > 1) {
@@ -1,15 +1,15 @@
1
1
  /**
2
- * Robinhood Chain token trading direct Uniswap V3 (NOXA Fun launchpad).
2
+ * Robinhood Chain token trading - direct Uniswap V3 (NOXA Fun launchpad).
3
3
  *
4
4
  * NOXA Fun tokens (fun.noxa.fi) launch straight into Uniswap V3 pools quoted
5
5
  * in WETH, so trading them is plain V3: quote via QuoterV2, execute via
6
- * SwapRouter02. No third-party API or key everything is on-chain against the
6
+ * SwapRouter02. No third-party API or key - everything is on-chain against the
7
7
  * chain's own RPC. GMGN was ruled out (no chain-4663 support, gated API).
8
8
  *
9
9
  * Scope v1: ETH ⇄ token only (buy with native ETH, sell back to native ETH).
10
10
  * The router auto-wraps ETH on buys; sells unwrap WETH → ETH via multicall.
11
11
  *
12
- * A trade is irreversible and risks wallet value, so exactly like `swap` —
12
+ * A trade is irreversible and risks wallet value, so, exactly like `swap`,
13
13
  * it runs through the guardrail *before* signing.
14
14
  */
15
15
  import type { Network } from "../types.js";
@@ -24,7 +24,7 @@ export declare const RH_CONTRACTS: {
24
24
  readonly weth: "0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73";
25
25
  readonly noxaLauncher: "0xD9eC2db5f3D1b236843925949fe5bd8a3836FCcB";
26
26
  };
27
- /** Trading settings profile `config.trading`, overridable per call. */
27
+ /** Trading settings - profile `config.trading`, overridable per call. */
28
28
  export interface TradeConfig {
29
29
  /** Default max slippage in bps (100 = 1%). */
30
30
  slippageBps?: number;
@@ -75,7 +75,7 @@ export interface TradeQuote {
75
75
  /** Input-side USD estimate (GeckoTerminal spot). Best-effort. */
76
76
  usdValue?: number;
77
77
  /**
78
- * True when the counterparty token was NOT confirmed as a NOXA Fun launch
78
+ * True when the counterparty token was NOT confirmed as a NOXA Fun launch -
79
79
  * it may still be tradeable, but treat the pool/price with more suspicion.
80
80
  */
81
81
  unverified: boolean;
@@ -86,7 +86,7 @@ export interface TradeResult extends TradeQuote {
86
86
  /** Transaction hash on Robinhood Chain. */
87
87
  txHash: string;
88
88
  }
89
- /** Quote a trade without executing no guardrail, no signing, no funds moved. */
89
+ /** Quote a trade without executing - no guardrail, no signing, no funds moved. */
90
90
  export declare function tradeQuote(args: Omit<TradeArgs, "guardrail">): Promise<TradeQuote>;
91
91
  /** Execute a trade on Robinhood Chain. Guardrail runs before signing. */
92
92
  export declare function trade(args: TradeArgs): Promise<TradeResult>;
@@ -1,15 +1,15 @@
1
1
  /**
2
- * Robinhood Chain token trading direct Uniswap V3 (NOXA Fun launchpad).
2
+ * Robinhood Chain token trading - direct Uniswap V3 (NOXA Fun launchpad).
3
3
  *
4
4
  * NOXA Fun tokens (fun.noxa.fi) launch straight into Uniswap V3 pools quoted
5
5
  * in WETH, so trading them is plain V3: quote via QuoterV2, execute via
6
- * SwapRouter02. No third-party API or key everything is on-chain against the
6
+ * SwapRouter02. No third-party API or key - everything is on-chain against the
7
7
  * chain's own RPC. GMGN was ruled out (no chain-4663 support, gated API).
8
8
  *
9
9
  * Scope v1: ETH ⇄ token only (buy with native ETH, sell back to native ETH).
10
10
  * The router auto-wraps ETH on buys; sells unwrap WETH → ETH via multicall.
11
11
  *
12
- * A trade is irreversible and risks wallet value, so exactly like `swap` —
12
+ * A trade is irreversible and risks wallet value, so, exactly like `swap`,
13
13
  * it runs through the guardrail *before* signing.
14
14
  */
15
15
  import { Contract, MaxUint256, getAddress, isAddress } from "ethers";
@@ -25,7 +25,7 @@ export const RH_CONTRACTS = {
25
25
  };
26
26
  /** Fee tiers probed (in bps*100) when the pool fee isn't known up front. NOXA uses 10000 (1%). */
27
27
  const FEE_TIERS = [10000, 3000, 500, 100];
28
- const DEFAULT_SLIPPAGE_BPS = 100; // 1% memecoin pools with a 1% fee move fast.
28
+ const DEFAULT_SLIPPAGE_BPS = 100; // 1% - memecoin pools with a 1% fee move fast.
29
29
  const MAX_SLIPPAGE_BPS = 5000; // 50% hard ceiling.
30
30
  const QUOTER_ABI = [
31
31
  "function quoteExactInputSingle((address tokenIn,address tokenOut,uint256 amountIn,uint24 fee,uint160 sqrtPriceLimitX96)) returns (uint256 amountOut,uint160 sqrtPriceX96After,uint32 initializedTicksCrossed,uint256 gasEstimate)",
@@ -42,7 +42,7 @@ const ERC20_ABI = [
42
42
  "function allowance(address owner,address spender) view returns (uint256)",
43
43
  "function approve(address spender,uint256 amount) returns (bool)",
44
44
  ];
45
- // NOXA Fun token surface non-standard getters a plain ERC-20 lacks.
45
+ // NOXA Fun token surface - non-standard getters a plain ERC-20 lacks.
46
46
  const NOXA_TOKEN_ABI = [
47
47
  "function liquidityPool() view returns (address)",
48
48
  "function pairToken() view returns (address)",
@@ -54,14 +54,14 @@ const NOXA_TOKEN_ABI = [
54
54
  // SwapRouter02 recipient constant: keep output in the router for a follow-up unwrap.
55
55
  const ROUTER_ADDRESS_THIS = "0x0000000000000000000000000000000000000002";
56
56
  const NATIVE_ETH = { symbol: "ETH", decimals: 18 };
57
- /** Quote a trade without executing no guardrail, no signing, no funds moved. */
57
+ /** Quote a trade without executing - no guardrail, no signing, no funds moved. */
58
58
  export async function tradeQuote(args) {
59
59
  return (await prepare(args)).quote;
60
60
  }
61
61
  /** Execute a trade on Robinhood Chain. Guardrail runs before signing. */
62
62
  export async function trade(args) {
63
63
  const { quote, ethersWallet, side, token } = await prepare(args);
64
- // Guardrail *before* signing same security boundary as swap/pay/transfer.
64
+ // Guardrail *before* signing - same security boundary as swap/pay/transfer.
65
65
  // Reuse the "swap" scheme so host-whitelist is skipped and the USD estimate
66
66
  // is priced from `extra.usdEstimate` (see Guardrail.estimateUsd).
67
67
  await args.guardrail.check({
@@ -140,7 +140,7 @@ async function prepare(args) {
140
140
  throw new Error(`xpay.trade: only Robinhood Chain ("robinhood") is supported (got "${network}")`);
141
141
  }
142
142
  if (!args.wallet.has(ROBINHOOD_NETWORK)) {
143
- throw new Error('xpay.trade: no "robinhood" signer configured add it to your profile networks');
143
+ throw new Error('xpay.trade: no "robinhood" signer configured - add it to your profile networks');
144
144
  }
145
145
  if (!Number.isFinite(args.amount) || args.amount <= 0) {
146
146
  throw new Error("xpay.trade: amount must be a positive number");
@@ -180,7 +180,7 @@ async function prepare(args) {
180
180
  // A buy that would breach a cap is failed up front with a clear message
181
181
  // rather than reverting opaquely on-chain. The cap info is surfaced on the
182
182
  // quote only when this trade is actually within striking distance of a cap
183
- // (>25% of it) established tokens leave a far-future endBlock set with wide
183
+ // (>25% of it) - established tokens leave a far-future endBlock set with wide
184
184
  // caps, so reporting it unconditionally would be misleading noise.
185
185
  let boundRestriction;
186
186
  if (restriction && side === "buy") {
@@ -232,7 +232,7 @@ function isEth(ref) {
232
232
  async function resolveToken(wallet, ref) {
233
233
  let address = ref.trim();
234
234
  if (!isAddress(address)) {
235
- // Treat as a symbol resolve via GeckoTerminal trending/new pools.
235
+ // Treat as a symbol - resolve via GeckoTerminal trending/new pools.
236
236
  const found = await resolveTokenBySymbol(address);
237
237
  address = found.address;
238
238
  }
@@ -244,7 +244,7 @@ async function resolveToken(wallet, ref) {
244
244
  ]);
245
245
  return { address, symbol, decimals };
246
246
  }
247
- /** Probe a token's NOXA Fun surface pool, fee tier, launch restrictions. */
247
+ /** Probe a token's NOXA Fun surface - pool, fee tier, launch restrictions. */
248
248
  async function inspectToken(wallet, address) {
249
249
  const t = new Contract(address, NOXA_TOKEN_ABI, wallet);
250
250
  try {
@@ -277,7 +277,7 @@ async function inspectToken(wallet, address) {
277
277
  return meta;
278
278
  }
279
279
  catch {
280
- // Not a NOXA token (getters reverted) still tradeable if a V3 pool exists.
280
+ // Not a NOXA token (getters reverted) - still tradeable if a V3 pool exists.
281
281
  return { isNoxa: false };
282
282
  }
283
283
  }
@@ -287,7 +287,7 @@ async function quoteBestFee(wallet, tokenIn, tokenOut, amountIn, fees) {
287
287
  let lastErr;
288
288
  for (const fee of fees) {
289
289
  try {
290
- // QuoterV2 quote fns are non-view (revert-to-return) must use staticCall.
290
+ // QuoterV2 quote fns are non-view (revert-to-return) - must use staticCall.
291
291
  const res = await quoter.quoteExactInputSingle.staticCall({
292
292
  tokenIn,
293
293
  tokenOut,