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.
- package/dist/cjs/run-server.cjs +1473 -3900
- package/dist/esm/chunk-2EHPJVCX.js +363 -0
- package/dist/esm/chunk-2EHPJVCX.js.map +1 -0
- package/dist/esm/{chunk-WL5N26N4.js → chunk-ITXG5QJ3.js} +5 -5
- package/dist/esm/{chunk-EDWPR5IJ.js → chunk-PJFATGPH.js} +28 -80
- package/dist/esm/chunk-PJFATGPH.js.map +1 -0
- package/dist/esm/{chunk-Y5BSCN5L.js → chunk-QUSINJQZ.js} +82 -22
- package/dist/esm/chunk-QUSINJQZ.js.map +1 -0
- package/dist/esm/chunk-WQANIP2X.js +22 -0
- package/dist/esm/chunk-WQANIP2X.js.map +1 -0
- package/dist/esm/{commands-XFTEJGGT.js → commands-7TBWTLKT.js} +12 -10
- package/dist/esm/commands-7TBWTLKT.js.map +1 -0
- package/dist/esm/{fund-56IKTU6D.js → fund-BJFTXRRM.js} +4 -4
- package/dist/esm/index.js +9 -9
- package/dist/esm/{install-WZ2WOFCE.js → install-QNDIKJT7.js} +7 -7
- package/dist/esm/install-QNDIKJT7.js.map +1 -0
- package/dist/esm/{server-B4N6JKFY.js → server-3ZQQXMUD.js} +50 -100
- package/dist/esm/server-3ZQQXMUD.js.map +1 -0
- package/dist/esm/shared/operations/index.d.ts +18 -18
- package/dist/esm/shared/operations/index.js +3 -3
- package/package.json +7 -5
- package/dist/esm/chunk-4Z3HKYI5.js +0 -190
- package/dist/esm/chunk-4Z3HKYI5.js.map +0 -1
- package/dist/esm/chunk-EDWPR5IJ.js.map +0 -1
- package/dist/esm/chunk-QO2UZVLV.js +0 -52
- package/dist/esm/chunk-QO2UZVLV.js.map +0 -1
- package/dist/esm/chunk-Y5BSCN5L.js.map +0 -1
- package/dist/esm/commands-XFTEJGGT.js.map +0 -1
- package/dist/esm/install-WZ2WOFCE.js.map +0 -1
- package/dist/esm/server-B4N6JKFY.js.map +0 -1
- /package/dist/esm/{chunk-WL5N26N4.js.map → chunk-ITXG5QJ3.js.map} +0 -0
- /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":"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","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-
|
|
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-
|
|
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-
|
|
790
|
+
//# sourceMappingURL=chunk-PJFATGPH.js.map
|