@xona-labs/xpay 0.2.24 → 0.2.26

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 (118) 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.d.ts.map +1 -1
  37. package/dist/cli/mcp-server.js +25 -22
  38. package/dist/cli/mcp-server.js.map +1 -1
  39. package/dist/cli/pay.d.ts +1 -1
  40. package/dist/cli/pay.js +1 -1
  41. package/dist/cli/report.d.ts +2 -2
  42. package/dist/cli/report.js +4 -4
  43. package/dist/cli/report.js.map +1 -1
  44. package/dist/cli/sana.d.ts +1 -1
  45. package/dist/cli/sana.js +3 -3
  46. package/dist/cli/shop.d.ts +1 -1
  47. package/dist/cli/shop.js +1 -1
  48. package/dist/cli/swap.d.ts +1 -1
  49. package/dist/cli/swap.js +3 -3
  50. package/dist/cli/token.d.ts +2 -2
  51. package/dist/cli/token.js +2 -2
  52. package/dist/cli/trade.d.ts +2 -2
  53. package/dist/cli/trade.js +8 -8
  54. package/dist/cli/trade.js.map +1 -1
  55. package/dist/cli/transfer.d.ts +1 -1
  56. package/dist/cli/transfer.js +1 -1
  57. package/dist/cli/x.d.ts +1 -1
  58. package/dist/cli/x.js +1 -1
  59. package/dist/cli/zauth.d.ts +1 -1
  60. package/dist/cli/zauth.js +5 -5
  61. package/dist/discover/cache.js +1 -1
  62. package/dist/discover/index.d.ts +2 -2
  63. package/dist/discover/index.js +6 -6
  64. package/dist/discover/orbitx402.d.ts +2 -2
  65. package/dist/discover/orbitx402.js +1 -1
  66. package/dist/discover/payai.js +1 -1
  67. package/dist/do/index.d.ts +2 -2
  68. package/dist/do/index.js +1 -1
  69. package/dist/guardrail/index.d.ts +4 -4
  70. package/dist/guardrail/index.js +14 -14
  71. package/dist/guardrail/index.js.map +1 -1
  72. package/dist/index.d.ts +7 -7
  73. package/dist/index.js +2 -2
  74. package/dist/magicblock/client.d.ts +2 -2
  75. package/dist/magicblock/client.js +4 -4
  76. package/dist/profile/index.d.ts +3 -3
  77. package/dist/profile/index.js +3 -3
  78. package/dist/profile/storage.d.ts +1 -1
  79. package/dist/profile/storage.js +4 -4
  80. package/dist/profile/types.d.ts +6 -6
  81. package/dist/profile/types.js +1 -1
  82. package/dist/report/index.d.ts +1 -1
  83. package/dist/report/index.js +2 -2
  84. package/dist/sana/tools.js +8 -8
  85. package/dist/signers/raw-evm.d.ts +1 -1
  86. package/dist/signers/raw-evm.js +5 -5
  87. package/dist/signers/raw-solana.d.ts +1 -1
  88. package/dist/signers/raw-solana.js +4 -4
  89. package/dist/swap/index.d.ts +6 -6
  90. package/dist/swap/index.js +12 -12
  91. package/dist/token/index.d.ts +8 -8
  92. package/dist/token/index.js +14 -14
  93. package/dist/token/rwa.d.ts +3 -3
  94. package/dist/token/rwa.js +3 -3
  95. package/dist/tools/index.d.ts +15 -1
  96. package/dist/tools/index.d.ts.map +1 -1
  97. package/dist/tools/index.js +71 -31
  98. package/dist/tools/index.js.map +1 -1
  99. package/dist/trading/discovery.d.ts +6 -6
  100. package/dist/trading/discovery.js +7 -7
  101. package/dist/trading/index.d.ts +6 -6
  102. package/dist/trading/index.js +13 -13
  103. package/dist/transfer/index.d.ts +4 -4
  104. package/dist/transfer/index.js +8 -8
  105. package/dist/types.d.ts +7 -7
  106. package/dist/use/index.d.ts +5 -5
  107. package/dist/use/index.js +20 -20
  108. package/dist/wallet/index.d.ts +2 -2
  109. package/dist/wallet/index.js +3 -3
  110. package/dist/x402/evm-payment.d.ts +4 -4
  111. package/dist/x402/evm-payment.js +6 -6
  112. package/dist/x402/extract.d.ts +1 -1
  113. package/dist/x402/extract.js +1 -1
  114. package/dist/x402/svm-payment.d.ts +2 -2
  115. package/dist/x402/svm-payment.js +2 -2
  116. package/dist/zauth/index.d.ts +4 -4
  117. package/dist/zauth/index.js +5 -5
  118. package/package.json +4 -3
package/dist/agenc/api.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * AgenC marketplace client keyless reads of Solana-mainnet marketplace state.
2
+ * AgenC marketplace client - keyless reads of Solana-mainnet marketplace state.
3
3
  *
4
4
  * AgenC (https://agenc.ag) lists standing service offers from registered
5
5
  * on-chain agents. Discovery goes through AgenC's hosted indexer via the SDK's
6
- * `createIndexerClient` their documented "intended scale read path" (the
6
+ * `createIndexerClient` - their documented "intended scale read path" (the
7
7
  * legacy REST `?hireable=true` filter went dark after a program upgrade).
8
- * Execution is NOT x402 hiring escrows native SOL on-chain via
8
+ * Execution is NOT x402 - hiring escrows native SOL on-chain via
9
9
  * `@tetsuo-ai/marketplace-sdk` (see ./hire.ts).
10
10
  */
11
11
  import { z } from "zod";
@@ -37,7 +37,7 @@ const AgencListingSchema = z
37
37
  createdAtUnix: z.number().optional(),
38
38
  })
39
39
  .passthrough();
40
- /** Task shape returned by GET /api/tasks/:pda used to poll hire progress. */
40
+ /** Task shape returned by GET /api/tasks/:pda - used to poll hire progress. */
41
41
  const AgencTaskSchema = z
42
42
  .object({
43
43
  pda: z.string(),
@@ -54,7 +54,7 @@ const AgencTaskSchema = z
54
54
  * Fetch all active, SOL-priced listings via AgenC's hosted indexer and map
55
55
  * them into xpay's Resource shape. Discovery is deliberately permissive:
56
56
  * listings without a fresh moderation attestation are still shown (matching
57
- * agenc.ag's own browse page) the hire path is the fail-closed gate.
57
+ * agenc.ag's own browse page) - the hire path is the fail-closed gate.
58
58
  */
59
59
  export async function fetchAgencResources(opts = {}) {
60
60
  const endpoint = opts.endpoint ?? process.env.XPAY_AGENC_ENDPOINT ?? DEFAULT_ENDPOINT;
@@ -76,7 +76,7 @@ export async function fetchAgencResources(opts = {}) {
76
76
  /**
77
77
  * Map an AgenC listing into xpay's Resource shape. Everything `hire.ts` needs
78
78
  * to execute rides in `accepts[0].extra`, so a discovered resource is
79
- * self-contained no extra API round-trips at hire time.
79
+ * self-contained - no extra API round-trips at hire time.
80
80
  */
81
81
  export function listingToResource(l) {
82
82
  return {
@@ -117,7 +117,7 @@ export function isAgencResource(r) {
117
117
  return r.accepts.some((a) => a.scheme === AGENC_SCHEME);
118
118
  }
119
119
  /**
120
- * Fetch a single listing by PDA via the indexer used as the pre-hire
120
+ * Fetch a single listing by PDA via the indexer - used as the pre-hire
121
121
  * freshness check. Decodes the raw on-chain account bytes for byte-true
122
122
  * parity with what the program will see. Returns undefined when the listing
123
123
  * doesn't exist.
@@ -186,17 +186,17 @@ function normalizeAccount(pda, a) {
186
186
  };
187
187
  }
188
188
  catch {
189
- return null; // malformed row skip rather than kill discovery
189
+ return null; // malformed row - skip rather than kill discovery
190
190
  }
191
191
  }
192
- /** Fetch a task by PDA (GET /api/tasks/:pda) the status of a hire. */
192
+ /** Fetch a task by PDA (GET /api/tasks/:pda) - the status of a hire. */
193
193
  export async function fetchAgencTask(pda, opts = {}) {
194
194
  const endpoint = opts.endpoint ?? process.env.XPAY_AGENC_ENDPOINT ?? DEFAULT_ENDPOINT;
195
195
  const fetchImpl = opts.fetch ?? fetch;
196
196
  const url = new URL(`/api/tasks/${encodeURIComponent(pda)}`, endpoint);
197
197
  const res = await fetchImpl(url.toString(), { headers: { accept: "application/json" } });
198
198
  if (res.status === 404) {
199
- throw new Error(`AgenC task ${pda} not found. The API snapshot rebuilds ~every 45s ` +
199
+ throw new Error(`AgenC task ${pda} not found. The API snapshot rebuilds ~every 45s - ` +
200
200
  `if this hire just landed, retry in about a minute.`);
201
201
  }
202
202
  if (!res.ok)
@@ -214,7 +214,7 @@ async function apiError(what, res) {
214
214
  try {
215
215
  const body = (await res.json());
216
216
  if (body?.error)
217
- reason = ` ${body.error}`;
217
+ reason = ` - ${body.error}`;
218
218
  }
219
219
  catch {
220
220
  /* no JSON body */
@@ -1,12 +1,12 @@
1
1
  /**
2
- * AgenC hire execution the non-x402 payment rail.
2
+ * AgenC hire execution - the non-x402 payment rail.
3
3
  *
4
4
  * Hiring a listing is a Solana transaction (program
5
5
  * HJsZ53Zb27b8QMRbQpuDngE44AdwCGxvEZr61Zmxw1xK) that escrows the listing's
6
6
  * price in native SOL and creates a Task + HireRecord on-chain. The provider
7
7
  * then works ASYNCHRONOUSLY: escrow → work → review → settle. So unlike an
8
8
  * x402 call, `use()` on an AgenC resource returns a hire *receipt*, not a
9
- * response body poll progress with `xpay agenc status <taskPda>`.
9
+ * response body - poll progress with `xpay agenc status <taskPda>`.
10
10
  *
11
11
  * The humanless entry point pins the task to CreatorReview, so escrowed funds
12
12
  * never auto-release without the buyer accepting the result.
@@ -26,7 +26,7 @@ export interface AgencHireReceipt {
26
26
  kind: "agenc-hire-receipt";
27
27
  /** Listing PDA that was hired. */
28
28
  listing: string;
29
- /** Task PDA created by the hire the handle for status polling and review. */
29
+ /** Task PDA created by the hire - the handle for status polling and review. */
30
30
  task: string;
31
31
  /** HireRecord PDA linking the task back to the listing. */
32
32
  hireRecord: string;
@@ -53,7 +53,7 @@ interface ResolvedModeration {
53
53
  * 2. v2 seeds ["listing_moderation_v2", listing, specHash, globalAuthority]
54
54
  * 3. getProgramAccounts scan (discriminator + listing memcmp)
55
55
  * Whatever record is found, its CONTENT names the moderator the hire gate
56
- * expects return both so the facade can skip its own derivation.
56
+ * expects - return both so the facade can skip its own derivation.
57
57
  */
58
58
  export declare function resolveListingModeration(sdk: AgencSdk, rpc: unknown, listingPda: string, specHashHex: string): Promise<ResolvedModeration | null>;
59
59
  export {};
@@ -1,12 +1,12 @@
1
1
  /**
2
- * AgenC hire execution the non-x402 payment rail.
2
+ * AgenC hire execution - the non-x402 payment rail.
3
3
  *
4
4
  * Hiring a listing is a Solana transaction (program
5
5
  * HJsZ53Zb27b8QMRbQpuDngE44AdwCGxvEZr61Zmxw1xK) that escrows the listing's
6
6
  * price in native SOL and creates a Task + HireRecord on-chain. The provider
7
7
  * then works ASYNCHRONOUSLY: escrow → work → review → settle. So unlike an
8
8
  * x402 call, `use()` on an AgenC resource returns a hire *receipt*, not a
9
- * response body poll progress with `xpay agenc status <taskPda>`.
9
+ * response body - poll progress with `xpay agenc status <taskPda>`.
10
10
  *
11
11
  * The humanless entry point pins the task to CreatorReview, so escrowed funds
12
12
  * never auto-release without the buyer accepting the result.
@@ -21,9 +21,9 @@ export async function useAgencHire(args) {
21
21
  }
22
22
  const extra = parseExtra(req);
23
23
  const cfg = args.agenc ?? {};
24
- // Guardrail runs *before* signing same security boundary as the x402 path.
24
+ // Guardrail runs *before* signing - same security boundary as the x402 path.
25
25
  await args.guardrail.check({ resource: args.resource, requirement: req });
26
- // Freshness check: the catalog snapshot may be stale refuse if the listing
26
+ // Freshness check: the catalog snapshot may be stale - refuse if the listing
27
27
  // was paused/retired or repriced upward since discovery. The on-chain
28
28
  // expectedPrice/expectedVersion checks are the fail-closed backstop.
29
29
  const live = await fetchAgencListing(extra.listingPda, { endpoint: cfg.endpoint });
@@ -43,14 +43,14 @@ export async function useAgencHire(args) {
43
43
  const kitSigner = (await signer.getKitSigner());
44
44
  const rpcUrl = cfg.rpcUrl ?? process.env.XPAY_SOLANA_RPC ?? DEFAULT_RPC;
45
45
  // Pre-flight: the hire escrows priceLamports in NATIVE SOL (plus fees/rent),
46
- // so check the SOL balance the USDC insufficient-balance path doesn't apply.
46
+ // so check the SOL balance - the USDC insufficient-balance path doesn't apply.
47
47
  const { createSolanaRpc, address } = await import("@solana/kit");
48
48
  const rpc = createSolanaRpc(rpcUrl);
49
49
  const FEE_BUFFER_LAMPORTS = 10000000n; // ~0.01 SOL for fees + PDA rent
50
50
  const needed = BigInt(live.priceLamports) + FEE_BUFFER_LAMPORTS;
51
51
  const { value: lamports } = await rpc.getBalance(address(signer.address)).send();
52
52
  if (BigInt(lamports) < needed) {
53
- throw new Error(`xpay.agenc: insufficient SOL hire needs ~${fmtSol(needed)} SOL ` +
53
+ throw new Error(`xpay.agenc: insufficient SOL - hire needs ~${fmtSol(needed)} SOL ` +
54
54
  `(${fmtSol(BigInt(live.priceLamports))} escrow + fees) but ${signer.address} ` +
55
55
  `holds ${fmtSol(BigInt(lamports))} SOL. Fund the wallet and retry.`);
56
56
  }
@@ -63,19 +63,19 @@ export async function useAgencHire(args) {
63
63
  const surface = await deployedSurface(sdk, rpc);
64
64
  if (!surface.listings) {
65
65
  throw new Error(`xpay.agenc: the deployed AgenC program (surface revision ${surface.surfaceRevision}) ` +
66
- `does not expose listings/hires on this cluster. xpay may need an update check ` +
66
+ `does not expose listings/hires on this cluster. xpay may need an update - check ` +
67
67
  `for a newer @xona-labs/xpay release.`);
68
68
  }
69
69
  // Resolve the listing's moderation attestation. The record's on-chain
70
70
  // ADDRESS has changed seed schemes across program upgrades, but its CONTENT
71
- // always names the moderator the hire gate expects so we locate the
71
+ // always names the moderator the hire gate expects - so we locate the
72
72
  // record (trying each known derivation, newest data wins) and pass both
73
73
  // the moderator and the explicit record address to the facade. Fail-closed
74
74
  // BEFORE the guardrail/payment path if no attestation exists.
75
75
  const moderation = await resolveListingModeration(sdk, rpc, extra.listingPda, extra.specHash);
76
76
  if (!moderation) {
77
77
  throw new Error(`xpay.agenc: listing ${extra.listingPda} has no on-chain moderation attestation yet ` +
78
- `(AgenC re-attests listings after program upgrades). The hire gate is fail-closed ` +
78
+ `(AgenC re-attests listings after program upgrades). The hire gate is fail-closed - ` +
79
79
  `pick another listing or retry later.`);
80
80
  }
81
81
  const client = createMarketplaceClient({ rpcUrl, signer: kitSigner });
@@ -103,7 +103,7 @@ export async function useAgencHire(args) {
103
103
  txSig: signature,
104
104
  status: "escrowed",
105
105
  statusHint: "SOL is escrowed on-chain; the provider works asynchronously. Poll progress with " +
106
- `\`xpay agenc status ${taskPda}\` funds settle to the provider after your review window.`,
106
+ `\`xpay agenc status ${taskPda}\` - funds settle to the provider after your review window.`,
107
107
  explorer: `https://solscan.io/tx/${signature}`,
108
108
  surfaceRevision: surface.surfaceRevision,
109
109
  };
@@ -127,13 +127,13 @@ function parseExtra(req) {
127
127
  if (typeof listingPda !== "string" ||
128
128
  typeof specHash !== "string" ||
129
129
  typeof version !== "string") {
130
- throw new Error("xpay.agenc: malformed AgenC resource missing listingPda/specHash/version in " +
130
+ throw new Error("xpay.agenc: malformed AgenC resource - missing listingPda/specHash/version in " +
131
131
  "accepts[].extra. Re-run discover to get a fresh listing.");
132
132
  }
133
133
  return { listingPda, specHash, version };
134
134
  }
135
135
  let surfaceCache;
136
- /** Deployed instruction surface, cached 10 min one account fetch. */
136
+ /** Deployed instruction surface, cached 10 min - one account fetch. */
137
137
  async function deployedSurface(sdk, rpc) {
138
138
  if (surfaceCache && Date.now() - surfaceCache.at < 600_000)
139
139
  return surfaceCache.value;
@@ -149,13 +149,13 @@ async function deployedSurface(sdk, rpc) {
149
149
  * 2. v2 seeds ["listing_moderation_v2", listing, specHash, globalAuthority]
150
150
  * 3. getProgramAccounts scan (discriminator + listing memcmp)
151
151
  * Whatever record is found, its CONTENT names the moderator the hire gate
152
- * expects return both so the facade can skip its own derivation.
152
+ * expects - return both so the facade can skip its own derivation.
153
153
  */
154
154
  export async function resolveListingModeration(sdk, rpc, listingPda, specHashHex) {
155
155
  const { getProgramDerivedAddress, getAddressEncoder, getUtf8Encoder, getBase58Decoder, address } = await import("@solana/kit");
156
156
  const specHash = hexToBytes(specHashHex);
157
157
  const candidates = [];
158
- // 1) v1 seeds pre-upgrade attestations (still honored by the program).
158
+ // 1) v1 seeds - pre-upgrade attestations (still honored by the program).
159
159
  const [v1] = await getProgramDerivedAddress({
160
160
  programAddress: sdk.AGENC_COORDINATION_PROGRAM_ADDRESS,
161
161
  seeds: [
@@ -179,7 +179,7 @@ export async function resolveListingModeration(sdk, rpc, listingPda, specHashHex
179
179
  }
180
180
  }
181
181
  catch {
182
- /* moderation config unreadable continue with what we have */
182
+ /* moderation config unreadable - continue with what we have */
183
183
  }
184
184
  for (const candidate of candidates) {
185
185
  const found = await tryDecodeModeration(sdk, rpc, candidate);
@@ -187,7 +187,7 @@ export async function resolveListingModeration(sdk, rpc, listingPda, specHashHex
187
187
  return found;
188
188
  }
189
189
  // 3) Seed-agnostic: scan the program's moderation records for this listing.
190
- // Best effort some RPCs rate-limit or forbid getProgramAccounts.
190
+ // Best effort - some RPCs rate-limit or forbid getProgramAccounts.
191
191
  try {
192
192
  const disc = getBase58Decoder().decode(sdk.LISTING_MODERATION_DISCRIMINATOR);
193
193
  const rows = await rpc
@@ -206,7 +206,7 @@ export async function resolveListingModeration(sdk, rpc, listingPda, specHashHex
206
206
  }
207
207
  }
208
208
  catch {
209
- /* scan unavailable fall through to fail-closed */
209
+ /* scan unavailable - fall through to fail-closed */
210
210
  }
211
211
  return null;
212
212
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SOL/USD spot price AgenC listings are priced in native SOL, but the
2
+ * SOL/USD spot price - AgenC listings are priced in native SOL, but the
3
3
  * guardrail's policy surface (maxPerTx / maxPerDay / requireApprovalAbove)
4
4
  * is USD-denominated. Tries several keyless public feeds in order (corporate
5
5
  * proxies commonly block one or another), cached for 60s.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SOL/USD spot price AgenC listings are priced in native SOL, but the
2
+ * SOL/USD spot price - AgenC listings are priced in native SOL, but the
3
3
  * guardrail's policy surface (maxPerTx / maxPerDay / requireApprovalAbove)
4
4
  * is USD-denominated. Tries several keyless public feeds in order (corporate
5
5
  * proxies commonly block one or another), cached for 60s.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Biometric unlock (macOS Touch ID / Watch) gates access to the wallet
2
+ * Biometric unlock (macOS Touch ID / Watch) - gates access to the wallet
3
3
  * passphrase, it does not replace it. The passphrase is stored in the user's
4
4
  * login keychain and only released by a small native helper after a
5
5
  * successful LocalAuthentication check. The scrypt/AES wallet encryption is
@@ -10,7 +10,7 @@
10
10
  * Embedding the source keeps the npm package dependency-free and lets tsc
11
11
  * ship it inside dist/ without a native build step at install time.
12
12
  */
13
- /** Keychain item identity must match `kService` in the Swift source. */
13
+ /** Keychain item identity - must match `kService` in the Swift source. */
14
14
  export declare const KEYCHAIN_SERVICE = "com.xona-labs.xpay.wallet";
15
15
  export type BiometryType = "touchid" | "faceid";
16
16
  /** Thrown when biometrics can't work here at all (non-macOS, no swiftc, no enrolled biometry). */
@@ -34,7 +34,7 @@ export declare function biometricPrompt(reason: string): Promise<boolean>;
34
34
  export declare function storeBiometricPassphrase(account: string, passphrase: string): Promise<void>;
35
35
  /**
36
36
  * Biometric-gated read of the stored passphrase. Returns null when the user
37
- * cancels/fails the check or no passphrase is stored both mean "fall back
37
+ * cancels/fails the check or no passphrase is stored - both mean "fall back
38
38
  * to typing the passphrase". Throws {@link BiometricUnavailableError} when
39
39
  * biometry can't be evaluated at all.
40
40
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Biometric unlock (macOS Touch ID / Watch) gates access to the wallet
2
+ * Biometric unlock (macOS Touch ID / Watch) - gates access to the wallet
3
3
  * passphrase, it does not replace it. The passphrase is stored in the user's
4
4
  * login keychain and only released by a small native helper after a
5
5
  * successful LocalAuthentication check. The scrypt/AES wallet encryption is
@@ -16,7 +16,7 @@ import { existsSync, mkdirSync, writeFileSync, readdirSync, unlinkSync } from "n
16
16
  import { createHash } from "node:crypto";
17
17
  import { execFileSync, execFile } from "node:child_process";
18
18
  import { xpayHome } from "../profile/storage.js";
19
- /** Keychain item identity must match `kService` in the Swift source. */
19
+ /** Keychain item identity - must match `kService` in the Swift source. */
20
20
  export const KEYCHAIN_SERVICE = "com.xona-labs.xpay.wallet";
21
21
  const HELPER_BASENAME = "xpay-biometric";
22
22
  // Helper exit codes (mirrored in the Swift source).
@@ -24,7 +24,7 @@ const EXIT_OK = 0;
24
24
  const EXIT_UNAVAILABLE = 2;
25
25
  const EXIT_DENIED = 3;
26
26
  const EXIT_NOT_FOUND = 4;
27
- const SWIFT_SOURCE = `// xpay-biometric generated by @xona-labs/xpay; do not edit.
27
+ const SWIFT_SOURCE = `// xpay-biometric - generated by @xona-labs/xpay; do not edit.
28
28
  import Foundation
29
29
  import LocalAuthentication
30
30
  import Security
@@ -136,7 +136,7 @@ function binDir() {
136
136
  * Compile the helper if this exact source hasn't been compiled yet. The
137
137
  * binary name carries a source hash so upgrades recompile automatically;
138
138
  * stale versions are swept. Note: a freshly compiled binary triggers a new
139
- * macOS "allow keychain access" prompt on its first read expected.
139
+ * macOS "allow keychain access" prompt on its first read - expected.
140
140
  */
141
141
  function ensureHelper() {
142
142
  if (!biometricPlatformSupported()) {
@@ -153,7 +153,7 @@ function ensureHelper() {
153
153
  execFileSync("swiftc", ["-O", "-o", bin, src], { stdio: ["ignore", "ignore", "pipe"] });
154
154
  }
155
155
  catch {
156
- throw new BiometricUnavailableError("Could not compile the Touch ID helper are the Xcode Command Line Tools installed? (xcode-select --install)");
156
+ throw new BiometricUnavailableError("Could not compile the Touch ID helper - are the Xcode Command Line Tools installed? (xcode-select --install)");
157
157
  }
158
158
  for (const f of readdirSync(binDir())) {
159
159
  if (f.startsWith(`${HELPER_BASENAME}-`) && f !== `${HELPER_BASENAME}-${hash}`) {
@@ -216,7 +216,7 @@ export async function storeBiometricPassphrase(account, passphrase) {
216
216
  }
217
217
  /**
218
218
  * Biometric-gated read of the stored passphrase. Returns null when the user
219
- * cancels/fails the check or no passphrase is stored both mean "fall back
219
+ * cancels/fails the check or no passphrase is stored - both mean "fall back
220
220
  * to typing the passphrase". Throws {@link BiometricUnavailableError} when
221
221
  * biometry can't be evaluated at all.
222
222
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay accounts` multi-profile management.
2
+ * `xpay accounts` - multi-profile management.
3
3
  *
4
4
  * xpay accounts list list known profiles
5
5
  * xpay accounts show [name] show addresses for a profile
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay accounts` multi-profile management.
2
+ * `xpay accounts` - multi-profile management.
3
3
  *
4
4
  * xpay accounts list list known profiles
5
5
  * xpay accounts show [name] show addresses for a profile
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay agenc <hire|status>` AgenC marketplace (agenc.ag).
2
+ * `xpay agenc <hire|status>` - AgenC marketplace (agenc.ag).
3
3
  *
4
4
  * AgenC listings show up in `xpay discover` alongside x402 services, but they
5
5
  * execute differently: hiring escrows the price in native SOL on-chain, the
@@ -17,6 +17,6 @@ export declare function runAgencHire(listingPda: string, opts: AgencHireCmdOptio
17
17
  export interface AgencStatusCmdOptions {
18
18
  json?: boolean;
19
19
  }
20
- /** Read-only no profile unlock needed. */
20
+ /** Read-only - no profile unlock needed. */
21
21
  export declare function runAgencStatus(taskPda: string, opts: AgencStatusCmdOptions): Promise<void>;
22
22
  //# sourceMappingURL=agenc.d.ts.map
package/dist/cli/agenc.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay agenc <hire|status>` AgenC marketplace (agenc.ag).
2
+ * `xpay agenc <hire|status>` - AgenC marketplace (agenc.ag).
3
3
  *
4
4
  * AgenC listings show up in `xpay discover` alongside x402 services, but they
5
5
  * execute differently: hiring escrows the price in native SOL on-chain, the
@@ -60,7 +60,7 @@ export async function runAgencHire(listingPda, opts) {
60
60
  const receipt = result.data;
61
61
  const elapsed = Date.now() - t0;
62
62
  console.log("");
63
- console.log(chalk.green(`✔ Hired ◎${sol.toFixed(4)} SOL escrowed in ${elapsed}ms`));
63
+ console.log(chalk.green(`✔ Hired - ◎${sol.toFixed(4)} SOL escrowed in ${elapsed}ms`));
64
64
  console.log(` ${chalk.dim("task:")} ${receipt.task}`);
65
65
  console.log(` ${chalk.dim("tx:")} ${receipt.txSig}`);
66
66
  console.log(` ${chalk.dim("explorer:")} ${receipt.explorer}`);
@@ -75,7 +75,7 @@ export async function runAgencHire(listingPda, opts) {
75
75
  process.exit(1);
76
76
  }
77
77
  }
78
- /** Read-only no profile unlock needed. */
78
+ /** Read-only - no profile unlock needed. */
79
79
  export async function runAgencStatus(taskPda, opts) {
80
80
  try {
81
81
  const task = await fetchAgencTask(taskPda);
@@ -99,7 +99,7 @@ export async function runAgencStatus(taskPda, opts) {
99
99
  }
100
100
  console.log("");
101
101
  if (task.status === "review") {
102
- console.log(chalk.dim("The provider submitted a result review it at:"));
102
+ console.log(chalk.dim("The provider submitted a result - review it at:"));
103
103
  console.log(chalk.cyan(` https://agenc.ag/tasks/${taskPda}`));
104
104
  }
105
105
  else if (!["settled", "cancelled", "disputed"].includes(task.status)) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay balance` show USDC balance per network for the active profile.
2
+ * `xpay balance` - show USDC balance per network for the active profile.
3
3
  *
4
4
  * Unlocks the active profile (prompts for passphrase if encrypted, unless
5
5
  * $XPAY_PASSPHRASE is set for non-interactive use), then queries each
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay balance` show USDC balance per network for the active profile.
2
+ * `xpay balance` - show USDC balance per network for the active profile.
3
3
  *
4
4
  * Unlocks the active profile (prompts for passphrase if encrypted, unless
5
5
  * $XPAY_PASSPHRASE is set for non-interactive use), then queries each
@@ -16,7 +16,7 @@ export async function runBalance(opts) {
16
16
  const signers = signersFromProfile(profile);
17
17
  // Robinhood Chain and Stable always have a signer (see signersFromProfile)
18
18
  // even when they're not in the profile's `networks`, so surface them in the
19
- // default view too handy as the deposit address for funding trades and
19
+ // default view too - handy as the deposit address for funding trades and
20
20
  // for /stable/* x402 calls.
21
21
  const configured = profile.config.networks;
22
22
  const networks = opts.network
@@ -41,7 +41,7 @@ export async function runBalance(opts) {
41
41
  // lookup (Solana only; EVM balances pass through unchanged).
42
42
  let tokens = net === "solana" ? await enrichTokenBalances(raw) : raw;
43
43
  // Robinhood Chain: the signer only knows a hardcoded token list (WETH),
44
- // so pull the wallet's full ERC-20 holdings from the chain explorer
44
+ // so pull the wallet's full ERC-20 holdings from the chain explorer -
45
45
  // this is how memecoins bought via `xpay trade` show up. Keep the
46
46
  // signer's native ETH entry and take every ERC-20 from the explorer.
47
47
  if (net === "robinhood") {
@@ -59,7 +59,7 @@ export async function runBalance(opts) {
59
59
  const flag = t.verified === false && !t.isNative ? chalk.yellow(" ⚠ unverified") : "";
60
60
  console.log(` ${label.padEnd(18)} ${chalk.white(val.padEnd(14))} ${usd}${flag}`);
61
61
  // USDT0 is Stable's USDT (an ERC-20 OFT), and its native gas coin
62
- // reports as USDT both are dollars, so both count.
62
+ // reports as USDT - both are dollars, so both count.
63
63
  if (t.symbol === "USDC" || t.symbol === "USDT" || t.symbol === "USDT0")
64
64
  usdcTotal += t.balance;
65
65
  if (t.usdValue !== undefined)
@@ -1,14 +1,14 @@
1
1
  /**
2
- * `xpay bento enable|disable|status` toggle the Bento Guard intent firewall
2
+ * `xpay bento enable|disable|status` - toggle the Bento Guard intent firewall
3
3
  * for the active profile.
4
4
  *
5
5
  * Unlike Sana, Bento has no API key: it authenticates with the wallet's own
6
6
  * key (createXPay exposes it via AGENT_WALLET_PRIVATE_KEY at runtime). The one
7
- * manual step is registering the wallet address once at app.bentoguard.xyz
7
+ * manual step is registering the wallet address once at app.bentoguard.xyz -
8
8
  * `enable` prints that address and walks you through it.
9
9
  *
10
10
  * When enabled, every pay / transfer is screened by Bento's protect() for
11
- * malicious intent (prompt-injection, wallet-drain) before signing a second
11
+ * malicious intent (prompt-injection, wallet-drain) before signing - a second
12
12
  * gate on top of the local guardrail caps.
13
13
  */
14
14
  export declare function runBentoEnable(opts: {
package/dist/cli/bento.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
- * `xpay bento enable|disable|status` toggle the Bento Guard intent firewall
2
+ * `xpay bento enable|disable|status` - toggle the Bento Guard intent firewall
3
3
  * for the active profile.
4
4
  *
5
5
  * Unlike Sana, Bento has no API key: it authenticates with the wallet's own
6
6
  * key (createXPay exposes it via AGENT_WALLET_PRIVATE_KEY at runtime). The one
7
- * manual step is registering the wallet address once at app.bentoguard.xyz
7
+ * manual step is registering the wallet address once at app.bentoguard.xyz -
8
8
  * `enable` prints that address and walks you through it.
9
9
  *
10
10
  * When enabled, every pay / transfer is screened by Bento's protect() for
11
- * malicious intent (prompt-injection, wallet-drain) before signing a second
11
+ * malicious intent (prompt-injection, wallet-drain) before signing - a second
12
12
  * gate on top of the local guardrail caps.
13
13
  */
14
14
  import chalk from "chalk";
@@ -31,18 +31,18 @@ export function runBentoEnable(opts) {
31
31
  console.log("");
32
32
  console.log(chalk.green(`✔ Bento intent firewall enabled for "${name}".`));
33
33
  console.log("");
34
- console.log(chalk.bold(" One-time setup register this AGENT wallet:"));
34
+ console.log(chalk.bold(" One-time setup - register this AGENT wallet:"));
35
35
  console.log(` 1. Log in to ${chalk.cyan(DASHBOARD)} with your owner wallet (e.g. Phantom).`);
36
- console.log(` 2. Register THIS agent wallet address (an on-chain tx owner pays gas):`);
36
+ console.log(` 2. Register THIS agent wallet address (an on-chain tx - owner pays gas):`);
37
37
  console.log(` ${chalk.yellow(addresses.solana)}`);
38
- console.log(` 3. Leave spend limits unset xPay's own guardrail handles caps; Bento adds intent screening.`);
39
- console.log(chalk.dim(" Note: the owner wallet (dashboard login) and this agent wallet are usually different "));
38
+ console.log(` 3. Leave spend limits unset - xPay's own guardrail handles caps; Bento adds intent screening.`);
39
+ console.log(chalk.dim(" Note: the owner wallet (dashboard login) and this agent wallet are usually different - "));
40
40
  console.log(chalk.dim(" register the address shown above, not your login wallet."));
41
41
  console.log("");
42
42
  console.log(chalk.dim(" From now on every pay / transfer is screened by Bento's intent"));
43
43
  console.log(chalk.dim(" analysis (prompt-injection / wallet-drain) before signing."));
44
44
  console.log(chalk.dim(" Until the address is registered, paid calls fail with a"));
45
- console.log(chalk.dim(' "not registered" error that is expected.'));
45
+ console.log(chalk.dim(' "not registered" error - that is expected.'));
46
46
  console.log("");
47
47
  }
48
48
  export function runBentoDisable(opts) {
@@ -1 +1 @@
1
- {"version":3,"file":"bento.js","sourceRoot":"","sources":["../../src/cli/bento.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,SAAS,GAAG,6BAA6B,CAAC;AAEhD,SAAS,oBAAoB,CAAC,WAAoB;IAChD,MAAM,IAAI,GAAG,WAAW,IAAI,gBAAgB,EAAE,CAAC;IAC/C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,IAAI,uCAAuC,CAAC,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA0B;IACvD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAExD,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAE5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wCAAwC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CACT,mGAAmG,CACpG,CAAC;IACF,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,4FAA4F,CAC7F,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAA0B;IACxD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yCAAyC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA0B;IACvD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAExD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,IAAI,GAAG,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"bento.js","sourceRoot":"","sources":["../../src/cli/bento.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay biometric enable|disable|status` Touch ID unlock for a profile
2
+ * `xpay biometric enable|disable|status` - Touch ID unlock for a profile
3
3
  * (macOS only). `enable` verifies the passphrase against the wallet, runs a
4
4
  * Touch ID check, then stores the passphrase in the login keychain; from
5
5
  * then on `unlockActive` offers Touch ID before falling back to typing.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `xpay biometric enable|disable|status` Touch ID unlock for a profile
2
+ * `xpay biometric enable|disable|status` - Touch ID unlock for a profile
3
3
  * (macOS only). `enable` verifies the passphrase against the wallet, runs a
4
4
  * Touch ID check, then stores the passphrase in the login keychain; from
5
5
  * then on `unlockActive` offers Touch ID before falling back to typing.
@@ -26,7 +26,7 @@ export async function runBiometricEnable(opts) {
26
26
  }
27
27
  const wallet = readWalletFile(profilePath(name));
28
28
  if (!wallet.encrypted) {
29
- console.error(chalk.red(`✗ Profile "${name}" is unencrypted (dev wallet) there is no passphrase to protect.`));
29
+ console.error(chalk.red(`✗ Profile "${name}" is unencrypted (dev wallet) - there is no passphrase to protect.`));
30
30
  process.exit(1);
31
31
  }
32
32
  let biometry;
@@ -38,7 +38,7 @@ export async function runBiometricEnable(opts) {
38
38
  process.exit(1);
39
39
  }
40
40
  if (!biometry) {
41
- console.error(chalk.red("✗ No usable biometry enroll Touch ID in System Settings first."));
41
+ console.error(chalk.red("✗ No usable biometry - enroll Touch ID in System Settings first."));
42
42
  process.exit(1);
43
43
  }
44
44
  // Verify the passphrase actually unlocks this wallet before storing it.
@@ -59,14 +59,14 @@ export async function runBiometricEnable(opts) {
59
59
  try {
60
60
  const ok = await biometricPrompt(`enable Touch ID unlock for the xPay profile "${name}"`);
61
61
  if (!ok) {
62
- console.log(chalk.yellow("Cancelled biometric unlock not enabled."));
62
+ console.log(chalk.yellow("Cancelled - biometric unlock not enabled."));
63
63
  return;
64
64
  }
65
65
  await storeBiometricPassphrase(name, passphrase);
66
66
  }
67
67
  catch (err) {
68
68
  const msg = err instanceof BiometricUnavailableError
69
- ? `${err.message} biometric unlock not enabled.`
69
+ ? `${err.message} - biometric unlock not enabled.`
70
70
  : err.message;
71
71
  console.error(chalk.red(`✗ ${msg}`));
72
72
  process.exit(1);
@@ -75,7 +75,7 @@ export async function runBiometricEnable(opts) {
75
75
  console.log("");
76
76
  console.log(chalk.green(`✔ Touch ID unlock enabled for "${name}".`));
77
77
  console.log(chalk.dim(" The passphrase now lives in your login keychain, gated by Touch ID."));
78
- console.log(chalk.dim(" macOS may ask once to allow keychain access choose \"Always Allow\"."));
78
+ console.log(chalk.dim(" macOS may ask once to allow keychain access - choose \"Always Allow\"."));
79
79
  console.log(chalk.dim(" Your passphrase still works everywhere and remains the recovery path."));
80
80
  }
81
81
  export async function runBiometricDisable(opts) {
@@ -88,10 +88,10 @@ export async function runBiometricDisable(opts) {
88
88
  console.error(chalk.red(`✗ ${err.message}`));
89
89
  process.exit(1);
90
90
  }
91
- // Helper unbuildable (e.g. CLT removed) still clear the config flag.
91
+ // Helper unbuildable (e.g. CLT removed) - still clear the config flag.
92
92
  }
93
93
  setProfileBiometric(name, false);
94
- console.log(chalk.green(`✔ Touch ID unlock disabled for "${name}" keychain entry removed.`));
94
+ console.log(chalk.green(`✔ Touch ID unlock disabled for "${name}" - keychain entry removed.`));
95
95
  }
96
96
  export async function runBiometricStatus(profileName) {
97
97
  const name = resolveProfileOrExit(profileName);