agentcash 0.3.1 → 0.3.3

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 (32) hide show
  1. package/dist/cjs/run-server.cjs +1473 -3900
  2. package/dist/esm/chunk-2EHPJVCX.js +363 -0
  3. package/dist/esm/chunk-2EHPJVCX.js.map +1 -0
  4. package/dist/esm/{chunk-WL5N26N4.js → chunk-ITXG5QJ3.js} +5 -5
  5. package/dist/esm/{chunk-EDWPR5IJ.js → chunk-PJFATGPH.js} +28 -80
  6. package/dist/esm/chunk-PJFATGPH.js.map +1 -0
  7. package/dist/esm/{chunk-Y5BSCN5L.js → chunk-QUSINJQZ.js} +82 -22
  8. package/dist/esm/chunk-QUSINJQZ.js.map +1 -0
  9. package/dist/esm/chunk-WQANIP2X.js +22 -0
  10. package/dist/esm/chunk-WQANIP2X.js.map +1 -0
  11. package/dist/esm/{commands-XFTEJGGT.js → commands-7TBWTLKT.js} +12 -10
  12. package/dist/esm/commands-7TBWTLKT.js.map +1 -0
  13. package/dist/esm/{fund-56IKTU6D.js → fund-BJFTXRRM.js} +4 -4
  14. package/dist/esm/index.js +9 -9
  15. package/dist/esm/{install-WZ2WOFCE.js → install-QNDIKJT7.js} +7 -7
  16. package/dist/esm/install-QNDIKJT7.js.map +1 -0
  17. package/dist/esm/{server-B4N6JKFY.js → server-3ZQQXMUD.js} +50 -100
  18. package/dist/esm/server-3ZQQXMUD.js.map +1 -0
  19. package/dist/esm/shared/operations/index.d.ts +18 -18
  20. package/dist/esm/shared/operations/index.js +3 -3
  21. package/package.json +7 -5
  22. package/dist/esm/chunk-4Z3HKYI5.js +0 -190
  23. package/dist/esm/chunk-4Z3HKYI5.js.map +0 -1
  24. package/dist/esm/chunk-EDWPR5IJ.js.map +0 -1
  25. package/dist/esm/chunk-QO2UZVLV.js +0 -52
  26. package/dist/esm/chunk-QO2UZVLV.js.map +0 -1
  27. package/dist/esm/chunk-Y5BSCN5L.js.map +0 -1
  28. package/dist/esm/commands-XFTEJGGT.js.map +0 -1
  29. package/dist/esm/install-WZ2WOFCE.js.map +0 -1
  30. package/dist/esm/server-B4N6JKFY.js.map +0 -1
  31. /package/dist/esm/{chunk-WL5N26N4.js.map → chunk-ITXG5QJ3.js.map} +0 -0
  32. /package/dist/esm/{fund-56IKTU6D.js.map → fund-BJFTXRRM.js.map} +0 -0
@@ -0,0 +1,363 @@
1
+ import {
2
+ LEGACY_DIRECTORY,
3
+ configFile,
4
+ err,
5
+ fsErr,
6
+ getBalance,
7
+ getBaseUrl,
8
+ log,
9
+ ok,
10
+ resultFromPromise,
11
+ resultFromThrowable,
12
+ safeChmod,
13
+ safeFetchJson,
14
+ safeParse,
15
+ safeReadFile,
16
+ safeWriteFile
17
+ } from "./chunk-PJFATGPH.js";
18
+
19
+ // src/shared/wallet.ts
20
+ import { existsSync, readFileSync } from "fs";
21
+ import { join } from "path";
22
+ import { getAddress } from "viem";
23
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
24
+ import z from "zod";
25
+
26
+ // src/shared/neverthrow/json/index.ts
27
+ var type = "json";
28
+ var jsonErr = (surface, error) => {
29
+ return err(type, surface, error);
30
+ };
31
+ var safeStringifyJson = (surface, value) => {
32
+ return resultFromThrowable(
33
+ type,
34
+ surface,
35
+ () => JSON.stringify(value, null, 2),
36
+ () => ({
37
+ cause: "stringify",
38
+ message: "Could not stringify JSON"
39
+ })
40
+ );
41
+ };
42
+ var safeParseJson = (surface, value) => {
43
+ return resultFromThrowable(
44
+ type,
45
+ surface,
46
+ () => JSON.parse(value),
47
+ (e) => ({
48
+ cause: "parse",
49
+ message: e instanceof Error ? e.message : "Could not parse JSON"
50
+ })
51
+ );
52
+ };
53
+
54
+ // src/shared/wallet.ts
55
+ var WALLET_FILE = configFile("wallet.json");
56
+ var storedWalletSchema = z.object({
57
+ privateKey: z.string().regex(/^0x[a-fA-F0-9]{64}$/, "Invalid Ethereum private key").transform((privateKey) => privateKey),
58
+ address: z.string().regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address").transform((address) => getAddress(address)),
59
+ createdAt: z.string()
60
+ });
61
+ var walletSurface = "wallet";
62
+ var LEGACY_WALLET = join(LEGACY_DIRECTORY, "wallet.json");
63
+ var reconcileSurface = "wallet-reconcile";
64
+ async function reconcileLegacyWallet(current, isNew) {
65
+ const noChange = { account: current, isNew };
66
+ if (!existsSync(LEGACY_WALLET)) {
67
+ return noChange;
68
+ }
69
+ const legacyResult = resultFromThrowable(
70
+ "wallet",
71
+ reconcileSurface,
72
+ () => {
73
+ const raw = readFileSync(LEGACY_WALLET, "utf-8");
74
+ return storedWalletSchema.parse(JSON.parse(raw));
75
+ },
76
+ () => ({
77
+ cause: "file_not_readable",
78
+ message: "Legacy wallet exists but is invalid"
79
+ })
80
+ );
81
+ if (legacyResult.isErr()) {
82
+ log.info("Legacy wallet exists but is invalid, skipping reconciliation");
83
+ return noChange;
84
+ }
85
+ const legacyKey = legacyResult.value.privateKey;
86
+ const legacyAccount = privateKeyToAccount(legacyKey);
87
+ if (legacyAccount.address === current.address) {
88
+ return noChange;
89
+ }
90
+ const flags = { dev: false };
91
+ const balancesResult = await resultFromPromise(
92
+ "wallet",
93
+ reconcileSurface,
94
+ Promise.all([
95
+ getBalance({
96
+ address: legacyAccount.address,
97
+ flags,
98
+ surface: reconcileSurface
99
+ }),
100
+ getBalance({
101
+ address: current.address,
102
+ flags,
103
+ surface: reconcileSurface
104
+ })
105
+ ]),
106
+ () => ({
107
+ cause: "balance_check",
108
+ message: "Network error during wallet reconciliation"
109
+ })
110
+ );
111
+ if (balancesResult.isErr()) {
112
+ log.info("Network error during wallet reconciliation, skipping");
113
+ return noChange;
114
+ }
115
+ const [legacyBalanceResult, currentBalanceResult] = balancesResult.value;
116
+ if (legacyBalanceResult.isErr() || currentBalanceResult.isErr()) {
117
+ log.info("Could not check balances for wallet reconciliation, skipping");
118
+ return noChange;
119
+ }
120
+ const legacyBalance = legacyBalanceResult.value.balance;
121
+ const currentBalance = currentBalanceResult.value.balance;
122
+ if (legacyBalance > 0 && currentBalance === 0) {
123
+ log.info(
124
+ `Recovering funded legacy wallet ${legacyAccount.address} (balance: ${legacyBalance})`
125
+ );
126
+ const stored = {
127
+ privateKey: legacyKey,
128
+ address: legacyAccount.address,
129
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
130
+ };
131
+ const writeResult = await safeWriteFile(
132
+ reconcileSurface,
133
+ WALLET_FILE,
134
+ JSON.stringify(stored, null, 2)
135
+ ).andThen(() => safeChmod(reconcileSurface, WALLET_FILE, 384));
136
+ if (writeResult.isErr()) {
137
+ log.error(
138
+ `Failed to write recovered wallet: ${writeResult.error.message}`
139
+ );
140
+ return noChange;
141
+ }
142
+ return { account: legacyAccount, isNew: false };
143
+ }
144
+ if (legacyBalance > 0 && currentBalance > 0) {
145
+ log.info(
146
+ `Both wallets have funds. Current: ${current.address} (${currentBalance}), Legacy: ${legacyAccount.address} (${legacyBalance}). Manually copy ${LEGACY_WALLET} to ${WALLET_FILE} if you want to use the legacy wallet.`
147
+ );
148
+ return noChange;
149
+ }
150
+ return noChange;
151
+ }
152
+ async function getWallet() {
153
+ if (process.env.X402_PRIVATE_KEY) {
154
+ const account2 = privateKeyToAccount(process.env.X402_PRIVATE_KEY);
155
+ log.info(`Using wallet from env: ${account2.address}`);
156
+ return ok({ account: account2, isNew: false });
157
+ }
158
+ const readFileResult = await safeReadFile(walletSurface, WALLET_FILE);
159
+ if (!readFileResult.isOk()) {
160
+ const fileExistsResult = existsSync(WALLET_FILE);
161
+ if (fileExistsResult) {
162
+ return fsErr(walletSurface, {
163
+ cause: "file_not_readable",
164
+ message: `The file exists but is not readable. Fix corrupted state file: ${WALLET_FILE}`
165
+ });
166
+ }
167
+ }
168
+ if (readFileResult.isOk()) {
169
+ const data = readFileResult.value;
170
+ const jsonParseResult = safeParseJson(walletSurface, data);
171
+ if (jsonParseResult.isErr()) {
172
+ return jsonErr(walletSurface, {
173
+ cause: "parse",
174
+ message: `The data in ${WALLET_FILE} is not valid JSON`
175
+ });
176
+ }
177
+ const parseResult = safeParse(
178
+ walletSurface,
179
+ storedWalletSchema,
180
+ jsonParseResult.value
181
+ );
182
+ if (parseResult.isErr()) {
183
+ return parseResult;
184
+ }
185
+ const account2 = privateKeyToAccount(parseResult.value.privateKey);
186
+ log.info(`Loaded wallet: ${account2.address}`);
187
+ const reconciled2 = await reconcileLegacyWallet(account2, false);
188
+ return ok(reconciled2);
189
+ }
190
+ const privateKey = generatePrivateKey();
191
+ const account = privateKeyToAccount(privateKey);
192
+ const stored = {
193
+ privateKey,
194
+ address: account.address,
195
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
196
+ };
197
+ const saveResult = await safeWriteFile(
198
+ walletSurface,
199
+ WALLET_FILE,
200
+ JSON.stringify(stored, null, 2)
201
+ ).andThen(() => safeChmod(walletSurface, WALLET_FILE, 384));
202
+ if (saveResult.isErr()) {
203
+ return saveResult;
204
+ }
205
+ log.info(`Created wallet: ${account.address}`);
206
+ log.info(`Saved to: ${WALLET_FILE}`);
207
+ const reconciled = await reconcileLegacyWallet(account, true);
208
+ return ok(reconciled);
209
+ }
210
+
211
+ // src/shared/redeem-invite.ts
212
+ import z3 from "zod";
213
+
214
+ // src/shared/state.ts
215
+ import z2 from "zod";
216
+ import fs from "fs";
217
+ var STATE_FILE = configFile("state.json");
218
+ var stateSchema = z2.looseObject({
219
+ redeemedCodes: z2.array(z2.string())
220
+ }).partial();
221
+ var getState = () => {
222
+ const stateFileExists = fs.existsSync(STATE_FILE);
223
+ if (!stateFileExists) {
224
+ fs.writeFileSync(STATE_FILE, "{}");
225
+ return {};
226
+ }
227
+ const stateFileContent = fs.readFileSync(STATE_FILE, "utf-8");
228
+ const result = stateSchema.safeParse(JSON.parse(stateFileContent));
229
+ if (!result.success) {
230
+ return {};
231
+ }
232
+ return result.data;
233
+ };
234
+ var setState = (state) => {
235
+ const existing = getState();
236
+ const newState = stateSchema.parse({ ...existing, ...state });
237
+ fs.writeFileSync(STATE_FILE, JSON.stringify(newState, null, 2));
238
+ };
239
+
240
+ // src/shared/redeem-invite.ts
241
+ var redeemInviteCode = async ({
242
+ code,
243
+ dev,
244
+ address,
245
+ surface
246
+ }) => {
247
+ const state = getState();
248
+ if (state.redeemedCodes?.includes(code)) {
249
+ return err("user", surface, {
250
+ cause: "conflict",
251
+ message: "This invite code has already been redeemed"
252
+ });
253
+ }
254
+ const result = await safeFetchJson(
255
+ surface,
256
+ new Request(`${getBaseUrl(dev)}/api/invite/redeem`, {
257
+ method: "POST",
258
+ headers: {
259
+ "Content-Type": "application/json"
260
+ },
261
+ body: JSON.stringify({
262
+ code,
263
+ recipientAddr: address
264
+ })
265
+ }),
266
+ z3.object({
267
+ redemptionId: z3.string(),
268
+ txHash: z3.string(),
269
+ amount: z3.coerce.number()
270
+ })
271
+ );
272
+ if (result.isOk()) {
273
+ setState({
274
+ redeemedCodes: [...state.redeemedCodes ?? [], code]
275
+ });
276
+ }
277
+ return result;
278
+ };
279
+
280
+ // src/shared/networks.ts
281
+ import {
282
+ base,
283
+ baseSepolia,
284
+ mainnet,
285
+ sepolia,
286
+ optimism,
287
+ arbitrum,
288
+ polygon
289
+ } from "viem/chains";
290
+ var CHAIN_CONFIGS = {
291
+ "eip155:8453": {
292
+ chain: base,
293
+ caip2: "eip155:8453",
294
+ v1Name: "base",
295
+ usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
296
+ },
297
+ "eip155:84532": {
298
+ chain: baseSepolia,
299
+ caip2: "eip155:84532",
300
+ v1Name: "base-sepolia",
301
+ usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
302
+ },
303
+ "eip155:1": {
304
+ chain: mainnet,
305
+ caip2: "eip155:1",
306
+ v1Name: "ethereum",
307
+ usdcAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
308
+ },
309
+ "eip155:11155111": {
310
+ chain: sepolia,
311
+ caip2: "eip155:11155111",
312
+ v1Name: "ethereum-sepolia",
313
+ usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
314
+ },
315
+ "eip155:10": {
316
+ chain: optimism,
317
+ caip2: "eip155:10",
318
+ v1Name: "optimism",
319
+ usdcAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
320
+ },
321
+ "eip155:42161": {
322
+ chain: arbitrum,
323
+ caip2: "eip155:42161",
324
+ v1Name: "arbitrum",
325
+ usdcAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
326
+ },
327
+ "eip155:137": {
328
+ chain: polygon,
329
+ caip2: "eip155:137",
330
+ v1Name: "polygon",
331
+ usdcAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
332
+ }
333
+ };
334
+ var V1_TO_CAIP2 = {
335
+ base: "eip155:8453",
336
+ "base-sepolia": "eip155:84532",
337
+ ethereum: "eip155:1",
338
+ "ethereum-sepolia": "eip155:11155111",
339
+ optimism: "eip155:10",
340
+ arbitrum: "eip155:42161",
341
+ polygon: "eip155:137"
342
+ };
343
+ var DEFAULT_NETWORK = "eip155:8453";
344
+ function toCaip2(network) {
345
+ if (network.startsWith("eip155:")) return network;
346
+ return V1_TO_CAIP2[network.toLowerCase()] ?? network;
347
+ }
348
+ function getChainConfig(network) {
349
+ return CHAIN_CONFIGS[toCaip2(network)];
350
+ }
351
+ function getChainName(network) {
352
+ return getChainConfig(network)?.chain.name ?? network;
353
+ }
354
+
355
+ export {
356
+ DEFAULT_NETWORK,
357
+ getChainName,
358
+ safeStringifyJson,
359
+ safeParseJson,
360
+ getWallet,
361
+ redeemInviteCode
362
+ };
363
+ //# sourceMappingURL=chunk-2EHPJVCX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/wallet.ts","../../src/shared/neverthrow/json/index.ts","../../src/shared/redeem-invite.ts","../../src/shared/state.ts","../../src/shared/networks.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n\nimport { getAddress } from 'viem';\nimport { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';\n\nimport z from 'zod';\n\nimport {\n ok,\n resultFromThrowable,\n resultFromPromise,\n} from '@agentcash/neverthrow';\n\nimport {\n fsErr,\n safeChmod,\n safeReadFile,\n safeWriteFile,\n} from '@/shared/neverthrow/fs';\nimport { jsonErr, safeParseJson } from '@/shared/neverthrow/json';\nimport { safeParse } from '@/shared/neverthrow/parse';\nimport { getBalance } from '@/shared/balance';\n\nimport { log } from './log';\nimport { configFile, LEGACY_DIRECTORY } from './fs';\n\nimport type { Hex } from 'viem';\nimport type { PrivateKeyAccount } from 'viem/accounts';\n\nconst WALLET_FILE = configFile('wallet.json');\n\nconst storedWalletSchema = z.object({\n privateKey: z\n .string()\n .regex(/^0x[a-fA-F0-9]{64}$/, 'Invalid Ethereum private key')\n .transform(privateKey => privateKey as Hex),\n address: z\n .string()\n .regex(/^0x[a-fA-F0-9]{40}$/, 'Invalid Ethereum address')\n .transform(address => getAddress(address)),\n createdAt: z.string(),\n});\n\nconst walletSurface = 'wallet';\n\nconst LEGACY_WALLET = join(LEGACY_DIRECTORY, 'wallet.json');\n\nconst reconcileSurface = 'wallet-reconcile';\n\nasync function reconcileLegacyWallet(\n current: PrivateKeyAccount,\n isNew: boolean\n): Promise<{ account: PrivateKeyAccount; isNew: boolean }> {\n const noChange = { account: current, isNew };\n\n // 1. No legacy wallet → nothing to reconcile\n if (!existsSync(LEGACY_WALLET)) {\n return noChange;\n }\n\n // 2. Read & parse legacy wallet\n const legacyResult = resultFromThrowable(\n 'wallet',\n reconcileSurface,\n () => {\n const raw = readFileSync(LEGACY_WALLET, 'utf-8');\n return storedWalletSchema.parse(JSON.parse(raw));\n },\n () => ({\n cause: 'file_not_readable' as const,\n message: 'Legacy wallet exists but is invalid',\n })\n );\n\n if (legacyResult.isErr()) {\n log.info('Legacy wallet exists but is invalid, skipping reconciliation');\n return noChange;\n }\n\n const legacyKey = legacyResult.value.privateKey;\n\n // 3. Same key → already reconciled\n const legacyAccount = privateKeyToAccount(legacyKey);\n if (legacyAccount.address === current.address) {\n return noChange;\n }\n\n // 4. Keys differ → check balances\n const flags = { dev: false };\n\n const balancesResult = await resultFromPromise(\n 'wallet',\n reconcileSurface,\n Promise.all([\n getBalance({\n address: legacyAccount.address,\n flags,\n surface: reconcileSurface,\n }),\n getBalance({\n address: current.address,\n flags,\n surface: reconcileSurface,\n }),\n ]),\n () => ({\n cause: 'balance_check' as const,\n message: 'Network error during wallet reconciliation',\n })\n );\n\n if (balancesResult.isErr()) {\n log.info('Network error during wallet reconciliation, skipping');\n return noChange;\n }\n\n const [legacyBalanceResult, currentBalanceResult] = balancesResult.value;\n\n if (legacyBalanceResult.isErr() || currentBalanceResult.isErr()) {\n log.info('Could not check balances for wallet reconciliation, skipping');\n return noChange;\n }\n\n const legacyBalance = legacyBalanceResult.value.balance;\n const currentBalance = currentBalanceResult.value.balance;\n\n // 4a. Legacy has balance, current is empty → recover legacy\n if (legacyBalance > 0 && currentBalance === 0) {\n log.info(\n `Recovering funded legacy wallet ${legacyAccount.address} (balance: ${legacyBalance})`\n );\n const stored = {\n privateKey: legacyKey,\n address: legacyAccount.address,\n createdAt: new Date().toISOString(),\n };\n const writeResult = await safeWriteFile(\n reconcileSurface,\n WALLET_FILE,\n JSON.stringify(stored, null, 2)\n ).andThen(() => safeChmod(reconcileSurface, WALLET_FILE, 0o600));\n\n if (writeResult.isErr()) {\n log.error(\n `Failed to write recovered wallet: ${writeResult.error.message}`\n );\n return noChange;\n }\n\n return { account: legacyAccount, isNew: false };\n }\n\n // 4b. Both have balance → manual intervention needed\n if (legacyBalance > 0 && currentBalance > 0) {\n log.info(\n `Both wallets have funds. Current: ${current.address} (${currentBalance}), Legacy: ${legacyAccount.address} (${legacyBalance}). ` +\n `Manually copy ${LEGACY_WALLET} to ${WALLET_FILE} if you want to use the legacy wallet.`\n );\n return noChange;\n }\n\n // 4c. Legacy has no balance → nothing to recover\n return noChange;\n}\n\nexport async function getWallet() {\n if (process.env.X402_PRIVATE_KEY) {\n const account = privateKeyToAccount(process.env.X402_PRIVATE_KEY as Hex);\n log.info(`Using wallet from env: ${account.address}`);\n return ok({ account, isNew: false });\n }\n\n const readFileResult = await safeReadFile(walletSurface, WALLET_FILE);\n\n if (!readFileResult.isOk()) {\n const fileExistsResult = existsSync(WALLET_FILE);\n // file exists but is not readable\n if (fileExistsResult) {\n return fsErr(walletSurface, {\n cause: 'file_not_readable',\n message: `The file exists but is not readable. Fix corrupted state file: ${WALLET_FILE}`,\n });\n }\n }\n\n if (readFileResult.isOk()) {\n const data = readFileResult.value;\n const jsonParseResult = safeParseJson(walletSurface, data);\n\n // file exists but is not valid JSON\n if (jsonParseResult.isErr()) {\n return jsonErr(walletSurface, {\n cause: 'parse',\n message: `The data in ${WALLET_FILE} is not valid JSON`,\n });\n }\n\n const parseResult = safeParse(\n walletSurface,\n storedWalletSchema,\n jsonParseResult.value\n );\n\n // file has valid JSON but is not a valid wallet configuration\n if (parseResult.isErr()) {\n return parseResult;\n }\n\n const account = privateKeyToAccount(parseResult.value.privateKey);\n log.info(`Loaded wallet: ${account.address}`);\n const reconciled = await reconcileLegacyWallet(account, false);\n return ok(reconciled);\n }\n\n // Generate new\n const privateKey = generatePrivateKey();\n const account = privateKeyToAccount(privateKey);\n const stored = {\n privateKey,\n address: account.address,\n createdAt: new Date().toISOString(),\n };\n\n const saveResult = await safeWriteFile(\n walletSurface,\n WALLET_FILE,\n JSON.stringify(stored, null, 2)\n ).andThen(() => safeChmod(walletSurface, WALLET_FILE, 0o600));\n\n if (saveResult.isErr()) {\n return saveResult;\n }\n\n log.info(`Created wallet: ${account.address}`);\n log.info(`Saved to: ${WALLET_FILE}`);\n\n const reconciled = await reconcileLegacyWallet(account, true);\n return ok(reconciled);\n}\n","import { err, resultFromThrowable } from '@agentcash/neverthrow';\n\nimport type { BaseJsonError, JsonObject } from './types';\n\nconst type = 'json';\n\nexport const jsonErr = (surface: string, error: BaseJsonError) => {\n return err(type, surface, error);\n};\n\nexport const safeStringifyJson = (surface: string, value: JsonObject) => {\n return resultFromThrowable(\n type,\n surface,\n () => JSON.stringify(value, null, 2),\n () => ({\n cause: 'stringify' as const,\n message: 'Could not stringify JSON',\n })\n );\n};\n\nexport const safeParseJson = (surface: string, value: string) => {\n return resultFromThrowable(\n type,\n surface,\n () => JSON.parse(value) as JsonObject,\n e => ({\n cause: 'parse' as const,\n message: e instanceof Error ? e.message : 'Could not parse JSON',\n })\n );\n};\n","import z from 'zod';\n\nimport { safeFetchJson } from '@/shared/neverthrow/fetch';\nimport { err } from '@agentcash/neverthrow';\n\nimport { getBaseUrl } from './utils';\nimport { getState, setState } from './state';\n\nimport type { Address } from 'viem';\n\nexport interface RedeemInviteProps {\n code: string;\n dev: boolean;\n address: Address;\n surface: string;\n}\n\nexport const redeemInviteCode = async ({\n code,\n dev,\n address,\n surface,\n}: RedeemInviteProps) => {\n const state = getState();\n\n if (state.redeemedCodes?.includes(code)) {\n return err('user', surface, {\n cause: 'conflict',\n message: 'This invite code has already been redeemed',\n });\n }\n\n const result = await safeFetchJson(\n surface,\n new Request(`${getBaseUrl(dev)}/api/invite/redeem`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n code,\n recipientAddr: address,\n }),\n }),\n z.object({\n redemptionId: z.string(),\n txHash: z.string(),\n amount: z.coerce.number(),\n })\n );\n\n if (result.isOk()) {\n setState({\n redeemedCodes: [...(state.redeemedCodes ?? []), code],\n });\n }\n\n return result;\n};\n","import z from 'zod';\nimport fs from 'fs';\n\nimport { configFile } from './fs';\n\nconst STATE_FILE = configFile('state.json');\n\nconst stateSchema = z\n .looseObject({\n redeemedCodes: z.array(z.string()),\n })\n .partial();\n\nexport const getState = () => {\n const stateFileExists = fs.existsSync(STATE_FILE);\n if (!stateFileExists) {\n fs.writeFileSync(STATE_FILE, '{}');\n return {};\n }\n\n const stateFileContent = fs.readFileSync(STATE_FILE, 'utf-8');\n const result = stateSchema.safeParse(JSON.parse(stateFileContent));\n if (!result.success) {\n return {};\n }\n return result.data;\n};\n\nexport const setState = (state: z.infer<typeof stateSchema>) => {\n const existing = getState();\n const newState = stateSchema.parse({ ...existing, ...state });\n fs.writeFileSync(STATE_FILE, JSON.stringify(newState, null, 2));\n};\n","import {\n base,\n baseSepolia,\n mainnet,\n sepolia,\n optimism,\n arbitrum,\n polygon,\n} from 'viem/chains';\n\nimport type { Chain } from 'viem';\n\nexport interface ChainConfig {\n chain: Chain;\n caip2: string;\n v1Name: string;\n usdcAddress: `0x${string}`;\n}\n\nconst CHAIN_CONFIGS: Record<string, ChainConfig> = {\n 'eip155:8453': {\n chain: base,\n caip2: 'eip155:8453',\n v1Name: 'base',\n usdcAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n },\n 'eip155:84532': {\n chain: baseSepolia,\n caip2: 'eip155:84532',\n v1Name: 'base-sepolia',\n usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n },\n 'eip155:1': {\n chain: mainnet,\n caip2: 'eip155:1',\n v1Name: 'ethereum',\n usdcAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n },\n 'eip155:11155111': {\n chain: sepolia,\n caip2: 'eip155:11155111',\n v1Name: 'ethereum-sepolia',\n usdcAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n },\n 'eip155:10': {\n chain: optimism,\n caip2: 'eip155:10',\n v1Name: 'optimism',\n usdcAddress: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n },\n 'eip155:42161': {\n chain: arbitrum,\n caip2: 'eip155:42161',\n v1Name: 'arbitrum',\n usdcAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n },\n 'eip155:137': {\n chain: polygon,\n caip2: 'eip155:137',\n v1Name: 'polygon',\n usdcAddress: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n },\n};\n\nconst V1_TO_CAIP2: Record<string, string> = {\n base: 'eip155:8453',\n 'base-sepolia': 'eip155:84532',\n ethereum: 'eip155:1',\n 'ethereum-sepolia': 'eip155:11155111',\n optimism: 'eip155:10',\n arbitrum: 'eip155:42161',\n polygon: 'eip155:137',\n};\n\nexport const DEFAULT_NETWORK = 'eip155:8453';\n\n/** Convert any network identifier to CAIP-2 format */\nexport function toCaip2(network: string): string {\n if (network.startsWith('eip155:')) return network;\n return V1_TO_CAIP2[network.toLowerCase()] ?? network;\n}\n\n/** Get chain config from network identifier */\nexport function getChainConfig(network: string): ChainConfig | undefined {\n return CHAIN_CONFIGS[toCaip2(network)];\n}\n\n/** Get USDC address for a network */\nexport function getUSDCAddress(network: string): `0x${string}` | undefined {\n return getChainConfig(network)?.usdcAddress;\n}\n\n/** Extract chain ID from CAIP-2 identifier */\nexport function getChainId(network: string): number | undefined {\n const caip2 = toCaip2(network);\n const match = /^eip155:(\\d+)$/.exec(caip2);\n return match ? parseInt(match[1]!, 10) : undefined;\n}\n\n/** Get human-readable chain name */\nexport function getChainName(network: string): string {\n return getChainConfig(network)?.chain.name ?? network;\n}\n\n/** Check if network is a testnet */\nexport function isTestnet(network: string): boolean {\n return getChainConfig(network)?.chain.testnet === true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AAErB,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB,2BAA2B;AAExD,OAAO,OAAO;;;ACFd,IAAM,OAAO;AAEN,IAAM,UAAU,CAAC,SAAiB,UAAyB;AAChE,SAAO,IAAI,MAAM,SAAS,KAAK;AACjC;AAEO,IAAM,oBAAoB,CAAC,SAAiB,UAAsB;AACvE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,IACnC,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEO,IAAM,gBAAgB,CAAC,SAAiB,UAAkB;AAC/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK,MAAM,KAAK;AAAA,IACtB,QAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS,aAAa,QAAQ,EAAE,UAAU;AAAA,IAC5C;AAAA,EACF;AACF;;;ADFA,IAAM,cAAc,WAAW,aAAa;AAE5C,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,YAAY,EACT,OAAO,EACP,MAAM,uBAAuB,8BAA8B,EAC3D,UAAU,gBAAc,UAAiB;AAAA,EAC5C,SAAS,EACN,OAAO,EACP,MAAM,uBAAuB,0BAA0B,EACvD,UAAU,aAAW,WAAW,OAAO,CAAC;AAAA,EAC3C,WAAW,EAAE,OAAO;AACtB,CAAC;AAED,IAAM,gBAAgB;AAEtB,IAAM,gBAAgB,KAAK,kBAAkB,aAAa;AAE1D,IAAM,mBAAmB;AAEzB,eAAe,sBACb,SACA,OACyD;AACzD,QAAM,WAAW,EAAE,SAAS,SAAS,MAAM;AAG3C,MAAI,CAAC,WAAW,aAAa,GAAG;AAC9B,WAAO;AAAA,EACT;AAGA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA,MAAM;AACJ,YAAM,MAAM,aAAa,eAAe,OAAO;AAC/C,aAAO,mBAAmB,MAAM,KAAK,MAAM,GAAG,CAAC;AAAA,IACjD;AAAA,IACA,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,aAAa,MAAM,GAAG;AACxB,QAAI,KAAK,8DAA8D;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,aAAa,MAAM;AAGrC,QAAM,gBAAgB,oBAAoB,SAAS;AACnD,MAAI,cAAc,YAAY,QAAQ,SAAS;AAC7C,WAAO;AAAA,EACT;AAGA,QAAM,QAAQ,EAAE,KAAK,MAAM;AAE3B,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,QAAQ,IAAI;AAAA,MACV,WAAW;AAAA,QACT,SAAS,cAAc;AAAA,QACvB;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAAA,MACD,WAAW;AAAA,QACT,SAAS,QAAQ;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AAAA,IACH,CAAC;AAAA,IACD,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,eAAe,MAAM,GAAG;AAC1B,QAAI,KAAK,sDAAsD;AAC/D,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,qBAAqB,oBAAoB,IAAI,eAAe;AAEnE,MAAI,oBAAoB,MAAM,KAAK,qBAAqB,MAAM,GAAG;AAC/D,QAAI,KAAK,8DAA8D;AACvE,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,oBAAoB,MAAM;AAChD,QAAM,iBAAiB,qBAAqB,MAAM;AAGlD,MAAI,gBAAgB,KAAK,mBAAmB,GAAG;AAC7C,QAAI;AAAA,MACF,mCAAmC,cAAc,OAAO,cAAc,aAAa;AAAA,IACrF;AACA,UAAM,SAAS;AAAA,MACb,YAAY;AAAA,MACZ,SAAS,cAAc;AAAA,MACvB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AACA,UAAM,cAAc,MAAM;AAAA,MACxB;AAAA,MACA;AAAA,MACA,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,IAChC,EAAE,QAAQ,MAAM,UAAU,kBAAkB,aAAa,GAAK,CAAC;AAE/D,QAAI,YAAY,MAAM,GAAG;AACvB,UAAI;AAAA,QACF,qCAAqC,YAAY,MAAM,OAAO;AAAA,MAChE;AACA,aAAO;AAAA,IACT;AAEA,WAAO,EAAE,SAAS,eAAe,OAAO,MAAM;AAAA,EAChD;AAGA,MAAI,gBAAgB,KAAK,iBAAiB,GAAG;AAC3C,QAAI;AAAA,MACF,qCAAqC,QAAQ,OAAO,KAAK,cAAc,cAAc,cAAc,OAAO,KAAK,aAAa,oBACzG,aAAa,OAAO,WAAW;AAAA,IACpD;AACA,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAEA,eAAsB,YAAY;AAChC,MAAI,QAAQ,IAAI,kBAAkB;AAChC,UAAMA,WAAU,oBAAoB,QAAQ,IAAI,gBAAuB;AACvE,QAAI,KAAK,0BAA0BA,SAAQ,OAAO,EAAE;AACpD,WAAO,GAAG,EAAE,SAAAA,UAAS,OAAO,MAAM,CAAC;AAAA,EACrC;AAEA,QAAM,iBAAiB,MAAM,aAAa,eAAe,WAAW;AAEpE,MAAI,CAAC,eAAe,KAAK,GAAG;AAC1B,UAAM,mBAAmB,WAAW,WAAW;AAE/C,QAAI,kBAAkB;AACpB,aAAO,MAAM,eAAe;AAAA,QAC1B,OAAO;AAAA,QACP,SAAS,kEAAkE,WAAW;AAAA,MACxF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,eAAe,KAAK,GAAG;AACzB,UAAM,OAAO,eAAe;AAC5B,UAAM,kBAAkB,cAAc,eAAe,IAAI;AAGzD,QAAI,gBAAgB,MAAM,GAAG;AAC3B,aAAO,QAAQ,eAAe;AAAA,QAC5B,OAAO;AAAA,QACP,SAAS,eAAe,WAAW;AAAA,MACrC,CAAC;AAAA,IACH;AAEA,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IAClB;AAGA,QAAI,YAAY,MAAM,GAAG;AACvB,aAAO;AAAA,IACT;AAEA,UAAMA,WAAU,oBAAoB,YAAY,MAAM,UAAU;AAChE,QAAI,KAAK,kBAAkBA,SAAQ,OAAO,EAAE;AAC5C,UAAMC,cAAa,MAAM,sBAAsBD,UAAS,KAAK;AAC7D,WAAO,GAAGC,WAAU;AAAA,EACtB;AAGA,QAAM,aAAa,mBAAmB;AACtC,QAAM,UAAU,oBAAoB,UAAU;AAC9C,QAAM,SAAS;AAAA,IACb;AAAA,IACA,SAAS,QAAQ;AAAA,IACjB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,EAChC,EAAE,QAAQ,MAAM,UAAU,eAAe,aAAa,GAAK,CAAC;AAE5D,MAAI,WAAW,MAAM,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,MAAI,KAAK,mBAAmB,QAAQ,OAAO,EAAE;AAC7C,MAAI,KAAK,aAAa,WAAW,EAAE;AAEnC,QAAM,aAAa,MAAM,sBAAsB,SAAS,IAAI;AAC5D,SAAO,GAAG,UAAU;AACtB;;;AE/OA,OAAOC,QAAO;;;ACAd,OAAOC,QAAO;AACd,OAAO,QAAQ;AAIf,IAAM,aAAa,WAAW,YAAY;AAE1C,IAAM,cAAcC,GACjB,YAAY;AAAA,EACX,eAAeA,GAAE,MAAMA,GAAE,OAAO,CAAC;AACnC,CAAC,EACA,QAAQ;AAEJ,IAAM,WAAW,MAAM;AAC5B,QAAM,kBAAkB,GAAG,WAAW,UAAU;AAChD,MAAI,CAAC,iBAAiB;AACpB,OAAG,cAAc,YAAY,IAAI;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,mBAAmB,GAAG,aAAa,YAAY,OAAO;AAC5D,QAAM,SAAS,YAAY,UAAU,KAAK,MAAM,gBAAgB,CAAC;AACjE,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO;AAChB;AAEO,IAAM,WAAW,CAAC,UAAuC;AAC9D,QAAM,WAAW,SAAS;AAC1B,QAAM,WAAW,YAAY,MAAM,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC;AAC5D,KAAG,cAAc,YAAY,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAChE;;;ADfO,IAAM,mBAAmB,OAAO;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAyB;AACvB,QAAM,QAAQ,SAAS;AAEvB,MAAI,MAAM,eAAe,SAAS,IAAI,GAAG;AACvC,WAAO,IAAI,QAAQ,SAAS;AAAA,MAC1B,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,IAAI,QAAQ,GAAG,WAAW,GAAG,CAAC,sBAAsB;AAAA,MAClD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB;AAAA,QACA,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAAA,IACDC,GAAE,OAAO;AAAA,MACP,cAAcA,GAAE,OAAO;AAAA,MACvB,QAAQA,GAAE,OAAO;AAAA,MACjB,QAAQA,GAAE,OAAO,OAAO;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,KAAK,GAAG;AACjB,aAAS;AAAA,MACP,eAAe,CAAC,GAAI,MAAM,iBAAiB,CAAC,GAAI,IAAI;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AE1DA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAWP,IAAM,gBAA6C;AAAA,EACjD,eAAe;AAAA,IACb,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,mBAAmB;AAAA,IACjB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,aAAa;AAAA,IACX,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA,cAAc;AAAA,IACZ,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AACF;AAEA,IAAM,cAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX;AAEO,IAAM,kBAAkB;AAGxB,SAAS,QAAQ,SAAyB;AAC/C,MAAI,QAAQ,WAAW,SAAS,EAAG,QAAO;AAC1C,SAAO,YAAY,QAAQ,YAAY,CAAC,KAAK;AAC/C;AAGO,SAAS,eAAe,SAA0C;AACvE,SAAO,cAAc,QAAQ,OAAO,CAAC;AACvC;AAeO,SAAS,aAAa,SAAyB;AACpD,SAAO,eAAe,OAAO,GAAG,MAAM,QAAQ;AAChD;","names":["account","reconciled","z","z","z","z"]}
@@ -1,11 +1,11 @@
1
- import {
2
- redeemInviteCode
3
- } from "./chunk-4Z3HKYI5.js";
4
1
  import {
5
2
  DEFAULT_NETWORK,
6
3
  getChainName,
4
+ redeemInviteCode
5
+ } from "./chunk-2EHPJVCX.js";
6
+ import {
7
7
  getDepositLink
8
- } from "./chunk-EDWPR5IJ.js";
8
+ } from "./chunk-PJFATGPH.js";
9
9
 
10
10
  // src/cli/lib/deposit.ts
11
11
  import chalk from "chalk";
@@ -111,4 +111,4 @@ export {
111
111
  wait,
112
112
  promptDeposit
113
113
  };
114
- //# sourceMappingURL=chunk-WL5N26N4.js.map
114
+ //# sourceMappingURL=chunk-ITXG5QJ3.js.map
@@ -536,7 +536,6 @@ var BASE_DIRECTORY = join(homedir(), ".agentcash");
536
536
  var LEGACY_DIRECTORY = join(homedir(), ".x402scan-mcp");
537
537
  function migrateFromLegacy() {
538
538
  if (!fs.existsSync(LEGACY_DIRECTORY)) return;
539
- if (fs.existsSync(join(BASE_DIRECTORY, "wallet.json"))) return;
540
539
  const result = resultFromThrowable(
541
540
  "migration",
542
541
  "fs",
@@ -599,81 +598,6 @@ var log = {
599
598
  path: LOG_FILE
600
599
  };
601
600
 
602
- // src/shared/networks.ts
603
- import {
604
- base,
605
- baseSepolia,
606
- mainnet,
607
- sepolia,
608
- optimism,
609
- arbitrum,
610
- polygon
611
- } from "viem/chains";
612
- var CHAIN_CONFIGS = {
613
- "eip155:8453": {
614
- chain: base,
615
- caip2: "eip155:8453",
616
- v1Name: "base",
617
- usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
618
- },
619
- "eip155:84532": {
620
- chain: baseSepolia,
621
- caip2: "eip155:84532",
622
- v1Name: "base-sepolia",
623
- usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
624
- },
625
- "eip155:1": {
626
- chain: mainnet,
627
- caip2: "eip155:1",
628
- v1Name: "ethereum",
629
- usdcAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
630
- },
631
- "eip155:11155111": {
632
- chain: sepolia,
633
- caip2: "eip155:11155111",
634
- v1Name: "ethereum-sepolia",
635
- usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
636
- },
637
- "eip155:10": {
638
- chain: optimism,
639
- caip2: "eip155:10",
640
- v1Name: "optimism",
641
- usdcAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
642
- },
643
- "eip155:42161": {
644
- chain: arbitrum,
645
- caip2: "eip155:42161",
646
- v1Name: "arbitrum",
647
- usdcAddress: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
648
- },
649
- "eip155:137": {
650
- chain: polygon,
651
- caip2: "eip155:137",
652
- v1Name: "polygon",
653
- usdcAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
654
- }
655
- };
656
- var V1_TO_CAIP2 = {
657
- base: "eip155:8453",
658
- "base-sepolia": "eip155:84532",
659
- ethereum: "eip155:1",
660
- "ethereum-sepolia": "eip155:11155111",
661
- optimism: "eip155:10",
662
- arbitrum: "eip155:42161",
663
- polygon: "eip155:137"
664
- };
665
- var DEFAULT_NETWORK = "eip155:8453";
666
- function toCaip2(network) {
667
- if (network.startsWith("eip155:")) return network;
668
- return V1_TO_CAIP2[network.toLowerCase()] ?? network;
669
- }
670
- function getChainConfig(network) {
671
- return CHAIN_CONFIGS[toCaip2(network)];
672
- }
673
- function getChainName(network) {
674
- return getChainConfig(network)?.chain.name ?? network;
675
- }
676
-
677
601
  // src/shared/neverthrow/parse/index.ts
678
602
  import z from "zod";
679
603
  var type = "json";
@@ -814,9 +738,31 @@ var openDepositLink = async (address, flags) => {
814
738
  await open(depositLink);
815
739
  };
816
740
 
741
+ // src/shared/balance.ts
742
+ import z2 from "zod";
743
+ var getBalance = async ({
744
+ address,
745
+ flags,
746
+ surface
747
+ }) => {
748
+ const url = `${getBaseUrl(flags.dev)}/api/rpc/balance/${address}`;
749
+ const res = await safeFetchJson(
750
+ surface,
751
+ new Request(url, {
752
+ method: "GET",
753
+ headers: {
754
+ accept: "application/json"
755
+ }
756
+ }),
757
+ z2.object({
758
+ chain: z2.number(),
759
+ balance: z2.coerce.number()
760
+ })
761
+ );
762
+ return res;
763
+ };
764
+
817
765
  export {
818
- DEFAULT_NETWORK,
819
- getChainName,
820
766
  resultFromPromise,
821
767
  resultFromThrowable,
822
768
  ok2 as ok,
@@ -833,10 +779,12 @@ export {
833
779
  safeReadFile,
834
780
  safeWriteFile,
835
781
  safeChmod,
782
+ LEGACY_DIRECTORY,
836
783
  configFile,
837
784
  log,
838
785
  getBaseUrl,
839
786
  getDepositLink,
840
- openDepositLink
787
+ openDepositLink,
788
+ getBalance
841
789
  };
842
- //# sourceMappingURL=chunk-EDWPR5IJ.js.map
790
+ //# sourceMappingURL=chunk-PJFATGPH.js.map