moneyos 0.6.0 → 0.6.1
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/CHANGELOG.md +24 -0
- package/dist/cli/index.js +195 -67
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +52 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -12
- package/dist/index.js.map +1 -1
- package/node_modules/@moneyos/gasless/dist/index.cjs +22 -2
- package/node_modules/@moneyos/gasless/dist/index.cjs.map +1 -1
- package/node_modules/@moneyos/gasless/dist/index.d.cts +11 -1
- package/node_modules/@moneyos/gasless/dist/index.d.ts +11 -1
- package/node_modules/@moneyos/gasless/dist/index.js +21 -2
- package/node_modules/@moneyos/gasless/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the repo's current `main` branch are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.6.1 - 2026-04-16
|
|
6
|
+
|
|
7
|
+
Patch release rolling up the gasless swap UX fixes from #101, #102, #108, and #110.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `moneyos balance` now shows both the EOA and smart-account balances when
|
|
12
|
+
gasless mode is enabled and `--address` is not passed, so users can see at a
|
|
13
|
+
glance which wallet actually holds funds (#103, #108).
|
|
14
|
+
- `moneyos swap` performs a client-side balance pre-check on the executor wallet
|
|
15
|
+
before requesting a quote, failing fast with a clear
|
|
16
|
+
`Insufficient <symbol> balance on <address>: need N, have M` error for both
|
|
17
|
+
ERC-20 and native inputs (#106, #108).
|
|
18
|
+
- Gasless swap failures surface the underlying revert reason in the error
|
|
19
|
+
message (e.g. `Gasless swap failed: ERC20: transfer amount exceeds balance
|
|
20
|
+
[simulation_failed]`) instead of the generic
|
|
21
|
+
`Relay accepted intent without txHash` (#105, #110).
|
|
22
|
+
- `@moneyos/gasless` exports a typed `GaslessRelayError` class that carries
|
|
23
|
+
`revertReason`, `policyCode`, `reason`, and `submissionId` for callers that
|
|
24
|
+
want to react programmatically to relay rejections (#110).
|
|
25
|
+
- Local session executor submits the `approve` + `swap` pair as a single atomic
|
|
26
|
+
batch on batching executors, matching the relay policy that only sponsors
|
|
27
|
+
`[approve, swap]` shapes for ERC-20-in swaps (#101, #102).
|
|
28
|
+
|
|
5
29
|
## 0.6.0 - 2026-04-15
|
|
6
30
|
|
|
7
31
|
Gasless execution, local contacts, and a wave of wallet UX cleanup.
|
package/dist/cli/index.js
CHANGED
|
@@ -1003,7 +1003,7 @@ function createRequestId() {
|
|
|
1003
1003
|
return `${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
|
|
1004
1004
|
}
|
|
1005
1005
|
function createSendRequestFingerprint(request) {
|
|
1006
|
-
return JSON.stringify(request.params);
|
|
1006
|
+
return JSON.stringify({ type: request.type, params: request.params });
|
|
1007
1007
|
}
|
|
1008
1008
|
function toGaslessExecutionConfig(config) {
|
|
1009
1009
|
return {
|
|
@@ -1142,6 +1142,14 @@ function unwrapSessionSendResponse(response) {
|
|
|
1142
1142
|
}
|
|
1143
1143
|
return response.result;
|
|
1144
1144
|
}
|
|
1145
|
+
function capabilitiesForMode(mode) {
|
|
1146
|
+
const smartAccount = mode === "smart-account";
|
|
1147
|
+
return {
|
|
1148
|
+
sponsoredGas: smartAccount,
|
|
1149
|
+
batching: false,
|
|
1150
|
+
simulation: smartAccount
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1145
1153
|
async function getSessionStatus(socketPath, tokenPath) {
|
|
1146
1154
|
try {
|
|
1147
1155
|
const response = await sendSessionRequest(
|
|
@@ -1157,10 +1165,12 @@ async function getSessionStatus(socketPath, tokenPath) {
|
|
|
1157
1165
|
return void 0;
|
|
1158
1166
|
}
|
|
1159
1167
|
const result = response.result;
|
|
1168
|
+
const mode = result.mode ?? "eoa";
|
|
1160
1169
|
return {
|
|
1161
1170
|
address: result.address,
|
|
1162
1171
|
expiresAt: result.expiresAt,
|
|
1163
|
-
mode
|
|
1172
|
+
mode,
|
|
1173
|
+
capabilities: result.capabilities ?? capabilitiesForMode(mode)
|
|
1164
1174
|
};
|
|
1165
1175
|
} catch {
|
|
1166
1176
|
removeFileIfPresent(socketPath);
|
|
@@ -1186,16 +1196,26 @@ async function lockSession(socketPath, tokenPath) {
|
|
|
1186
1196
|
return false;
|
|
1187
1197
|
}
|
|
1188
1198
|
}
|
|
1199
|
+
function serializeCallForSession(call) {
|
|
1200
|
+
return {
|
|
1201
|
+
to: call.to,
|
|
1202
|
+
chainId: call.chainId,
|
|
1203
|
+
data: call.data,
|
|
1204
|
+
value: call.value?.toString()
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1189
1207
|
var SessionExecutionClient = class {
|
|
1190
1208
|
mode;
|
|
1191
1209
|
socketPath;
|
|
1192
1210
|
tokenPath;
|
|
1193
1211
|
address;
|
|
1212
|
+
caps;
|
|
1194
1213
|
constructor(params) {
|
|
1195
1214
|
this.socketPath = params.socketPath;
|
|
1196
1215
|
this.tokenPath = params.tokenPath;
|
|
1197
1216
|
this.address = params.address;
|
|
1198
1217
|
this.mode = params.mode ?? "eoa";
|
|
1218
|
+
this.caps = params.capabilities ?? capabilitiesForMode(this.mode);
|
|
1199
1219
|
}
|
|
1200
1220
|
getAddress() {
|
|
1201
1221
|
return this.address;
|
|
@@ -1211,6 +1231,20 @@ var SessionExecutionClient = class {
|
|
|
1211
1231
|
return this.sendWithRequestId(requestId, call);
|
|
1212
1232
|
}
|
|
1213
1233
|
}
|
|
1234
|
+
async sendBatch(calls) {
|
|
1235
|
+
if (calls.length === 0) {
|
|
1236
|
+
throw new Error("sendBatch requires at least one call");
|
|
1237
|
+
}
|
|
1238
|
+
const requestId = createRequestId();
|
|
1239
|
+
try {
|
|
1240
|
+
return await this.sendBatchWithRequestId(requestId, calls);
|
|
1241
|
+
} catch (error) {
|
|
1242
|
+
if (!isRetryableSessionTransportError(error)) {
|
|
1243
|
+
throw error;
|
|
1244
|
+
}
|
|
1245
|
+
return this.sendBatchWithRequestId(requestId, calls);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1214
1248
|
async sendWithRequestId(requestId, call) {
|
|
1215
1249
|
const response = await sendSessionRequest(
|
|
1216
1250
|
this.socketPath,
|
|
@@ -1218,11 +1252,21 @@ var SessionExecutionClient = class {
|
|
|
1218
1252
|
{
|
|
1219
1253
|
id: requestId,
|
|
1220
1254
|
type: "send",
|
|
1255
|
+
params: serializeCallForSession(call)
|
|
1256
|
+
},
|
|
1257
|
+
SESSION_SEND_TIMEOUT_MS
|
|
1258
|
+
);
|
|
1259
|
+
return unwrapSessionSendResponse(response);
|
|
1260
|
+
}
|
|
1261
|
+
async sendBatchWithRequestId(requestId, calls) {
|
|
1262
|
+
const response = await sendSessionRequest(
|
|
1263
|
+
this.socketPath,
|
|
1264
|
+
this.tokenPath,
|
|
1265
|
+
{
|
|
1266
|
+
id: requestId,
|
|
1267
|
+
type: "sendBatch",
|
|
1221
1268
|
params: {
|
|
1222
|
-
|
|
1223
|
-
chainId: call.chainId,
|
|
1224
|
-
data: call.data,
|
|
1225
|
-
value: call.value?.toString()
|
|
1269
|
+
calls: calls.map(serializeCallForSession)
|
|
1226
1270
|
}
|
|
1227
1271
|
},
|
|
1228
1272
|
SESSION_SEND_TIMEOUT_MS
|
|
@@ -1230,14 +1274,54 @@ var SessionExecutionClient = class {
|
|
|
1230
1274
|
return unwrapSessionSendResponse(response);
|
|
1231
1275
|
}
|
|
1232
1276
|
capabilities() {
|
|
1233
|
-
|
|
1277
|
+
return { ...this.caps };
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
function deserializeSessionCall(params) {
|
|
1281
|
+
return {
|
|
1282
|
+
to: params.to,
|
|
1283
|
+
chainId: params.chainId,
|
|
1284
|
+
data: params.data,
|
|
1285
|
+
value: params.value !== void 0 ? BigInt(params.value) : void 0
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
async function executeSendLikeRequest(executor, request) {
|
|
1289
|
+
try {
|
|
1290
|
+
let result;
|
|
1291
|
+
if (request.type === "send") {
|
|
1292
|
+
result = await executor.send(deserializeSessionCall(request.params));
|
|
1293
|
+
} else {
|
|
1294
|
+
if (typeof executor.sendBatch !== "function") {
|
|
1295
|
+
return {
|
|
1296
|
+
id: request.id,
|
|
1297
|
+
ok: false,
|
|
1298
|
+
error: "Session executor does not support batched execution."
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
if (request.params.calls.length === 0) {
|
|
1302
|
+
return {
|
|
1303
|
+
id: request.id,
|
|
1304
|
+
ok: false,
|
|
1305
|
+
error: "sendBatch requires at least one call"
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
result = await executor.sendBatch(
|
|
1309
|
+
request.params.calls.map(deserializeSessionCall)
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1234
1312
|
return {
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1313
|
+
id: request.id,
|
|
1314
|
+
ok: true,
|
|
1315
|
+
result
|
|
1316
|
+
};
|
|
1317
|
+
} catch (error) {
|
|
1318
|
+
return {
|
|
1319
|
+
id: request.id,
|
|
1320
|
+
ok: false,
|
|
1321
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1238
1322
|
};
|
|
1239
1323
|
}
|
|
1240
|
-
}
|
|
1324
|
+
}
|
|
1241
1325
|
async function startSessionServer(start, hooks = {}) {
|
|
1242
1326
|
ensureSecureParent(start.tokenPath);
|
|
1243
1327
|
ensureSecureParent(start.socketPath);
|
|
@@ -1328,7 +1412,8 @@ async function startSessionServer(start, hooks = {}) {
|
|
|
1328
1412
|
result: {
|
|
1329
1413
|
address: executor.getAddress(),
|
|
1330
1414
|
expiresAt: expiresAt.toISOString(),
|
|
1331
|
-
mode: executor.mode
|
|
1415
|
+
mode: executor.mode,
|
|
1416
|
+
capabilities: executor.capabilities()
|
|
1332
1417
|
}
|
|
1333
1418
|
});
|
|
1334
1419
|
return;
|
|
@@ -1361,27 +1446,7 @@ async function startSessionServer(start, hooks = {}) {
|
|
|
1361
1446
|
respond(await existing.response);
|
|
1362
1447
|
return;
|
|
1363
1448
|
}
|
|
1364
|
-
const responsePromise = (
|
|
1365
|
-
try {
|
|
1366
|
-
const result = await executor.send({
|
|
1367
|
-
to: request.params.to,
|
|
1368
|
-
chainId: request.params.chainId,
|
|
1369
|
-
data: request.params.data,
|
|
1370
|
-
value: request.params.value !== void 0 ? BigInt(request.params.value) : void 0
|
|
1371
|
-
});
|
|
1372
|
-
return {
|
|
1373
|
-
id: request.id,
|
|
1374
|
-
ok: true,
|
|
1375
|
-
result
|
|
1376
|
-
};
|
|
1377
|
-
} catch (error) {
|
|
1378
|
-
return {
|
|
1379
|
-
id: request.id,
|
|
1380
|
-
ok: false,
|
|
1381
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1382
|
-
};
|
|
1383
|
-
}
|
|
1384
|
-
})();
|
|
1449
|
+
const responsePromise = executeSendLikeRequest(executor, request);
|
|
1385
1450
|
sendResponses.set(request.id, {
|
|
1386
1451
|
fingerprint,
|
|
1387
1452
|
response: responsePromise
|
|
@@ -1416,6 +1481,7 @@ async function startSessionServer(start, hooks = {}) {
|
|
|
1416
1481
|
address: executor.getAddress(),
|
|
1417
1482
|
expiresAt: expiresAt.toISOString(),
|
|
1418
1483
|
mode: executor.mode,
|
|
1484
|
+
capabilities: executor.capabilities(),
|
|
1419
1485
|
close
|
|
1420
1486
|
};
|
|
1421
1487
|
}
|
|
@@ -1473,7 +1539,8 @@ async function startDetachedSessionDaemon(params) {
|
|
|
1473
1539
|
finish(void 0, {
|
|
1474
1540
|
address: payload.address,
|
|
1475
1541
|
expiresAt: payload.expiresAt,
|
|
1476
|
-
mode: payload.mode
|
|
1542
|
+
mode: payload.mode,
|
|
1543
|
+
capabilities: payload.capabilities ?? capabilitiesForMode(payload.mode)
|
|
1477
1544
|
});
|
|
1478
1545
|
} else if (payload?.type === "error") {
|
|
1479
1546
|
finish(new Error(payload.error));
|
|
@@ -1519,7 +1586,8 @@ async function runSessionDaemonProcess() {
|
|
|
1519
1586
|
type: "ready",
|
|
1520
1587
|
address: handle.address,
|
|
1521
1588
|
expiresAt: handle.expiresAt,
|
|
1522
|
-
mode: handle.mode
|
|
1589
|
+
mode: handle.mode,
|
|
1590
|
+
capabilities: handle.capabilities
|
|
1523
1591
|
});
|
|
1524
1592
|
process.on("SIGTERM", () => {
|
|
1525
1593
|
void handle.close().then(() => shutdown());
|
|
@@ -1876,7 +1944,8 @@ async function connectLocalSession(options = {}) {
|
|
|
1876
1944
|
socketPath,
|
|
1877
1945
|
tokenPath,
|
|
1878
1946
|
address: session.address,
|
|
1879
|
-
mode: session.mode
|
|
1947
|
+
mode: session.mode,
|
|
1948
|
+
capabilities: session.capabilities
|
|
1880
1949
|
});
|
|
1881
1950
|
}
|
|
1882
1951
|
|
|
@@ -1940,6 +2009,7 @@ async function resolveGaslessExecutionConfig(config, options = {}) {
|
|
|
1940
2009
|
}
|
|
1941
2010
|
|
|
1942
2011
|
// src/cli/wallet.ts
|
|
2012
|
+
var GASLESS_MISSING_ENV_ERROR = "Gasless mode is enabled but required environment variables are missing. Set MONEYOS_GASLESS_RELAY_URL, MONEYOS_GASLESS_ACCOUNT, and MONEYOS_GASLESS_SPONSOR.";
|
|
1943
2013
|
function resolveEnvPrivateKey(explicit) {
|
|
1944
2014
|
return explicit ?? process.env.MONEYOS_PRIVATE_KEY;
|
|
1945
2015
|
}
|
|
@@ -1979,6 +2049,24 @@ async function loadCliAddress(config, options = {}) {
|
|
|
1979
2049
|
}
|
|
1980
2050
|
throw new Error("No wallet configured. Run `moneyos init`.");
|
|
1981
2051
|
}
|
|
2052
|
+
async function resolveCliOwnedAddresses(config, options = {}) {
|
|
2053
|
+
const { address } = await loadCliAddress(config, options);
|
|
2054
|
+
if (!isGaslessEnabled(config)) {
|
|
2055
|
+
return { eoa: address };
|
|
2056
|
+
}
|
|
2057
|
+
const gasless = await resolveGaslessExecutionConfig(config, {
|
|
2058
|
+
ownerAddress: address,
|
|
2059
|
+
chainId: options.chainId ?? config.chainId ?? 42161,
|
|
2060
|
+
rpcUrl: config.rpcUrl
|
|
2061
|
+
});
|
|
2062
|
+
if (!gasless) {
|
|
2063
|
+
throw new Error(GASLESS_MISSING_ENV_ERROR);
|
|
2064
|
+
}
|
|
2065
|
+
return {
|
|
2066
|
+
eoa: address,
|
|
2067
|
+
smartAccount: gasless.account
|
|
2068
|
+
};
|
|
2069
|
+
}
|
|
1982
2070
|
async function buildCliMoneyOSConfig(config, options = {}) {
|
|
1983
2071
|
const moneyosConfig = {
|
|
1984
2072
|
chainId: options.chainId ?? config.chainId ?? 42161,
|
|
@@ -1998,9 +2086,7 @@ async function buildCliMoneyOSConfig(config, options = {}) {
|
|
|
1998
2086
|
});
|
|
1999
2087
|
if (!gasless) {
|
|
2000
2088
|
if (gaslessEnabled) {
|
|
2001
|
-
throw new Error(
|
|
2002
|
-
"Gasless mode is enabled but required environment variables are missing. Set MONEYOS_GASLESS_RELAY_URL, MONEYOS_GASLESS_ACCOUNT, and MONEYOS_GASLESS_SPONSOR."
|
|
2003
|
-
);
|
|
2089
|
+
throw new Error(GASLESS_MISSING_ENV_ERROR);
|
|
2004
2090
|
}
|
|
2005
2091
|
return {
|
|
2006
2092
|
...moneyosConfig,
|
|
@@ -2059,6 +2145,28 @@ async function buildCliMoneyOSConfig(config, options = {}) {
|
|
|
2059
2145
|
}
|
|
2060
2146
|
|
|
2061
2147
|
// src/cli/commands/balance.ts
|
|
2148
|
+
function shortenAddress(address) {
|
|
2149
|
+
return `${address.slice(0, 6)}\u2026${address.slice(-4)}`;
|
|
2150
|
+
}
|
|
2151
|
+
function formatTargetLabel(target) {
|
|
2152
|
+
return `${target.label} (${shortenAddress(target.address)}):`;
|
|
2153
|
+
}
|
|
2154
|
+
function targetLineWidth(targets) {
|
|
2155
|
+
return Math.max(...targets.map((target) => formatTargetLabel(target).length));
|
|
2156
|
+
}
|
|
2157
|
+
async function resolveBalanceTargets(config, chainId, address) {
|
|
2158
|
+
if (address) {
|
|
2159
|
+
return [{ address }];
|
|
2160
|
+
}
|
|
2161
|
+
const resolved = await resolveCliOwnedAddresses(config, { chainId });
|
|
2162
|
+
if (resolved.smartAccount && resolved.smartAccount.toLowerCase() !== resolved.eoa.toLowerCase()) {
|
|
2163
|
+
return [
|
|
2164
|
+
{ label: "EOA", address: resolved.eoa },
|
|
2165
|
+
{ label: "Smart account", address: resolved.smartAccount }
|
|
2166
|
+
];
|
|
2167
|
+
}
|
|
2168
|
+
return [{ address: resolved.eoa }];
|
|
2169
|
+
}
|
|
2062
2170
|
var balanceCommand = new Command2("balance").description("Check token balance").argument("[token]", "Token symbol (e.g. USDC, ETH, RYZE). Omit with --all.").option("-a, --address <address>", "Address to check (defaults to your own)").option("-c, --chain <chainId>", "Chain ID (default: 42161 Arbitrum)").option("--all", "Show balances for every built-in token on the selected chain").action(async (token, options) => {
|
|
2063
2171
|
if (options.all && token !== void 0) {
|
|
2064
2172
|
console.error("Cannot combine a token argument with --all.");
|
|
@@ -2071,17 +2179,15 @@ var balanceCommand = new Command2("balance").description("Check token balance").
|
|
|
2071
2179
|
return;
|
|
2072
2180
|
}
|
|
2073
2181
|
const config = loadConfig();
|
|
2074
|
-
const chainId = options.chain ? parseInt(options.chain) : config.chainId;
|
|
2075
|
-
|
|
2182
|
+
const chainId = options.chain ? parseInt(options.chain) : config.chainId ?? 42161;
|
|
2183
|
+
const address = options.address;
|
|
2076
2184
|
let moneyos;
|
|
2185
|
+
let targets;
|
|
2077
2186
|
try {
|
|
2078
|
-
|
|
2079
|
-
const resolved = await loadCliAddress(config);
|
|
2080
|
-
address = resolved.address;
|
|
2081
|
-
}
|
|
2187
|
+
targets = await resolveBalanceTargets(config, chainId, address);
|
|
2082
2188
|
moneyos = new MoneyOS(
|
|
2083
2189
|
await buildCliMoneyOSConfig(config, {
|
|
2084
|
-
chainId
|
|
2190
|
+
chainId,
|
|
2085
2191
|
requireSigner: false
|
|
2086
2192
|
})
|
|
2087
2193
|
);
|
|
@@ -2093,40 +2199,62 @@ var balanceCommand = new Command2("balance").description("Check token balance").
|
|
|
2093
2199
|
return;
|
|
2094
2200
|
}
|
|
2095
2201
|
if (options.all) {
|
|
2096
|
-
const
|
|
2097
|
-
const candidates = listTokens(resolvedChainId);
|
|
2202
|
+
const candidates = listTokens(chainId);
|
|
2098
2203
|
if (candidates.length === 0) {
|
|
2099
2204
|
console.error(
|
|
2100
|
-
`No built-in tokens registered on chain ${
|
|
2205
|
+
`No built-in tokens registered on chain ${chainId}.`
|
|
2101
2206
|
);
|
|
2102
2207
|
process.exitCode = 1;
|
|
2103
2208
|
return;
|
|
2104
2209
|
}
|
|
2105
|
-
const results = await Promise.allSettled(
|
|
2106
|
-
candidates.map(
|
|
2107
|
-
(t) => moneyos.balance(t.symbol, { address, chainId: resolvedChainId })
|
|
2108
|
-
)
|
|
2109
|
-
);
|
|
2110
|
-
const width = Math.max(...candidates.map((t) => t.symbol.length));
|
|
2111
2210
|
let anyFailed = false;
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
console.log(
|
|
2116
|
-
}
|
|
2211
|
+
for (const [index, target] of targets.entries()) {
|
|
2212
|
+
if (target.label) {
|
|
2213
|
+
if (index > 0) console.log("");
|
|
2214
|
+
console.log(formatTargetLabel(target));
|
|
2215
|
+
}
|
|
2216
|
+
const results2 = await Promise.allSettled(
|
|
2217
|
+
candidates.map(
|
|
2218
|
+
(candidate) => moneyos.balance(candidate.symbol, { address: target.address, chainId })
|
|
2219
|
+
)
|
|
2220
|
+
);
|
|
2221
|
+
const width2 = Math.max(...candidates.map((candidate) => candidate.symbol.length));
|
|
2222
|
+
results2.forEach((result, resultIndex) => {
|
|
2223
|
+
const symbol = candidates[resultIndex].symbol.padEnd(width2);
|
|
2224
|
+
if (result.status === "fulfilled") {
|
|
2225
|
+
console.log(`${symbol} ${result.value.amount}`);
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2117
2228
|
anyFailed = true;
|
|
2118
|
-
const message =
|
|
2229
|
+
const message = result.reason instanceof Error ? result.reason.message : String(result.reason);
|
|
2119
2230
|
console.log(`${symbol} error: ${message}`);
|
|
2120
|
-
}
|
|
2121
|
-
}
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2122
2233
|
if (anyFailed) process.exitCode = 1;
|
|
2123
2234
|
return;
|
|
2124
2235
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2236
|
+
if (targets.length === 1) {
|
|
2237
|
+
const result = await moneyos.balance(token, {
|
|
2238
|
+
address: targets[0].address,
|
|
2239
|
+
chainId
|
|
2240
|
+
});
|
|
2241
|
+
console.log(`${result.amount} ${result.symbol}`);
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
const width = targetLineWidth(targets);
|
|
2245
|
+
const results = await Promise.all(
|
|
2246
|
+
targets.map(
|
|
2247
|
+
(target) => moneyos.balance(token, {
|
|
2248
|
+
address: target.address,
|
|
2249
|
+
chainId
|
|
2250
|
+
})
|
|
2251
|
+
)
|
|
2252
|
+
);
|
|
2253
|
+
results.forEach((result, index) => {
|
|
2254
|
+
console.log(
|
|
2255
|
+
`${formatTargetLabel(targets[index]).padEnd(width)} ${result.symbol} ${result.amount}`
|
|
2256
|
+
);
|
|
2128
2257
|
});
|
|
2129
|
-
console.log(`${result.amount} ${result.symbol}`);
|
|
2130
2258
|
});
|
|
2131
2259
|
|
|
2132
2260
|
// src/cli/commands/send.ts
|