moneyos 0.3.3 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/cli/index.js +195 -47
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ moneyos init [--key 0x...] [--force] [--chain 42161] [--rpc https://...]
|
|
|
22
22
|
moneyos auth unlock
|
|
23
23
|
moneyos auth lock
|
|
24
24
|
moneyos auth status
|
|
25
|
+
moneyos auth change-password
|
|
25
26
|
moneyos backup export [--out ./wallet-backup.json] [--force]
|
|
26
27
|
moneyos backup restore <path> [--force]
|
|
27
28
|
moneyos backup status
|
|
@@ -78,6 +79,7 @@ What is landed in code today:
|
|
|
78
79
|
- `~/.moneyos/config.json` now stores only non-secret settings such as chain and RPC configuration
|
|
79
80
|
- `MONEYOS_PRIVATE_KEY` remains an explicit override for ephemeral CI or agent runs
|
|
80
81
|
- `moneyos auth unlock` opens a short-lived local session for write commands
|
|
82
|
+
- `moneyos auth change-password` rotates the local wallet password and locks the current session
|
|
81
83
|
- `moneyos backup export|restore|status` manages encrypted wallet backups
|
|
82
84
|
- Normal wallet commands resolve their write path through one shared session-aware flow
|
|
83
85
|
- Local EOA signers use viem's nonce manager, so back-to-back live transactions
|
|
@@ -119,6 +121,19 @@ If you have a legacy `~/.moneyos/config.json` with a plaintext `privateKey`
|
|
|
119
121
|
field from a pre-encrypted-wallet version of the CLI, `moneyos init` with no
|
|
120
122
|
flags will detect and import that key automatically.
|
|
121
123
|
|
|
124
|
+
## Changing the wallet password
|
|
125
|
+
|
|
126
|
+
Use:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
moneyos auth change-password
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This re-encrypts the active local wallet file with a new password and locks the
|
|
133
|
+
current local session. Existing backup files and previously exported backups
|
|
134
|
+
remain snapshots encrypted with the old password. If you want a backup under
|
|
135
|
+
the new password, run `moneyos backup export` after the password change.
|
|
136
|
+
|
|
122
137
|
## Threat model
|
|
123
138
|
|
|
124
139
|
What this wallet model is meant to protect against:
|
package/dist/cli/index.js
CHANGED
|
@@ -47,6 +47,10 @@ var DEFAULT_KDF = {
|
|
|
47
47
|
};
|
|
48
48
|
var SECURE_FILE_MODE = 384;
|
|
49
49
|
var SECURE_PARENT_MODE = 448;
|
|
50
|
+
var WALLET_WRITE_LABELS = {
|
|
51
|
+
parentDescription: "Wallet directory",
|
|
52
|
+
fileDescription: "Wallet file"
|
|
53
|
+
};
|
|
50
54
|
function normalizePassphrase(passphrase) {
|
|
51
55
|
return passphrase.normalize("NFC");
|
|
52
56
|
}
|
|
@@ -59,7 +63,7 @@ function walletProofMessage(wallet) {
|
|
|
59
63
|
`createdAt=${wallet.createdAt}`
|
|
60
64
|
].join("|");
|
|
61
65
|
}
|
|
62
|
-
function ensureParentDir(path) {
|
|
66
|
+
function ensureParentDir(path, label) {
|
|
63
67
|
const dir = dirname(path);
|
|
64
68
|
if (!existsSync(dir)) {
|
|
65
69
|
mkdirSync(dir, { recursive: true, mode: SECURE_PARENT_MODE });
|
|
@@ -68,7 +72,7 @@ function ensureParentDir(path) {
|
|
|
68
72
|
const mode = statSync(dir).mode & 511;
|
|
69
73
|
if ((mode & 63) !== 0) {
|
|
70
74
|
throw new Error(
|
|
71
|
-
|
|
75
|
+
`${label} ${dir} has insecure permissions (${mode.toString(8)}). Restrict it to 700 before continuing.`
|
|
72
76
|
);
|
|
73
77
|
}
|
|
74
78
|
}
|
|
@@ -161,9 +165,9 @@ function walletAad(kdf) {
|
|
|
161
165
|
"utf8"
|
|
162
166
|
);
|
|
163
167
|
}
|
|
164
|
-
function writeFileAtomicSecure(path, contents) {
|
|
165
|
-
ensureParentDir(path);
|
|
166
|
-
assertSecureFileMode(path,
|
|
168
|
+
function writeFileAtomicSecure(path, contents, labels = WALLET_WRITE_LABELS) {
|
|
169
|
+
ensureParentDir(path, labels.parentDescription);
|
|
170
|
+
assertSecureFileMode(path, labels.fileDescription);
|
|
167
171
|
const tmpPath = join(
|
|
168
172
|
dirname(path),
|
|
169
173
|
`.${basename(path)}.${randomBytes(6).toString("hex")}.tmp`
|
|
@@ -190,7 +194,7 @@ function writeFileAtomicSecure(path, contents) {
|
|
|
190
194
|
}
|
|
191
195
|
async function encryptWallet(params) {
|
|
192
196
|
const account = privateKeyToAccount(params.privateKey);
|
|
193
|
-
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
197
|
+
const createdAt = params.identity?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
194
198
|
const salt = randomBytes(16);
|
|
195
199
|
const nonce = randomBytes(12);
|
|
196
200
|
const key = deriveKey(params.passphrase, salt, DEFAULT_KDF);
|
|
@@ -202,7 +206,7 @@ async function encryptWallet(params) {
|
|
|
202
206
|
);
|
|
203
207
|
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
204
208
|
const authTag = cipher.getAuthTag();
|
|
205
|
-
const addressProof = await account.signMessage({
|
|
209
|
+
const addressProof = params.identity?.addressProof ?? await account.signMessage({
|
|
206
210
|
message: walletProofMessage({
|
|
207
211
|
version: 1,
|
|
208
212
|
kind: "encrypted-local-eoa",
|
|
@@ -210,10 +214,13 @@ async function encryptWallet(params) {
|
|
|
210
214
|
createdAt
|
|
211
215
|
})
|
|
212
216
|
});
|
|
217
|
+
if (params.identity && account.address.toLowerCase() !== params.identity.address.toLowerCase()) {
|
|
218
|
+
throw new Error("wallet address metadata mismatch");
|
|
219
|
+
}
|
|
213
220
|
return {
|
|
214
|
-
version: 1,
|
|
215
|
-
kind: "encrypted-local-eoa",
|
|
216
|
-
address: account.address,
|
|
221
|
+
version: params.identity?.version ?? 1,
|
|
222
|
+
kind: params.identity?.kind ?? "encrypted-local-eoa",
|
|
223
|
+
address: params.identity?.address ?? account.address,
|
|
217
224
|
createdAt,
|
|
218
225
|
addressProof,
|
|
219
226
|
kdf: DEFAULT_KDF,
|
|
@@ -226,6 +233,15 @@ async function encryptWallet(params) {
|
|
|
226
233
|
}
|
|
227
234
|
};
|
|
228
235
|
}
|
|
236
|
+
function walletIdentity(wallet) {
|
|
237
|
+
return {
|
|
238
|
+
version: wallet.version,
|
|
239
|
+
kind: wallet.kind,
|
|
240
|
+
address: wallet.address,
|
|
241
|
+
createdAt: wallet.createdAt,
|
|
242
|
+
addressProof: wallet.addressProof
|
|
243
|
+
};
|
|
244
|
+
}
|
|
229
245
|
async function decryptWalletFile(wallet, passphrase) {
|
|
230
246
|
try {
|
|
231
247
|
const salt = Buffer.from(wallet.crypto.salt, "base64");
|
|
@@ -276,9 +292,32 @@ var FileEncryptedWalletStore = class {
|
|
|
276
292
|
}
|
|
277
293
|
async save(params) {
|
|
278
294
|
const wallet = await encryptWallet(params);
|
|
279
|
-
writeFileAtomicSecure(
|
|
295
|
+
writeFileAtomicSecure(
|
|
296
|
+
this.walletPath,
|
|
297
|
+
JSON.stringify(wallet, null, 2),
|
|
298
|
+
WALLET_WRITE_LABELS
|
|
299
|
+
);
|
|
280
300
|
return toMetadata(wallet);
|
|
281
301
|
}
|
|
302
|
+
async rotatePassphrase(params) {
|
|
303
|
+
if (!this.exists()) {
|
|
304
|
+
throw new Error("No wallet configured. Run `moneyos init`.");
|
|
305
|
+
}
|
|
306
|
+
assertSecureFileMode(this.walletPath, "Wallet file");
|
|
307
|
+
const wallet = parseWalletFile(
|
|
308
|
+
readFileSync(this.walletPath, "utf8"),
|
|
309
|
+
this.walletPath
|
|
310
|
+
);
|
|
311
|
+
await verifyWalletAddressProof(wallet, this.walletPath);
|
|
312
|
+
const privateKey = await decryptWalletFile(wallet, params.oldPassphrase);
|
|
313
|
+
const rotated = await encryptWallet({
|
|
314
|
+
privateKey,
|
|
315
|
+
passphrase: params.newPassphrase,
|
|
316
|
+
identity: walletIdentity(wallet)
|
|
317
|
+
});
|
|
318
|
+
writeFileAtomicSecure(this.walletPath, JSON.stringify(rotated, null, 2));
|
|
319
|
+
return toMetadata(rotated);
|
|
320
|
+
}
|
|
282
321
|
async decrypt(passphrase) {
|
|
283
322
|
if (!this.exists()) {
|
|
284
323
|
throw new Error("No wallet configured. Run `moneyos init`.");
|
|
@@ -306,10 +345,20 @@ var FileEncryptedWalletStore = class {
|
|
|
306
345
|
async restore(data) {
|
|
307
346
|
const wallet = parseWalletFile(JSON.stringify(data), this.walletPath);
|
|
308
347
|
await verifyWalletAddressProof(wallet, this.walletPath);
|
|
309
|
-
writeFileAtomicSecure(
|
|
348
|
+
writeFileAtomicSecure(
|
|
349
|
+
this.walletPath,
|
|
350
|
+
JSON.stringify(wallet, null, 2),
|
|
351
|
+
WALLET_WRITE_LABELS
|
|
352
|
+
);
|
|
310
353
|
return toMetadata(wallet);
|
|
311
354
|
}
|
|
312
355
|
};
|
|
356
|
+
async function writeEncryptedWalletFile(path, data, labels = WALLET_WRITE_LABELS) {
|
|
357
|
+
const wallet = parseWalletFile(JSON.stringify(data), path);
|
|
358
|
+
await verifyWalletAddressProof(wallet, path);
|
|
359
|
+
writeFileAtomicSecure(path, JSON.stringify(wallet, null, 2), labels);
|
|
360
|
+
return toMetadata(wallet);
|
|
361
|
+
}
|
|
313
362
|
async function readEncryptedWalletFile(path) {
|
|
314
363
|
assertSecureFileMode(path, "Wallet file");
|
|
315
364
|
const wallet = parseWalletFile(readFileSync(path, "utf8"), path);
|
|
@@ -360,7 +409,10 @@ var FileBackupProvider = class {
|
|
|
360
409
|
"Backup file already exists. Re-run with `--force` if you really want to overwrite it."
|
|
361
410
|
);
|
|
362
411
|
}
|
|
363
|
-
await
|
|
412
|
+
await writeEncryptedWalletFile(targetPath, wallet, {
|
|
413
|
+
parentDescription: "Backup export destination directory",
|
|
414
|
+
fileDescription: "Backup export file"
|
|
415
|
+
});
|
|
364
416
|
return targetPath;
|
|
365
417
|
}
|
|
366
418
|
async restoreWallet(fromPath, options) {
|
|
@@ -1259,38 +1311,58 @@ function parseChainId(value, fallback) {
|
|
|
1259
1311
|
}
|
|
1260
1312
|
return parsed;
|
|
1261
1313
|
}
|
|
1262
|
-
var
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1314
|
+
var defaultInitCommandDependencies = {
|
|
1315
|
+
loadFileConfig,
|
|
1316
|
+
getWalletPath,
|
|
1317
|
+
getBackupDir,
|
|
1318
|
+
getConfigPath,
|
|
1319
|
+
createWalletStore: (walletPath) => new FileEncryptedWalletStore(walletPath),
|
|
1320
|
+
createBackupProvider: (params) => new FileBackupProvider(params),
|
|
1321
|
+
hasRemovedOnePasswordConfig,
|
|
1322
|
+
getRemovedOnePasswordStorageMessage,
|
|
1323
|
+
hasLegacyPlaintextWalletConfig,
|
|
1324
|
+
getLegacyPlaintextWalletStorageMessage,
|
|
1325
|
+
promptHidden,
|
|
1326
|
+
lockSession,
|
|
1327
|
+
getSessionSocketPath,
|
|
1328
|
+
getSessionTokenPath,
|
|
1329
|
+
saveConfig,
|
|
1330
|
+
generatePrivateKey,
|
|
1331
|
+
log: (message) => console.log(message),
|
|
1332
|
+
error: (message) => console.error(message)
|
|
1333
|
+
};
|
|
1334
|
+
async function runInitCommand(options, deps = defaultInitCommandDependencies) {
|
|
1335
|
+
const existing = deps.loadFileConfig();
|
|
1336
|
+
const walletPath = deps.getWalletPath(existing);
|
|
1337
|
+
const backupDir = deps.getBackupDir(existing);
|
|
1338
|
+
const wallet = deps.createWalletStore(walletPath);
|
|
1267
1339
|
if (wallet.exists() && !options.force) {
|
|
1268
1340
|
const metadata = await wallet.metadata();
|
|
1269
|
-
|
|
1341
|
+
deps.log(`Already initialized.`);
|
|
1270
1342
|
if (metadata?.address) {
|
|
1271
|
-
|
|
1343
|
+
deps.log(`Address: ${metadata.address}`);
|
|
1272
1344
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1345
|
+
deps.log(`Wallet: ${walletPath}`);
|
|
1346
|
+
deps.log(`Config: ${deps.getConfigPath()}`);
|
|
1347
|
+
deps.log(`
|
|
1276
1348
|
To reinitialize, run: moneyos init --force --key <privateKey>`);
|
|
1277
1349
|
return;
|
|
1278
1350
|
}
|
|
1279
|
-
if (hasRemovedOnePasswordConfig(existing) && !options.key) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1351
|
+
if (deps.hasRemovedOnePasswordConfig(existing) && !options.key) {
|
|
1352
|
+
deps.error(deps.getRemovedOnePasswordStorageMessage());
|
|
1353
|
+
deps.error(`Config: ${deps.getConfigPath()}`);
|
|
1282
1354
|
return;
|
|
1283
1355
|
}
|
|
1284
1356
|
try {
|
|
1285
|
-
const privateKey = options.key ?? (hasLegacyPlaintextWalletConfig(existing) ? existing.privateKey : generatePrivateKey());
|
|
1357
|
+
const privateKey = options.key ?? (deps.hasLegacyPlaintextWalletConfig(existing) ? existing.privateKey : deps.generatePrivateKey());
|
|
1286
1358
|
const account = privateKeyToAccount3(privateKey);
|
|
1287
1359
|
const chainId = parseChainId(options.chain, existing.chainId ?? 42161);
|
|
1288
1360
|
const rpcUrl = options.rpc ?? existing.rpcUrl;
|
|
1289
|
-
const passphrase = await promptHidden("Choose wallet password: ");
|
|
1361
|
+
const passphrase = await deps.promptHidden("Choose wallet password: ");
|
|
1290
1362
|
if (passphrase.length < 8) {
|
|
1291
1363
|
throw new Error("Wallet password must be at least 8 characters long.");
|
|
1292
1364
|
}
|
|
1293
|
-
const confirmPassphrase = await promptHidden("Confirm wallet password: ");
|
|
1365
|
+
const confirmPassphrase = await deps.promptHidden("Confirm wallet password: ");
|
|
1294
1366
|
if (passphrase !== confirmPassphrase) {
|
|
1295
1367
|
throw new Error("Wallet password confirmation did not match.");
|
|
1296
1368
|
}
|
|
@@ -1298,41 +1370,47 @@ To reinitialize, run: moneyos init --force --key <privateKey>`);
|
|
|
1298
1370
|
privateKey,
|
|
1299
1371
|
passphrase
|
|
1300
1372
|
});
|
|
1301
|
-
await lockSession(
|
|
1302
|
-
|
|
1373
|
+
await deps.lockSession(
|
|
1374
|
+
deps.getSessionSocketPath(),
|
|
1375
|
+
deps.getSessionTokenPath()
|
|
1376
|
+
);
|
|
1377
|
+
deps.saveConfig({
|
|
1303
1378
|
chainId,
|
|
1304
1379
|
rpcUrl,
|
|
1305
1380
|
walletPath: existing.walletPath,
|
|
1306
1381
|
backupDir: existing.backupDir
|
|
1307
1382
|
});
|
|
1308
|
-
const backupProvider =
|
|
1383
|
+
const backupProvider = deps.createBackupProvider({
|
|
1309
1384
|
walletPath,
|
|
1310
1385
|
backupDir
|
|
1311
1386
|
});
|
|
1312
1387
|
const backupPath = await backupProvider.exportWallet();
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1388
|
+
deps.log(`MoneyOS initialized.`);
|
|
1389
|
+
deps.log(`Address: ${account.address}`);
|
|
1390
|
+
deps.log(`Wallet: ${walletPath}`);
|
|
1391
|
+
deps.log(`Config: ${deps.getConfigPath()}`);
|
|
1392
|
+
deps.log(`Backup: ${backupPath}`);
|
|
1393
|
+
deps.log(
|
|
1319
1394
|
`
|
|
1320
1395
|
Save your wallet password in your password manager of choice. MoneyOS does not store or sync it for you.`
|
|
1321
1396
|
);
|
|
1322
|
-
if (hasLegacyPlaintextWalletConfig(existing) && !options.key) {
|
|
1323
|
-
|
|
1397
|
+
if (deps.hasLegacyPlaintextWalletConfig(existing) && !options.key) {
|
|
1398
|
+
deps.log(`
|
|
1324
1399
|
Imported legacy plaintext wallet into the encrypted wallet file.`);
|
|
1325
|
-
|
|
1400
|
+
deps.log(deps.getLegacyPlaintextWalletStorageMessage());
|
|
1326
1401
|
} else if (!options.key) {
|
|
1327
|
-
|
|
1402
|
+
deps.log(
|
|
1328
1403
|
`
|
|
1329
1404
|
This is a new account. Fund it before sending transactions.`
|
|
1330
1405
|
);
|
|
1331
1406
|
}
|
|
1332
1407
|
} catch (error) {
|
|
1333
|
-
|
|
1408
|
+
deps.error(error instanceof Error ? error.message : String(error));
|
|
1334
1409
|
process.exitCode = 1;
|
|
1335
1410
|
}
|
|
1411
|
+
}
|
|
1412
|
+
var initCommand = new Command("init").description("Initialize MoneyOS with a new or imported encrypted wallet").option("-k, --key <privateKey>", "Import an existing private key").option("--force", "Overwrite the existing encrypted wallet").option("--chain <chainId>", "Default chain ID (default: 42161 Arbitrum)").option("--rpc <url>", "Custom RPC URL").action(async (options) => {
|
|
1413
|
+
await runInitCommand(options);
|
|
1336
1414
|
});
|
|
1337
1415
|
|
|
1338
1416
|
// src/cli/commands/balance.ts
|
|
@@ -1992,8 +2070,70 @@ function formatSessionStatus(params) {
|
|
|
1992
2070
|
}
|
|
1993
2071
|
return lines.join("\n");
|
|
1994
2072
|
}
|
|
2073
|
+
var defaultChangePasswordCommandDependencies = {
|
|
2074
|
+
loadFileConfig,
|
|
2075
|
+
getWalletPath,
|
|
2076
|
+
createWalletStore: (walletPath) => new FileEncryptedWalletStore(walletPath),
|
|
2077
|
+
promptHidden,
|
|
2078
|
+
lockSession,
|
|
2079
|
+
getSessionSocketPath,
|
|
2080
|
+
getSessionTokenPath,
|
|
2081
|
+
log: (message) => console.log(message),
|
|
2082
|
+
error: (message) => console.error(message)
|
|
2083
|
+
};
|
|
2084
|
+
async function runChangePasswordCommand(deps = defaultChangePasswordCommandDependencies) {
|
|
2085
|
+
const config = deps.loadFileConfig();
|
|
2086
|
+
const walletPath = deps.getWalletPath(config);
|
|
2087
|
+
const wallet = deps.createWalletStore(walletPath);
|
|
2088
|
+
if (!wallet.exists()) {
|
|
2089
|
+
deps.error("No encrypted wallet found. Run `moneyos init` first.");
|
|
2090
|
+
process.exitCode = 1;
|
|
2091
|
+
return;
|
|
2092
|
+
}
|
|
2093
|
+
try {
|
|
2094
|
+
const currentPassphrase = await deps.promptHidden("Current wallet password: ");
|
|
2095
|
+
if (currentPassphrase.length === 0) {
|
|
2096
|
+
throw new Error("Current wallet password cannot be empty.");
|
|
2097
|
+
}
|
|
2098
|
+
const newPassphrase = await deps.promptHidden("New wallet password: ");
|
|
2099
|
+
if (newPassphrase.length < 8) {
|
|
2100
|
+
throw new Error("New wallet password must be at least 8 characters long.");
|
|
2101
|
+
}
|
|
2102
|
+
if (newPassphrase === currentPassphrase) {
|
|
2103
|
+
throw new Error(
|
|
2104
|
+
"New wallet password must differ from the current password."
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
const confirmPassphrase = await deps.promptHidden(
|
|
2108
|
+
"Confirm new wallet password: "
|
|
2109
|
+
);
|
|
2110
|
+
if (newPassphrase !== confirmPassphrase) {
|
|
2111
|
+
throw new Error("New wallet password confirmation did not match.");
|
|
2112
|
+
}
|
|
2113
|
+
const metadata = await wallet.rotatePassphrase({
|
|
2114
|
+
oldPassphrase: currentPassphrase,
|
|
2115
|
+
newPassphrase
|
|
2116
|
+
});
|
|
2117
|
+
await deps.lockSession(
|
|
2118
|
+
deps.getSessionSocketPath(),
|
|
2119
|
+
deps.getSessionTokenPath()
|
|
2120
|
+
);
|
|
2121
|
+
deps.log("Wallet password changed.");
|
|
2122
|
+
deps.log(`Address: ${metadata.address}`);
|
|
2123
|
+
deps.log(formatSessionStatus({ state: "locked" }));
|
|
2124
|
+
deps.log(
|
|
2125
|
+
"Existing backup files and exported copies still require the old wallet password."
|
|
2126
|
+
);
|
|
2127
|
+
deps.log(
|
|
2128
|
+
"Run `moneyos backup export` to create a backup encrypted with the new wallet password."
|
|
2129
|
+
);
|
|
2130
|
+
} catch (error) {
|
|
2131
|
+
deps.error(error instanceof Error ? error.message : String(error));
|
|
2132
|
+
process.exitCode = 1;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
1995
2135
|
var authCommand = new Command6("auth").description(
|
|
1996
|
-
"Unlock, inspect, and
|
|
2136
|
+
"Unlock, inspect, lock, and change the local MoneyOS wallet password"
|
|
1997
2137
|
);
|
|
1998
2138
|
authCommand.command("unlock").description("Unlock the local wallet and start a short-lived session").action(async () => {
|
|
1999
2139
|
const config = loadFileConfig();
|
|
@@ -2032,6 +2172,9 @@ authCommand.command("unlock").description("Unlock the local wallet and start a s
|
|
|
2032
2172
|
process.exitCode = 1;
|
|
2033
2173
|
}
|
|
2034
2174
|
});
|
|
2175
|
+
authCommand.command("change-password").description("Change the local wallet password and lock the current session").action(async () => {
|
|
2176
|
+
await runChangePasswordCommand();
|
|
2177
|
+
});
|
|
2035
2178
|
authCommand.command("lock").description("Lock the local MoneyOS wallet session").action(async () => {
|
|
2036
2179
|
const locked = await lockSession(
|
|
2037
2180
|
getSessionSocketPath(),
|
|
@@ -2084,6 +2227,13 @@ function formatBackupStatus(params) {
|
|
|
2084
2227
|
}
|
|
2085
2228
|
return lines.join("\n");
|
|
2086
2229
|
}
|
|
2230
|
+
function getBackupExportPasswordGuidance() {
|
|
2231
|
+
return [
|
|
2232
|
+
"This backup is encrypted with the same wallet password as your active wallet.",
|
|
2233
|
+
"You will need that same wallet password to restore it.",
|
|
2234
|
+
"MoneyOS does not store or sync it for you."
|
|
2235
|
+
].join(" ");
|
|
2236
|
+
}
|
|
2087
2237
|
var backupCommand = new Command7("backup").description(
|
|
2088
2238
|
"Export, restore, and inspect encrypted wallet backups"
|
|
2089
2239
|
);
|
|
@@ -2099,9 +2249,7 @@ backupCommand.command("export").description("Write a copy of the encrypted walle
|
|
|
2099
2249
|
allowOverwrite: Boolean(options.force)
|
|
2100
2250
|
});
|
|
2101
2251
|
console.log(`Backup exported to ${targetPath}`);
|
|
2102
|
-
console.log(
|
|
2103
|
-
"Save your wallet password in your password manager of choice. MoneyOS does not store or sync it for you."
|
|
2104
|
-
);
|
|
2252
|
+
console.log(getBackupExportPasswordGuidance());
|
|
2105
2253
|
} catch (error) {
|
|
2106
2254
|
console.error(error instanceof Error ? error.message : String(error));
|
|
2107
2255
|
process.exitCode = 1;
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/core/backup-file.ts","../../src/core/encrypted-wallet.ts","../../src/cli/config.ts","../../src/cli/prompt.ts","../../src/cli/session.ts","../../src/core/eoa.ts","../../packages/core/src/tokens.ts","../../packages/core/src/chains.ts","../../src/core/signer.ts","../../src/cli/commands/balance.ts","../../src/core/client.ts","../../src/tools/swap.ts","../../src/cli/wallet.ts","../../src/cli/commands/send.ts","../../src/cli/commands/swap.ts","../../src/providers/odos.ts","../../src/cli/commands/keystore.ts","../../src/cli/wallet-status.ts","../../src/cli/commands/auth.ts","../../src/cli/commands/backup.ts","../../src/cli/version.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { balanceCommand } from \"./commands/balance.js\";\nimport { sendCommand } from \"./commands/send.js\";\nimport { swapCommand } from \"./commands/swap.js\";\nimport { keystoreCommand } from \"./commands/keystore.js\";\nimport { authCommand } from \"./commands/auth.js\";\nimport { backupCommand } from \"./commands/backup.js\";\nimport { runSessionDaemonProcess } from \"./session.js\";\nimport { version } from \"./version.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"moneyos\")\n .description(\"The operating system for money\")\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(balanceCommand);\nprogram.addCommand(sendCommand);\nprogram.addCommand(swapCommand);\nprogram.addCommand(keystoreCommand);\nprogram.addCommand(authCommand);\nprogram.addCommand(backupCommand);\nprogram\n .command(\"__session-daemon\", { hidden: true })\n .action(async () => {\n await runSessionDaemonProcess();\n });\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex } from \"viem\";\nimport { FileBackupProvider } from \"../../core/backup-file.js\";\nimport { FileEncryptedWalletStore } from \"../../core/encrypted-wallet.js\";\nimport {\n getBackupDir,\n getConfigPath,\n getLegacyPlaintextWalletStorageMessage,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n getRemovedOnePasswordStorageMessage,\n hasRemovedOnePasswordConfig,\n hasLegacyPlaintextWalletConfig,\n loadFileConfig,\n saveConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport { lockSession } from \"../session.js\";\n\nfunction parseChainId(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`Invalid chain ID: \"${value}\"`);\n }\n return parsed;\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize MoneyOS with a new or imported encrypted wallet\")\n .option(\"-k, --key <privateKey>\", \"Import an existing private key\")\n .option(\"--force\", \"Overwrite the existing encrypted wallet\")\n .option(\"--chain <chainId>\", \"Default chain ID (default: 42161 Arbitrum)\")\n .option(\"--rpc <url>\", \"Custom RPC URL\")\n .action(async (options) => {\n const existing = loadFileConfig();\n const walletPath = getWalletPath(existing);\n const backupDir = getBackupDir(existing);\n const wallet = new FileEncryptedWalletStore(walletPath);\n\n if (wallet.exists() && !options.force) {\n const metadata = await wallet.metadata();\n console.log(`Already initialized.`);\n if (metadata?.address) {\n console.log(`Address: ${metadata.address}`);\n }\n console.log(`Wallet: ${walletPath}`);\n console.log(`Config: ${getConfigPath()}`);\n console.log(`\\nTo reinitialize, run: moneyos init --force --key <privateKey>`);\n return;\n }\n\n if (hasRemovedOnePasswordConfig(existing) && !options.key) {\n console.error(getRemovedOnePasswordStorageMessage());\n console.error(`Config: ${getConfigPath()}`);\n return;\n }\n\n try {\n const privateKey: Hex =\n options.key ??\n (hasLegacyPlaintextWalletConfig(existing)\n ? existing.privateKey!\n : generatePrivateKey());\n const account = privateKeyToAccount(privateKey);\n const chainId = parseChainId(options.chain, existing.chainId ?? 42161);\n const rpcUrl = options.rpc ?? existing.rpcUrl;\n const passphrase = await promptHidden(\"Choose wallet password: \");\n if (passphrase.length < 8) {\n throw new Error(\"Wallet password must be at least 8 characters long.\");\n }\n const confirmPassphrase = await promptHidden(\"Confirm wallet password: \");\n if (passphrase !== confirmPassphrase) {\n throw new Error(\"Wallet password confirmation did not match.\");\n }\n\n await wallet.save({\n privateKey,\n passphrase,\n });\n await lockSession(getSessionSocketPath(), getSessionTokenPath());\n\n saveConfig({\n chainId,\n rpcUrl,\n walletPath: existing.walletPath,\n backupDir: existing.backupDir,\n });\n\n const backupProvider = new FileBackupProvider({\n walletPath,\n backupDir,\n });\n const backupPath = await backupProvider.exportWallet();\n\n console.log(`MoneyOS initialized.`);\n console.log(`Address: ${account.address}`);\n console.log(`Wallet: ${walletPath}`);\n console.log(`Config: ${getConfigPath()}`);\n console.log(`Backup: ${backupPath}`);\n console.log(\n `\\nSave your wallet password in your password manager of choice. MoneyOS does not store or sync it for you.`,\n );\n\n if (hasLegacyPlaintextWalletConfig(existing) && !options.key) {\n console.log(`\\nImported legacy plaintext wallet into the encrypted wallet file.`);\n console.log(getLegacyPlaintextWalletStorageMessage());\n } else if (!options.key) {\n console.log(\n `\\nThis is a new account. Fund it before sending transactions.`,\n );\n }\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n","import {\n existsSync,\n readdirSync,\n statSync,\n} from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { Address } from \"viem\";\nimport {\n FileEncryptedWalletStore,\n type EncryptedWalletMetadata,\n readEncryptedWalletFile,\n verifyEncryptedWalletPassphrase,\n} from \"./encrypted-wallet.js\";\n\nexport interface BackupProvider {\n readonly kind: \"file\";\n exportWallet(options?: { outPath?: string; allowOverwrite?: boolean }): Promise<string>;\n restoreWallet(\n fromPath: string,\n options: { passphrase: string; allowOverwrite?: boolean },\n ): Promise<EncryptedWalletMetadata>;\n status(): Promise<{\n walletPath: string;\n backupDir: string;\n exists: boolean;\n latestBackupPath?: string;\n backupCount: number;\n address?: Address;\n }>;\n}\n\nfunction formatTimestamp(now: Date): string {\n const pad = (value: number) => value.toString().padStart(2, \"0\");\n return [\n now.getUTCFullYear().toString(),\n pad(now.getUTCMonth() + 1),\n pad(now.getUTCDate()),\n \"-\",\n pad(now.getUTCHours()),\n pad(now.getUTCMinutes()),\n pad(now.getUTCSeconds()),\n ].join(\"\");\n}\n\nexport class FileBackupProvider implements BackupProvider {\n readonly kind = \"file\" as const;\n private readonly store: FileEncryptedWalletStore;\n private readonly backupDir: string;\n\n constructor(params: { walletPath: string; backupDir: string }) {\n this.store = new FileEncryptedWalletStore(params.walletPath);\n this.backupDir = params.backupDir;\n }\n\n private defaultBackupPath(address: Address): string {\n return join(\n this.backupDir,\n `wallet-${address}-${formatTimestamp(new Date())}.json`,\n );\n }\n\n async exportWallet(\n options: { outPath?: string; allowOverwrite?: boolean } = {},\n ): Promise<string> {\n if (options.outPath === \"-\") {\n throw new Error(\"Refusing to export an encrypted wallet backup to stdout.\");\n }\n const wallet = await this.store.exportData();\n const targetPath = options.outPath\n ? resolve(options.outPath)\n : this.defaultBackupPath(wallet.address);\n if (existsSync(targetPath) && !options.allowOverwrite) {\n throw new Error(\n \"Backup file already exists. Re-run with `--force` if you really want to overwrite it.\",\n );\n }\n await new FileEncryptedWalletStore(targetPath).restore(wallet);\n return targetPath;\n }\n\n async restoreWallet(\n fromPath: string,\n options: { passphrase: string; allowOverwrite?: boolean },\n ): Promise<EncryptedWalletMetadata> {\n if (this.store.exists() && !options.allowOverwrite) {\n throw new Error(\n \"A wallet already exists. Re-run with `--force` if you really want to overwrite it.\",\n );\n }\n\n const sourcePath = resolve(fromPath);\n const wallet = await readEncryptedWalletFile(sourcePath);\n await verifyEncryptedWalletPassphrase(wallet, options.passphrase);\n return this.store.restore(wallet);\n }\n\n async status(): Promise<{\n walletPath: string;\n backupDir: string;\n exists: boolean;\n latestBackupPath?: string;\n backupCount: number;\n address?: Address;\n }> {\n const exists = this.store.exists();\n const metadata = exists ? await this.store.metadata() : undefined;\n\n if (!existsSync(this.backupDir)) {\n return {\n walletPath: this.store.walletPath,\n backupDir: this.backupDir,\n exists,\n backupCount: 0,\n address: metadata?.address,\n };\n }\n\n const files = readdirSync(this.backupDir)\n .filter((name) => name.endsWith(\".json\"))\n .map((name) => join(this.backupDir, name))\n .sort(\n (a, b) => statSync(b).mtimeMs - statSync(a).mtimeMs,\n );\n\n return {\n walletPath: this.store.walletPath,\n backupDir: this.backupDir,\n exists,\n latestBackupPath: files[0],\n backupCount: files.length,\n address: metadata?.address,\n };\n }\n}\n","import {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n scryptSync,\n} from \"node:crypto\";\nimport {\n chmodSync,\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeSync,\n} from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { recoverMessageAddress, type Address, type Hex } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nexport interface EncryptedWalletKdfConfig {\n name: \"scrypt\";\n N: number;\n r: number;\n p: number;\n keyLength: number;\n}\n\nexport interface EncryptedWalletCrypto {\n cipher: \"aes-256-gcm\";\n salt: string;\n nonce: string;\n authTag: string;\n ciphertext: string;\n}\n\nexport interface EncryptedWalletFile {\n version: 1;\n kind: \"encrypted-local-eoa\";\n address: Address;\n createdAt: string;\n addressProof: Hex;\n kdf: EncryptedWalletKdfConfig;\n crypto: EncryptedWalletCrypto;\n}\n\nexport interface EncryptedWalletMetadata {\n version: 1;\n kind: \"encrypted-local-eoa\";\n address: Address;\n createdAt: string;\n}\n\nexport interface EncryptedWalletStore {\n readonly walletPath: string;\n exists(): boolean;\n metadata(): Promise<EncryptedWalletMetadata | undefined>;\n save(params: { privateKey: Hex; passphrase: string }): Promise<EncryptedWalletMetadata>;\n decrypt(passphrase: string): Promise<Hex>;\n exportData(): Promise<EncryptedWalletFile>;\n restore(data: EncryptedWalletFile): Promise<EncryptedWalletMetadata>;\n}\n\nconst DEFAULT_KDF: EncryptedWalletKdfConfig = {\n name: \"scrypt\",\n N: 131072,\n r: 8,\n p: 1,\n keyLength: 32,\n};\n\nconst SECURE_FILE_MODE = 0o600;\nconst SECURE_PARENT_MODE = 0o700;\n\nfunction normalizePassphrase(passphrase: string): string {\n return passphrase.normalize(\"NFC\");\n}\n\nfunction walletProofMessage(wallet: Pick<\n EncryptedWalletFile,\n \"version\" | \"kind\" | \"address\" | \"createdAt\"\n>): string {\n return [\n \"MoneyOS wallet metadata\",\n `v=${wallet.version}`,\n `kind=${wallet.kind}`,\n `address=${wallet.address}`,\n `createdAt=${wallet.createdAt}`,\n ].join(\"|\");\n}\n\nfunction ensureParentDir(path: string): void {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: SECURE_PARENT_MODE });\n return;\n }\n\n const mode = statSync(dir).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `Wallet directory ${dir} has insecure permissions (${mode.toString(8)}). Restrict it to 700 before continuing.`,\n );\n }\n}\n\nfunction assertSecureFileMode(path: string, label: string): void {\n if (!existsSync(path)) {\n return;\n }\n\n const mode = statSync(path).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `${label} at ${path} has insecure permissions (${mode.toString(8)}). Restrict it to 600 before continuing.`,\n );\n }\n}\n\nfunction parseWalletFile(raw: string, path: string): EncryptedWalletFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `Encrypted wallet at ${path} is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(`Encrypted wallet at ${path} must be a JSON object`);\n }\n\n const wallet = parsed as Partial<EncryptedWalletFile>;\n if (wallet.version !== 1) {\n throw new Error(`Encrypted wallet at ${path} has unsupported version`);\n }\n if (wallet.kind !== \"encrypted-local-eoa\") {\n throw new Error(`Encrypted wallet at ${path} has unsupported kind`);\n }\n if (typeof wallet.address !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing address metadata`);\n }\n if (typeof wallet.addressProof !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing address proof`);\n }\n if (\n !wallet.kdf ||\n wallet.kdf.name !== \"scrypt\" ||\n !Number.isInteger(wallet.kdf.N) ||\n !Number.isInteger(wallet.kdf.r) ||\n !Number.isInteger(wallet.kdf.p) ||\n !Number.isInteger(wallet.kdf.keyLength)\n ) {\n throw new Error(`Encrypted wallet at ${path} has invalid KDF parameters`);\n }\n if (\n !wallet.crypto ||\n wallet.crypto.cipher !== \"aes-256-gcm\" ||\n typeof wallet.crypto.salt !== \"string\" ||\n typeof wallet.crypto.nonce !== \"string\" ||\n typeof wallet.crypto.authTag !== \"string\" ||\n typeof wallet.crypto.ciphertext !== \"string\"\n ) {\n throw new Error(`Encrypted wallet at ${path} has invalid crypto metadata`);\n }\n if (typeof wallet.createdAt !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing createdAt`);\n }\n\n return wallet as EncryptedWalletFile;\n}\n\nfunction toMetadata(wallet: EncryptedWalletFile): EncryptedWalletMetadata {\n return {\n version: wallet.version,\n kind: wallet.kind,\n address: wallet.address,\n createdAt: wallet.createdAt,\n };\n}\n\nasync function verifyWalletAddressProof(\n wallet: EncryptedWalletFile,\n path: string,\n): Promise<void> {\n let recovered: Address;\n try {\n recovered = await recoverMessageAddress({\n message: walletProofMessage(wallet),\n signature: wallet.addressProof,\n });\n } catch {\n throw new Error(`Encrypted wallet at ${path} has an invalid address proof`);\n }\n\n if (recovered.toLowerCase() !== wallet.address.toLowerCase()) {\n throw new Error(`Encrypted wallet at ${path} failed address proof validation`);\n }\n}\n\nfunction deriveKey(\n passphrase: string,\n salt: Buffer,\n kdf: EncryptedWalletKdfConfig,\n): Buffer {\n return scryptSync(normalizePassphrase(passphrase), salt, kdf.keyLength, {\n N: kdf.N,\n r: kdf.r,\n p: kdf.p,\n maxmem: 256 * 1024 * 1024,\n }) as Buffer;\n}\n\nfunction walletAad(kdf: EncryptedWalletKdfConfig): Buffer {\n // If the KDF shape changes in a future wallet version, update this payload so\n // all KDF fields remain bound to the AEAD tag.\n return Buffer.from(\n JSON.stringify({\n name: kdf.name,\n N: kdf.N,\n r: kdf.r,\n p: kdf.p,\n keyLength: kdf.keyLength,\n }),\n \"utf8\",\n );\n}\n\nfunction writeFileAtomicSecure(path: string, contents: string): void {\n ensureParentDir(path);\n assertSecureFileMode(path, \"Wallet file\");\n\n const tmpPath = join(\n dirname(path),\n `.${basename(path)}.${randomBytes(6).toString(\"hex\")}.tmp`,\n );\n const fd = openSync(tmpPath, \"wx\", SECURE_FILE_MODE);\n let writeError: unknown;\n\n try {\n writeSync(fd, contents);\n fsyncSync(fd);\n } catch (error) {\n writeError = error;\n } finally {\n closeSync(fd);\n }\n\n if (writeError) {\n try {\n unlinkSync(tmpPath);\n } catch {\n // best effort cleanup\n }\n throw writeError;\n }\n\n renameSync(tmpPath, path);\n chmodSync(path, SECURE_FILE_MODE);\n}\n\nasync function encryptWallet(params: {\n privateKey: Hex;\n passphrase: string;\n}): Promise<EncryptedWalletFile> {\n const account = privateKeyToAccount(params.privateKey);\n const createdAt = new Date().toISOString();\n const salt = randomBytes(16);\n const nonce = randomBytes(12);\n const key = deriveKey(params.passphrase, salt, DEFAULT_KDF);\n const cipher = createCipheriv(\"aes-256-gcm\", key, nonce);\n cipher.setAAD(walletAad(DEFAULT_KDF));\n const plaintext = Buffer.from(\n JSON.stringify({ privateKey: params.privateKey }),\n \"utf8\",\n );\n const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const authTag = cipher.getAuthTag();\n const addressProof = await account.signMessage({\n message: walletProofMessage({\n version: 1,\n kind: \"encrypted-local-eoa\",\n address: account.address,\n createdAt,\n }),\n });\n\n return {\n version: 1,\n kind: \"encrypted-local-eoa\",\n address: account.address,\n createdAt,\n addressProof,\n kdf: DEFAULT_KDF,\n crypto: {\n cipher: \"aes-256-gcm\",\n salt: salt.toString(\"base64\"),\n nonce: nonce.toString(\"base64\"),\n authTag: authTag.toString(\"base64\"),\n ciphertext: ciphertext.toString(\"base64\"),\n },\n };\n}\n\nasync function decryptWalletFile(\n wallet: EncryptedWalletFile,\n passphrase: string,\n): Promise<Hex> {\n try {\n const salt = Buffer.from(wallet.crypto.salt, \"base64\");\n const nonce = Buffer.from(wallet.crypto.nonce, \"base64\");\n const authTag = Buffer.from(wallet.crypto.authTag, \"base64\");\n const ciphertext = Buffer.from(wallet.crypto.ciphertext, \"base64\");\n const key = deriveKey(passphrase, salt, wallet.kdf);\n const decipher = createDecipheriv(\"aes-256-gcm\", key, nonce);\n decipher.setAAD(walletAad(wallet.kdf));\n decipher.setAuthTag(authTag);\n const plaintext = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf8\");\n const parsed = JSON.parse(plaintext) as { privateKey?: unknown };\n if (typeof parsed.privateKey !== \"string\") {\n throw new Error(\"wallet payload missing privateKey\");\n }\n const privateKey = parsed.privateKey as Hex;\n const derivedAddress = privateKeyToAccount(privateKey).address;\n if (derivedAddress.toLowerCase() !== wallet.address.toLowerCase()) {\n throw new Error(\"wallet address metadata mismatch\");\n }\n\n return privateKey;\n } catch {\n throw new Error(\"Invalid password or corrupted wallet.\");\n }\n}\n\nexport class FileEncryptedWalletStore implements EncryptedWalletStore {\n readonly walletPath: string;\n\n constructor(walletPath: string) {\n this.walletPath = walletPath;\n }\n\n exists(): boolean {\n return existsSync(this.walletPath);\n }\n\n async metadata(): Promise<EncryptedWalletMetadata | undefined> {\n if (!this.exists()) {\n return undefined;\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return toMetadata(wallet);\n }\n\n async save(params: {\n privateKey: Hex;\n passphrase: string;\n }): Promise<EncryptedWalletMetadata> {\n const wallet = await encryptWallet(params);\n writeFileAtomicSecure(this.walletPath, JSON.stringify(wallet, null, 2));\n return toMetadata(wallet);\n }\n\n async decrypt(passphrase: string): Promise<Hex> {\n if (!this.exists()) {\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return decryptWalletFile(wallet, passphrase);\n }\n\n async exportData(): Promise<EncryptedWalletFile> {\n if (!this.exists()) {\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return wallet;\n }\n\n async restore(data: EncryptedWalletFile): Promise<EncryptedWalletMetadata> {\n const wallet = parseWalletFile(JSON.stringify(data), this.walletPath);\n await verifyWalletAddressProof(wallet, this.walletPath);\n writeFileAtomicSecure(this.walletPath, JSON.stringify(wallet, null, 2));\n return toMetadata(wallet);\n }\n}\n\nexport async function readEncryptedWalletFile(\n path: string,\n): Promise<EncryptedWalletFile> {\n assertSecureFileMode(path, \"Wallet file\");\n const wallet = parseWalletFile(readFileSync(path, \"utf8\"), path);\n await verifyWalletAddressProof(wallet, path);\n return wallet;\n}\n\nexport async function verifyEncryptedWalletPassphrase(\n wallet: EncryptedWalletFile,\n passphrase: string,\n): Promise<EncryptedWalletMetadata> {\n await verifyWalletAddressProof(wallet, \"(in-memory wallet)\");\n await decryptWalletFile(wallet, passphrase);\n return toMetadata(wallet);\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { Address, Hex } from \"viem\";\n\nconst CONFIG_DIR = join(homedir(), \".moneyos\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\n/**\n * Local CLI configuration persisted at `~/.moneyos/config.json`.\n *\n * Only non-secret settings should be persisted here. Wallet secrets now live\n * in the encrypted wallet file, while `privateKey` remains as a legacy-only\n * field so older configs can be detected and upgraded through `moneyos init`.\n */\nexport interface CLIConfig {\n chainId?: number;\n rpcUrl?: string;\n walletPath?: string;\n backupDir?: string;\n /**\n * Legacy plaintext wallet field from earlier MoneyOS versions. This should\n * never be written by the current CLI.\n */\n privateKey?: Hex;\n}\n\ninterface RemovedOnePasswordConfigShape {\n keyStore?: {\n kind?: unknown;\n address?: unknown;\n };\n}\n\nexport function hasRemovedOnePasswordConfig(config: CLIConfig): boolean {\n return (\n (config as CLIConfig & RemovedOnePasswordConfigShape).keyStore?.kind ===\n \"1password\"\n );\n}\n\nexport function getRemovedOnePasswordCachedAddress(\n config: CLIConfig,\n): Address | undefined {\n const address = (config as CLIConfig & RemovedOnePasswordConfigShape)\n .keyStore?.address;\n return typeof address === \"string\" ? (address as Address) : undefined;\n}\n\nexport function getRemovedOnePasswordStorageMessage(): string {\n return \"This repo no longer supports the old 1Password-backed private-key storage path. Re-import the wallet into the local file path with `moneyos init --key <privateKey>`.\";\n}\n\n/**\n * Read the CLI config file.\n *\n * @param path Optional absolute path to the config file. Defaults to\n * `~/.moneyos/config.json`. Primarily exposed so tests can point at a\n * tmpdir without mocking `homedir`.\n */\nexport function loadFileConfig(path: string = CONFIG_FILE): CLIConfig {\n if (!existsSync(path)) {\n return {};\n }\n return JSON.parse(readFileSync(path, \"utf-8\")) as CLIConfig;\n}\n\nexport function loadConfig(): CLIConfig {\n const config: CLIConfig = { ...loadFileConfig() };\n\n // Env vars override file config — standard for agents/CI\n if (process.env.MONEYOS_PRIVATE_KEY) {\n config.privateKey = process.env.MONEYOS_PRIVATE_KEY as Hex;\n }\n if (process.env.MONEYOS_RPC_URL) {\n config.rpcUrl = process.env.MONEYOS_RPC_URL;\n }\n if (process.env.MONEYOS_CHAIN_ID) {\n const parsed = Number(process.env.MONEYOS_CHAIN_ID);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\n `Invalid MONEYOS_CHAIN_ID: \"${process.env.MONEYOS_CHAIN_ID}\" — must be a positive integer`,\n );\n }\n config.chainId = parsed;\n }\n\n return config;\n}\n\n/**\n * Write the CLI config file.\n *\n * @param config The config to persist.\n * @param path Optional absolute path to the config file. Defaults to\n * `~/.moneyos/config.json`. Primarily exposed so tests can point at a\n * tmpdir without mocking `homedir`. When a custom path is passed, the\n * parent directory is created with mode 0o700 if it does not already\n * exist.\n */\nexport function saveConfig(\n config: CLIConfig,\n path: string = CONFIG_FILE,\n): void {\n const safeConfig = { ...config };\n delete safeConfig.privateKey;\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(path, JSON.stringify(safeConfig, null, 2), {\n mode: 0o600,\n });\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function getMoneyOSDir(): string {\n return CONFIG_DIR;\n}\n\nexport function getWalletPath(config?: CLIConfig): string {\n return config?.walletPath ?? join(CONFIG_DIR, \"wallet.json\");\n}\n\nexport function getBackupDir(config?: CLIConfig): string {\n return config?.backupDir ?? join(CONFIG_DIR, \"backups\");\n}\n\nexport function getSessionSocketPath(): string {\n if (process.platform === \"win32\") {\n const suffix = createHash(\"sha256\")\n .update(CONFIG_DIR)\n .digest(\"hex\")\n .slice(0, 16);\n return `\\\\\\\\.\\\\pipe\\\\moneyos-session-${suffix}`;\n }\n\n return join(CONFIG_DIR, \"session.sock\");\n}\n\nexport function getSessionTokenPath(): string {\n return join(CONFIG_DIR, \"session.token\");\n}\n\nexport function hasLegacyPlaintextWalletConfig(config: CLIConfig): boolean {\n return typeof config.privateKey === \"string\";\n}\n\nexport function getLegacyPlaintextWalletStorageMessage(): string {\n return \"Plaintext local wallet configs are no longer used for runtime access. Run `moneyos init` locally to encrypt your wallet into the new MoneyOS wallet file.\";\n}\n","export async function promptHidden(question: string): Promise<string> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(\n \"This action requires a local terminal. Run it directly in your terminal, not through a non-interactive agent session.\",\n );\n }\n\n return new Promise<string>((resolve, reject) => {\n const stdin = process.stdin;\n const stdout = process.stdout;\n let value = \"\";\n\n const cleanup = () => {\n stdin.off(\"data\", onData);\n stdin.pause();\n if (typeof stdin.setRawMode === \"function\") {\n stdin.setRawMode(false);\n }\n };\n\n const finish = (result?: string, error?: Error) => {\n cleanup();\n stdout.write(\"\\n\");\n if (error) {\n reject(error);\n return;\n }\n resolve(result ?? \"\");\n };\n\n const onData = (chunk: Buffer | string) => {\n const text = chunk.toString(\"utf8\");\n for (const char of text) {\n if (char === \"\\u0003\") {\n finish(undefined, new Error(\"Cancelled.\"));\n return;\n }\n if (char === \"\\r\" || char === \"\\n\") {\n finish(value);\n return;\n }\n if (char === \"\\u007f\" || char === \"\\b\") {\n value = value.slice(0, -1);\n continue;\n }\n value += char;\n }\n };\n\n stdout.write(question);\n if (typeof stdin.setRawMode === \"function\") {\n stdin.setRawMode(true);\n }\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n","import { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport net from \"node:net\";\nimport { EOL } from \"node:os\";\nimport { dirname } from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport type { Address } from \"viem\";\nimport type { CallRequest, ExecutionClient, ExecutionResult } from \"@moneyos/core\";\nimport { EOAExecutor } from \"../core/eoa.js\";\nimport { privateKeyToManagedAccount } from \"../core/signer.js\";\n\nexport interface SessionServerStartMessage {\n type: \"start\";\n privateKey: `0x${string}`;\n chainId: number;\n rpcUrl?: string;\n socketPath: string;\n tokenPath: string;\n ttlMs: number;\n}\n\nexport interface SessionStatusResult {\n address: Address;\n expiresAt: string;\n}\n\nexport interface SessionServerHandle {\n readonly address: Address;\n readonly expiresAt: string;\n close(): Promise<void>;\n}\n\ninterface SessionSendParams {\n to: Address;\n chainId: number;\n data?: `0x${string}`;\n value?: string;\n}\n\ntype SessionRequest =\n | { id: string; token: string; type: \"status\" }\n | { id: string; token: string; type: \"lock\" }\n | { id: string; token: string; type: \"send\"; params: SessionSendParams };\n\ntype SessionRequestWithoutToken =\n | { id: string; type: \"status\" }\n | { id: string; type: \"lock\" }\n | { id: string; type: \"send\"; params: SessionSendParams };\n\ntype SessionResponse =\n | {\n id: string;\n ok: true;\n result: SessionStatusResult | ExecutionResult | { locked: true };\n }\n | { id: string; ok: false; error: string };\n\nconst SESSION_CONTROL_TIMEOUT_MS = 750;\n// Intentionally much longer than control operations: on-chain submission does\n// real RPC work, and PR #12 fixed a live timeout-after-broadcast bug here.\nconst SESSION_SEND_TIMEOUT_MS = 60_000;\nconst MAX_MESSAGE_BYTES = 32 * 1024;\nconst SECURE_DIR_MODE = 0o700;\nconst SECURE_FILE_MODE = 0o600;\nconst SERVER_SOCKET_TIMEOUT_MS = 5000;\nconst SESSION_SHUTDOWN_TIMEOUT_MS = 15000;\n\nfunction isWindowsPipe(path: string): boolean {\n return path.startsWith(\"\\\\\\\\.\\\\pipe\\\\\");\n}\n\nfunction removeFileIfPresent(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nfunction ensureSecureParent(path: string): void {\n if (isWindowsPipe(path)) {\n return;\n }\n\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: SECURE_DIR_MODE });\n return;\n }\n\n const mode = statSync(dir).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `MoneyOS directory ${dir} has insecure permissions (${mode.toString(8)}). Restrict it to 700 before continuing.`,\n );\n }\n}\n\nfunction createRequestId(): string {\n return `${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;\n}\n\nfunction loadSessionToken(tokenPath: string): string {\n try {\n return readFileSync(tokenPath, \"utf8\").trim();\n } catch {\n throw new Error(\"No active local MoneyOS session found.\");\n }\n}\n\nfunction writeSecureToken(tokenPath: string, token: string): void {\n ensureSecureParent(tokenPath);\n writeFileSync(tokenPath, `${token}\\n`, { mode: SECURE_FILE_MODE });\n chmodSync(tokenPath, SECURE_FILE_MODE);\n}\n\nfunction sessionFilesGone(socketPath: string, tokenPath: string): boolean {\n const tokenMissing = !existsSync(tokenPath);\n const socketMissing = isWindowsPipe(socketPath) ? true : !existsSync(socketPath);\n return tokenMissing && socketMissing;\n}\n\nasync function waitForSessionShutdown(\n socketPath: string,\n tokenPath: string,\n timeoutMs: number = SESSION_SHUTDOWN_TIMEOUT_MS,\n): Promise<void> {\n const startedAt = Date.now();\n while (!sessionFilesGone(socketPath, tokenPath)) {\n if (Date.now() - startedAt > timeoutMs) {\n throw new Error(\n \"Timed out waiting for the previous MoneyOS session to shut down cleanly.\",\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n}\n\nfunction tokensMatch(expectedToken: string, receivedToken: string): boolean {\n const expected = Buffer.from(expectedToken, \"utf8\");\n const received = Buffer.from(receivedToken, \"utf8\");\n return (\n expected.length === received.length &&\n timingSafeEqual(expected, received)\n );\n}\n\nfunction readLine(socket: net.Socket): Promise<string> {\n return new Promise((resolve, reject) => {\n let buffer = \"\";\n\n const onData = (chunk: Buffer) => {\n buffer += chunk.toString(\"utf8\");\n if (buffer.length > MAX_MESSAGE_BYTES) {\n cleanup();\n reject(new Error(\"Session response exceeded the maximum allowed size.\"));\n return;\n }\n const index = buffer.indexOf(\"\\n\");\n if (index >= 0) {\n cleanup();\n resolve(buffer.slice(0, index));\n }\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n const onClose = () => {\n cleanup();\n reject(new Error(\"Session daemon closed the connection unexpectedly.\"));\n };\n\n const cleanup = () => {\n socket.off(\"data\", onData);\n socket.off(\"error\", onError);\n socket.off(\"close\", onClose);\n };\n\n socket.on(\"data\", onData);\n socket.once(\"error\", onError);\n socket.once(\"close\", onClose);\n });\n}\n\nasync function sendSessionRequest(\n socketPath: string,\n tokenPath: string,\n request: SessionRequestWithoutToken,\n timeoutMs: number = SESSION_CONTROL_TIMEOUT_MS,\n): Promise<SessionResponse> {\n const fullRequest = {\n ...request,\n token: loadSessionToken(tokenPath),\n } as SessionRequest;\n const socket = net.createConnection(socketPath);\n\n return new Promise<SessionResponse>((resolve, reject) => {\n let settled = false;\n const timer = setTimeout(() => {\n settled = true;\n socket.destroy();\n reject(new Error(\"Timed out waiting for local MoneyOS session.\"));\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timer);\n socket.removeAllListeners();\n };\n\n socket.once(\"connect\", async () => {\n try {\n socket.write(`${JSON.stringify(fullRequest)}${EOL}`);\n const line = await readLine(socket);\n settled = true;\n cleanup();\n socket.end();\n resolve(JSON.parse(line) as SessionResponse);\n } catch (error) {\n settled = true;\n cleanup();\n socket.destroy();\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n\n socket.once(\"error\", (error) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n reject(error);\n });\n });\n}\n\nexport async function getSessionStatus(\n socketPath: string,\n tokenPath: string,\n): Promise<SessionStatusResult | undefined> {\n try {\n const response = await sendSessionRequest(\n socketPath,\n tokenPath,\n {\n id: createRequestId(),\n type: \"status\",\n },\n SESSION_CONTROL_TIMEOUT_MS,\n );\n return response.ok ? (response.result as SessionStatusResult) : undefined;\n } catch {\n removeFileIfPresent(socketPath);\n removeFileIfPresent(tokenPath);\n return undefined;\n }\n}\n\nexport async function lockSession(\n socketPath: string,\n tokenPath: string,\n): Promise<boolean> {\n try {\n const response = await sendSessionRequest(\n socketPath,\n tokenPath,\n {\n id: createRequestId(),\n type: \"lock\",\n },\n SESSION_CONTROL_TIMEOUT_MS,\n );\n return response.ok;\n } catch {\n removeFileIfPresent(socketPath);\n removeFileIfPresent(tokenPath);\n return false;\n }\n}\n\nexport class SessionExecutionClient implements ExecutionClient {\n readonly mode = \"eoa\" as const;\n private readonly socketPath: string;\n private readonly tokenPath: string;\n private readonly address: Address;\n\n constructor(params: {\n socketPath: string;\n tokenPath: string;\n address: Address;\n }) {\n this.socketPath = params.socketPath;\n this.tokenPath = params.tokenPath;\n this.address = params.address;\n }\n\n getAddress(): Address {\n return this.address;\n }\n\n async send(call: CallRequest): Promise<ExecutionResult> {\n const response = await sendSessionRequest(\n this.socketPath,\n this.tokenPath,\n {\n id: createRequestId(),\n type: \"send\",\n params: {\n to: call.to,\n chainId: call.chainId,\n data: call.data,\n value: call.value?.toString(),\n },\n },\n SESSION_SEND_TIMEOUT_MS,\n );\n\n if (!response.ok) {\n throw new Error(response.error);\n }\n\n return response.result as ExecutionResult;\n }\n\n capabilities() {\n return {\n sponsoredGas: false,\n batching: false,\n simulation: false,\n };\n }\n}\n\nexport async function startSessionServer(\n start: SessionServerStartMessage,\n hooks: {\n executor?: ExecutionClient;\n onError?: (error: Error) => void;\n onExit?: () => void;\n } = {},\n): Promise<SessionServerHandle> {\n ensureSecureParent(start.tokenPath);\n ensureSecureParent(start.socketPath);\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n\n const signer = privateKeyToManagedAccount(start.privateKey);\n const executor = hooks.executor ?? new EOAExecutor(signer, {\n defaultChainId: start.chainId,\n rpcUrl: start.rpcUrl,\n });\n const expiresAt = new Date(Date.now() + start.ttlMs);\n const token = randomBytes(32).toString(\"hex\");\n writeSecureToken(start.tokenPath, token);\n\n let closed = false;\n\n const close = async () => {\n if (closed) return;\n closed = true;\n await new Promise<void>((resolve) => {\n server.close(() => {\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n hooks.onExit?.();\n resolve();\n });\n });\n };\n\n const server = net.createServer((socket) => {\n let buffer = \"\";\n socket.setTimeout(SERVER_SOCKET_TIMEOUT_MS, () => {\n socket.destroy();\n });\n\n socket.on(\"data\", async (chunk) => {\n buffer += chunk.toString(\"utf8\");\n if (buffer.length > MAX_MESSAGE_BYTES) {\n socket.write(\n `${JSON.stringify({\n id: \"unknown\",\n ok: false,\n error: \"Session request exceeded the maximum allowed size.\",\n })}${EOL}`,\n );\n socket.end();\n return;\n }\n\n const index = buffer.indexOf(\"\\n\");\n if (index < 0) {\n return;\n }\n\n const raw = buffer.slice(0, index);\n buffer = buffer.slice(index + 1);\n let request: SessionRequest;\n try {\n request = JSON.parse(raw) as SessionRequest;\n } catch {\n socket.write(\n `${JSON.stringify({\n id: \"unknown\",\n ok: false,\n error: \"Invalid session request.\",\n })}${EOL}`,\n );\n socket.end();\n return;\n }\n\n const respond = (response: SessionResponse) => {\n socket.write(`${JSON.stringify(response)}${EOL}`);\n socket.end();\n };\n\n try {\n if (!tokensMatch(token, String(request.token ?? \"\"))) {\n respond({\n id: request.id,\n ok: false,\n error: \"Session authentication failed.\",\n });\n return;\n }\n\n if (request.type === \"status\") {\n respond({\n id: request.id,\n ok: true,\n result: {\n address: executor.getAddress(),\n expiresAt: expiresAt.toISOString(),\n },\n });\n return;\n }\n\n if (request.type === \"lock\") {\n respond({\n id: request.id,\n ok: true,\n result: { locked: true },\n });\n setImmediate(() => {\n void close();\n });\n return;\n }\n\n socket.setTimeout(SESSION_SEND_TIMEOUT_MS, () => {\n socket.destroy();\n });\n const result = await executor.send({\n to: request.params.to,\n chainId: request.params.chainId,\n data: request.params.data,\n value:\n request.params.value !== undefined\n ? BigInt(request.params.value)\n : undefined,\n });\n\n respond({\n id: request.id,\n ok: true,\n result,\n });\n } catch (error) {\n respond({\n id: request.id,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", (error) => {\n hooks.onError?.(error instanceof Error ? error : new Error(String(error)));\n reject(error);\n });\n server.listen(start.socketPath, () => {\n if (!isWindowsPipe(start.socketPath)) {\n chmodSync(start.socketPath, SECURE_FILE_MODE);\n }\n resolve();\n });\n });\n\n const timer = setTimeout(() => {\n void close();\n }, start.ttlMs);\n timer.unref();\n\n return {\n address: executor.getAddress(),\n expiresAt: expiresAt.toISOString(),\n close,\n };\n}\n\nexport async function startDetachedSessionDaemon(\n params: SessionServerStartMessage,\n): Promise<SessionStatusResult> {\n const existing = await getSessionStatus(params.socketPath, params.tokenPath);\n if (existing) {\n const locked = await lockSession(params.socketPath, params.tokenPath);\n if (!locked && !sessionFilesGone(params.socketPath, params.tokenPath)) {\n throw new Error(\n \"Failed to replace the existing MoneyOS session. Run `moneyos auth lock` and try again.\",\n );\n }\n if (locked) {\n await waitForSessionShutdown(params.socketPath, params.tokenPath);\n }\n } else {\n removeFileIfPresent(params.socketPath);\n removeFileIfPresent(params.tokenPath);\n }\n\n return new Promise<SessionStatusResult>((resolve, reject) => {\n const child = spawn(\n process.execPath,\n [...process.execArgv, process.argv[1], \"__session-daemon\"],\n {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n },\n );\n\n let settled = false;\n\n const finish = (error?: Error, status?: SessionStatusResult) => {\n if (settled) return;\n settled = true;\n child.removeAllListeners();\n if (error) {\n reject(error);\n return;\n }\n resolve(status as SessionStatusResult);\n };\n\n child.once(\"error\", (error) => finish(error));\n child.once(\"exit\", (code) => {\n if (!settled) {\n finish(\n new Error(\n `Session daemon exited unexpectedly with code ${code ?? \"unknown\"}.`,\n ),\n );\n }\n });\n child.on(\"message\", (message: unknown) => {\n const payload = message as\n | { type: \"ready\"; address: Address; expiresAt: string }\n | { type: \"error\"; error: string };\n if (payload?.type === \"ready\") {\n child.disconnect();\n child.unref();\n finish(undefined, {\n address: payload.address,\n expiresAt: payload.expiresAt,\n });\n } else if (payload?.type === \"error\") {\n finish(new Error(payload.error));\n }\n });\n\n child.send(params);\n });\n}\n\nexport async function runSessionDaemonProcess(): Promise<void> {\n if (!process.send) {\n throw new Error(\"Session daemon must be started through MoneyOS.\");\n }\n\n const start = await new Promise<SessionServerStartMessage>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Session daemon did not receive startup parameters.\"));\n }, 1000);\n\n process.once(\"message\", (message: unknown) => {\n clearTimeout(timeout);\n const payload = message as SessionServerStartMessage;\n if (payload?.type !== \"start\") {\n reject(new Error(\"Session daemon received invalid startup message.\"));\n return;\n }\n resolve(payload);\n });\n });\n\n const shutdown = (code: number = 0) => {\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n process.exit(code);\n };\n\n const handle = await startSessionServer(start, {\n onError: (error) => {\n process.send?.({\n type: \"error\",\n error: error.message,\n });\n shutdown(1);\n },\n onExit: () => shutdown(),\n });\n\n process.send?.({\n type: \"ready\",\n address: handle.address,\n expiresAt: handle.expiresAt,\n });\n process.on(\"SIGTERM\", () => {\n void handle.close().then(() => shutdown());\n });\n process.on(\"SIGINT\", () => {\n void handle.close().then(() => shutdown());\n });\n}\n","import {\n createPublicClient,\n createWalletClient,\n http,\n type Account,\n type Address,\n type Hex,\n type PublicClient,\n type WalletClient,\n type Chain as ViemChain,\n} from \"viem\";\nimport { arbitrum, mainnet, polygon } from \"viem/chains\";\nimport { getChain } from \"@moneyos/core\";\nimport type {\n CallRequest,\n ExecutionClient,\n ExecutionResult,\n ReadClient,\n RuntimeConfig,\n} from \"@moneyos/core\";\nimport { privateKeyToManagedAccount } from \"./signer.js\";\n\nconst viemChainMap: Record<number, ViemChain> = {\n 42161: arbitrum,\n 1: mainnet,\n 137: polygon,\n};\n\nfunction getViemChain(chainId: number): ViemChain | undefined {\n return viemChainMap[chainId];\n}\n\n// --- Read ---\n\nexport class ViemReadClient implements ReadClient {\n private clients: Map<number, PublicClient> = new Map();\n private config: RuntimeConfig;\n\n constructor(config: RuntimeConfig) {\n this.config = config;\n }\n\n private getClient(chainId: number): PublicClient {\n let client = this.clients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createPublicClient({\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.clients.set(chainId, client);\n }\n return client;\n }\n\n async getBalance(params: {\n address: Address;\n chainId: number;\n }): Promise<bigint> {\n const client = this.getClient(params.chainId);\n return client.getBalance({ address: params.address });\n }\n\n async readContract<T = unknown>(params: {\n address: Address;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n chainId: number;\n }): Promise<T> {\n const client = this.getClient(params.chainId);\n return client.readContract({\n address: params.address,\n abi: params.abi,\n functionName: params.functionName,\n args: params.args,\n }) as Promise<T>;\n }\n}\n\n// --- Execute ---\n\nexport class EOAExecutor implements ExecutionClient {\n readonly mode = \"eoa\" as const;\n private signer: Account;\n private walletClients: Map<number, WalletClient> = new Map();\n private publicClients: Map<number, PublicClient> = new Map();\n private config: RuntimeConfig;\n\n constructor(signer: Account, config: RuntimeConfig) {\n this.signer = signer;\n this.config = config;\n }\n\n /**\n * Convenience factory: build an EOAExecutor from a raw private key.\n * Equivalent to `new EOAExecutor(privateKeyToAccount(privateKey), config)`.\n * Kept as a helper so the common \"I have a hex key\" path stays one line\n * while the constructor itself takes a viem `Account` to accommodate\n * future keystore-backed signers (hardware, KMS, MPC).\n *\n * Attach viem's nonce manager so back-to-back live transactions use a\n * pending-aware nonce source instead of relying on RPC fill behavior.\n */\n static fromPrivateKey(privateKey: Hex, config: RuntimeConfig): EOAExecutor {\n return new EOAExecutor(privateKeyToManagedAccount(privateKey), config);\n }\n\n private getWalletClient(chainId: number): WalletClient {\n let client = this.walletClients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createWalletClient({\n account: this.signer,\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.walletClients.set(chainId, client);\n }\n return client;\n }\n\n private getPublicClient(chainId: number): PublicClient {\n let client = this.publicClients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createPublicClient({\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.publicClients.set(chainId, client);\n }\n return client;\n }\n\n getAddress(): Address {\n return this.signer.address;\n }\n\n async send(call: CallRequest): Promise<ExecutionResult> {\n const walletClient = this.getWalletClient(call.chainId);\n const hash = await walletClient.sendTransaction({\n account: walletClient.account!,\n to: call.to,\n data: call.data,\n value: call.value ?? 0n,\n chain: walletClient.chain,\n });\n\n // Wait for inclusion before resolving. Returning on broadcast makes\n // sequenced operations like \"approve then swap\" unsafe: the next\n // call's preflight (eth_estimateGas / eth_call) runs against the\n // latest mined block, so a still-pending approve is invisible and\n // the swap reverts at simulation time. The same broadcast-only\n // resolution also lets viem's nonce manager drift past the chain\n // when a sequenced call fails preflight, leaving the executor stuck\n // submitting nonces the chain has not yet reached.\n //\n // For an interactive CLI, slower is acceptable; ambiguous transaction\n // state is not.\n const publicClient = this.getPublicClient(call.chainId);\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status !== \"success\") {\n throw new Error(\n `Transaction ${hash} reverted on chain ${call.chainId} (block ${receipt.blockNumber}).`,\n );\n }\n\n return { hash, chainId: call.chainId };\n }\n\n capabilities() {\n return {\n sponsoredGas: false,\n batching: false,\n simulation: false,\n };\n }\n}\n","import type { Address } from \"viem\";\n\nexport interface Token {\n symbol: string;\n name: string;\n decimals: number;\n addresses: Record<number, Address>;\n}\n\nexport const NATIVE_TOKEN_ADDRESS =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\" as Address;\n\nexport const tokens: Record<string, Token> = {\n ETH: {\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n addresses: {\n 42161: NATIVE_TOKEN_ADDRESS,\n 1: NATIVE_TOKEN_ADDRESS,\n },\n },\n POL: {\n symbol: \"POL\",\n name: \"POL\",\n decimals: 18,\n addresses: {\n 137: NATIVE_TOKEN_ADDRESS,\n },\n },\n USDC: {\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n addresses: {\n 42161: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n 1: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n 137: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n },\n },\n USDT: {\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n addresses: {\n 42161: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n 1: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n 137: \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n },\n },\n RYZE: {\n symbol: \"RYZE\",\n name: \"RYZE\",\n decimals: 18,\n addresses: {\n 42161: \"0x7712da72127d5dD213B621497D6E4899d5989e5C\",\n },\n },\n};\n\nexport function getToken(symbol: string): Token | undefined {\n return tokens[symbol.toUpperCase()];\n}\n\nexport function getTokenAddress(\n symbol: string,\n chainId: number,\n): Address | undefined {\n return getToken(symbol)?.addresses[chainId];\n}\n","import type { Chain } from \"./types.js\";\n\nexport const chains: Record<string, Chain> = {\n arbitrum: {\n id: 42161,\n name: \"Arbitrum One\",\n rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://arbiscan.io\",\n },\n ethereum: {\n id: 1,\n name: \"Ethereum\",\n rpcUrl: \"https://eth.public-rpc.com\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://etherscan.io\",\n },\n polygon: {\n id: 137,\n name: \"Polygon\",\n rpcUrl: \"https://polygon-rpc.com\",\n nativeCurrency: { name: \"POL\", symbol: \"POL\", decimals: 18 },\n blockExplorer: \"https://polygonscan.com\",\n },\n};\n\nexport const defaultChain = chains.arbitrum;\n\nexport function getChain(idOrName: number | string): Chain | undefined {\n if (typeof idOrName === \"number\") {\n return Object.values(chains).find((c) => c.id === idOrName);\n }\n return chains[idOrName.toLowerCase()];\n}\n","import type { Account, Hex } from \"viem\";\nimport { nonceManager } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\n/**\n * Build a local viem Account with nonce management enabled so back-to-back\n * live transactions use a pending-aware nonce source.\n */\nexport function privateKeyToManagedAccount(privateKey: Hex): Account {\n return privateKeyToAccount(privateKey, { nonceManager });\n}\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\nimport { buildCliMoneyOSConfig, loadCliAddress } from \"../wallet.js\";\n\nexport const balanceCommand = new Command(\"balance\")\n .description(\"Check token balance\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .option(\"-a, --address <address>\", \"Address to check (defaults to your own)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (token: string, options) => {\n const config = loadConfig();\n const chainId = options.chain ? parseInt(options.chain) : config.chainId;\n let address = options.address as Address | undefined;\n\n let moneyos: MoneyOS;\n try {\n if (!address) {\n const resolved = await loadCliAddress(config);\n address = resolved.address;\n }\n\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId: chainId ?? 42161,\n requireSigner: false,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const result = await moneyos.balance(token, {\n address,\n chainId,\n });\n\n console.log(`${result.amount} ${result.symbol}`);\n });\n","import {\n formatUnits,\n parseUnits,\n encodeFunctionData,\n type Address,\n} from \"viem\";\nimport type {\n MoneyOSConfig,\n Balance,\n SendResult,\n SwapProvider,\n SwapResult,\n ReadClient,\n ExecutionClient,\n AssetRegistry,\n MoneyOSRuntime,\n RuntimeConfig,\n} from \"@moneyos/core\";\nimport {\n getChain,\n defaultChain,\n getToken,\n getTokenAddress,\n NATIVE_TOKEN_ADDRESS,\n} from \"@moneyos/core\";\nimport { ViemReadClient, EOAExecutor } from \"./eoa.js\";\nimport { executeSwap } from \"../tools/swap.js\";\n\nconst ERC20_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"decimals\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n name: \"symbol\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n] as const;\n\nclass DefaultAssetRegistry implements AssetRegistry {\n readonly nativeTokenAddress = NATIVE_TOKEN_ADDRESS;\n getToken = getToken;\n getTokenAddress = getTokenAddress;\n getChain = getChain;\n}\n\nexport class MoneyOS {\n private read: ReadClient;\n private executor: ExecutionClient | undefined;\n private assets: AssetRegistry;\n private runtimeConfig: RuntimeConfig;\n\n constructor(config: MoneyOSConfig) {\n // Mutual exclusion: at most one of `execute`, `privateKey`, `signer`.\n // These represent three different ways to produce a signing identity;\n // combining them would be ambiguous.\n const provided: string[] = [];\n if (config.execute) provided.push(\"execute\");\n if (config.privateKey) provided.push(\"privateKey\");\n if (config.signer) provided.push(\"signer\");\n if (provided.length > 1) {\n throw new Error(\n `MoneyOSConfig: pass at most one of \\`execute\\`, \\`privateKey\\`, or \\`signer\\`. Received: ${provided.join(\", \")}.`,\n );\n }\n\n this.runtimeConfig = {\n defaultChainId: config.chainId ?? defaultChain.id,\n rpcUrl: config.rpcUrl,\n };\n\n this.read = config.read ?? new ViemReadClient(this.runtimeConfig);\n this.assets = config.assets ?? new DefaultAssetRegistry();\n\n if (config.execute) {\n this.executor = config.execute;\n } else if (config.signer) {\n this.executor = new EOAExecutor(config.signer, this.runtimeConfig);\n } else if (config.privateKey) {\n this.executor = EOAExecutor.fromPrivateKey(\n config.privateKey,\n this.runtimeConfig,\n );\n }\n }\n\n get runtime(): MoneyOSRuntime {\n return {\n read: this.read,\n execute: this.requireExecutor(),\n assets: this.assets,\n config: this.runtimeConfig,\n };\n }\n\n get address(): Address {\n return this.requireExecutor().getAddress();\n }\n\n private requireExecutor(): ExecutionClient {\n if (!this.executor) {\n throw new Error(\n \"No signing account configured. Set `signer`, `privateKey`, or `execute` in MoneyOS config.\",\n );\n }\n return this.executor;\n }\n\n async balance(\n token: string,\n options?: { address?: Address; chainId?: number },\n ): Promise<Balance> {\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n const account = options?.address ?? this.address;\n\n const tokenAddress = this.assets.getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = this.assets.getToken(token)!;\n\n if (tokenAddress === NATIVE_TOKEN_ADDRESS) {\n const raw = await this.read.getBalance({ address: account, chainId });\n return {\n token: tokenInfo.name,\n symbol: tokenInfo.symbol,\n amount: formatUnits(raw, tokenInfo.decimals),\n rawAmount: raw,\n decimals: tokenInfo.decimals,\n chainId,\n };\n }\n\n const raw = await this.read.readContract<bigint>({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account],\n chainId,\n });\n\n return {\n token: tokenInfo.name,\n symbol: tokenInfo.symbol,\n amount: formatUnits(raw, tokenInfo.decimals),\n rawAmount: raw,\n decimals: tokenInfo.decimals,\n chainId,\n };\n }\n\n async send(\n token: string,\n to: Address,\n amount: string,\n options?: { chainId?: number },\n ): Promise<SendResult> {\n const execute = this.requireExecutor();\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n const from = execute.getAddress();\n\n const tokenAddress = this.assets.getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = this.assets.getToken(token)!;\n const value = parseUnits(amount, tokenInfo.decimals);\n\n if (tokenAddress === NATIVE_TOKEN_ADDRESS) {\n const result = await execute.send({ to, value, chainId });\n return {\n hash: result.hash,\n from,\n to,\n amount,\n token: tokenInfo.symbol,\n chainId,\n };\n }\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to, value],\n });\n\n const result = await execute.send({ to: tokenAddress, data, chainId });\n return {\n hash: result.hash,\n from,\n to,\n amount,\n token: tokenInfo.symbol,\n chainId,\n };\n }\n\n async swap(\n tokenIn: string,\n tokenOut: string,\n amount: string,\n provider: SwapProvider,\n options?: { chainId?: number; slippage?: number },\n ): Promise<SwapResult> {\n const execute = this.requireExecutor();\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n\n return executeSwap(\n { tokenIn, tokenOut, amount, provider, chainId, slippage: options?.slippage },\n { read: this.read, execute, assets: this.assets },\n );\n }\n}\n","import {\n formatUnits,\n parseUnits,\n encodeFunctionData,\n} from \"viem\";\nimport type { ReadClient, ExecutionClient, AssetRegistry, SwapProvider, SwapResult } from \"@moneyos/core\";\n\nconst ERC20_ABI = [\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n] as const;\n\nexport interface SwapInput {\n tokenIn: string;\n tokenOut: string;\n amount: string;\n provider: SwapProvider;\n chainId: number;\n slippage?: number;\n}\n\nexport async function executeSwap(\n input: SwapInput,\n ctx: { read: ReadClient; execute: ExecutionClient; assets: AssetRegistry },\n): Promise<SwapResult> {\n const { tokenIn, tokenOut, amount, provider, chainId, slippage } = input;\n const { read, execute, assets } = ctx;\n const sender = execute.getAddress();\n\n const tokenInAddress = assets.getTokenAddress(tokenIn, chainId);\n const tokenOutAddress = assets.getTokenAddress(tokenOut, chainId);\n if (!tokenInAddress) {\n throw new Error(`Token ${tokenIn} not found on chain ${chainId}`);\n }\n if (!tokenOutAddress) {\n throw new Error(`Token ${tokenOut} not found on chain ${chainId}`);\n }\n\n const tokenInInfo = assets.getToken(tokenIn)!;\n const amountWei = parseUnits(amount, tokenInInfo.decimals);\n\n const quote = await provider.getQuote({\n chainId,\n tokenIn: tokenInAddress,\n tokenOut: tokenOutAddress,\n amount: amountWei,\n sender,\n slippage,\n });\n\n const calldata = await provider.getCalldata(quote);\n\n const isNativeIn = tokenInAddress === assets.nativeTokenAddress;\n\n if (!isNativeIn) {\n const currentAllowance = await read.readContract<bigint>({\n address: tokenInAddress,\n abi: ERC20_ABI,\n functionName: \"allowance\",\n args: [sender, calldata.to],\n chainId,\n });\n\n if (currentAllowance < amountWei) {\n const approveData = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"approve\",\n args: [calldata.to, amountWei],\n });\n await execute.send({ to: tokenInAddress, data: approveData, chainId });\n }\n }\n\n const result = await execute.send({\n to: calldata.to,\n data: calldata.data,\n value: isNativeIn ? amountWei : calldata.value,\n chainId,\n });\n\n const tokenOutInfo = assets.getToken(tokenOut)!;\n return {\n hash: result.hash,\n tokenIn: tokenInInfo.symbol,\n tokenOut: tokenOutInfo.symbol,\n amountIn: amount,\n amountOut: formatUnits(BigInt(quote.expectedOut), tokenOutInfo.decimals),\n chainId,\n };\n}\n","import type { MoneyOSConfig } from \"@moneyos/core\";\nimport type { Address, Hex } from \"viem\";\nimport { FileEncryptedWalletStore } from \"../core/encrypted-wallet.js\";\nimport { privateKeyToManagedAccount } from \"../core/signer.js\";\nimport {\n getLegacyPlaintextWalletStorageMessage,\n getRemovedOnePasswordStorageMessage,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n hasLegacyPlaintextWalletConfig,\n hasRemovedOnePasswordConfig,\n type CLIConfig,\n} from \"./config.js\";\nimport { getSessionStatus, SessionExecutionClient } from \"./session.js\";\n\nexport type CliWalletBackendKind = \"env\" | \"wallet-file\" | \"session\";\n\nexport interface ResolvedCliAddress {\n kind: \"env\" | \"wallet-file\";\n address: Address;\n source: \"env\" | \"encrypted-wallet\";\n}\n\nexport interface ResolveCliWalletOptions {\n walletPath?: string;\n sessionSocketPath?: string;\n sessionTokenPath?: string;\n envPrivateKey?: Hex;\n}\n\nexport interface BuildCliMoneyOSConfigOptions extends ResolveCliWalletOptions {\n chainId?: number;\n requireSigner?: boolean;\n}\n\nfunction resolveEnvPrivateKey(explicit?: Hex): Hex | undefined {\n return explicit ?? (process.env.MONEYOS_PRIVATE_KEY as Hex | undefined);\n}\n\nfunction getWalletStore(\n config: CLIConfig,\n options: ResolveCliWalletOptions = {},\n): FileEncryptedWalletStore {\n return new FileEncryptedWalletStore(options.walletPath ?? getWalletPath(config));\n}\n\nfunction getSessionPath(options: ResolveCliWalletOptions = {}): string {\n return options.sessionSocketPath ?? getSessionSocketPath();\n}\n\nfunction getTokenPath(options: ResolveCliWalletOptions = {}): string {\n return options.sessionTokenPath ?? getSessionTokenPath();\n}\n\n/**\n * Resolve the address the CLI should use for read-only \"my wallet\" commands.\n *\n * This prefers cheap wallet metadata over any signing path so read-only\n * balance checks do not require an unlocked session.\n */\nexport async function loadCliAddress(\n config: CLIConfig,\n options: ResolveCliWalletOptions = {},\n): Promise<ResolvedCliAddress> {\n const envPrivateKey = resolveEnvPrivateKey(options.envPrivateKey);\n if (envPrivateKey) {\n const signer = privateKeyToManagedAccount(envPrivateKey);\n return {\n kind: \"env\",\n address: signer.address,\n source: \"env\",\n };\n }\n\n if (hasRemovedOnePasswordConfig(config)) {\n throw new Error(getRemovedOnePasswordStorageMessage());\n }\n\n const wallet = getWalletStore(config, options);\n const metadata = await wallet.metadata();\n if (metadata?.address) {\n return {\n kind: \"wallet-file\",\n address: metadata.address,\n source: \"encrypted-wallet\",\n };\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n throw new Error(getLegacyPlaintextWalletStorageMessage());\n }\n\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n}\n\nexport async function buildCliMoneyOSConfig(\n config: CLIConfig,\n options: BuildCliMoneyOSConfigOptions = {},\n): Promise<MoneyOSConfig> {\n const moneyosConfig: MoneyOSConfig = {\n chainId: options.chainId ?? config.chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n };\n\n if (!options.requireSigner) {\n return moneyosConfig;\n }\n\n const envPrivateKey = resolveEnvPrivateKey(options.envPrivateKey);\n if (envPrivateKey) {\n return {\n ...moneyosConfig,\n signer: privateKeyToManagedAccount(envPrivateKey),\n };\n }\n\n if (hasRemovedOnePasswordConfig(config)) {\n throw new Error(getRemovedOnePasswordStorageMessage());\n }\n\n const socketPath = getSessionPath(options);\n const tokenPath = getTokenPath(options);\n const session = await getSessionStatus(socketPath, tokenPath);\n if (session) {\n return {\n ...moneyosConfig,\n execute: new SessionExecutionClient({\n socketPath,\n tokenPath,\n address: session.address,\n }),\n };\n }\n\n const wallet = getWalletStore(config, options);\n if (wallet.exists()) {\n throw new Error(\n \"Wallet is locked. Run `moneyos auth unlock` locally before using write commands.\",\n );\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n throw new Error(getLegacyPlaintextWalletStorageMessage());\n }\n\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n}\n","import { Command } from \"commander\";\nimport { getChain } from \"@moneyos/core\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\nimport { buildCliMoneyOSConfig } from \"../wallet.js\";\n\nexport const sendCommand = new Command(\"send\")\n .description(\"Send tokens to an address\")\n .argument(\"<amount>\", \"Amount to send (e.g. 10)\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .argument(\"<to>\", \"Recipient address\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (amount: string, token: string, to: string, options) => {\n const config = loadConfig();\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n let moneyos: MoneyOS;\n try {\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId,\n requireSigner: true,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const chain = getChain(chainId);\n console.log(\n `Sending ${amount} ${token.toUpperCase()} to ${to} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.send(token, to as Address, amount, {\n chainId,\n });\n\n console.log(`Sent. tx: ${result.hash}`);\n });\n","import { Command } from \"commander\";\nimport { getChain } from \"@moneyos/core\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { OdosProvider } from \"../../providers/odos.js\";\nimport { loadConfig } from \"../config.js\";\nimport { buildCliMoneyOSConfig } from \"../wallet.js\";\n\nexport const swapCommand = new Command(\"swap\")\n .description(\"Swap tokens\")\n .argument(\"<amount>\", \"Amount to swap (e.g. 100)\")\n .argument(\"<tokenIn>\", \"Token to sell (e.g. USDC)\")\n .argument(\"<tokenOut>\", \"Token to buy (e.g. RYZE)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .option(\"-s, --slippage <percent>\", \"Slippage tolerance in percent (default: 1)\")\n .action(async (amount: string, tokenIn: string, tokenOut: string, options) => {\n const config = loadConfig();\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n let moneyos: MoneyOS;\n try {\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId,\n requireSigner: true,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const provider = new OdosProvider();\n const chain = getChain(chainId);\n const slippage = options.slippage ? parseFloat(options.slippage) : undefined;\n\n console.log(\n `Swapping ${amount} ${tokenIn.toUpperCase()} \\u2192 ${tokenOut.toUpperCase()} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.swap(tokenIn, tokenOut, amount, provider, {\n chainId,\n slippage,\n });\n\n console.log(`Swapped. Expected: ~${result.amountOut} ${result.tokenOut}`);\n console.log(`tx: ${result.hash}`);\n });\n","import type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"@moneyos/core\";\nimport { NATIVE_TOKEN_ADDRESS } from \"@moneyos/core\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\nconst ODOS_NATIVE_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n\ninterface OdosQuoteResponse {\n pathId: string;\n outAmounts: string[];\n outValues: number[];\n}\n\ninterface OdosAssembleResponse {\n transaction: {\n to: string;\n data: string;\n value: string;\n };\n}\n\nexport class OdosProvider implements SwapProvider {\n name = \"odos\";\n private apiKey?: string;\n\n constructor(options?: { apiKey?: string }) {\n this.apiKey = options?.apiKey;\n }\n\n private toOdosAddress(address: Address): Address {\n return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;\n }\n\n async getQuote(params: {\n chainId: number;\n tokenIn: Address;\n tokenOut: Address;\n amount: bigint;\n sender: Address;\n slippage?: number;\n }): Promise<SwapQuote & { pathId: string; sender: Address }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/quote/v2`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n chainId: params.chainId,\n inputTokens: [\n {\n tokenAddress: this.toOdosAddress(params.tokenIn),\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: this.toOdosAddress(params.tokenOut),\n proportion: 1,\n },\n ],\n userAddr: params.sender,\n slippageLimitPercent: params.slippage ?? 1,\n referralCode: 0,\n compact: true,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos quote failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosQuoteResponse;\n\n return {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amount.toString(),\n expectedOut: data.outAmounts[0],\n router: \"\" as Address,\n chainId: params.chainId,\n pathId: data.pathId,\n sender: params.sender,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string; sender: Address },\n ): Promise<{ to: Address; data: Hex; value: bigint }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/assemble`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n userAddr: quote.sender,\n pathId: quote.pathId,\n simulate: false,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos assemble failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosAssembleResponse;\n\n return {\n to: data.transaction.to as Address,\n data: data.transaction.data as Hex,\n value: BigInt(data.transaction.value),\n };\n }\n}\n","import { Command } from \"commander\";\nimport {\n loadFileConfig,\n} from \"../config.js\";\nimport {\n formatWalletStatus,\n resolveWalletStatus,\n} from \"../wallet-status.js\";\n\nexport const keystoreCommand = new Command(\"keystore\").description(\n \"Compatibility alias for wallet status\",\n);\n\nkeystoreCommand\n .command(\"status\")\n .description(\"Show the current wallet storage status\")\n .action(async () => {\n const config = loadFileConfig();\n const status = await resolveWalletStatus(config);\n console.log(formatWalletStatus(status));\n });\n","import type { Address } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { FileEncryptedWalletStore } from \"../core/encrypted-wallet.js\";\nimport {\n getLegacyPlaintextWalletStorageMessage,\n getRemovedOnePasswordCachedAddress,\n getRemovedOnePasswordStorageMessage,\n getWalletPath,\n hasLegacyPlaintextWalletConfig,\n hasRemovedOnePasswordConfig,\n type CLIConfig,\n} from \"./config.js\";\n\nexport type WalletStatusKind =\n | \"encrypted\"\n | \"none\"\n | \"legacy\"\n | \"unsupported\"\n | \"invalid\";\n\nexport interface ResolvedWalletStatus {\n kind: WalletStatusKind;\n address?: Address;\n walletPath: string;\n reason?: string;\n}\n\nexport async function resolveWalletStatus(\n config: CLIConfig,\n walletPath: string = getWalletPath(config),\n): Promise<ResolvedWalletStatus> {\n if (hasRemovedOnePasswordConfig(config)) {\n return {\n kind: \"unsupported\",\n address: getRemovedOnePasswordCachedAddress(config),\n walletPath,\n reason: getRemovedOnePasswordStorageMessage(),\n };\n }\n\n const store = new FileEncryptedWalletStore(walletPath);\n if (store.exists()) {\n try {\n const metadata = await store.metadata();\n return {\n kind: metadata ? \"encrypted\" : \"none\",\n address: metadata?.address,\n walletPath,\n };\n } catch (error) {\n return {\n kind: \"invalid\",\n walletPath,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n try {\n const address = privateKeyToAccount(config.privateKey!).address;\n return {\n kind: \"legacy\",\n walletPath,\n address,\n reason: getLegacyPlaintextWalletStorageMessage(),\n };\n } catch (error) {\n return {\n kind: \"legacy\",\n walletPath,\n reason:\n error instanceof Error\n ? `${getLegacyPlaintextWalletStorageMessage()} (${error.message})`\n : getLegacyPlaintextWalletStorageMessage(),\n };\n }\n }\n\n return {\n kind: \"none\",\n walletPath,\n };\n}\n\nexport function formatWalletStatus(status: ResolvedWalletStatus): string {\n const lines: string[] = [];\n\n if (status.kind === \"none\") {\n lines.push(\"Wallet: (none)\");\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\"Status: no wallet configured — run `moneyos init`\");\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"unsupported\") {\n lines.push(\"Wallet: removed legacy model\");\n if (status.address) {\n lines.push(`Address: ${status.address} (cached metadata)`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\n `Status: removed — ${status.reason ?? \"unsupported legacy config\"}`,\n );\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"legacy\") {\n lines.push(\"Wallet: legacy plaintext config\");\n if (status.address) {\n lines.push(`Address: ${status.address}`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\n `Status: upgrade required — ${status.reason ?? 'run `moneyos init`'}`,\n );\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"invalid\") {\n lines.push(\"Wallet: encrypted local wallet\");\n lines.push(`Path: ${status.walletPath}`);\n lines.push(`Status: invalid — ${status.reason ?? \"wallet file is unreadable\"}`);\n return lines.join(\"\\n\");\n }\n\n lines.push(\"Wallet: encrypted local wallet\");\n if (status.address) {\n lines.push(`Address: ${status.address}`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\"Status: ready\");\n return lines.join(\"\\n\");\n}\n","import { Command } from \"commander\";\nimport { FileEncryptedWalletStore } from \"../../core/encrypted-wallet.js\";\nimport {\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n loadFileConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport {\n getSessionStatus,\n lockSession,\n startDetachedSessionDaemon,\n} from \"../session.js\";\n\nconst DEFAULT_TTL_MS = 15 * 60 * 1000;\n\nfunction formatSessionStatus(params: {\n state: \"locked\" | \"unlocked\";\n address?: string;\n expiresAt?: string;\n}): string {\n const lines: string[] = [];\n lines.push(`Session: ${params.state}`);\n if (params.address) {\n lines.push(`Address: ${params.address}`);\n }\n if (params.expiresAt) {\n lines.push(`Expires: ${params.expiresAt}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport const authCommand = new Command(\"auth\").description(\n \"Unlock, inspect, and lock the local MoneyOS wallet session\",\n);\n\nauthCommand\n .command(\"unlock\")\n .description(\"Unlock the local wallet and start a short-lived session\")\n .action(async () => {\n const config = loadFileConfig();\n const walletPath = getWalletPath(config);\n const wallet = new FileEncryptedWalletStore(walletPath);\n\n if (!wallet.exists()) {\n console.error(\"No encrypted wallet found. Run `moneyos init` first.\");\n process.exitCode = 1;\n return;\n }\n\n try {\n const passphrase = await promptHidden(\"Wallet password: \");\n if (passphrase.length === 0) {\n throw new Error(\"Wallet password cannot be empty.\");\n }\n\n const privateKey = await wallet.decrypt(passphrase);\n const status = await startDetachedSessionDaemon({\n type: \"start\",\n privateKey,\n chainId: config.chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n socketPath: getSessionSocketPath(),\n tokenPath: getSessionTokenPath(),\n ttlMs: DEFAULT_TTL_MS,\n });\n\n console.log(\"Wallet unlocked.\");\n console.log(\n formatSessionStatus({\n state: \"unlocked\",\n address: status.address,\n expiresAt: status.expiresAt,\n }),\n );\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nauthCommand\n .command(\"lock\")\n .description(\"Lock the local MoneyOS wallet session\")\n .action(async () => {\n const locked = await lockSession(\n getSessionSocketPath(),\n getSessionTokenPath(),\n );\n console.log(\n formatSessionStatus({\n state: \"locked\",\n }),\n );\n if (!locked) {\n console.log(\"No active local session was running.\");\n }\n });\n\nauthCommand\n .command(\"status\")\n .description(\"Show whether the local wallet session is unlocked\")\n .action(async () => {\n const status = await getSessionStatus(\n getSessionSocketPath(),\n getSessionTokenPath(),\n );\n if (!status) {\n console.log(\n formatSessionStatus({\n state: \"locked\",\n }),\n );\n return;\n }\n\n console.log(\n formatSessionStatus({\n state: \"unlocked\",\n address: status.address,\n expiresAt: status.expiresAt,\n }),\n );\n });\n","import { Command } from \"commander\";\nimport { FileBackupProvider } from \"../../core/backup-file.js\";\nimport {\n getBackupDir,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n loadFileConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport { lockSession } from \"../session.js\";\n\nfunction formatBackupStatus(params: {\n walletPath: string;\n backupDir: string;\n exists: boolean;\n backupCount: number;\n latestBackupPath?: string;\n address?: string;\n}): string {\n const lines: string[] = [];\n lines.push(`Wallet: ${params.exists ? \"present\" : \"missing\"}`);\n if (params.address) {\n lines.push(`Address: ${params.address}`);\n }\n lines.push(`Wallet at: ${params.walletPath}`);\n lines.push(`Backups: ${params.backupCount}`);\n lines.push(`Directory: ${params.backupDir}`);\n if (params.latestBackupPath) {\n lines.push(`Latest: ${params.latestBackupPath}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport const backupCommand = new Command(\"backup\").description(\n \"Export, restore, and inspect encrypted wallet backups\",\n);\n\nbackupCommand\n .command(\"export\")\n .description(\"Write a copy of the encrypted wallet backup\")\n .option(\"-o, --out <path>\", \"Custom path for the backup file\")\n .option(\"--force\", \"Overwrite an existing backup file at --out\")\n .action(async (options) => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n\n try {\n const targetPath = await provider.exportWallet({\n outPath: options.out,\n allowOverwrite: Boolean(options.force),\n });\n console.log(`Backup exported to ${targetPath}`);\n console.log(\n \"Save your wallet password in your password manager of choice. MoneyOS does not store or sync it for you.\",\n );\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nbackupCommand\n .command(\"restore\")\n .description(\"Restore the encrypted wallet from a backup file\")\n .argument(\"<path>\", \"Path to the encrypted backup file\")\n .option(\"--force\", \"Overwrite an existing encrypted wallet\")\n .action(async (path: string, options) => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n\n try {\n const passphrase = await promptHidden(\n \"Wallet password for backup verification: \",\n );\n const metadata = await provider.restoreWallet(path, {\n passphrase,\n allowOverwrite: Boolean(options.force),\n });\n await lockSession(getSessionSocketPath(), getSessionTokenPath());\n console.log(\"Encrypted wallet restored.\");\n console.log(`Address: ${metadata.address}`);\n console.log(`Wallet: ${getWalletPath(config)}`);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nbackupCommand\n .command(\"status\")\n .description(\"Show the local wallet backup status\")\n .action(async () => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n const status = await provider.status();\n console.log(formatBackupStatus(status));\n });\n","import { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\n\nconst packageJsonPath = resolve(\n dirname(fileURLToPath(import.meta.url)),\n \"../../package.json\",\n);\n\ntype PackageJson = {\n version: string;\n};\n\nexport const version = (JSON.parse(\n readFileSync(packageJsonPath, \"utf8\"),\n) as PackageJson).version;\n"],"mappings":"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","names":["Command","privateKeyToAccount","existsSync","statSync","join","join","existsSync","statSync","readFileSync","existsSync","mkdirSync","dirname","join","join","resolve","randomBytes","chmodSync","existsSync","mkdirSync","readFileSync","statSync","writeFileSync","dirname","privateKeyToAccount","SECURE_FILE_MODE","existsSync","dirname","mkdirSync","statSync","readFileSync","writeFileSync","chmodSync","resolve","randomBytes","privateKeyToAccount","Command","formatUnits","parseUnits","encodeFunctionData","ERC20_ABI","raw","formatUnits","parseUnits","result","encodeFunctionData","Command","Command","Command","Command","Command","Command","privateKeyToAccount","privateKeyToAccount","Command","Command","Command","Command","Command","readFileSync","dirname","resolve","Command"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/core/backup-file.ts","../../src/core/encrypted-wallet.ts","../../src/cli/config.ts","../../src/cli/prompt.ts","../../src/cli/session.ts","../../src/core/eoa.ts","../../packages/core/src/tokens.ts","../../packages/core/src/chains.ts","../../src/core/signer.ts","../../src/cli/commands/balance.ts","../../src/core/client.ts","../../src/tools/swap.ts","../../src/cli/wallet.ts","../../src/cli/commands/send.ts","../../src/cli/commands/swap.ts","../../src/providers/odos.ts","../../src/cli/commands/keystore.ts","../../src/cli/wallet-status.ts","../../src/cli/commands/auth.ts","../../src/cli/commands/backup.ts","../../src/cli/version.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { balanceCommand } from \"./commands/balance.js\";\nimport { sendCommand } from \"./commands/send.js\";\nimport { swapCommand } from \"./commands/swap.js\";\nimport { keystoreCommand } from \"./commands/keystore.js\";\nimport { authCommand } from \"./commands/auth.js\";\nimport { backupCommand } from \"./commands/backup.js\";\nimport { runSessionDaemonProcess } from \"./session.js\";\nimport { version } from \"./version.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"moneyos\")\n .description(\"The operating system for money\")\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(balanceCommand);\nprogram.addCommand(sendCommand);\nprogram.addCommand(swapCommand);\nprogram.addCommand(keystoreCommand);\nprogram.addCommand(authCommand);\nprogram.addCommand(backupCommand);\nprogram\n .command(\"__session-daemon\", { hidden: true })\n .action(async () => {\n await runSessionDaemonProcess();\n });\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex } from \"viem\";\nimport {\n FileBackupProvider,\n type BackupProvider,\n} from \"../../core/backup-file.js\";\nimport {\n FileEncryptedWalletStore,\n type EncryptedWalletStore,\n} from \"../../core/encrypted-wallet.js\";\nimport {\n type CLIConfig,\n getBackupDir,\n getConfigPath,\n getLegacyPlaintextWalletStorageMessage,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n getRemovedOnePasswordStorageMessage,\n hasRemovedOnePasswordConfig,\n hasLegacyPlaintextWalletConfig,\n loadFileConfig,\n saveConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport { lockSession } from \"../session.js\";\n\nfunction parseChainId(value: string | undefined, fallback: number): number {\n if (!value) return fallback;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`Invalid chain ID: \"${value}\"`);\n }\n return parsed;\n}\n\nexport interface InitCommandOptions {\n key?: string;\n force?: boolean;\n chain?: string;\n rpc?: string;\n}\n\nexport interface InitCommandDependencies {\n loadFileConfig: () => CLIConfig;\n getWalletPath: (config?: CLIConfig) => string;\n getBackupDir: (config?: CLIConfig) => string;\n getConfigPath: () => string;\n createWalletStore: (walletPath: string) => EncryptedWalletStore;\n createBackupProvider: (params: {\n walletPath: string;\n backupDir: string;\n }) => BackupProvider;\n hasRemovedOnePasswordConfig: (config: CLIConfig) => boolean;\n getRemovedOnePasswordStorageMessage: () => string;\n hasLegacyPlaintextWalletConfig: (config: CLIConfig) => boolean;\n getLegacyPlaintextWalletStorageMessage: () => string;\n promptHidden: (question: string) => Promise<string>;\n lockSession: (socketPath: string, tokenPath: string) => Promise<boolean>;\n getSessionSocketPath: () => string;\n getSessionTokenPath: () => string;\n saveConfig: (config: CLIConfig) => void;\n generatePrivateKey: () => Hex;\n log: (message: string) => void;\n error: (message: string) => void;\n}\n\nconst defaultInitCommandDependencies: InitCommandDependencies = {\n loadFileConfig,\n getWalletPath,\n getBackupDir,\n getConfigPath,\n createWalletStore: (walletPath) => new FileEncryptedWalletStore(walletPath),\n createBackupProvider: (params) => new FileBackupProvider(params),\n hasRemovedOnePasswordConfig,\n getRemovedOnePasswordStorageMessage,\n hasLegacyPlaintextWalletConfig,\n getLegacyPlaintextWalletStorageMessage,\n promptHidden,\n lockSession,\n getSessionSocketPath,\n getSessionTokenPath,\n saveConfig,\n generatePrivateKey,\n log: (message) => console.log(message),\n error: (message) => console.error(message),\n};\n\nexport async function runInitCommand(\n options: InitCommandOptions,\n deps: InitCommandDependencies = defaultInitCommandDependencies,\n): Promise<void> {\n const existing = deps.loadFileConfig();\n const walletPath = deps.getWalletPath(existing);\n const backupDir = deps.getBackupDir(existing);\n const wallet = deps.createWalletStore(walletPath);\n\n if (wallet.exists() && !options.force) {\n const metadata = await wallet.metadata();\n deps.log(`Already initialized.`);\n if (metadata?.address) {\n deps.log(`Address: ${metadata.address}`);\n }\n deps.log(`Wallet: ${walletPath}`);\n deps.log(`Config: ${deps.getConfigPath()}`);\n deps.log(`\\nTo reinitialize, run: moneyos init --force --key <privateKey>`);\n return;\n }\n\n if (deps.hasRemovedOnePasswordConfig(existing) && !options.key) {\n deps.error(deps.getRemovedOnePasswordStorageMessage());\n deps.error(`Config: ${deps.getConfigPath()}`);\n return;\n }\n\n try {\n const privateKey =\n options.key ??\n (deps.hasLegacyPlaintextWalletConfig(existing)\n ? existing.privateKey!\n : deps.generatePrivateKey());\n const account = privateKeyToAccount(privateKey as Hex);\n const chainId = parseChainId(options.chain, existing.chainId ?? 42161);\n const rpcUrl = options.rpc ?? existing.rpcUrl;\n const passphrase = await deps.promptHidden(\"Choose wallet password: \");\n if (passphrase.length < 8) {\n throw new Error(\"Wallet password must be at least 8 characters long.\");\n }\n const confirmPassphrase = await deps.promptHidden(\"Confirm wallet password: \");\n if (passphrase !== confirmPassphrase) {\n throw new Error(\"Wallet password confirmation did not match.\");\n }\n\n await wallet.save({\n privateKey: privateKey as Hex,\n passphrase,\n });\n await deps.lockSession(\n deps.getSessionSocketPath(),\n deps.getSessionTokenPath(),\n );\n\n deps.saveConfig({\n chainId,\n rpcUrl,\n walletPath: existing.walletPath,\n backupDir: existing.backupDir,\n });\n\n const backupProvider = deps.createBackupProvider({\n walletPath,\n backupDir,\n });\n const backupPath = await backupProvider.exportWallet();\n\n deps.log(`MoneyOS initialized.`);\n deps.log(`Address: ${account.address}`);\n deps.log(`Wallet: ${walletPath}`);\n deps.log(`Config: ${deps.getConfigPath()}`);\n deps.log(`Backup: ${backupPath}`);\n deps.log(\n `\\nSave your wallet password in your password manager of choice. MoneyOS does not store or sync it for you.`,\n );\n\n if (deps.hasLegacyPlaintextWalletConfig(existing) && !options.key) {\n deps.log(`\\nImported legacy plaintext wallet into the encrypted wallet file.`);\n deps.log(deps.getLegacyPlaintextWalletStorageMessage());\n } else if (!options.key) {\n deps.log(\n `\\nThis is a new account. Fund it before sending transactions.`,\n );\n }\n } catch (error) {\n deps.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n}\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize MoneyOS with a new or imported encrypted wallet\")\n .option(\"-k, --key <privateKey>\", \"Import an existing private key\")\n .option(\"--force\", \"Overwrite the existing encrypted wallet\")\n .option(\"--chain <chainId>\", \"Default chain ID (default: 42161 Arbitrum)\")\n .option(\"--rpc <url>\", \"Custom RPC URL\")\n .action(async (options) => {\n await runInitCommand(options);\n });\n","import {\n existsSync,\n readdirSync,\n statSync,\n} from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { Address } from \"viem\";\nimport {\n FileEncryptedWalletStore,\n type EncryptedWalletMetadata,\n readEncryptedWalletFile,\n verifyEncryptedWalletPassphrase,\n writeEncryptedWalletFile,\n} from \"./encrypted-wallet.js\";\n\nexport interface BackupProvider {\n readonly kind: \"file\";\n exportWallet(options?: { outPath?: string; allowOverwrite?: boolean }): Promise<string>;\n restoreWallet(\n fromPath: string,\n options: { passphrase: string; allowOverwrite?: boolean },\n ): Promise<EncryptedWalletMetadata>;\n status(): Promise<{\n walletPath: string;\n backupDir: string;\n exists: boolean;\n latestBackupPath?: string;\n backupCount: number;\n address?: Address;\n }>;\n}\n\nfunction formatTimestamp(now: Date): string {\n const pad = (value: number) => value.toString().padStart(2, \"0\");\n return [\n now.getUTCFullYear().toString(),\n pad(now.getUTCMonth() + 1),\n pad(now.getUTCDate()),\n \"-\",\n pad(now.getUTCHours()),\n pad(now.getUTCMinutes()),\n pad(now.getUTCSeconds()),\n ].join(\"\");\n}\n\nexport class FileBackupProvider implements BackupProvider {\n readonly kind = \"file\" as const;\n private readonly store: FileEncryptedWalletStore;\n private readonly backupDir: string;\n\n constructor(params: { walletPath: string; backupDir: string }) {\n this.store = new FileEncryptedWalletStore(params.walletPath);\n this.backupDir = params.backupDir;\n }\n\n private defaultBackupPath(address: Address): string {\n return join(\n this.backupDir,\n `wallet-${address}-${formatTimestamp(new Date())}.json`,\n );\n }\n\n async exportWallet(\n options: { outPath?: string; allowOverwrite?: boolean } = {},\n ): Promise<string> {\n if (options.outPath === \"-\") {\n throw new Error(\"Refusing to export an encrypted wallet backup to stdout.\");\n }\n const wallet = await this.store.exportData();\n const targetPath = options.outPath\n ? resolve(options.outPath)\n : this.defaultBackupPath(wallet.address);\n if (existsSync(targetPath) && !options.allowOverwrite) {\n throw new Error(\n \"Backup file already exists. Re-run with `--force` if you really want to overwrite it.\",\n );\n }\n await writeEncryptedWalletFile(targetPath, wallet, {\n parentDescription: \"Backup export destination directory\",\n fileDescription: \"Backup export file\",\n });\n return targetPath;\n }\n\n async restoreWallet(\n fromPath: string,\n options: { passphrase: string; allowOverwrite?: boolean },\n ): Promise<EncryptedWalletMetadata> {\n if (this.store.exists() && !options.allowOverwrite) {\n throw new Error(\n \"A wallet already exists. Re-run with `--force` if you really want to overwrite it.\",\n );\n }\n\n const sourcePath = resolve(fromPath);\n const wallet = await readEncryptedWalletFile(sourcePath);\n await verifyEncryptedWalletPassphrase(wallet, options.passphrase);\n return this.store.restore(wallet);\n }\n\n async status(): Promise<{\n walletPath: string;\n backupDir: string;\n exists: boolean;\n latestBackupPath?: string;\n backupCount: number;\n address?: Address;\n }> {\n const exists = this.store.exists();\n const metadata = exists ? await this.store.metadata() : undefined;\n\n if (!existsSync(this.backupDir)) {\n return {\n walletPath: this.store.walletPath,\n backupDir: this.backupDir,\n exists,\n backupCount: 0,\n address: metadata?.address,\n };\n }\n\n const files = readdirSync(this.backupDir)\n .filter((name) => name.endsWith(\".json\"))\n .map((name) => join(this.backupDir, name))\n .sort(\n (a, b) => statSync(b).mtimeMs - statSync(a).mtimeMs,\n );\n\n return {\n walletPath: this.store.walletPath,\n backupDir: this.backupDir,\n exists,\n latestBackupPath: files[0],\n backupCount: files.length,\n address: metadata?.address,\n };\n }\n}\n","import {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n scryptSync,\n} from \"node:crypto\";\nimport {\n chmodSync,\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n statSync,\n unlinkSync,\n writeSync,\n} from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { recoverMessageAddress, type Address, type Hex } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nexport interface EncryptedWalletKdfConfig {\n name: \"scrypt\";\n N: number;\n r: number;\n p: number;\n keyLength: number;\n}\n\nexport interface EncryptedWalletCrypto {\n cipher: \"aes-256-gcm\";\n salt: string;\n nonce: string;\n authTag: string;\n ciphertext: string;\n}\n\nexport interface EncryptedWalletFile {\n version: 1;\n kind: \"encrypted-local-eoa\";\n address: Address;\n createdAt: string;\n addressProof: Hex;\n kdf: EncryptedWalletKdfConfig;\n crypto: EncryptedWalletCrypto;\n}\n\nexport interface EncryptedWalletMetadata {\n version: 1;\n kind: \"encrypted-local-eoa\";\n address: Address;\n createdAt: string;\n}\n\nexport interface SecureWriteLabels {\n parentDescription: string;\n fileDescription: string;\n}\n\ntype WalletIdentityMetadata = Pick<\n EncryptedWalletFile,\n \"version\" | \"kind\" | \"address\" | \"createdAt\" | \"addressProof\"\n>;\n\nexport interface EncryptedWalletStore {\n readonly walletPath: string;\n exists(): boolean;\n metadata(): Promise<EncryptedWalletMetadata | undefined>;\n save(params: { privateKey: Hex; passphrase: string }): Promise<EncryptedWalletMetadata>;\n rotatePassphrase(params: {\n oldPassphrase: string;\n newPassphrase: string;\n }): Promise<EncryptedWalletMetadata>;\n decrypt(passphrase: string): Promise<Hex>;\n exportData(): Promise<EncryptedWalletFile>;\n restore(data: EncryptedWalletFile): Promise<EncryptedWalletMetadata>;\n}\n\nconst DEFAULT_KDF: EncryptedWalletKdfConfig = {\n name: \"scrypt\",\n N: 131072,\n r: 8,\n p: 1,\n keyLength: 32,\n};\n\nconst SECURE_FILE_MODE = 0o600;\nconst SECURE_PARENT_MODE = 0o700;\nconst WALLET_WRITE_LABELS: SecureWriteLabels = {\n parentDescription: \"Wallet directory\",\n fileDescription: \"Wallet file\",\n};\n\nfunction normalizePassphrase(passphrase: string): string {\n return passphrase.normalize(\"NFC\");\n}\n\nfunction walletProofMessage(wallet: Pick<\n EncryptedWalletFile,\n \"version\" | \"kind\" | \"address\" | \"createdAt\"\n>): string {\n return [\n \"MoneyOS wallet metadata\",\n `v=${wallet.version}`,\n `kind=${wallet.kind}`,\n `address=${wallet.address}`,\n `createdAt=${wallet.createdAt}`,\n ].join(\"|\");\n}\n\nfunction ensureParentDir(path: string, label: string): void {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: SECURE_PARENT_MODE });\n return;\n }\n\n const mode = statSync(dir).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `${label} ${dir} has insecure permissions (${mode.toString(8)}). Restrict it to 700 before continuing.`,\n );\n }\n}\n\nfunction assertSecureFileMode(path: string, label: string): void {\n if (!existsSync(path)) {\n return;\n }\n\n const mode = statSync(path).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `${label} at ${path} has insecure permissions (${mode.toString(8)}). Restrict it to 600 before continuing.`,\n );\n }\n}\n\nfunction parseWalletFile(raw: string, path: string): EncryptedWalletFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n throw new Error(\n `Encrypted wallet at ${path} is not valid JSON: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(`Encrypted wallet at ${path} must be a JSON object`);\n }\n\n const wallet = parsed as Partial<EncryptedWalletFile>;\n if (wallet.version !== 1) {\n throw new Error(`Encrypted wallet at ${path} has unsupported version`);\n }\n if (wallet.kind !== \"encrypted-local-eoa\") {\n throw new Error(`Encrypted wallet at ${path} has unsupported kind`);\n }\n if (typeof wallet.address !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing address metadata`);\n }\n if (typeof wallet.addressProof !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing address proof`);\n }\n if (\n !wallet.kdf ||\n wallet.kdf.name !== \"scrypt\" ||\n !Number.isInteger(wallet.kdf.N) ||\n !Number.isInteger(wallet.kdf.r) ||\n !Number.isInteger(wallet.kdf.p) ||\n !Number.isInteger(wallet.kdf.keyLength)\n ) {\n throw new Error(`Encrypted wallet at ${path} has invalid KDF parameters`);\n }\n if (\n !wallet.crypto ||\n wallet.crypto.cipher !== \"aes-256-gcm\" ||\n typeof wallet.crypto.salt !== \"string\" ||\n typeof wallet.crypto.nonce !== \"string\" ||\n typeof wallet.crypto.authTag !== \"string\" ||\n typeof wallet.crypto.ciphertext !== \"string\"\n ) {\n throw new Error(`Encrypted wallet at ${path} has invalid crypto metadata`);\n }\n if (typeof wallet.createdAt !== \"string\") {\n throw new Error(`Encrypted wallet at ${path} is missing createdAt`);\n }\n\n return wallet as EncryptedWalletFile;\n}\n\nfunction toMetadata(wallet: EncryptedWalletFile): EncryptedWalletMetadata {\n return {\n version: wallet.version,\n kind: wallet.kind,\n address: wallet.address,\n createdAt: wallet.createdAt,\n };\n}\n\nasync function verifyWalletAddressProof(\n wallet: EncryptedWalletFile,\n path: string,\n): Promise<void> {\n let recovered: Address;\n try {\n recovered = await recoverMessageAddress({\n message: walletProofMessage(wallet),\n signature: wallet.addressProof,\n });\n } catch {\n throw new Error(`Encrypted wallet at ${path} has an invalid address proof`);\n }\n\n if (recovered.toLowerCase() !== wallet.address.toLowerCase()) {\n throw new Error(`Encrypted wallet at ${path} failed address proof validation`);\n }\n}\n\nfunction deriveKey(\n passphrase: string,\n salt: Buffer,\n kdf: EncryptedWalletKdfConfig,\n): Buffer {\n return scryptSync(normalizePassphrase(passphrase), salt, kdf.keyLength, {\n N: kdf.N,\n r: kdf.r,\n p: kdf.p,\n maxmem: 256 * 1024 * 1024,\n }) as Buffer;\n}\n\nfunction walletAad(kdf: EncryptedWalletKdfConfig): Buffer {\n // If the KDF shape changes in a future wallet version, update this payload so\n // all KDF fields remain bound to the AEAD tag.\n return Buffer.from(\n JSON.stringify({\n name: kdf.name,\n N: kdf.N,\n r: kdf.r,\n p: kdf.p,\n keyLength: kdf.keyLength,\n }),\n \"utf8\",\n );\n}\n\nfunction writeFileAtomicSecure(\n path: string,\n contents: string,\n labels: SecureWriteLabels = WALLET_WRITE_LABELS,\n): void {\n ensureParentDir(path, labels.parentDescription);\n assertSecureFileMode(path, labels.fileDescription);\n\n const tmpPath = join(\n dirname(path),\n `.${basename(path)}.${randomBytes(6).toString(\"hex\")}.tmp`,\n );\n const fd = openSync(tmpPath, \"wx\", SECURE_FILE_MODE);\n let writeError: unknown;\n\n try {\n writeSync(fd, contents);\n fsyncSync(fd);\n } catch (error) {\n writeError = error;\n } finally {\n closeSync(fd);\n }\n\n if (writeError) {\n try {\n unlinkSync(tmpPath);\n } catch {\n // best effort cleanup\n }\n throw writeError;\n }\n\n renameSync(tmpPath, path);\n chmodSync(path, SECURE_FILE_MODE);\n}\n\nasync function encryptWallet(params: {\n privateKey: Hex;\n passphrase: string;\n identity?: WalletIdentityMetadata;\n}): Promise<EncryptedWalletFile> {\n const account = privateKeyToAccount(params.privateKey);\n const createdAt = params.identity?.createdAt ?? new Date().toISOString();\n const salt = randomBytes(16);\n const nonce = randomBytes(12);\n const key = deriveKey(params.passphrase, salt, DEFAULT_KDF);\n const cipher = createCipheriv(\"aes-256-gcm\", key, nonce);\n cipher.setAAD(walletAad(DEFAULT_KDF));\n const plaintext = Buffer.from(\n JSON.stringify({ privateKey: params.privateKey }),\n \"utf8\",\n );\n const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const authTag = cipher.getAuthTag();\n const addressProof =\n params.identity?.addressProof ??\n (await account.signMessage({\n message: walletProofMessage({\n version: 1,\n kind: \"encrypted-local-eoa\",\n address: account.address,\n createdAt,\n }),\n }));\n\n if (\n params.identity &&\n account.address.toLowerCase() !== params.identity.address.toLowerCase()\n ) {\n throw new Error(\"wallet address metadata mismatch\");\n }\n\n return {\n version: params.identity?.version ?? 1,\n kind: params.identity?.kind ?? \"encrypted-local-eoa\",\n address: params.identity?.address ?? account.address,\n createdAt,\n addressProof,\n kdf: DEFAULT_KDF,\n crypto: {\n cipher: \"aes-256-gcm\",\n salt: salt.toString(\"base64\"),\n nonce: nonce.toString(\"base64\"),\n authTag: authTag.toString(\"base64\"),\n ciphertext: ciphertext.toString(\"base64\"),\n },\n };\n}\n\nfunction walletIdentity(wallet: EncryptedWalletFile): WalletIdentityMetadata {\n return {\n version: wallet.version,\n kind: wallet.kind,\n address: wallet.address,\n createdAt: wallet.createdAt,\n addressProof: wallet.addressProof,\n };\n}\n\nasync function decryptWalletFile(\n wallet: EncryptedWalletFile,\n passphrase: string,\n): Promise<Hex> {\n try {\n const salt = Buffer.from(wallet.crypto.salt, \"base64\");\n const nonce = Buffer.from(wallet.crypto.nonce, \"base64\");\n const authTag = Buffer.from(wallet.crypto.authTag, \"base64\");\n const ciphertext = Buffer.from(wallet.crypto.ciphertext, \"base64\");\n const key = deriveKey(passphrase, salt, wallet.kdf);\n const decipher = createDecipheriv(\"aes-256-gcm\", key, nonce);\n decipher.setAAD(walletAad(wallet.kdf));\n decipher.setAuthTag(authTag);\n const plaintext = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf8\");\n const parsed = JSON.parse(plaintext) as { privateKey?: unknown };\n if (typeof parsed.privateKey !== \"string\") {\n throw new Error(\"wallet payload missing privateKey\");\n }\n const privateKey = parsed.privateKey as Hex;\n const derivedAddress = privateKeyToAccount(privateKey).address;\n if (derivedAddress.toLowerCase() !== wallet.address.toLowerCase()) {\n throw new Error(\"wallet address metadata mismatch\");\n }\n\n return privateKey;\n } catch {\n throw new Error(\"Invalid password or corrupted wallet.\");\n }\n}\n\nexport class FileEncryptedWalletStore implements EncryptedWalletStore {\n readonly walletPath: string;\n\n constructor(walletPath: string) {\n this.walletPath = walletPath;\n }\n\n exists(): boolean {\n return existsSync(this.walletPath);\n }\n\n async metadata(): Promise<EncryptedWalletMetadata | undefined> {\n if (!this.exists()) {\n return undefined;\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return toMetadata(wallet);\n }\n\n async save(params: {\n privateKey: Hex;\n passphrase: string;\n }): Promise<EncryptedWalletMetadata> {\n const wallet = await encryptWallet(params);\n writeFileAtomicSecure(\n this.walletPath,\n JSON.stringify(wallet, null, 2),\n WALLET_WRITE_LABELS,\n );\n return toMetadata(wallet);\n }\n\n async rotatePassphrase(params: {\n oldPassphrase: string;\n newPassphrase: string;\n }): Promise<EncryptedWalletMetadata> {\n if (!this.exists()) {\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n const privateKey = await decryptWalletFile(wallet, params.oldPassphrase);\n const rotated = await encryptWallet({\n privateKey,\n passphrase: params.newPassphrase,\n identity: walletIdentity(wallet),\n });\n writeFileAtomicSecure(this.walletPath, JSON.stringify(rotated, null, 2));\n return toMetadata(rotated);\n }\n\n async decrypt(passphrase: string): Promise<Hex> {\n if (!this.exists()) {\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return decryptWalletFile(wallet, passphrase);\n }\n\n async exportData(): Promise<EncryptedWalletFile> {\n if (!this.exists()) {\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n }\n\n assertSecureFileMode(this.walletPath, \"Wallet file\");\n const wallet = parseWalletFile(\n readFileSync(this.walletPath, \"utf8\"),\n this.walletPath,\n );\n await verifyWalletAddressProof(wallet, this.walletPath);\n return wallet;\n }\n\n async restore(data: EncryptedWalletFile): Promise<EncryptedWalletMetadata> {\n const wallet = parseWalletFile(JSON.stringify(data), this.walletPath);\n await verifyWalletAddressProof(wallet, this.walletPath);\n writeFileAtomicSecure(\n this.walletPath,\n JSON.stringify(wallet, null, 2),\n WALLET_WRITE_LABELS,\n );\n return toMetadata(wallet);\n }\n}\n\nexport async function writeEncryptedWalletFile(\n path: string,\n data: EncryptedWalletFile,\n labels: SecureWriteLabels = WALLET_WRITE_LABELS,\n): Promise<EncryptedWalletMetadata> {\n const wallet = parseWalletFile(JSON.stringify(data), path);\n await verifyWalletAddressProof(wallet, path);\n writeFileAtomicSecure(path, JSON.stringify(wallet, null, 2), labels);\n return toMetadata(wallet);\n}\n\nexport async function readEncryptedWalletFile(\n path: string,\n): Promise<EncryptedWalletFile> {\n assertSecureFileMode(path, \"Wallet file\");\n const wallet = parseWalletFile(readFileSync(path, \"utf8\"), path);\n await verifyWalletAddressProof(wallet, path);\n return wallet;\n}\n\nexport async function verifyEncryptedWalletPassphrase(\n wallet: EncryptedWalletFile,\n passphrase: string,\n): Promise<EncryptedWalletMetadata> {\n await verifyWalletAddressProof(wallet, \"(in-memory wallet)\");\n await decryptWalletFile(wallet, passphrase);\n return toMetadata(wallet);\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { Address, Hex } from \"viem\";\n\nconst CONFIG_DIR = join(homedir(), \".moneyos\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\n/**\n * Local CLI configuration persisted at `~/.moneyos/config.json`.\n *\n * Only non-secret settings should be persisted here. Wallet secrets now live\n * in the encrypted wallet file, while `privateKey` remains as a legacy-only\n * field so older configs can be detected and upgraded through `moneyos init`.\n */\nexport interface CLIConfig {\n chainId?: number;\n rpcUrl?: string;\n walletPath?: string;\n backupDir?: string;\n /**\n * Legacy plaintext wallet field from earlier MoneyOS versions. This should\n * never be written by the current CLI.\n */\n privateKey?: Hex;\n}\n\ninterface RemovedOnePasswordConfigShape {\n keyStore?: {\n kind?: unknown;\n address?: unknown;\n };\n}\n\nexport function hasRemovedOnePasswordConfig(config: CLIConfig): boolean {\n return (\n (config as CLIConfig & RemovedOnePasswordConfigShape).keyStore?.kind ===\n \"1password\"\n );\n}\n\nexport function getRemovedOnePasswordCachedAddress(\n config: CLIConfig,\n): Address | undefined {\n const address = (config as CLIConfig & RemovedOnePasswordConfigShape)\n .keyStore?.address;\n return typeof address === \"string\" ? (address as Address) : undefined;\n}\n\nexport function getRemovedOnePasswordStorageMessage(): string {\n return \"This repo no longer supports the old 1Password-backed private-key storage path. Re-import the wallet into the local file path with `moneyos init --key <privateKey>`.\";\n}\n\n/**\n * Read the CLI config file.\n *\n * @param path Optional absolute path to the config file. Defaults to\n * `~/.moneyos/config.json`. Primarily exposed so tests can point at a\n * tmpdir without mocking `homedir`.\n */\nexport function loadFileConfig(path: string = CONFIG_FILE): CLIConfig {\n if (!existsSync(path)) {\n return {};\n }\n return JSON.parse(readFileSync(path, \"utf-8\")) as CLIConfig;\n}\n\nexport function loadConfig(): CLIConfig {\n const config: CLIConfig = { ...loadFileConfig() };\n\n // Env vars override file config — standard for agents/CI\n if (process.env.MONEYOS_PRIVATE_KEY) {\n config.privateKey = process.env.MONEYOS_PRIVATE_KEY as Hex;\n }\n if (process.env.MONEYOS_RPC_URL) {\n config.rpcUrl = process.env.MONEYOS_RPC_URL;\n }\n if (process.env.MONEYOS_CHAIN_ID) {\n const parsed = Number(process.env.MONEYOS_CHAIN_ID);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(\n `Invalid MONEYOS_CHAIN_ID: \"${process.env.MONEYOS_CHAIN_ID}\" — must be a positive integer`,\n );\n }\n config.chainId = parsed;\n }\n\n return config;\n}\n\n/**\n * Write the CLI config file.\n *\n * @param config The config to persist.\n * @param path Optional absolute path to the config file. Defaults to\n * `~/.moneyos/config.json`. Primarily exposed so tests can point at a\n * tmpdir without mocking `homedir`. When a custom path is passed, the\n * parent directory is created with mode 0o700 if it does not already\n * exist.\n */\nexport function saveConfig(\n config: CLIConfig,\n path: string = CONFIG_FILE,\n): void {\n const safeConfig = { ...config };\n delete safeConfig.privateKey;\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(path, JSON.stringify(safeConfig, null, 2), {\n mode: 0o600,\n });\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function getMoneyOSDir(): string {\n return CONFIG_DIR;\n}\n\nexport function getWalletPath(config?: CLIConfig): string {\n return config?.walletPath ?? join(CONFIG_DIR, \"wallet.json\");\n}\n\nexport function getBackupDir(config?: CLIConfig): string {\n return config?.backupDir ?? join(CONFIG_DIR, \"backups\");\n}\n\nexport function getSessionSocketPath(): string {\n if (process.platform === \"win32\") {\n const suffix = createHash(\"sha256\")\n .update(CONFIG_DIR)\n .digest(\"hex\")\n .slice(0, 16);\n return `\\\\\\\\.\\\\pipe\\\\moneyos-session-${suffix}`;\n }\n\n return join(CONFIG_DIR, \"session.sock\");\n}\n\nexport function getSessionTokenPath(): string {\n return join(CONFIG_DIR, \"session.token\");\n}\n\nexport function hasLegacyPlaintextWalletConfig(config: CLIConfig): boolean {\n return typeof config.privateKey === \"string\";\n}\n\nexport function getLegacyPlaintextWalletStorageMessage(): string {\n return \"Plaintext local wallet configs are no longer used for runtime access. Run `moneyos init` locally to encrypt your wallet into the new MoneyOS wallet file.\";\n}\n","export async function promptHidden(question: string): Promise<string> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n throw new Error(\n \"This action requires a local terminal. Run it directly in your terminal, not through a non-interactive agent session.\",\n );\n }\n\n return new Promise<string>((resolve, reject) => {\n const stdin = process.stdin;\n const stdout = process.stdout;\n let value = \"\";\n\n const cleanup = () => {\n stdin.off(\"data\", onData);\n stdin.pause();\n if (typeof stdin.setRawMode === \"function\") {\n stdin.setRawMode(false);\n }\n };\n\n const finish = (result?: string, error?: Error) => {\n cleanup();\n stdout.write(\"\\n\");\n if (error) {\n reject(error);\n return;\n }\n resolve(result ?? \"\");\n };\n\n const onData = (chunk: Buffer | string) => {\n const text = chunk.toString(\"utf8\");\n for (const char of text) {\n if (char === \"\\u0003\") {\n finish(undefined, new Error(\"Cancelled.\"));\n return;\n }\n if (char === \"\\r\" || char === \"\\n\") {\n finish(value);\n return;\n }\n if (char === \"\\u007f\" || char === \"\\b\") {\n value = value.slice(0, -1);\n continue;\n }\n value += char;\n }\n };\n\n stdout.write(question);\n if (typeof stdin.setRawMode === \"function\") {\n stdin.setRawMode(true);\n }\n stdin.resume();\n stdin.on(\"data\", onData);\n });\n}\n","import { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport net from \"node:net\";\nimport { EOL } from \"node:os\";\nimport { dirname } from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport type { Address } from \"viem\";\nimport type { CallRequest, ExecutionClient, ExecutionResult } from \"@moneyos/core\";\nimport { EOAExecutor } from \"../core/eoa.js\";\nimport { privateKeyToManagedAccount } from \"../core/signer.js\";\n\nexport interface SessionServerStartMessage {\n type: \"start\";\n privateKey: `0x${string}`;\n chainId: number;\n rpcUrl?: string;\n socketPath: string;\n tokenPath: string;\n ttlMs: number;\n}\n\nexport interface SessionStatusResult {\n address: Address;\n expiresAt: string;\n}\n\nexport interface SessionServerHandle {\n readonly address: Address;\n readonly expiresAt: string;\n close(): Promise<void>;\n}\n\ninterface SessionSendParams {\n to: Address;\n chainId: number;\n data?: `0x${string}`;\n value?: string;\n}\n\ntype SessionRequest =\n | { id: string; token: string; type: \"status\" }\n | { id: string; token: string; type: \"lock\" }\n | { id: string; token: string; type: \"send\"; params: SessionSendParams };\n\ntype SessionRequestWithoutToken =\n | { id: string; type: \"status\" }\n | { id: string; type: \"lock\" }\n | { id: string; type: \"send\"; params: SessionSendParams };\n\ntype SessionResponse =\n | {\n id: string;\n ok: true;\n result: SessionStatusResult | ExecutionResult | { locked: true };\n }\n | { id: string; ok: false; error: string };\n\nconst SESSION_CONTROL_TIMEOUT_MS = 750;\n// Intentionally much longer than control operations: on-chain submission does\n// real RPC work, and PR #12 fixed a live timeout-after-broadcast bug here.\nconst SESSION_SEND_TIMEOUT_MS = 60_000;\nconst MAX_MESSAGE_BYTES = 32 * 1024;\nconst SECURE_DIR_MODE = 0o700;\nconst SECURE_FILE_MODE = 0o600;\nconst SERVER_SOCKET_TIMEOUT_MS = 5000;\nconst SESSION_SHUTDOWN_TIMEOUT_MS = 15000;\n\nfunction isWindowsPipe(path: string): boolean {\n return path.startsWith(\"\\\\\\\\.\\\\pipe\\\\\");\n}\n\nfunction removeFileIfPresent(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { force: true });\n }\n}\n\nfunction ensureSecureParent(path: string): void {\n if (isWindowsPipe(path)) {\n return;\n }\n\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: SECURE_DIR_MODE });\n return;\n }\n\n const mode = statSync(dir).mode & 0o777;\n if ((mode & 0o077) !== 0) {\n throw new Error(\n `MoneyOS directory ${dir} has insecure permissions (${mode.toString(8)}). Restrict it to 700 before continuing.`,\n );\n }\n}\n\nfunction createRequestId(): string {\n return `${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;\n}\n\nfunction loadSessionToken(tokenPath: string): string {\n try {\n return readFileSync(tokenPath, \"utf8\").trim();\n } catch {\n throw new Error(\"No active local MoneyOS session found.\");\n }\n}\n\nfunction writeSecureToken(tokenPath: string, token: string): void {\n ensureSecureParent(tokenPath);\n writeFileSync(tokenPath, `${token}\\n`, { mode: SECURE_FILE_MODE });\n chmodSync(tokenPath, SECURE_FILE_MODE);\n}\n\nfunction sessionFilesGone(socketPath: string, tokenPath: string): boolean {\n const tokenMissing = !existsSync(tokenPath);\n const socketMissing = isWindowsPipe(socketPath) ? true : !existsSync(socketPath);\n return tokenMissing && socketMissing;\n}\n\nasync function waitForSessionShutdown(\n socketPath: string,\n tokenPath: string,\n timeoutMs: number = SESSION_SHUTDOWN_TIMEOUT_MS,\n): Promise<void> {\n const startedAt = Date.now();\n while (!sessionFilesGone(socketPath, tokenPath)) {\n if (Date.now() - startedAt > timeoutMs) {\n throw new Error(\n \"Timed out waiting for the previous MoneyOS session to shut down cleanly.\",\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n}\n\nfunction tokensMatch(expectedToken: string, receivedToken: string): boolean {\n const expected = Buffer.from(expectedToken, \"utf8\");\n const received = Buffer.from(receivedToken, \"utf8\");\n return (\n expected.length === received.length &&\n timingSafeEqual(expected, received)\n );\n}\n\nfunction readLine(socket: net.Socket): Promise<string> {\n return new Promise((resolve, reject) => {\n let buffer = \"\";\n\n const onData = (chunk: Buffer) => {\n buffer += chunk.toString(\"utf8\");\n if (buffer.length > MAX_MESSAGE_BYTES) {\n cleanup();\n reject(new Error(\"Session response exceeded the maximum allowed size.\"));\n return;\n }\n const index = buffer.indexOf(\"\\n\");\n if (index >= 0) {\n cleanup();\n resolve(buffer.slice(0, index));\n }\n };\n\n const onError = (error: Error) => {\n cleanup();\n reject(error);\n };\n\n const onClose = () => {\n cleanup();\n reject(new Error(\"Session daemon closed the connection unexpectedly.\"));\n };\n\n const cleanup = () => {\n socket.off(\"data\", onData);\n socket.off(\"error\", onError);\n socket.off(\"close\", onClose);\n };\n\n socket.on(\"data\", onData);\n socket.once(\"error\", onError);\n socket.once(\"close\", onClose);\n });\n}\n\nasync function sendSessionRequest(\n socketPath: string,\n tokenPath: string,\n request: SessionRequestWithoutToken,\n timeoutMs: number = SESSION_CONTROL_TIMEOUT_MS,\n): Promise<SessionResponse> {\n const fullRequest = {\n ...request,\n token: loadSessionToken(tokenPath),\n } as SessionRequest;\n const socket = net.createConnection(socketPath);\n\n return new Promise<SessionResponse>((resolve, reject) => {\n let settled = false;\n const timer = setTimeout(() => {\n settled = true;\n socket.destroy();\n reject(new Error(\"Timed out waiting for local MoneyOS session.\"));\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(timer);\n socket.removeAllListeners();\n };\n\n socket.once(\"connect\", async () => {\n try {\n socket.write(`${JSON.stringify(fullRequest)}${EOL}`);\n const line = await readLine(socket);\n settled = true;\n cleanup();\n socket.end();\n resolve(JSON.parse(line) as SessionResponse);\n } catch (error) {\n settled = true;\n cleanup();\n socket.destroy();\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n\n socket.once(\"error\", (error) => {\n if (settled) {\n return;\n }\n settled = true;\n cleanup();\n reject(error);\n });\n });\n}\n\nexport async function getSessionStatus(\n socketPath: string,\n tokenPath: string,\n): Promise<SessionStatusResult | undefined> {\n try {\n const response = await sendSessionRequest(\n socketPath,\n tokenPath,\n {\n id: createRequestId(),\n type: \"status\",\n },\n SESSION_CONTROL_TIMEOUT_MS,\n );\n return response.ok ? (response.result as SessionStatusResult) : undefined;\n } catch {\n removeFileIfPresent(socketPath);\n removeFileIfPresent(tokenPath);\n return undefined;\n }\n}\n\nexport async function lockSession(\n socketPath: string,\n tokenPath: string,\n): Promise<boolean> {\n try {\n const response = await sendSessionRequest(\n socketPath,\n tokenPath,\n {\n id: createRequestId(),\n type: \"lock\",\n },\n SESSION_CONTROL_TIMEOUT_MS,\n );\n return response.ok;\n } catch {\n removeFileIfPresent(socketPath);\n removeFileIfPresent(tokenPath);\n return false;\n }\n}\n\nexport class SessionExecutionClient implements ExecutionClient {\n readonly mode = \"eoa\" as const;\n private readonly socketPath: string;\n private readonly tokenPath: string;\n private readonly address: Address;\n\n constructor(params: {\n socketPath: string;\n tokenPath: string;\n address: Address;\n }) {\n this.socketPath = params.socketPath;\n this.tokenPath = params.tokenPath;\n this.address = params.address;\n }\n\n getAddress(): Address {\n return this.address;\n }\n\n async send(call: CallRequest): Promise<ExecutionResult> {\n const response = await sendSessionRequest(\n this.socketPath,\n this.tokenPath,\n {\n id: createRequestId(),\n type: \"send\",\n params: {\n to: call.to,\n chainId: call.chainId,\n data: call.data,\n value: call.value?.toString(),\n },\n },\n SESSION_SEND_TIMEOUT_MS,\n );\n\n if (!response.ok) {\n throw new Error(response.error);\n }\n\n return response.result as ExecutionResult;\n }\n\n capabilities() {\n return {\n sponsoredGas: false,\n batching: false,\n simulation: false,\n };\n }\n}\n\nexport async function startSessionServer(\n start: SessionServerStartMessage,\n hooks: {\n executor?: ExecutionClient;\n onError?: (error: Error) => void;\n onExit?: () => void;\n } = {},\n): Promise<SessionServerHandle> {\n ensureSecureParent(start.tokenPath);\n ensureSecureParent(start.socketPath);\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n\n const signer = privateKeyToManagedAccount(start.privateKey);\n const executor = hooks.executor ?? new EOAExecutor(signer, {\n defaultChainId: start.chainId,\n rpcUrl: start.rpcUrl,\n });\n const expiresAt = new Date(Date.now() + start.ttlMs);\n const token = randomBytes(32).toString(\"hex\");\n writeSecureToken(start.tokenPath, token);\n\n let closed = false;\n\n const close = async () => {\n if (closed) return;\n closed = true;\n await new Promise<void>((resolve) => {\n server.close(() => {\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n hooks.onExit?.();\n resolve();\n });\n });\n };\n\n const server = net.createServer((socket) => {\n let buffer = \"\";\n socket.setTimeout(SERVER_SOCKET_TIMEOUT_MS, () => {\n socket.destroy();\n });\n\n socket.on(\"data\", async (chunk) => {\n buffer += chunk.toString(\"utf8\");\n if (buffer.length > MAX_MESSAGE_BYTES) {\n socket.write(\n `${JSON.stringify({\n id: \"unknown\",\n ok: false,\n error: \"Session request exceeded the maximum allowed size.\",\n })}${EOL}`,\n );\n socket.end();\n return;\n }\n\n const index = buffer.indexOf(\"\\n\");\n if (index < 0) {\n return;\n }\n\n const raw = buffer.slice(0, index);\n buffer = buffer.slice(index + 1);\n let request: SessionRequest;\n try {\n request = JSON.parse(raw) as SessionRequest;\n } catch {\n socket.write(\n `${JSON.stringify({\n id: \"unknown\",\n ok: false,\n error: \"Invalid session request.\",\n })}${EOL}`,\n );\n socket.end();\n return;\n }\n\n const respond = (response: SessionResponse) => {\n socket.write(`${JSON.stringify(response)}${EOL}`);\n socket.end();\n };\n\n try {\n if (!tokensMatch(token, String(request.token ?? \"\"))) {\n respond({\n id: request.id,\n ok: false,\n error: \"Session authentication failed.\",\n });\n return;\n }\n\n if (request.type === \"status\") {\n respond({\n id: request.id,\n ok: true,\n result: {\n address: executor.getAddress(),\n expiresAt: expiresAt.toISOString(),\n },\n });\n return;\n }\n\n if (request.type === \"lock\") {\n respond({\n id: request.id,\n ok: true,\n result: { locked: true },\n });\n setImmediate(() => {\n void close();\n });\n return;\n }\n\n socket.setTimeout(SESSION_SEND_TIMEOUT_MS, () => {\n socket.destroy();\n });\n const result = await executor.send({\n to: request.params.to,\n chainId: request.params.chainId,\n data: request.params.data,\n value:\n request.params.value !== undefined\n ? BigInt(request.params.value)\n : undefined,\n });\n\n respond({\n id: request.id,\n ok: true,\n result,\n });\n } catch (error) {\n respond({\n id: request.id,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", (error) => {\n hooks.onError?.(error instanceof Error ? error : new Error(String(error)));\n reject(error);\n });\n server.listen(start.socketPath, () => {\n if (!isWindowsPipe(start.socketPath)) {\n chmodSync(start.socketPath, SECURE_FILE_MODE);\n }\n resolve();\n });\n });\n\n const timer = setTimeout(() => {\n void close();\n }, start.ttlMs);\n timer.unref();\n\n return {\n address: executor.getAddress(),\n expiresAt: expiresAt.toISOString(),\n close,\n };\n}\n\nexport async function startDetachedSessionDaemon(\n params: SessionServerStartMessage,\n): Promise<SessionStatusResult> {\n const existing = await getSessionStatus(params.socketPath, params.tokenPath);\n if (existing) {\n const locked = await lockSession(params.socketPath, params.tokenPath);\n if (!locked && !sessionFilesGone(params.socketPath, params.tokenPath)) {\n throw new Error(\n \"Failed to replace the existing MoneyOS session. Run `moneyos auth lock` and try again.\",\n );\n }\n if (locked) {\n await waitForSessionShutdown(params.socketPath, params.tokenPath);\n }\n } else {\n removeFileIfPresent(params.socketPath);\n removeFileIfPresent(params.tokenPath);\n }\n\n return new Promise<SessionStatusResult>((resolve, reject) => {\n const child = spawn(\n process.execPath,\n [...process.execArgv, process.argv[1], \"__session-daemon\"],\n {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n },\n );\n\n let settled = false;\n\n const finish = (error?: Error, status?: SessionStatusResult) => {\n if (settled) return;\n settled = true;\n child.removeAllListeners();\n if (error) {\n reject(error);\n return;\n }\n resolve(status as SessionStatusResult);\n };\n\n child.once(\"error\", (error) => finish(error));\n child.once(\"exit\", (code) => {\n if (!settled) {\n finish(\n new Error(\n `Session daemon exited unexpectedly with code ${code ?? \"unknown\"}.`,\n ),\n );\n }\n });\n child.on(\"message\", (message: unknown) => {\n const payload = message as\n | { type: \"ready\"; address: Address; expiresAt: string }\n | { type: \"error\"; error: string };\n if (payload?.type === \"ready\") {\n child.disconnect();\n child.unref();\n finish(undefined, {\n address: payload.address,\n expiresAt: payload.expiresAt,\n });\n } else if (payload?.type === \"error\") {\n finish(new Error(payload.error));\n }\n });\n\n child.send(params);\n });\n}\n\nexport async function runSessionDaemonProcess(): Promise<void> {\n if (!process.send) {\n throw new Error(\"Session daemon must be started through MoneyOS.\");\n }\n\n const start = await new Promise<SessionServerStartMessage>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Session daemon did not receive startup parameters.\"));\n }, 1000);\n\n process.once(\"message\", (message: unknown) => {\n clearTimeout(timeout);\n const payload = message as SessionServerStartMessage;\n if (payload?.type !== \"start\") {\n reject(new Error(\"Session daemon received invalid startup message.\"));\n return;\n }\n resolve(payload);\n });\n });\n\n const shutdown = (code: number = 0) => {\n removeFileIfPresent(start.socketPath);\n removeFileIfPresent(start.tokenPath);\n process.exit(code);\n };\n\n const handle = await startSessionServer(start, {\n onError: (error) => {\n process.send?.({\n type: \"error\",\n error: error.message,\n });\n shutdown(1);\n },\n onExit: () => shutdown(),\n });\n\n process.send?.({\n type: \"ready\",\n address: handle.address,\n expiresAt: handle.expiresAt,\n });\n process.on(\"SIGTERM\", () => {\n void handle.close().then(() => shutdown());\n });\n process.on(\"SIGINT\", () => {\n void handle.close().then(() => shutdown());\n });\n}\n","import {\n createPublicClient,\n createWalletClient,\n http,\n type Account,\n type Address,\n type Hex,\n type PublicClient,\n type WalletClient,\n type Chain as ViemChain,\n} from \"viem\";\nimport { arbitrum, mainnet, polygon } from \"viem/chains\";\nimport { getChain } from \"@moneyos/core\";\nimport type {\n CallRequest,\n ExecutionClient,\n ExecutionResult,\n ReadClient,\n RuntimeConfig,\n} from \"@moneyos/core\";\nimport { privateKeyToManagedAccount } from \"./signer.js\";\n\nconst viemChainMap: Record<number, ViemChain> = {\n 42161: arbitrum,\n 1: mainnet,\n 137: polygon,\n};\n\nfunction getViemChain(chainId: number): ViemChain | undefined {\n return viemChainMap[chainId];\n}\n\n// --- Read ---\n\nexport class ViemReadClient implements ReadClient {\n private clients: Map<number, PublicClient> = new Map();\n private config: RuntimeConfig;\n\n constructor(config: RuntimeConfig) {\n this.config = config;\n }\n\n private getClient(chainId: number): PublicClient {\n let client = this.clients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createPublicClient({\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.clients.set(chainId, client);\n }\n return client;\n }\n\n async getBalance(params: {\n address: Address;\n chainId: number;\n }): Promise<bigint> {\n const client = this.getClient(params.chainId);\n return client.getBalance({ address: params.address });\n }\n\n async readContract<T = unknown>(params: {\n address: Address;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n chainId: number;\n }): Promise<T> {\n const client = this.getClient(params.chainId);\n return client.readContract({\n address: params.address,\n abi: params.abi,\n functionName: params.functionName,\n args: params.args,\n }) as Promise<T>;\n }\n}\n\n// --- Execute ---\n\nexport class EOAExecutor implements ExecutionClient {\n readonly mode = \"eoa\" as const;\n private signer: Account;\n private walletClients: Map<number, WalletClient> = new Map();\n private publicClients: Map<number, PublicClient> = new Map();\n private config: RuntimeConfig;\n\n constructor(signer: Account, config: RuntimeConfig) {\n this.signer = signer;\n this.config = config;\n }\n\n /**\n * Convenience factory: build an EOAExecutor from a raw private key.\n * Equivalent to `new EOAExecutor(privateKeyToAccount(privateKey), config)`.\n * Kept as a helper so the common \"I have a hex key\" path stays one line\n * while the constructor itself takes a viem `Account` to accommodate\n * future keystore-backed signers (hardware, KMS, MPC).\n *\n * Attach viem's nonce manager so back-to-back live transactions use a\n * pending-aware nonce source instead of relying on RPC fill behavior.\n */\n static fromPrivateKey(privateKey: Hex, config: RuntimeConfig): EOAExecutor {\n return new EOAExecutor(privateKeyToManagedAccount(privateKey), config);\n }\n\n private getWalletClient(chainId: number): WalletClient {\n let client = this.walletClients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createWalletClient({\n account: this.signer,\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.walletClients.set(chainId, client);\n }\n return client;\n }\n\n private getPublicClient(chainId: number): PublicClient {\n let client = this.publicClients.get(chainId);\n if (!client) {\n const chain = getViemChain(chainId);\n const chainInfo = getChain(chainId);\n const rpcUrl =\n chainId === this.config.defaultChainId\n ? this.config.rpcUrl\n : undefined;\n\n client = createPublicClient({\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.publicClients.set(chainId, client);\n }\n return client;\n }\n\n getAddress(): Address {\n return this.signer.address;\n }\n\n async send(call: CallRequest): Promise<ExecutionResult> {\n const walletClient = this.getWalletClient(call.chainId);\n const hash = await walletClient.sendTransaction({\n account: walletClient.account!,\n to: call.to,\n data: call.data,\n value: call.value ?? 0n,\n chain: walletClient.chain,\n });\n\n // Wait for inclusion before resolving. Returning on broadcast makes\n // sequenced operations like \"approve then swap\" unsafe: the next\n // call's preflight (eth_estimateGas / eth_call) runs against the\n // latest mined block, so a still-pending approve is invisible and\n // the swap reverts at simulation time. The same broadcast-only\n // resolution also lets viem's nonce manager drift past the chain\n // when a sequenced call fails preflight, leaving the executor stuck\n // submitting nonces the chain has not yet reached.\n //\n // For an interactive CLI, slower is acceptable; ambiguous transaction\n // state is not.\n const publicClient = this.getPublicClient(call.chainId);\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status !== \"success\") {\n throw new Error(\n `Transaction ${hash} reverted on chain ${call.chainId} (block ${receipt.blockNumber}).`,\n );\n }\n\n return { hash, chainId: call.chainId };\n }\n\n capabilities() {\n return {\n sponsoredGas: false,\n batching: false,\n simulation: false,\n };\n }\n}\n","import type { Address } from \"viem\";\n\nexport interface Token {\n symbol: string;\n name: string;\n decimals: number;\n addresses: Record<number, Address>;\n}\n\nexport const NATIVE_TOKEN_ADDRESS =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\" as Address;\n\nexport const tokens: Record<string, Token> = {\n ETH: {\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n addresses: {\n 42161: NATIVE_TOKEN_ADDRESS,\n 1: NATIVE_TOKEN_ADDRESS,\n },\n },\n POL: {\n symbol: \"POL\",\n name: \"POL\",\n decimals: 18,\n addresses: {\n 137: NATIVE_TOKEN_ADDRESS,\n },\n },\n USDC: {\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n addresses: {\n 42161: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n 1: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n 137: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n },\n },\n USDT: {\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n addresses: {\n 42161: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n 1: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n 137: \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n },\n },\n RYZE: {\n symbol: \"RYZE\",\n name: \"RYZE\",\n decimals: 18,\n addresses: {\n 42161: \"0x7712da72127d5dD213B621497D6E4899d5989e5C\",\n },\n },\n};\n\nexport function getToken(symbol: string): Token | undefined {\n return tokens[symbol.toUpperCase()];\n}\n\nexport function getTokenAddress(\n symbol: string,\n chainId: number,\n): Address | undefined {\n return getToken(symbol)?.addresses[chainId];\n}\n","import type { Chain } from \"./types.js\";\n\nexport const chains: Record<string, Chain> = {\n arbitrum: {\n id: 42161,\n name: \"Arbitrum One\",\n rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://arbiscan.io\",\n },\n ethereum: {\n id: 1,\n name: \"Ethereum\",\n rpcUrl: \"https://eth.public-rpc.com\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://etherscan.io\",\n },\n polygon: {\n id: 137,\n name: \"Polygon\",\n rpcUrl: \"https://polygon-rpc.com\",\n nativeCurrency: { name: \"POL\", symbol: \"POL\", decimals: 18 },\n blockExplorer: \"https://polygonscan.com\",\n },\n};\n\nexport const defaultChain = chains.arbitrum;\n\nexport function getChain(idOrName: number | string): Chain | undefined {\n if (typeof idOrName === \"number\") {\n return Object.values(chains).find((c) => c.id === idOrName);\n }\n return chains[idOrName.toLowerCase()];\n}\n","import type { Account, Hex } from \"viem\";\nimport { nonceManager } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\n/**\n * Build a local viem Account with nonce management enabled so back-to-back\n * live transactions use a pending-aware nonce source.\n */\nexport function privateKeyToManagedAccount(privateKey: Hex): Account {\n return privateKeyToAccount(privateKey, { nonceManager });\n}\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\nimport { buildCliMoneyOSConfig, loadCliAddress } from \"../wallet.js\";\n\nexport const balanceCommand = new Command(\"balance\")\n .description(\"Check token balance\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .option(\"-a, --address <address>\", \"Address to check (defaults to your own)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (token: string, options) => {\n const config = loadConfig();\n const chainId = options.chain ? parseInt(options.chain) : config.chainId;\n let address = options.address as Address | undefined;\n\n let moneyos: MoneyOS;\n try {\n if (!address) {\n const resolved = await loadCliAddress(config);\n address = resolved.address;\n }\n\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId: chainId ?? 42161,\n requireSigner: false,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const result = await moneyos.balance(token, {\n address,\n chainId,\n });\n\n console.log(`${result.amount} ${result.symbol}`);\n });\n","import {\n formatUnits,\n parseUnits,\n encodeFunctionData,\n type Address,\n} from \"viem\";\nimport type {\n MoneyOSConfig,\n Balance,\n SendResult,\n SwapProvider,\n SwapResult,\n ReadClient,\n ExecutionClient,\n AssetRegistry,\n MoneyOSRuntime,\n RuntimeConfig,\n} from \"@moneyos/core\";\nimport {\n getChain,\n defaultChain,\n getToken,\n getTokenAddress,\n NATIVE_TOKEN_ADDRESS,\n} from \"@moneyos/core\";\nimport { ViemReadClient, EOAExecutor } from \"./eoa.js\";\nimport { executeSwap } from \"../tools/swap.js\";\n\nconst ERC20_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"decimals\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n name: \"symbol\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n] as const;\n\nclass DefaultAssetRegistry implements AssetRegistry {\n readonly nativeTokenAddress = NATIVE_TOKEN_ADDRESS;\n getToken = getToken;\n getTokenAddress = getTokenAddress;\n getChain = getChain;\n}\n\nexport class MoneyOS {\n private read: ReadClient;\n private executor: ExecutionClient | undefined;\n private assets: AssetRegistry;\n private runtimeConfig: RuntimeConfig;\n\n constructor(config: MoneyOSConfig) {\n // Mutual exclusion: at most one of `execute`, `privateKey`, `signer`.\n // These represent three different ways to produce a signing identity;\n // combining them would be ambiguous.\n const provided: string[] = [];\n if (config.execute) provided.push(\"execute\");\n if (config.privateKey) provided.push(\"privateKey\");\n if (config.signer) provided.push(\"signer\");\n if (provided.length > 1) {\n throw new Error(\n `MoneyOSConfig: pass at most one of \\`execute\\`, \\`privateKey\\`, or \\`signer\\`. Received: ${provided.join(\", \")}.`,\n );\n }\n\n this.runtimeConfig = {\n defaultChainId: config.chainId ?? defaultChain.id,\n rpcUrl: config.rpcUrl,\n };\n\n this.read = config.read ?? new ViemReadClient(this.runtimeConfig);\n this.assets = config.assets ?? new DefaultAssetRegistry();\n\n if (config.execute) {\n this.executor = config.execute;\n } else if (config.signer) {\n this.executor = new EOAExecutor(config.signer, this.runtimeConfig);\n } else if (config.privateKey) {\n this.executor = EOAExecutor.fromPrivateKey(\n config.privateKey,\n this.runtimeConfig,\n );\n }\n }\n\n get runtime(): MoneyOSRuntime {\n return {\n read: this.read,\n execute: this.requireExecutor(),\n assets: this.assets,\n config: this.runtimeConfig,\n };\n }\n\n get address(): Address {\n return this.requireExecutor().getAddress();\n }\n\n private requireExecutor(): ExecutionClient {\n if (!this.executor) {\n throw new Error(\n \"No signing account configured. Set `signer`, `privateKey`, or `execute` in MoneyOS config.\",\n );\n }\n return this.executor;\n }\n\n async balance(\n token: string,\n options?: { address?: Address; chainId?: number },\n ): Promise<Balance> {\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n const account = options?.address ?? this.address;\n\n const tokenAddress = this.assets.getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = this.assets.getToken(token)!;\n\n if (tokenAddress === NATIVE_TOKEN_ADDRESS) {\n const raw = await this.read.getBalance({ address: account, chainId });\n return {\n token: tokenInfo.name,\n symbol: tokenInfo.symbol,\n amount: formatUnits(raw, tokenInfo.decimals),\n rawAmount: raw,\n decimals: tokenInfo.decimals,\n chainId,\n };\n }\n\n const raw = await this.read.readContract<bigint>({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account],\n chainId,\n });\n\n return {\n token: tokenInfo.name,\n symbol: tokenInfo.symbol,\n amount: formatUnits(raw, tokenInfo.decimals),\n rawAmount: raw,\n decimals: tokenInfo.decimals,\n chainId,\n };\n }\n\n async send(\n token: string,\n to: Address,\n amount: string,\n options?: { chainId?: number },\n ): Promise<SendResult> {\n const execute = this.requireExecutor();\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n const from = execute.getAddress();\n\n const tokenAddress = this.assets.getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = this.assets.getToken(token)!;\n const value = parseUnits(amount, tokenInfo.decimals);\n\n if (tokenAddress === NATIVE_TOKEN_ADDRESS) {\n const result = await execute.send({ to, value, chainId });\n return {\n hash: result.hash,\n from,\n to,\n amount,\n token: tokenInfo.symbol,\n chainId,\n };\n }\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to, value],\n });\n\n const result = await execute.send({ to: tokenAddress, data, chainId });\n return {\n hash: result.hash,\n from,\n to,\n amount,\n token: tokenInfo.symbol,\n chainId,\n };\n }\n\n async swap(\n tokenIn: string,\n tokenOut: string,\n amount: string,\n provider: SwapProvider,\n options?: { chainId?: number; slippage?: number },\n ): Promise<SwapResult> {\n const execute = this.requireExecutor();\n const chainId = options?.chainId ?? this.runtimeConfig.defaultChainId;\n\n return executeSwap(\n { tokenIn, tokenOut, amount, provider, chainId, slippage: options?.slippage },\n { read: this.read, execute, assets: this.assets },\n );\n }\n}\n","import {\n formatUnits,\n parseUnits,\n encodeFunctionData,\n} from \"viem\";\nimport type { ReadClient, ExecutionClient, AssetRegistry, SwapProvider, SwapResult } from \"@moneyos/core\";\n\nconst ERC20_ABI = [\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n] as const;\n\nexport interface SwapInput {\n tokenIn: string;\n tokenOut: string;\n amount: string;\n provider: SwapProvider;\n chainId: number;\n slippage?: number;\n}\n\nexport async function executeSwap(\n input: SwapInput,\n ctx: { read: ReadClient; execute: ExecutionClient; assets: AssetRegistry },\n): Promise<SwapResult> {\n const { tokenIn, tokenOut, amount, provider, chainId, slippage } = input;\n const { read, execute, assets } = ctx;\n const sender = execute.getAddress();\n\n const tokenInAddress = assets.getTokenAddress(tokenIn, chainId);\n const tokenOutAddress = assets.getTokenAddress(tokenOut, chainId);\n if (!tokenInAddress) {\n throw new Error(`Token ${tokenIn} not found on chain ${chainId}`);\n }\n if (!tokenOutAddress) {\n throw new Error(`Token ${tokenOut} not found on chain ${chainId}`);\n }\n\n const tokenInInfo = assets.getToken(tokenIn)!;\n const amountWei = parseUnits(amount, tokenInInfo.decimals);\n\n const quote = await provider.getQuote({\n chainId,\n tokenIn: tokenInAddress,\n tokenOut: tokenOutAddress,\n amount: amountWei,\n sender,\n slippage,\n });\n\n const calldata = await provider.getCalldata(quote);\n\n const isNativeIn = tokenInAddress === assets.nativeTokenAddress;\n\n if (!isNativeIn) {\n const currentAllowance = await read.readContract<bigint>({\n address: tokenInAddress,\n abi: ERC20_ABI,\n functionName: \"allowance\",\n args: [sender, calldata.to],\n chainId,\n });\n\n if (currentAllowance < amountWei) {\n const approveData = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"approve\",\n args: [calldata.to, amountWei],\n });\n await execute.send({ to: tokenInAddress, data: approveData, chainId });\n }\n }\n\n const result = await execute.send({\n to: calldata.to,\n data: calldata.data,\n value: isNativeIn ? amountWei : calldata.value,\n chainId,\n });\n\n const tokenOutInfo = assets.getToken(tokenOut)!;\n return {\n hash: result.hash,\n tokenIn: tokenInInfo.symbol,\n tokenOut: tokenOutInfo.symbol,\n amountIn: amount,\n amountOut: formatUnits(BigInt(quote.expectedOut), tokenOutInfo.decimals),\n chainId,\n };\n}\n","import type { MoneyOSConfig } from \"@moneyos/core\";\nimport type { Address, Hex } from \"viem\";\nimport { FileEncryptedWalletStore } from \"../core/encrypted-wallet.js\";\nimport { privateKeyToManagedAccount } from \"../core/signer.js\";\nimport {\n getLegacyPlaintextWalletStorageMessage,\n getRemovedOnePasswordStorageMessage,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n hasLegacyPlaintextWalletConfig,\n hasRemovedOnePasswordConfig,\n type CLIConfig,\n} from \"./config.js\";\nimport { getSessionStatus, SessionExecutionClient } from \"./session.js\";\n\nexport type CliWalletBackendKind = \"env\" | \"wallet-file\" | \"session\";\n\nexport interface ResolvedCliAddress {\n kind: \"env\" | \"wallet-file\";\n address: Address;\n source: \"env\" | \"encrypted-wallet\";\n}\n\nexport interface ResolveCliWalletOptions {\n walletPath?: string;\n sessionSocketPath?: string;\n sessionTokenPath?: string;\n envPrivateKey?: Hex;\n}\n\nexport interface BuildCliMoneyOSConfigOptions extends ResolveCliWalletOptions {\n chainId?: number;\n requireSigner?: boolean;\n}\n\nfunction resolveEnvPrivateKey(explicit?: Hex): Hex | undefined {\n return explicit ?? (process.env.MONEYOS_PRIVATE_KEY as Hex | undefined);\n}\n\nfunction getWalletStore(\n config: CLIConfig,\n options: ResolveCliWalletOptions = {},\n): FileEncryptedWalletStore {\n return new FileEncryptedWalletStore(options.walletPath ?? getWalletPath(config));\n}\n\nfunction getSessionPath(options: ResolveCliWalletOptions = {}): string {\n return options.sessionSocketPath ?? getSessionSocketPath();\n}\n\nfunction getTokenPath(options: ResolveCliWalletOptions = {}): string {\n return options.sessionTokenPath ?? getSessionTokenPath();\n}\n\n/**\n * Resolve the address the CLI should use for read-only \"my wallet\" commands.\n *\n * This prefers cheap wallet metadata over any signing path so read-only\n * balance checks do not require an unlocked session.\n */\nexport async function loadCliAddress(\n config: CLIConfig,\n options: ResolveCliWalletOptions = {},\n): Promise<ResolvedCliAddress> {\n const envPrivateKey = resolveEnvPrivateKey(options.envPrivateKey);\n if (envPrivateKey) {\n const signer = privateKeyToManagedAccount(envPrivateKey);\n return {\n kind: \"env\",\n address: signer.address,\n source: \"env\",\n };\n }\n\n if (hasRemovedOnePasswordConfig(config)) {\n throw new Error(getRemovedOnePasswordStorageMessage());\n }\n\n const wallet = getWalletStore(config, options);\n const metadata = await wallet.metadata();\n if (metadata?.address) {\n return {\n kind: \"wallet-file\",\n address: metadata.address,\n source: \"encrypted-wallet\",\n };\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n throw new Error(getLegacyPlaintextWalletStorageMessage());\n }\n\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n}\n\nexport async function buildCliMoneyOSConfig(\n config: CLIConfig,\n options: BuildCliMoneyOSConfigOptions = {},\n): Promise<MoneyOSConfig> {\n const moneyosConfig: MoneyOSConfig = {\n chainId: options.chainId ?? config.chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n };\n\n if (!options.requireSigner) {\n return moneyosConfig;\n }\n\n const envPrivateKey = resolveEnvPrivateKey(options.envPrivateKey);\n if (envPrivateKey) {\n return {\n ...moneyosConfig,\n signer: privateKeyToManagedAccount(envPrivateKey),\n };\n }\n\n if (hasRemovedOnePasswordConfig(config)) {\n throw new Error(getRemovedOnePasswordStorageMessage());\n }\n\n const socketPath = getSessionPath(options);\n const tokenPath = getTokenPath(options);\n const session = await getSessionStatus(socketPath, tokenPath);\n if (session) {\n return {\n ...moneyosConfig,\n execute: new SessionExecutionClient({\n socketPath,\n tokenPath,\n address: session.address,\n }),\n };\n }\n\n const wallet = getWalletStore(config, options);\n if (wallet.exists()) {\n throw new Error(\n \"Wallet is locked. Run `moneyos auth unlock` locally before using write commands.\",\n );\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n throw new Error(getLegacyPlaintextWalletStorageMessage());\n }\n\n throw new Error(\"No wallet configured. Run `moneyos init`.\");\n}\n","import { Command } from \"commander\";\nimport { getChain } from \"@moneyos/core\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\nimport { buildCliMoneyOSConfig } from \"../wallet.js\";\n\nexport const sendCommand = new Command(\"send\")\n .description(\"Send tokens to an address\")\n .argument(\"<amount>\", \"Amount to send (e.g. 10)\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .argument(\"<to>\", \"Recipient address\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (amount: string, token: string, to: string, options) => {\n const config = loadConfig();\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n let moneyos: MoneyOS;\n try {\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId,\n requireSigner: true,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const chain = getChain(chainId);\n console.log(\n `Sending ${amount} ${token.toUpperCase()} to ${to} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.send(token, to as Address, amount, {\n chainId,\n });\n\n console.log(`Sent. tx: ${result.hash}`);\n });\n","import { Command } from \"commander\";\nimport { getChain } from \"@moneyos/core\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { OdosProvider } from \"../../providers/odos.js\";\nimport { loadConfig } from \"../config.js\";\nimport { buildCliMoneyOSConfig } from \"../wallet.js\";\n\nexport const swapCommand = new Command(\"swap\")\n .description(\"Swap tokens\")\n .argument(\"<amount>\", \"Amount to swap (e.g. 100)\")\n .argument(\"<tokenIn>\", \"Token to sell (e.g. USDC)\")\n .argument(\"<tokenOut>\", \"Token to buy (e.g. RYZE)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .option(\"-s, --slippage <percent>\", \"Slippage tolerance in percent (default: 1)\")\n .action(async (amount: string, tokenIn: string, tokenOut: string, options) => {\n const config = loadConfig();\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n let moneyos: MoneyOS;\n try {\n moneyos = new MoneyOS(\n await buildCliMoneyOSConfig(config, {\n chainId,\n requireSigner: true,\n }),\n );\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : String(error),\n );\n process.exitCode = 1;\n return;\n }\n\n const provider = new OdosProvider();\n const chain = getChain(chainId);\n const slippage = options.slippage ? parseFloat(options.slippage) : undefined;\n\n console.log(\n `Swapping ${amount} ${tokenIn.toUpperCase()} \\u2192 ${tokenOut.toUpperCase()} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.swap(tokenIn, tokenOut, amount, provider, {\n chainId,\n slippage,\n });\n\n console.log(`Swapped. Expected: ~${result.amountOut} ${result.tokenOut}`);\n console.log(`tx: ${result.hash}`);\n });\n","import type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"@moneyos/core\";\nimport { NATIVE_TOKEN_ADDRESS } from \"@moneyos/core\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\nconst ODOS_NATIVE_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n\ninterface OdosQuoteResponse {\n pathId: string;\n outAmounts: string[];\n outValues: number[];\n}\n\ninterface OdosAssembleResponse {\n transaction: {\n to: string;\n data: string;\n value: string;\n };\n}\n\nexport class OdosProvider implements SwapProvider {\n name = \"odos\";\n private apiKey?: string;\n\n constructor(options?: { apiKey?: string }) {\n this.apiKey = options?.apiKey;\n }\n\n private toOdosAddress(address: Address): Address {\n return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;\n }\n\n async getQuote(params: {\n chainId: number;\n tokenIn: Address;\n tokenOut: Address;\n amount: bigint;\n sender: Address;\n slippage?: number;\n }): Promise<SwapQuote & { pathId: string; sender: Address }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/quote/v2`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n chainId: params.chainId,\n inputTokens: [\n {\n tokenAddress: this.toOdosAddress(params.tokenIn),\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: this.toOdosAddress(params.tokenOut),\n proportion: 1,\n },\n ],\n userAddr: params.sender,\n slippageLimitPercent: params.slippage ?? 1,\n referralCode: 0,\n compact: true,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos quote failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosQuoteResponse;\n\n return {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amount.toString(),\n expectedOut: data.outAmounts[0],\n router: \"\" as Address,\n chainId: params.chainId,\n pathId: data.pathId,\n sender: params.sender,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string; sender: Address },\n ): Promise<{ to: Address; data: Hex; value: bigint }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/assemble`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n userAddr: quote.sender,\n pathId: quote.pathId,\n simulate: false,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos assemble failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosAssembleResponse;\n\n return {\n to: data.transaction.to as Address,\n data: data.transaction.data as Hex,\n value: BigInt(data.transaction.value),\n };\n }\n}\n","import { Command } from \"commander\";\nimport {\n loadFileConfig,\n} from \"../config.js\";\nimport {\n formatWalletStatus,\n resolveWalletStatus,\n} from \"../wallet-status.js\";\n\nexport const keystoreCommand = new Command(\"keystore\").description(\n \"Compatibility alias for wallet status\",\n);\n\nkeystoreCommand\n .command(\"status\")\n .description(\"Show the current wallet storage status\")\n .action(async () => {\n const config = loadFileConfig();\n const status = await resolveWalletStatus(config);\n console.log(formatWalletStatus(status));\n });\n","import type { Address } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { FileEncryptedWalletStore } from \"../core/encrypted-wallet.js\";\nimport {\n getLegacyPlaintextWalletStorageMessage,\n getRemovedOnePasswordCachedAddress,\n getRemovedOnePasswordStorageMessage,\n getWalletPath,\n hasLegacyPlaintextWalletConfig,\n hasRemovedOnePasswordConfig,\n type CLIConfig,\n} from \"./config.js\";\n\nexport type WalletStatusKind =\n | \"encrypted\"\n | \"none\"\n | \"legacy\"\n | \"unsupported\"\n | \"invalid\";\n\nexport interface ResolvedWalletStatus {\n kind: WalletStatusKind;\n address?: Address;\n walletPath: string;\n reason?: string;\n}\n\nexport async function resolveWalletStatus(\n config: CLIConfig,\n walletPath: string = getWalletPath(config),\n): Promise<ResolvedWalletStatus> {\n if (hasRemovedOnePasswordConfig(config)) {\n return {\n kind: \"unsupported\",\n address: getRemovedOnePasswordCachedAddress(config),\n walletPath,\n reason: getRemovedOnePasswordStorageMessage(),\n };\n }\n\n const store = new FileEncryptedWalletStore(walletPath);\n if (store.exists()) {\n try {\n const metadata = await store.metadata();\n return {\n kind: metadata ? \"encrypted\" : \"none\",\n address: metadata?.address,\n walletPath,\n };\n } catch (error) {\n return {\n kind: \"invalid\",\n walletPath,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n if (hasLegacyPlaintextWalletConfig(config)) {\n try {\n const address = privateKeyToAccount(config.privateKey!).address;\n return {\n kind: \"legacy\",\n walletPath,\n address,\n reason: getLegacyPlaintextWalletStorageMessage(),\n };\n } catch (error) {\n return {\n kind: \"legacy\",\n walletPath,\n reason:\n error instanceof Error\n ? `${getLegacyPlaintextWalletStorageMessage()} (${error.message})`\n : getLegacyPlaintextWalletStorageMessage(),\n };\n }\n }\n\n return {\n kind: \"none\",\n walletPath,\n };\n}\n\nexport function formatWalletStatus(status: ResolvedWalletStatus): string {\n const lines: string[] = [];\n\n if (status.kind === \"none\") {\n lines.push(\"Wallet: (none)\");\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\"Status: no wallet configured — run `moneyos init`\");\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"unsupported\") {\n lines.push(\"Wallet: removed legacy model\");\n if (status.address) {\n lines.push(`Address: ${status.address} (cached metadata)`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\n `Status: removed — ${status.reason ?? \"unsupported legacy config\"}`,\n );\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"legacy\") {\n lines.push(\"Wallet: legacy plaintext config\");\n if (status.address) {\n lines.push(`Address: ${status.address}`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\n `Status: upgrade required — ${status.reason ?? 'run `moneyos init`'}`,\n );\n return lines.join(\"\\n\");\n }\n\n if (status.kind === \"invalid\") {\n lines.push(\"Wallet: encrypted local wallet\");\n lines.push(`Path: ${status.walletPath}`);\n lines.push(`Status: invalid — ${status.reason ?? \"wallet file is unreadable\"}`);\n return lines.join(\"\\n\");\n }\n\n lines.push(\"Wallet: encrypted local wallet\");\n if (status.address) {\n lines.push(`Address: ${status.address}`);\n }\n lines.push(`Path: ${status.walletPath}`);\n lines.push(\"Status: ready\");\n return lines.join(\"\\n\");\n}\n","import { Command } from \"commander\";\nimport {\n FileEncryptedWalletStore,\n type EncryptedWalletStore,\n} from \"../../core/encrypted-wallet.js\";\nimport {\n type CLIConfig,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n loadFileConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport {\n getSessionStatus,\n lockSession,\n startDetachedSessionDaemon,\n} from \"../session.js\";\n\nconst DEFAULT_TTL_MS = 15 * 60 * 1000;\n\nfunction formatSessionStatus(params: {\n state: \"locked\" | \"unlocked\";\n address?: string;\n expiresAt?: string;\n}): string {\n const lines: string[] = [];\n lines.push(`Session: ${params.state}`);\n if (params.address) {\n lines.push(`Address: ${params.address}`);\n }\n if (params.expiresAt) {\n lines.push(`Expires: ${params.expiresAt}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport interface ChangePasswordCommandDependencies {\n loadFileConfig: () => CLIConfig;\n getWalletPath: (config?: CLIConfig) => string;\n createWalletStore: (walletPath: string) => EncryptedWalletStore;\n promptHidden: (question: string) => Promise<string>;\n lockSession: (socketPath: string, tokenPath: string) => Promise<boolean>;\n getSessionSocketPath: () => string;\n getSessionTokenPath: () => string;\n log: (message: string) => void;\n error: (message: string) => void;\n}\n\nconst defaultChangePasswordCommandDependencies: ChangePasswordCommandDependencies = {\n loadFileConfig,\n getWalletPath,\n createWalletStore: (walletPath) => new FileEncryptedWalletStore(walletPath),\n promptHidden,\n lockSession,\n getSessionSocketPath,\n getSessionTokenPath,\n log: (message) => console.log(message),\n error: (message) => console.error(message),\n};\n\nexport async function runChangePasswordCommand(\n deps: ChangePasswordCommandDependencies = defaultChangePasswordCommandDependencies,\n): Promise<void> {\n const config = deps.loadFileConfig();\n const walletPath = deps.getWalletPath(config);\n const wallet = deps.createWalletStore(walletPath);\n\n if (!wallet.exists()) {\n deps.error(\"No encrypted wallet found. Run `moneyos init` first.\");\n process.exitCode = 1;\n return;\n }\n\n try {\n const currentPassphrase = await deps.promptHidden(\"Current wallet password: \");\n if (currentPassphrase.length === 0) {\n throw new Error(\"Current wallet password cannot be empty.\");\n }\n\n const newPassphrase = await deps.promptHidden(\"New wallet password: \");\n if (newPassphrase.length < 8) {\n throw new Error(\"New wallet password must be at least 8 characters long.\");\n }\n if (newPassphrase === currentPassphrase) {\n throw new Error(\n \"New wallet password must differ from the current password.\",\n );\n }\n\n const confirmPassphrase = await deps.promptHidden(\n \"Confirm new wallet password: \",\n );\n if (newPassphrase !== confirmPassphrase) {\n throw new Error(\"New wallet password confirmation did not match.\");\n }\n\n const metadata = await wallet.rotatePassphrase({\n oldPassphrase: currentPassphrase,\n newPassphrase,\n });\n await deps.lockSession(\n deps.getSessionSocketPath(),\n deps.getSessionTokenPath(),\n );\n\n deps.log(\"Wallet password changed.\");\n deps.log(`Address: ${metadata.address}`);\n deps.log(formatSessionStatus({ state: \"locked\" }));\n deps.log(\n \"Existing backup files and exported copies still require the old wallet password.\",\n );\n deps.log(\n \"Run `moneyos backup export` to create a backup encrypted with the new wallet password.\",\n );\n } catch (error) {\n deps.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n}\n\nexport const authCommand = new Command(\"auth\").description(\n \"Unlock, inspect, lock, and change the local MoneyOS wallet password\",\n);\n\nauthCommand\n .command(\"unlock\")\n .description(\"Unlock the local wallet and start a short-lived session\")\n .action(async () => {\n const config = loadFileConfig();\n const walletPath = getWalletPath(config);\n const wallet = new FileEncryptedWalletStore(walletPath);\n\n if (!wallet.exists()) {\n console.error(\"No encrypted wallet found. Run `moneyos init` first.\");\n process.exitCode = 1;\n return;\n }\n\n try {\n const passphrase = await promptHidden(\"Wallet password: \");\n if (passphrase.length === 0) {\n throw new Error(\"Wallet password cannot be empty.\");\n }\n\n const privateKey = await wallet.decrypt(passphrase);\n const status = await startDetachedSessionDaemon({\n type: \"start\",\n privateKey,\n chainId: config.chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n socketPath: getSessionSocketPath(),\n tokenPath: getSessionTokenPath(),\n ttlMs: DEFAULT_TTL_MS,\n });\n\n console.log(\"Wallet unlocked.\");\n console.log(\n formatSessionStatus({\n state: \"unlocked\",\n address: status.address,\n expiresAt: status.expiresAt,\n }),\n );\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nauthCommand\n .command(\"change-password\")\n .description(\"Change the local wallet password and lock the current session\")\n .action(async () => {\n await runChangePasswordCommand();\n });\n\nauthCommand\n .command(\"lock\")\n .description(\"Lock the local MoneyOS wallet session\")\n .action(async () => {\n const locked = await lockSession(\n getSessionSocketPath(),\n getSessionTokenPath(),\n );\n console.log(\n formatSessionStatus({\n state: \"locked\",\n }),\n );\n if (!locked) {\n console.log(\"No active local session was running.\");\n }\n });\n\nauthCommand\n .command(\"status\")\n .description(\"Show whether the local wallet session is unlocked\")\n .action(async () => {\n const status = await getSessionStatus(\n getSessionSocketPath(),\n getSessionTokenPath(),\n );\n if (!status) {\n console.log(\n formatSessionStatus({\n state: \"locked\",\n }),\n );\n return;\n }\n\n console.log(\n formatSessionStatus({\n state: \"unlocked\",\n address: status.address,\n expiresAt: status.expiresAt,\n }),\n );\n });\n","import { Command } from \"commander\";\nimport { FileBackupProvider } from \"../../core/backup-file.js\";\nimport {\n getBackupDir,\n getSessionSocketPath,\n getSessionTokenPath,\n getWalletPath,\n loadFileConfig,\n} from \"../config.js\";\nimport { promptHidden } from \"../prompt.js\";\nimport { lockSession } from \"../session.js\";\n\nfunction formatBackupStatus(params: {\n walletPath: string;\n backupDir: string;\n exists: boolean;\n backupCount: number;\n latestBackupPath?: string;\n address?: string;\n}): string {\n const lines: string[] = [];\n lines.push(`Wallet: ${params.exists ? \"present\" : \"missing\"}`);\n if (params.address) {\n lines.push(`Address: ${params.address}`);\n }\n lines.push(`Wallet at: ${params.walletPath}`);\n lines.push(`Backups: ${params.backupCount}`);\n lines.push(`Directory: ${params.backupDir}`);\n if (params.latestBackupPath) {\n lines.push(`Latest: ${params.latestBackupPath}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport function getBackupExportPasswordGuidance(): string {\n return [\n \"This backup is encrypted with the same wallet password as your active wallet.\",\n \"You will need that same wallet password to restore it.\",\n \"MoneyOS does not store or sync it for you.\",\n ].join(\" \");\n}\n\nexport const backupCommand = new Command(\"backup\").description(\n \"Export, restore, and inspect encrypted wallet backups\",\n);\n\nbackupCommand\n .command(\"export\")\n .description(\"Write a copy of the encrypted wallet backup\")\n .option(\"-o, --out <path>\", \"Custom path for the backup file\")\n .option(\"--force\", \"Overwrite an existing backup file at --out\")\n .action(async (options) => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n\n try {\n const targetPath = await provider.exportWallet({\n outPath: options.out,\n allowOverwrite: Boolean(options.force),\n });\n console.log(`Backup exported to ${targetPath}`);\n console.log(getBackupExportPasswordGuidance());\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nbackupCommand\n .command(\"restore\")\n .description(\"Restore the encrypted wallet from a backup file\")\n .argument(\"<path>\", \"Path to the encrypted backup file\")\n .option(\"--force\", \"Overwrite an existing encrypted wallet\")\n .action(async (path: string, options) => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n\n try {\n const passphrase = await promptHidden(\n \"Wallet password for backup verification: \",\n );\n const metadata = await provider.restoreWallet(path, {\n passphrase,\n allowOverwrite: Boolean(options.force),\n });\n await lockSession(getSessionSocketPath(), getSessionTokenPath());\n console.log(\"Encrypted wallet restored.\");\n console.log(`Address: ${metadata.address}`);\n console.log(`Wallet: ${getWalletPath(config)}`);\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n });\n\nbackupCommand\n .command(\"status\")\n .description(\"Show the local wallet backup status\")\n .action(async () => {\n const config = loadFileConfig();\n const provider = new FileBackupProvider({\n walletPath: getWalletPath(config),\n backupDir: getBackupDir(config),\n });\n const status = await provider.status();\n console.log(formatBackupStatus(status));\n });\n","import { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\n\nconst packageJsonPath = resolve(\n dirname(fileURLToPath(import.meta.url)),\n \"../../package.json\",\n);\n\ntype PackageJson = {\n version: string;\n};\n\nexport const version = (JSON.parse(\n readFileSync(packageJsonPath, \"utf8\"),\n) as PackageJson).version;\n"],"mappings":"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","names":["Command","privateKeyToAccount","existsSync","statSync","join","join","existsSync","statSync","readFileSync","existsSync","mkdirSync","dirname","join","join","resolve","randomBytes","chmodSync","existsSync","mkdirSync","readFileSync","statSync","writeFileSync","dirname","privateKeyToAccount","SECURE_FILE_MODE","existsSync","dirname","mkdirSync","statSync","readFileSync","writeFileSync","chmodSync","resolve","randomBytes","privateKeyToAccount","Command","formatUnits","parseUnits","encodeFunctionData","ERC20_ABI","raw","formatUnits","parseUnits","result","encodeFunctionData","Command","Command","Command","Command","Command","Command","privateKeyToAccount","privateKeyToAccount","Command","Command","Command","Command","Command","readFileSync","dirname","resolve","Command"]}
|