@vultisig/cli 2.19.14 → 2.20.0
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 +37 -0
- package/README.md +136 -58
- package/dist/index.js +663 -644
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -4872,7 +4872,7 @@ var init_secp256k1 = __esm({
|
|
|
4872
4872
|
import "dotenv/config";
|
|
4873
4873
|
import { promises as fs4 } from "node:fs";
|
|
4874
4874
|
import { descriptions } from "@vultisig/client-shared";
|
|
4875
|
-
import { parseKeygenQR, Vultisig as Vultisig6 } from "@vultisig/sdk";
|
|
4875
|
+
import { Chain as Chain14, parseKeygenQR, Vultisig as Vultisig6 } from "@vultisig/sdk";
|
|
4876
4876
|
import chalk16 from "chalk";
|
|
4877
4877
|
import { InvalidArgumentError, program } from "commander";
|
|
4878
4878
|
|
|
@@ -4966,7 +4966,8 @@ var EXIT_CODE_DESCRIPTIONS = {
|
|
|
4966
4966
|
[9 /* DUPLICATE_BROADCAST */]: "Duplicate broadcast refused (nothing sent) \u2014 retry with --force to override",
|
|
4967
4967
|
[10 /* AGENT_TURN_BLOCKED */]: "agent ask: a fund-safety guardrail blocked the requested action",
|
|
4968
4968
|
[11 /* AGENT_TURN_REFUSAL */]: "agent ask: the model refused or asked a clarifying question (no action taken)",
|
|
4969
|
-
[12 /* CONFIRMATION_REQUIRED */]: "Interactive confirmation/input required but the session is non-interactive \u2014 pass --yes/--confirm or the required flag"
|
|
4969
|
+
[12 /* CONFIRMATION_REQUIRED */]: "Interactive confirmation/input required but the session is non-interactive \u2014 pass --yes/--confirm or the required flag",
|
|
4970
|
+
[13 /* BROADCAST_COMMITTED */]: "agent ask: transaction broadcast but the overall request may be incomplete \u2014 inspect the hash, do NOT blindly retry"
|
|
4970
4971
|
};
|
|
4971
4972
|
var VsigError = class extends Error {
|
|
4972
4973
|
hint;
|
|
@@ -5027,6 +5028,13 @@ var InvalidInputError = class extends VsigError {
|
|
|
5027
5028
|
super(message, hint, suggestions, context);
|
|
5028
5029
|
}
|
|
5029
5030
|
};
|
|
5031
|
+
var InvalidTxHashError = class extends VsigError {
|
|
5032
|
+
exitCode = 4 /* INVALID_INPUT */;
|
|
5033
|
+
code = "INVALID_HASH";
|
|
5034
|
+
constructor(message, hint, suggestions, context) {
|
|
5035
|
+
super(message, hint, suggestions, context);
|
|
5036
|
+
}
|
|
5037
|
+
};
|
|
5030
5038
|
var InsufficientBalanceError = class extends VsigError {
|
|
5031
5039
|
exitCode = 4 /* INVALID_INPUT */;
|
|
5032
5040
|
code = "INSUFFICIENT_BALANCE";
|
|
@@ -5055,6 +5063,13 @@ var TxNotFoundError = class extends VsigError {
|
|
|
5055
5063
|
super(message, hint, suggestions, context);
|
|
5056
5064
|
}
|
|
5057
5065
|
};
|
|
5066
|
+
var VaultNotFoundError = class extends VsigError {
|
|
5067
|
+
exitCode = 5 /* RESOURCE_NOT_FOUND */;
|
|
5068
|
+
code = "VAULT_NOT_FOUND";
|
|
5069
|
+
constructor(message, hint, suggestions, context) {
|
|
5070
|
+
super(message, hint, suggestions, context);
|
|
5071
|
+
}
|
|
5072
|
+
};
|
|
5058
5073
|
var TxStatusTimeoutError = class extends VsigError {
|
|
5059
5074
|
exitCode = 3 /* NETWORK */;
|
|
5060
5075
|
code = "TX_STATUS_TIMEOUT";
|
|
@@ -5103,53 +5118,78 @@ var DuplicateBroadcastRefusedError = class extends VsigError {
|
|
|
5103
5118
|
]);
|
|
5104
5119
|
}
|
|
5105
5120
|
};
|
|
5106
|
-
function
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5121
|
+
function isPermanentBroadcastInputError(err) {
|
|
5122
|
+
const details = `${err.message}
|
|
5123
|
+
${err.originalError?.message ?? ""}`;
|
|
5124
|
+
return /failed to decode signed transaction|could not decode (?:signed )?transaction|invalid raw transaction|invalid transaction encoding|invalid (?:transaction )?signature|invalid sender|invalid rlp|rlp:|unsupported transaction type/i.test(
|
|
5125
|
+
details
|
|
5126
|
+
);
|
|
5127
|
+
}
|
|
5128
|
+
var INVALID_ADDRESS_RE = /invalid (?:receiver |recipient |destination )?address|bad address|malformed address/i;
|
|
5129
|
+
function invalidAddressError(message) {
|
|
5130
|
+
const addrMatch = message.match(/(0x[a-fA-F0-9]+|bc1[a-z0-9]+|[13][a-km-zA-HJ-NP-Z1-9]+)/i);
|
|
5131
|
+
return new InvalidAddressError(message, void 0, void 0, addrMatch ? { address: addrMatch[1] } : void 0);
|
|
5132
|
+
}
|
|
5133
|
+
function classifyVaultError(err) {
|
|
5134
|
+
if (err.code === VaultErrorCode.BalanceFetchFailed && err.originalError) {
|
|
5135
|
+
const inner = classifyError(err.originalError);
|
|
5136
|
+
if (!(inner instanceof UnknownError)) return inner;
|
|
5110
5137
|
}
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5138
|
+
switch (err.code) {
|
|
5139
|
+
case VaultErrorCode.UnsupportedChain:
|
|
5140
|
+
case VaultErrorCode.ChainNotSupported:
|
|
5141
|
+
return new InvalidChainError(err.message);
|
|
5142
|
+
case VaultErrorCode.NetworkError:
|
|
5143
|
+
case VaultErrorCode.BalanceFetchFailed:
|
|
5144
|
+
case VaultErrorCode.Timeout:
|
|
5145
|
+
return new NetworkError(err.message);
|
|
5146
|
+
case VaultErrorCode.InvalidAmount:
|
|
5147
|
+
return new InvalidInputError(err.message);
|
|
5148
|
+
case VaultErrorCode.InvalidConfig: {
|
|
5149
|
+
const lowerMsg = err.message.toLowerCase();
|
|
5150
|
+
if (lowerMsg.includes("unknown chain") || lowerMsg.includes("unsupported chain") || lowerMsg.includes("chain not supported")) {
|
|
5151
|
+
const chainMatch = err.message.match(/chain[:\s]*"([^"]+)"/i);
|
|
5152
|
+
return new InvalidChainError(
|
|
5153
|
+
err.message,
|
|
5154
|
+
void 0,
|
|
5155
|
+
void 0,
|
|
5156
|
+
chainMatch ? { chain: chainMatch[1] } : void 0
|
|
5157
|
+
);
|
|
5158
|
+
}
|
|
5159
|
+
if (INVALID_ADDRESS_RE.test(lowerMsg)) return invalidAddressError(err.message);
|
|
5160
|
+
if (lowerMsg.includes("failed to unlock vault") || lowerMsg.includes("invalid password")) {
|
|
5161
|
+
return new AuthRequiredError(err.message);
|
|
5162
|
+
}
|
|
5163
|
+
return new UsageError(err.message);
|
|
5115
5164
|
}
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5165
|
+
case VaultErrorCode.VaultNotFound:
|
|
5166
|
+
return new VaultNotFoundError(err.message);
|
|
5167
|
+
case VaultErrorCode.UnsupportedToken:
|
|
5168
|
+
return new TokenNotFoundError(err.message);
|
|
5169
|
+
case VaultErrorCode.BroadcastFailed:
|
|
5170
|
+
if (isPermanentBroadcastInputError(err)) {
|
|
5171
|
+
return new InvalidInputError(err.message, "Check the signed transaction encoding and signature");
|
|
5172
|
+
}
|
|
5173
|
+
return new ExternalServiceError(err.message, "Broadcast failed \u2014 the node may be temporarily unavailable", [
|
|
5174
|
+
"Retry the transaction"
|
|
5175
|
+
]);
|
|
5176
|
+
case VaultErrorCode.GasEstimationFailed:
|
|
5177
|
+
return new InvalidInputError(err.message, "Gas estimation failed \u2014 check balance and transaction params");
|
|
5178
|
+
case VaultErrorCode.SigningFailed:
|
|
5179
|
+
if (/must be 32 bytes|expected 32 bytes|non-32-byte/i.test(err.message)) {
|
|
5125
5180
|
return new InvalidInputError(err.message);
|
|
5126
|
-
case VaultErrorCode.InvalidConfig: {
|
|
5127
|
-
const lowerMsg = err.message.toLowerCase();
|
|
5128
|
-
if (lowerMsg.includes("unknown chain") || lowerMsg.includes("unsupported chain") || lowerMsg.includes("chain not supported")) {
|
|
5129
|
-
const chainMatch = err.message.match(/chain[:\s]*"([^"]+)"/i);
|
|
5130
|
-
return new InvalidChainError(
|
|
5131
|
-
err.message,
|
|
5132
|
-
void 0,
|
|
5133
|
-
void 0,
|
|
5134
|
-
chainMatch ? { chain: chainMatch[1] } : void 0
|
|
5135
|
-
);
|
|
5136
|
-
}
|
|
5137
|
-
return new UsageError(err.message);
|
|
5138
5181
|
}
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
return new UnknownError(err.message);
|
|
5149
|
-
default:
|
|
5150
|
-
return new UnknownError(err.message);
|
|
5151
|
-
}
|
|
5182
|
+
return new UnknownError(err.message);
|
|
5183
|
+
default:
|
|
5184
|
+
return new UnknownError(err.message);
|
|
5185
|
+
}
|
|
5186
|
+
}
|
|
5187
|
+
function classifyError(err) {
|
|
5188
|
+
if (err instanceof VsigError) return err;
|
|
5189
|
+
if (err.code === "DUPLICATE_BROADCAST") {
|
|
5190
|
+
return new DuplicateBroadcastRefusedError(err.message);
|
|
5152
5191
|
}
|
|
5192
|
+
if (err instanceof VaultError) return classifyVaultError(err);
|
|
5153
5193
|
if (err instanceof VaultImportError) {
|
|
5154
5194
|
switch (err.code) {
|
|
5155
5195
|
case VaultImportErrorCode.PASSWORD_REQUIRED:
|
|
@@ -5159,18 +5199,24 @@ function classifyError(err) {
|
|
|
5159
5199
|
return new UsageError(err.message);
|
|
5160
5200
|
}
|
|
5161
5201
|
}
|
|
5202
|
+
if (err.code === "ENOENT") {
|
|
5203
|
+
return new InvalidInputError(err.message, "Check that the file or directory exists");
|
|
5204
|
+
}
|
|
5162
5205
|
const msg = err.message.toLowerCase();
|
|
5206
|
+
if (msg.includes("no vault found matching") || msg.includes("vault not found")) {
|
|
5207
|
+
return new VaultNotFoundError(err.message);
|
|
5208
|
+
}
|
|
5163
5209
|
if (msg.includes("unsupported chain") || msg.includes("invalid chain") || msg.includes("unknown chain")) {
|
|
5164
5210
|
const chainMatch = err.message.match(/chain[:\s]*"([^"]+)"/i) || err.message.match(/chain[:\s]+(\S+)/i);
|
|
5165
5211
|
return new InvalidChainError(err.message, void 0, void 0, chainMatch ? { chain: chainMatch[1] } : void 0);
|
|
5166
5212
|
}
|
|
5167
|
-
if (
|
|
5168
|
-
const addrMatch = err.message.match(/(0x[a-fA-F0-9]+|bc1[a-z0-9]+|[13][a-km-zA-HJ-NP-Z1-9]+)/i);
|
|
5169
|
-
return new InvalidAddressError(err.message, void 0, void 0, addrMatch ? { address: addrMatch[1] } : void 0);
|
|
5170
|
-
}
|
|
5213
|
+
if (INVALID_ADDRESS_RE.test(msg)) return invalidAddressError(err.message);
|
|
5171
5214
|
if (msg.includes("insufficient") && msg.includes("balance")) {
|
|
5172
5215
|
return new InsufficientBalanceError(err.message);
|
|
5173
5216
|
}
|
|
5217
|
+
if (msg.includes("invalid currency") || msg.includes("invalid amount") || msg.includes("invalid mnemonic") || msg.includes("invalid seedphrase") || msg.includes("must be 32 bytes") || msg.includes("expected 32 bytes") || msg.includes("non-32-byte")) {
|
|
5218
|
+
return new InvalidInputError(err.message);
|
|
5219
|
+
}
|
|
5174
5220
|
if (msg.includes("no route") || msg.includes("no swap") || msg.includes("no provider")) {
|
|
5175
5221
|
return new NoRouteError(err.message);
|
|
5176
5222
|
}
|
|
@@ -5482,16 +5528,30 @@ function clearCachedPassword(vaultIdOrName) {
|
|
|
5482
5528
|
}
|
|
5483
5529
|
function parseVaultPasswords() {
|
|
5484
5530
|
const passwordMap = /* @__PURE__ */ new Map();
|
|
5485
|
-
const passwordsEnv = process.env.VAULT_PASSWORDS;
|
|
5486
|
-
if (passwordsEnv)
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
const
|
|
5490
|
-
if (
|
|
5491
|
-
const
|
|
5492
|
-
|
|
5493
|
-
|
|
5531
|
+
const passwordsEnv = process.env.VAULT_PASSWORDS?.trim();
|
|
5532
|
+
if (!passwordsEnv) return passwordMap;
|
|
5533
|
+
if (passwordsEnv.startsWith("{")) {
|
|
5534
|
+
try {
|
|
5535
|
+
const parsed = JSON.parse(passwordsEnv);
|
|
5536
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
5537
|
+
const entries = Object.entries(parsed);
|
|
5538
|
+
if (entries.every(([vaultKey, password]) => vaultKey.length > 0 && typeof password === "string")) {
|
|
5539
|
+
return new Map(entries);
|
|
5540
|
+
}
|
|
5494
5541
|
}
|
|
5542
|
+
throw new Error("expected an object with string values");
|
|
5543
|
+
} catch {
|
|
5544
|
+
process.stderr.write(
|
|
5545
|
+
"Warning: VAULT_PASSWORDS is not a valid JSON object with string values; falling back to legacy key:password parsing.\n"
|
|
5546
|
+
);
|
|
5547
|
+
}
|
|
5548
|
+
}
|
|
5549
|
+
for (const pair of passwordsEnv.split(/\s+/)) {
|
|
5550
|
+
const colonIndex = pair.indexOf(":");
|
|
5551
|
+
if (colonIndex > 0) {
|
|
5552
|
+
const vaultKey = pair.substring(0, colonIndex);
|
|
5553
|
+
const password = pair.substring(colonIndex + 1);
|
|
5554
|
+
passwordMap.set(vaultKey, password);
|
|
5495
5555
|
}
|
|
5496
5556
|
}
|
|
5497
5557
|
return passwordMap;
|
|
@@ -5511,7 +5571,7 @@ function getPasswordFromEnv(vaultId, vaultName) {
|
|
|
5511
5571
|
}
|
|
5512
5572
|
async function promptForPassword(vaultName, vaultId) {
|
|
5513
5573
|
requireInteractive(
|
|
5514
|
-
'Use --password
|
|
5574
|
+
'Use --password, a vault password environment variable, or "vsig auth setup" to store credentials.'
|
|
5515
5575
|
);
|
|
5516
5576
|
const displayName = vaultName || vaultId || "vault";
|
|
5517
5577
|
const { password } = await prompt([
|
|
@@ -5530,11 +5590,11 @@ async function resolvePasswordNonInteractive(vaultId, vaultName) {
|
|
|
5530
5590
|
return cachedPassword;
|
|
5531
5591
|
}
|
|
5532
5592
|
try {
|
|
5533
|
-
const
|
|
5534
|
-
if (
|
|
5535
|
-
cachePassword(vaultId,
|
|
5536
|
-
if (vaultName) cachePassword(vaultName,
|
|
5537
|
-
return
|
|
5593
|
+
const storedPassword = await getStoredServerPassword(vaultId);
|
|
5594
|
+
if (storedPassword) {
|
|
5595
|
+
cachePassword(vaultId, storedPassword);
|
|
5596
|
+
if (vaultName) cachePassword(vaultName, storedPassword);
|
|
5597
|
+
return storedPassword;
|
|
5538
5598
|
}
|
|
5539
5599
|
} catch {
|
|
5540
5600
|
}
|
|
@@ -5703,7 +5763,7 @@ function displayVaultInfo(vault) {
|
|
|
5703
5763
|
printResult(` Chain Code: ${vault.hexChainCode.substring(0, 20)}...
|
|
5704
5764
|
`);
|
|
5705
5765
|
}
|
|
5706
|
-
function displayTransactionPreview(fromAddress, toAddress, amount, symbol, chain, memo, gas) {
|
|
5766
|
+
function displayTransactionPreview(fromAddress, toAddress, amount, symbol, chain, memo, destinationTag, gas) {
|
|
5707
5767
|
if (gas) {
|
|
5708
5768
|
const bigIntReplacer2 = (_k, v) => typeof v === "bigint" ? v.toString() : v;
|
|
5709
5769
|
info(chalk2.blue(`
|
|
@@ -5717,6 +5777,9 @@ Estimated gas: ${JSON.stringify(gas, bigIntReplacer2, 2)}`));
|
|
|
5717
5777
|
if (memo) {
|
|
5718
5778
|
printResult(` Memo: ${memo}`);
|
|
5719
5779
|
}
|
|
5780
|
+
if (destinationTag !== void 0) {
|
|
5781
|
+
printResult(` Destination tag: ${destinationTag}`);
|
|
5782
|
+
}
|
|
5720
5783
|
}
|
|
5721
5784
|
function displayTransactionResult(chain, txHash) {
|
|
5722
5785
|
const explorerUrl = Vultisig.getTxExplorerUrl(chain, txHash);
|
|
@@ -5985,6 +6048,122 @@ function shouldAutoSelectActiveVault(hasActiveVault, corruptPointer, vaultCount)
|
|
|
5985
6048
|
return !hasActiveVault && !corruptPointer && vaultCount > 0;
|
|
5986
6049
|
}
|
|
5987
6050
|
|
|
6051
|
+
// ../../packages/core/chain/dist/Chain.js
|
|
6052
|
+
var EthereumL2Chain = {
|
|
6053
|
+
Arbitrum: "Arbitrum",
|
|
6054
|
+
Base: "Base",
|
|
6055
|
+
Blast: "Blast",
|
|
6056
|
+
Optimism: "Optimism",
|
|
6057
|
+
Zksync: "Zksync",
|
|
6058
|
+
Mantle: "Mantle"
|
|
6059
|
+
};
|
|
6060
|
+
var EvmChain = {
|
|
6061
|
+
...EthereumL2Chain,
|
|
6062
|
+
Avalanche: "Avalanche",
|
|
6063
|
+
CronosChain: "CronosChain",
|
|
6064
|
+
BSC: "BSC",
|
|
6065
|
+
Ethereum: "Ethereum",
|
|
6066
|
+
Polygon: "Polygon",
|
|
6067
|
+
Hyperliquid: "Hyperliquid",
|
|
6068
|
+
Sei: "Sei"
|
|
6069
|
+
};
|
|
6070
|
+
var UtxoChain;
|
|
6071
|
+
(function(UtxoChain2) {
|
|
6072
|
+
UtxoChain2["Bitcoin"] = "Bitcoin";
|
|
6073
|
+
UtxoChain2["BitcoinCash"] = "Bitcoin-Cash";
|
|
6074
|
+
UtxoChain2["Litecoin"] = "Litecoin";
|
|
6075
|
+
UtxoChain2["Dogecoin"] = "Dogecoin";
|
|
6076
|
+
UtxoChain2["Dash"] = "Dash";
|
|
6077
|
+
UtxoChain2["Zcash"] = "Zcash";
|
|
6078
|
+
})(UtxoChain || (UtxoChain = {}));
|
|
6079
|
+
var cosmosChainsByKind = {
|
|
6080
|
+
ibcEnabled: {
|
|
6081
|
+
Cosmos: "Cosmos",
|
|
6082
|
+
Osmosis: "Osmosis",
|
|
6083
|
+
Dydx: "Dydx",
|
|
6084
|
+
Kujira: "Kujira",
|
|
6085
|
+
Terra: "Terra",
|
|
6086
|
+
TerraClassic: "TerraClassic",
|
|
6087
|
+
Noble: "Noble",
|
|
6088
|
+
Akash: "Akash"
|
|
6089
|
+
},
|
|
6090
|
+
vaultBased: {
|
|
6091
|
+
THORChain: "THORChain",
|
|
6092
|
+
MayaChain: "MayaChain"
|
|
6093
|
+
}
|
|
6094
|
+
};
|
|
6095
|
+
var IbcEnabledCosmosChain = cosmosChainsByKind.ibcEnabled;
|
|
6096
|
+
var VaultBasedCosmosChain = cosmosChainsByKind.vaultBased;
|
|
6097
|
+
var CosmosChain = {
|
|
6098
|
+
...IbcEnabledCosmosChain,
|
|
6099
|
+
...VaultBasedCosmosChain
|
|
6100
|
+
};
|
|
6101
|
+
var OtherChain;
|
|
6102
|
+
(function(OtherChain2) {
|
|
6103
|
+
OtherChain2["Sui"] = "Sui";
|
|
6104
|
+
OtherChain2["Solana"] = "Solana";
|
|
6105
|
+
OtherChain2["Polkadot"] = "Polkadot";
|
|
6106
|
+
OtherChain2["Bittensor"] = "Bittensor";
|
|
6107
|
+
OtherChain2["Ton"] = "Ton";
|
|
6108
|
+
OtherChain2["Ripple"] = "Ripple";
|
|
6109
|
+
OtherChain2["Tron"] = "Tron";
|
|
6110
|
+
OtherChain2["Cardano"] = "Cardano";
|
|
6111
|
+
OtherChain2["QBTC"] = "QBTC";
|
|
6112
|
+
})(OtherChain || (OtherChain = {}));
|
|
6113
|
+
var Chain = {
|
|
6114
|
+
...EvmChain,
|
|
6115
|
+
...UtxoChain,
|
|
6116
|
+
...CosmosChain,
|
|
6117
|
+
...OtherChain
|
|
6118
|
+
};
|
|
6119
|
+
var UtxoBasedChain = [...Object.values(UtxoChain), OtherChain.Cardano];
|
|
6120
|
+
var defaultChains = [Chain.Bitcoin, Chain.Ethereum, Chain.THORChain, Chain.Solana, Chain.BSC];
|
|
6121
|
+
|
|
6122
|
+
// ../../packages/core/chain/dist/ChainKind.js
|
|
6123
|
+
var chainKindRecord = {
|
|
6124
|
+
[EvmChain.Arbitrum]: "evm",
|
|
6125
|
+
[EvmChain.Avalanche]: "evm",
|
|
6126
|
+
[EvmChain.Base]: "evm",
|
|
6127
|
+
[EvmChain.CronosChain]: "evm",
|
|
6128
|
+
[EvmChain.BSC]: "evm",
|
|
6129
|
+
[EvmChain.Blast]: "evm",
|
|
6130
|
+
[EvmChain.Ethereum]: "evm",
|
|
6131
|
+
[EvmChain.Optimism]: "evm",
|
|
6132
|
+
[EvmChain.Polygon]: "evm",
|
|
6133
|
+
[EvmChain.Zksync]: "evm",
|
|
6134
|
+
[EvmChain.Mantle]: "evm",
|
|
6135
|
+
[EvmChain.Hyperliquid]: "evm",
|
|
6136
|
+
[EvmChain.Sei]: "evm",
|
|
6137
|
+
[UtxoChain.Bitcoin]: "utxo",
|
|
6138
|
+
[UtxoChain.BitcoinCash]: "utxo",
|
|
6139
|
+
[UtxoChain.Litecoin]: "utxo",
|
|
6140
|
+
[UtxoChain.Dogecoin]: "utxo",
|
|
6141
|
+
[UtxoChain.Dash]: "utxo",
|
|
6142
|
+
[UtxoChain.Zcash]: "utxo",
|
|
6143
|
+
[CosmosChain.THORChain]: "cosmos",
|
|
6144
|
+
[CosmosChain.Cosmos]: "cosmos",
|
|
6145
|
+
[CosmosChain.Osmosis]: "cosmos",
|
|
6146
|
+
[CosmosChain.MayaChain]: "cosmos",
|
|
6147
|
+
[CosmosChain.Dydx]: "cosmos",
|
|
6148
|
+
[CosmosChain.Kujira]: "cosmos",
|
|
6149
|
+
[CosmosChain.Terra]: "cosmos",
|
|
6150
|
+
[CosmosChain.TerraClassic]: "cosmos",
|
|
6151
|
+
[CosmosChain.Noble]: "cosmos",
|
|
6152
|
+
[CosmosChain.Akash]: "cosmos",
|
|
6153
|
+
[OtherChain.Sui]: "sui",
|
|
6154
|
+
[OtherChain.Solana]: "solana",
|
|
6155
|
+
[OtherChain.Polkadot]: "polkadot",
|
|
6156
|
+
[OtherChain.Bittensor]: "bittensor",
|
|
6157
|
+
[OtherChain.Ton]: "ton",
|
|
6158
|
+
[OtherChain.Ripple]: "ripple",
|
|
6159
|
+
[OtherChain.Tron]: "tron",
|
|
6160
|
+
[OtherChain.Cardano]: "cardano",
|
|
6161
|
+
[OtherChain.QBTC]: "qbtc"
|
|
6162
|
+
};
|
|
6163
|
+
function getChainKind(chain) {
|
|
6164
|
+
return chainKindRecord[chain];
|
|
6165
|
+
}
|
|
6166
|
+
|
|
5988
6167
|
// src/agent/broadcastJournal.ts
|
|
5989
6168
|
import { createHash } from "node:crypto";
|
|
5990
6169
|
import {
|
|
@@ -6019,6 +6198,10 @@ var AgentErrorCode = /* @__PURE__ */ ((AgentErrorCode3) => {
|
|
|
6019
6198
|
AgentErrorCode3["TRANSACTION_FAILED"] = "TRANSACTION_FAILED";
|
|
6020
6199
|
AgentErrorCode3["SIGNING_FAILED"] = "SIGNING_FAILED";
|
|
6021
6200
|
AgentErrorCode3["ACK_FAILED"] = "ACK_FAILED";
|
|
6201
|
+
AgentErrorCode3["BROADCAST_COMMITTED"] = "BROADCAST_COMMITTED";
|
|
6202
|
+
AgentErrorCode3["AGENT_TURN_BLOCKED"] = "AGENT_TURN_BLOCKED";
|
|
6203
|
+
AgentErrorCode3["AGENT_TURN_REFUSAL"] = "AGENT_TURN_REFUSAL";
|
|
6204
|
+
AgentErrorCode3["AGENT_TURN_ERROR"] = "AGENT_TURN_ERROR";
|
|
6022
6205
|
AgentErrorCode3["DUPLICATE_BROADCAST"] = "DUPLICATE_BROADCAST";
|
|
6023
6206
|
AgentErrorCode3["SESSION_NOT_INITIALIZED"] = "SESSION_NOT_INITIALIZED";
|
|
6024
6207
|
AgentErrorCode3["LOOP_DEPTH_EXCEEDED"] = "LOOP_DEPTH_EXCEEDED";
|
|
@@ -6138,6 +6321,14 @@ function agentErrorCodeToExitCode(code) {
|
|
|
6138
6321
|
switch (code) {
|
|
6139
6322
|
case "ACK_FAILED" /* ACK_FAILED */:
|
|
6140
6323
|
return 8 /* ACK_FAILED */;
|
|
6324
|
+
case "BROADCAST_COMMITTED" /* BROADCAST_COMMITTED */:
|
|
6325
|
+
return 13 /* BROADCAST_COMMITTED */;
|
|
6326
|
+
case "AGENT_TURN_BLOCKED" /* AGENT_TURN_BLOCKED */:
|
|
6327
|
+
return 10 /* AGENT_TURN_BLOCKED */;
|
|
6328
|
+
case "AGENT_TURN_REFUSAL" /* AGENT_TURN_REFUSAL */:
|
|
6329
|
+
return 11 /* AGENT_TURN_REFUSAL */;
|
|
6330
|
+
case "AGENT_TURN_ERROR" /* AGENT_TURN_ERROR */:
|
|
6331
|
+
return 1 /* USAGE */;
|
|
6141
6332
|
case "AUTH_FAILED" /* AUTH_FAILED */:
|
|
6142
6333
|
case "VAULT_LOCKED" /* VAULT_LOCKED */:
|
|
6143
6334
|
case "PASSWORD_REQUIRED" /* PASSWORD_REQUIRED */:
|
|
@@ -6157,8 +6348,9 @@ function agentErrorCodeToExitCode(code) {
|
|
|
6157
6348
|
case "ACTION_NOT_IMPLEMENTED" /* ACTION_NOT_IMPLEMENTED */:
|
|
6158
6349
|
case "TOOL_UNSUPPORTED" /* TOOL_UNSUPPORTED */:
|
|
6159
6350
|
case "SESSION_NOT_INITIALIZED" /* SESSION_NOT_INITIALIZED */:
|
|
6160
|
-
case "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */:
|
|
6161
6351
|
return 1 /* USAGE */;
|
|
6352
|
+
case "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */:
|
|
6353
|
+
return 12 /* CONFIRMATION_REQUIRED */;
|
|
6162
6354
|
case "SIGNING_FAILED" /* SIGNING_FAILED */:
|
|
6163
6355
|
case "LOOP_DEPTH_EXCEEDED" /* LOOP_DEPTH_EXCEEDED */:
|
|
6164
6356
|
case "UNKNOWN_ERROR" /* UNKNOWN_ERROR */:
|
|
@@ -6214,8 +6406,9 @@ function journalPath() {
|
|
|
6214
6406
|
const dir = process.env.VULTISIG_CONFIG_DIR && process.env.VULTISIG_CONFIG_DIR.trim() ? process.env.VULTISIG_CONFIG_DIR : join(homedir(), ".vultisig");
|
|
6215
6407
|
return join(dir, "broadcasts.jsonl");
|
|
6216
6408
|
}
|
|
6217
|
-
function normalize(v) {
|
|
6218
|
-
|
|
6409
|
+
function normalize(v, canonicalizeEmptyCalldata = false) {
|
|
6410
|
+
const normalized = (v ?? "").trim().toLowerCase();
|
|
6411
|
+
return canonicalizeEmptyCalldata && normalized === "0x" ? "" : normalized;
|
|
6219
6412
|
}
|
|
6220
6413
|
function computeFingerprint(intent) {
|
|
6221
6414
|
const canonical = [
|
|
@@ -6223,7 +6416,10 @@ function computeFingerprint(intent) {
|
|
|
6223
6416
|
normalize(intent.chain),
|
|
6224
6417
|
normalize(intent.to),
|
|
6225
6418
|
normalize(intent.value),
|
|
6226
|
-
|
|
6419
|
+
// Fold empty `"0x"` calldata to `""` for EVM only. For a memo (the default)
|
|
6420
|
+
// `"0x"` is a real, distinct value and must survive — collapsing it would
|
|
6421
|
+
// falsely dedupe two different memo-chain sends (PR #1259).
|
|
6422
|
+
normalize(intent.data, intent.dataIsEvmCalldata === true),
|
|
6227
6423
|
normalize(intent.asset)
|
|
6228
6424
|
].join("|");
|
|
6229
6425
|
return createHash("sha256").update(canonical).digest("hex").slice(0, 32);
|
|
@@ -6528,7 +6724,17 @@ function buildSendBroadcastIntent(vault, chain, keysignPayload, opts = {}) {
|
|
|
6528
6724
|
chain: chain.toString(),
|
|
6529
6725
|
to: keysignPayload.toAddress || void 0,
|
|
6530
6726
|
value: opts.isMax ? MAX_AMOUNT_SENTINEL : keysignPayload.toAmount || void 0,
|
|
6727
|
+
// `data` is the user-supplied memo. On an EVM chain the signer encodes a
|
|
6728
|
+
// `0x`-prefixed memo AS calldata (memoToTxData), so a memo of `"0x"` is empty
|
|
6729
|
+
// calldata — functionally identical to a no-memo native transfer, and it must
|
|
6730
|
+
// fold to `""` to cross-path dedupe with the agent path (which fingerprints the
|
|
6731
|
+
// same send as empty `"0x"` calldata). On a memo-routed chain (THORChain,
|
|
6732
|
+
// Cosmos, UTXO) the memo is a real distinct value and must NOT fold (PR #1259).
|
|
6733
|
+
// So the fold is gated on chain kind — the single "is this data EVM calldata?"
|
|
6734
|
+
// authority — not hardcoded, which keeps a new chain family from silently
|
|
6735
|
+
// reintroducing the memo collision.
|
|
6531
6736
|
data: keysignPayload.memo || void 0,
|
|
6737
|
+
dataIsEvmCalldata: getChainKind(chain) === "evm",
|
|
6532
6738
|
asset: isNative ? void 0 : coin?.contractAddress || coin?.ticker || void 0
|
|
6533
6739
|
};
|
|
6534
6740
|
}
|
|
@@ -6794,11 +7000,37 @@ Use --add <contractAddress> to add or --remove <tokenId> to remove`));
|
|
|
6794
7000
|
}
|
|
6795
7001
|
}
|
|
6796
7002
|
|
|
7003
|
+
// ../../packages/core/chain/dist/chains/ripple/address.js
|
|
7004
|
+
import { classicAddressToXAddress, isValidXAddress, xAddressToClassicAddress } from "ripple-address-codec";
|
|
7005
|
+
var assertSupportedTag = (tag) => {
|
|
7006
|
+
if (tag === false)
|
|
7007
|
+
return void 0;
|
|
7008
|
+
return tag;
|
|
7009
|
+
};
|
|
7010
|
+
var decodeRippleXAddress = (address) => {
|
|
7011
|
+
const value = address.trim();
|
|
7012
|
+
if (!isValidXAddress(value))
|
|
7013
|
+
throw new Error("Invalid XRP X-address");
|
|
7014
|
+
const decoded = xAddressToClassicAddress(value);
|
|
7015
|
+
if (decoded.test)
|
|
7016
|
+
throw new Error("XRP testnet X-addresses are not supported");
|
|
7017
|
+
return {
|
|
7018
|
+
address: decoded.classicAddress,
|
|
7019
|
+
destinationTag: assertSupportedTag(decoded.tag)
|
|
7020
|
+
};
|
|
7021
|
+
};
|
|
7022
|
+
var normalizeRippleDestination = (address) => {
|
|
7023
|
+
const value = address.trim();
|
|
7024
|
+
if (value.startsWith("X") || value.startsWith("T"))
|
|
7025
|
+
return decodeRippleXAddress(value);
|
|
7026
|
+
return { address: value };
|
|
7027
|
+
};
|
|
7028
|
+
|
|
6797
7029
|
// src/commands/transaction.ts
|
|
6798
|
-
import { Chain, Vultisig as Vultisig2 } from "@vultisig/sdk";
|
|
7030
|
+
import { Chain as Chain2, Vultisig as Vultisig2 } from "@vultisig/sdk";
|
|
6799
7031
|
async function executeSend(ctx2, params) {
|
|
6800
7032
|
const vault = await ctx2.ensureActiveVault();
|
|
6801
|
-
if (!Object.values(
|
|
7033
|
+
if (!Object.values(Chain2).includes(params.chain)) {
|
|
6802
7034
|
throw new Error(`Invalid chain: ${params.chain}`);
|
|
6803
7035
|
}
|
|
6804
7036
|
const isMax = params.amount === "max";
|
|
@@ -6814,6 +7046,14 @@ async function sendTransaction(vault, params) {
|
|
|
6814
7046
|
"Pass --yes to confirm, or --dry-run to preview without signing."
|
|
6815
7047
|
);
|
|
6816
7048
|
}
|
|
7049
|
+
const rippleDestination = params.chain === Chain2.Ripple ? normalizeRippleDestination(params.to) : { address: params.to };
|
|
7050
|
+
const to = rippleDestination.address;
|
|
7051
|
+
if (params.destinationTag !== void 0 && rippleDestination.destinationTag !== void 0 && params.destinationTag !== rippleDestination.destinationTag) {
|
|
7052
|
+
throw new Error(
|
|
7053
|
+
`Conflicting XRP destination tags: --destination-tag=${params.destinationTag} does not match the tag embedded in the X-address (${rippleDestination.destinationTag})`
|
|
7054
|
+
);
|
|
7055
|
+
}
|
|
7056
|
+
const destinationTag = params.destinationTag ?? rippleDestination.destinationTag;
|
|
6817
7057
|
const prepareSpinner = createSpinner("Preparing transaction...");
|
|
6818
7058
|
const dryResult = await vault.send({
|
|
6819
7059
|
chain: params.chain,
|
|
@@ -6821,6 +7061,7 @@ async function sendTransaction(vault, params) {
|
|
|
6821
7061
|
amount: params.amount,
|
|
6822
7062
|
symbol: params.tokenId,
|
|
6823
7063
|
memo: params.memo,
|
|
7064
|
+
destinationTag,
|
|
6824
7065
|
dryRun: true
|
|
6825
7066
|
});
|
|
6826
7067
|
prepareSpinner.succeed("Transaction prepared");
|
|
@@ -6831,10 +7072,11 @@ async function sendTransaction(vault, params) {
|
|
|
6831
7072
|
const result = {
|
|
6832
7073
|
dryRun: true,
|
|
6833
7074
|
chain: params.chain,
|
|
6834
|
-
to
|
|
7075
|
+
to,
|
|
6835
7076
|
amount: params.amount,
|
|
6836
7077
|
symbol: balance2.symbol,
|
|
6837
|
-
balance: balance2.formattedAmount
|
|
7078
|
+
balance: balance2.formattedAmount,
|
|
7079
|
+
destinationTag
|
|
6838
7080
|
};
|
|
6839
7081
|
if (hasInsufficientBalance) {
|
|
6840
7082
|
result.warning = `Insufficient balance: you have ${balance2.formattedAmount} ${balance2.symbol}`;
|
|
@@ -6847,6 +7089,7 @@ Dry-run preview:`);
|
|
|
6847
7089
|
info(` Chain: ${result.chain}`);
|
|
6848
7090
|
info(` To: ${result.to}`);
|
|
6849
7091
|
info(` Amount: ${result.amount} ${result.symbol}`);
|
|
7092
|
+
if (result.destinationTag !== void 0) info(` Destination tag: ${result.destinationTag}`);
|
|
6850
7093
|
info(` Fee: ${dryResult.fee} ${result.symbol}`);
|
|
6851
7094
|
info(` Balance: ${result.balance} ${result.symbol}`);
|
|
6852
7095
|
if (result.warning) warn(` Warning: ${result.warning}`);
|
|
@@ -6862,7 +7105,16 @@ Dry-run preview:`);
|
|
|
6862
7105
|
const balance = await vault.balance(params.chain, params.tokenId);
|
|
6863
7106
|
if (!isJsonOutput()) {
|
|
6864
7107
|
const address = await vault.address(params.chain);
|
|
6865
|
-
displayTransactionPreview(
|
|
7108
|
+
displayTransactionPreview(
|
|
7109
|
+
address,
|
|
7110
|
+
to,
|
|
7111
|
+
dryResult.total,
|
|
7112
|
+
balance.symbol,
|
|
7113
|
+
params.chain,
|
|
7114
|
+
params.memo,
|
|
7115
|
+
destinationTag,
|
|
7116
|
+
gas
|
|
7117
|
+
);
|
|
6866
7118
|
}
|
|
6867
7119
|
if (!params.yes) {
|
|
6868
7120
|
const confirmed = await confirmTransaction();
|
|
@@ -6889,7 +7141,8 @@ Dry-run preview:`);
|
|
|
6889
7141
|
to: params.to,
|
|
6890
7142
|
amount: params.amount,
|
|
6891
7143
|
symbol: params.tokenId,
|
|
6892
|
-
memo: params.memo
|
|
7144
|
+
memo: params.memo,
|
|
7145
|
+
destinationTag
|
|
6893
7146
|
});
|
|
6894
7147
|
if (result.dryRun) throw new Error("unreachable");
|
|
6895
7148
|
return result;
|
|
@@ -6916,7 +7169,7 @@ Dry-run preview:`);
|
|
|
6916
7169
|
|
|
6917
7170
|
// src/commands/execute.ts
|
|
6918
7171
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
6919
|
-
import { Vultisig as Vultisig3 } from "@vultisig/sdk";
|
|
7172
|
+
import { buildCosmosWasmExecuteMsg, Vultisig as Vultisig3 } from "@vultisig/sdk";
|
|
6920
7173
|
var COSMOS_CHAIN_CONFIG = {
|
|
6921
7174
|
THORChain: {
|
|
6922
7175
|
chainId: "thorchain-1",
|
|
@@ -6948,7 +7201,9 @@ async function executeExecute(ctx2, params) {
|
|
|
6948
7201
|
const chainConfig = COSMOS_CHAIN_CONFIG[params.chain];
|
|
6949
7202
|
if (!chainConfig) {
|
|
6950
7203
|
throw new Error(
|
|
6951
|
-
`Chain ${params.chain} does not support CosmWasm execute. Supported chains: ${Object.keys(
|
|
7204
|
+
`Chain ${params.chain} does not support CosmWasm execute. Supported chains: ${Object.keys(
|
|
7205
|
+
COSMOS_CHAIN_CONFIG
|
|
7206
|
+
).join(", ")}`
|
|
6952
7207
|
);
|
|
6953
7208
|
}
|
|
6954
7209
|
let msg;
|
|
@@ -7069,15 +7324,12 @@ Or use this URL: ${qrPayload}
|
|
|
7069
7324
|
decimals: chainConfig.decimals,
|
|
7070
7325
|
ticker: chainConfig.denom.toUpperCase()
|
|
7071
7326
|
};
|
|
7072
|
-
const executeContractMsg = {
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
funds: funds.map((f) => ({ denom: f.denom, amount: f.amount }))
|
|
7079
|
-
})
|
|
7080
|
-
};
|
|
7327
|
+
const executeContractMsg = buildCosmosWasmExecuteMsg({
|
|
7328
|
+
sender: address,
|
|
7329
|
+
contract: params.contract,
|
|
7330
|
+
msg,
|
|
7331
|
+
funds
|
|
7332
|
+
});
|
|
7081
7333
|
const fee = {
|
|
7082
7334
|
amount: [{ denom: chainConfig.denom, amount: "0" }],
|
|
7083
7335
|
gas: chainConfig.gasLimit
|
|
@@ -7128,10 +7380,10 @@ Or use this URL: ${qrPayload}
|
|
|
7128
7380
|
|
|
7129
7381
|
// src/commands/sign.ts
|
|
7130
7382
|
var import_qrcode_terminal2 = __toESM(require_main(), 1);
|
|
7131
|
-
import { Chain as
|
|
7383
|
+
import { Chain as Chain4 } from "@vultisig/sdk";
|
|
7132
7384
|
async function executeSignBytes(ctx2, params) {
|
|
7133
7385
|
const vault = await ctx2.ensureActiveVault();
|
|
7134
|
-
if (!Object.values(
|
|
7386
|
+
if (!Object.values(Chain4).includes(params.chain)) {
|
|
7135
7387
|
throw new Error(`Invalid chain: ${params.chain}`);
|
|
7136
7388
|
}
|
|
7137
7389
|
return signBytes(vault, params);
|
|
@@ -7211,10 +7463,10 @@ Or use this URL: ${qrPayload}
|
|
|
7211
7463
|
}
|
|
7212
7464
|
|
|
7213
7465
|
// src/commands/broadcast.ts
|
|
7214
|
-
import { Chain as
|
|
7466
|
+
import { Chain as Chain5, Vultisig as Vultisig4 } from "@vultisig/sdk";
|
|
7215
7467
|
async function executeBroadcast(ctx2, params) {
|
|
7216
7468
|
const vault = await ctx2.ensureActiveVault();
|
|
7217
|
-
if (!Object.values(
|
|
7469
|
+
if (!Object.values(Chain5).includes(params.chain)) {
|
|
7218
7470
|
throw new Error(`Invalid chain: ${params.chain}`);
|
|
7219
7471
|
}
|
|
7220
7472
|
const broadcastSpinner = createSpinner("Broadcasting transaction...");
|
|
@@ -7243,7 +7495,21 @@ async function executeBroadcast(ctx2, params) {
|
|
|
7243
7495
|
}
|
|
7244
7496
|
|
|
7245
7497
|
// src/commands/tx-status.ts
|
|
7246
|
-
import { Chain as
|
|
7498
|
+
import { Chain as Chain6, isValidTxHash, Vultisig as Vultisig5 } from "@vultisig/sdk";
|
|
7499
|
+
function resolveTxStatusParams(params) {
|
|
7500
|
+
if (!Object.values(Chain6).includes(params.chain)) {
|
|
7501
|
+
throw new InvalidInputError(`Invalid chain: ${params.chain}`);
|
|
7502
|
+
}
|
|
7503
|
+
if (!isValidTxHash(params.chain, params.txHash)) {
|
|
7504
|
+
throw new InvalidTxHashError(
|
|
7505
|
+
`Invalid transaction hash for ${params.chain}: "${params.txHash}"`,
|
|
7506
|
+
"Check the hash \u2014 it must match the expected format for the chain.",
|
|
7507
|
+
void 0,
|
|
7508
|
+
{ chain: params.chain, txHash: params.txHash, status: "invalid_hash" }
|
|
7509
|
+
);
|
|
7510
|
+
}
|
|
7511
|
+
return params;
|
|
7512
|
+
}
|
|
7247
7513
|
var POLL_INTERVAL_MS = 5e3;
|
|
7248
7514
|
var DEFAULT_TIMEOUT_SEC = 120;
|
|
7249
7515
|
var isTerminal = (status) => status === "success" || status === "error";
|
|
@@ -7251,21 +7517,12 @@ function resolveTimeoutMs(timeoutSec) {
|
|
|
7251
7517
|
if (typeof timeoutSec !== "number" || !Number.isFinite(timeoutSec)) {
|
|
7252
7518
|
return DEFAULT_TIMEOUT_SEC * 1e3;
|
|
7253
7519
|
}
|
|
7254
|
-
|
|
7520
|
+
const ms = Math.max(0, timeoutSec) * 1e3;
|
|
7521
|
+
return Number.isFinite(ms) ? ms : Number.MAX_SAFE_INTEGER;
|
|
7255
7522
|
}
|
|
7256
7523
|
async function executeTxStatus(ctx2, params, opts = {}) {
|
|
7524
|
+
resolveTxStatusParams(params);
|
|
7257
7525
|
const vault = await ctx2.ensureActiveVault();
|
|
7258
|
-
if (!Object.values(Chain5).includes(params.chain)) {
|
|
7259
|
-
throw new InvalidInputError(`Invalid chain: ${params.chain}`);
|
|
7260
|
-
}
|
|
7261
|
-
if (!isValidTxHash(params.chain, params.txHash)) {
|
|
7262
|
-
throw new InvalidInputError(
|
|
7263
|
-
`Invalid transaction hash for ${params.chain}: "${params.txHash}"`,
|
|
7264
|
-
"Check the hash \u2014 it must match the expected format for the chain.",
|
|
7265
|
-
void 0,
|
|
7266
|
-
{ chain: params.chain, txHash: params.txHash }
|
|
7267
|
-
);
|
|
7268
|
-
}
|
|
7269
7526
|
const pollIntervalMs = opts.pollIntervalMs ?? POLL_INTERVAL_MS;
|
|
7270
7527
|
const spinner = createSpinner("Checking transaction status...");
|
|
7271
7528
|
try {
|
|
@@ -7286,7 +7543,12 @@ async function executeTxStatus(ctx2, params, opts = {}) {
|
|
|
7286
7543
|
result = await vault.getTxStatus({ chain: params.chain, txHash: params.txHash });
|
|
7287
7544
|
}
|
|
7288
7545
|
}
|
|
7289
|
-
|
|
7546
|
+
if (result.status === "success") {
|
|
7547
|
+
recordResolution(params.txHash, "confirmed");
|
|
7548
|
+
} else if (result.status === "error") {
|
|
7549
|
+
recordResolution(params.txHash, "failed");
|
|
7550
|
+
}
|
|
7551
|
+
spinner.succeed(`Transaction status: ${toCliStatus(result.status)}`);
|
|
7290
7552
|
displayResult(params.chain, params.txHash, result);
|
|
7291
7553
|
return result;
|
|
7292
7554
|
} catch (error2) {
|
|
@@ -7316,11 +7578,12 @@ function giveUpError(params, result, waitedMs) {
|
|
|
7316
7578
|
);
|
|
7317
7579
|
}
|
|
7318
7580
|
function displayResult(chain, txHash, result) {
|
|
7581
|
+
const status = toCliStatus(result.status);
|
|
7319
7582
|
if (isJsonOutput()) {
|
|
7320
7583
|
outputJson({
|
|
7321
7584
|
chain,
|
|
7322
7585
|
txHash,
|
|
7323
|
-
status
|
|
7586
|
+
status,
|
|
7324
7587
|
receipt: result.receipt ? {
|
|
7325
7588
|
feeAmount: result.receipt.feeAmount.toString(),
|
|
7326
7589
|
feeDecimals: result.receipt.feeDecimals,
|
|
@@ -7329,7 +7592,7 @@ function displayResult(chain, txHash, result) {
|
|
|
7329
7592
|
explorerUrl: Vultisig5.getTxExplorerUrl(chain, txHash)
|
|
7330
7593
|
});
|
|
7331
7594
|
} else {
|
|
7332
|
-
printResult(`Status: ${
|
|
7595
|
+
printResult(`Status: ${status}`);
|
|
7333
7596
|
if (result.receipt) {
|
|
7334
7597
|
const fee = formatFee(result.receipt.feeAmount, result.receipt.feeDecimals);
|
|
7335
7598
|
printResult(`Fee: ${fee} ${result.receipt.feeTicker}`);
|
|
@@ -7337,6 +7600,11 @@ function displayResult(chain, txHash, result) {
|
|
|
7337
7600
|
printResult(`Explorer: ${Vultisig5.getTxExplorerUrl(chain, txHash)}`);
|
|
7338
7601
|
}
|
|
7339
7602
|
}
|
|
7603
|
+
function toCliStatus(status) {
|
|
7604
|
+
if (status === "success") return "confirmed";
|
|
7605
|
+
if (status === "error") return "failed";
|
|
7606
|
+
return status;
|
|
7607
|
+
}
|
|
7340
7608
|
function formatFee(amount, decimals) {
|
|
7341
7609
|
const str2 = amount.toString().padStart(decimals + 1, "0");
|
|
7342
7610
|
const whole = str2.slice(0, -decimals) || "0";
|
|
@@ -8394,7 +8662,7 @@ async function executeSwap(ctx2, options) {
|
|
|
8394
8662
|
}
|
|
8395
8663
|
|
|
8396
8664
|
// src/commands/settings.ts
|
|
8397
|
-
import { Chain as
|
|
8665
|
+
import { Chain as Chain7, fiatCurrencies as fiatCurrencies2, fiatCurrencyNameRecord as fiatCurrencyNameRecord3 } from "@vultisig/sdk";
|
|
8398
8666
|
import chalk6 from "chalk";
|
|
8399
8667
|
async function executeCurrency(ctx2, newCurrency) {
|
|
8400
8668
|
const vault = await ctx2.ensureActiveVault();
|
|
@@ -8461,7 +8729,7 @@ async function executeAddressBook(ctx2, options = {}) {
|
|
|
8461
8729
|
type: "select",
|
|
8462
8730
|
name: "chain",
|
|
8463
8731
|
message: "Select chain:",
|
|
8464
|
-
choices: Object.values(
|
|
8732
|
+
choices: Object.values(Chain7)
|
|
8465
8733
|
});
|
|
8466
8734
|
}
|
|
8467
8735
|
if (!address) {
|
|
@@ -9340,11 +9608,11 @@ var genKeccak = (suffix, blockLen, outputLen, info2 = {}) => createHasher(() =>
|
|
|
9340
9608
|
var keccak_256 = /* @__PURE__ */ genKeccak(1, 136, 32);
|
|
9341
9609
|
|
|
9342
9610
|
// src/agent/auth.ts
|
|
9343
|
-
import { Chain as
|
|
9611
|
+
import { Chain as Chain8 } from "@vultisig/sdk";
|
|
9344
9612
|
async function authenticateVault(client, vault, password, maxAttempts = 3) {
|
|
9345
9613
|
const publicKey = vault.publicKeys.ecdsa;
|
|
9346
9614
|
const chainCode = vault.hexChainCode;
|
|
9347
|
-
const ethAddress = await vault.address(
|
|
9615
|
+
const ethAddress = await vault.address(Chain8.Ethereum);
|
|
9348
9616
|
const nonce = "0x" + randomBytes(16).toString("hex");
|
|
9349
9617
|
const expiresAt = new Date(Date.now() + 15 * 60 * 1e3).toISOString();
|
|
9350
9618
|
const authMessage = JSON.stringify({
|
|
@@ -9361,7 +9629,7 @@ async function authenticateVault(client, vault, password, maxAttempts = 3) {
|
|
|
9361
9629
|
process.stderr.write(` Retry ${attempt}/${maxAttempts}...
|
|
9362
9630
|
`);
|
|
9363
9631
|
}
|
|
9364
|
-
const signature = await vault.signBytes({ data: Buffer.from(messageHash), chain:
|
|
9632
|
+
const signature = await vault.signBytes({ data: Buffer.from(messageHash), chain: Chain8.Ethereum }, {});
|
|
9365
9633
|
const sigHex = formatSignature65(signature.signature, signature.recovery ?? 0);
|
|
9366
9634
|
const authResponse = await client.authenticate({
|
|
9367
9635
|
public_key: publicKey,
|
|
@@ -9592,380 +9860,19 @@ function renderBalanceSummaryCard(card) {
|
|
|
9592
9860
|
return lines.join("\n");
|
|
9593
9861
|
}
|
|
9594
9862
|
|
|
9595
|
-
//
|
|
9596
|
-
|
|
9597
|
-
Arbitrum: "Arbitrum",
|
|
9598
|
-
Base: "Base",
|
|
9599
|
-
Blast: "Blast",
|
|
9600
|
-
Optimism: "Optimism",
|
|
9601
|
-
Zksync: "Zksync",
|
|
9602
|
-
Mantle: "Mantle"
|
|
9603
|
-
};
|
|
9604
|
-
var EvmChain = {
|
|
9605
|
-
...EthereumL2Chain,
|
|
9606
|
-
Avalanche: "Avalanche",
|
|
9607
|
-
CronosChain: "CronosChain",
|
|
9608
|
-
BSC: "BSC",
|
|
9609
|
-
Ethereum: "Ethereum",
|
|
9610
|
-
Polygon: "Polygon",
|
|
9611
|
-
Hyperliquid: "Hyperliquid",
|
|
9612
|
-
Sei: "Sei"
|
|
9613
|
-
};
|
|
9614
|
-
var UtxoChain;
|
|
9615
|
-
(function(UtxoChain2) {
|
|
9616
|
-
UtxoChain2["Bitcoin"] = "Bitcoin";
|
|
9617
|
-
UtxoChain2["BitcoinCash"] = "Bitcoin-Cash";
|
|
9618
|
-
UtxoChain2["Litecoin"] = "Litecoin";
|
|
9619
|
-
UtxoChain2["Dogecoin"] = "Dogecoin";
|
|
9620
|
-
UtxoChain2["Dash"] = "Dash";
|
|
9621
|
-
UtxoChain2["Zcash"] = "Zcash";
|
|
9622
|
-
})(UtxoChain || (UtxoChain = {}));
|
|
9623
|
-
var cosmosChainsByKind = {
|
|
9624
|
-
ibcEnabled: {
|
|
9625
|
-
Cosmos: "Cosmos",
|
|
9626
|
-
Osmosis: "Osmosis",
|
|
9627
|
-
Dydx: "Dydx",
|
|
9628
|
-
Kujira: "Kujira",
|
|
9629
|
-
Terra: "Terra",
|
|
9630
|
-
TerraClassic: "TerraClassic",
|
|
9631
|
-
Noble: "Noble",
|
|
9632
|
-
Akash: "Akash"
|
|
9633
|
-
},
|
|
9634
|
-
vaultBased: {
|
|
9635
|
-
THORChain: "THORChain",
|
|
9636
|
-
MayaChain: "MayaChain"
|
|
9637
|
-
}
|
|
9638
|
-
};
|
|
9639
|
-
var IbcEnabledCosmosChain = cosmosChainsByKind.ibcEnabled;
|
|
9640
|
-
var VaultBasedCosmosChain = cosmosChainsByKind.vaultBased;
|
|
9641
|
-
var CosmosChain = {
|
|
9642
|
-
...IbcEnabledCosmosChain,
|
|
9643
|
-
...VaultBasedCosmosChain
|
|
9644
|
-
};
|
|
9645
|
-
var OtherChain;
|
|
9646
|
-
(function(OtherChain2) {
|
|
9647
|
-
OtherChain2["Sui"] = "Sui";
|
|
9648
|
-
OtherChain2["Solana"] = "Solana";
|
|
9649
|
-
OtherChain2["Polkadot"] = "Polkadot";
|
|
9650
|
-
OtherChain2["Bittensor"] = "Bittensor";
|
|
9651
|
-
OtherChain2["Ton"] = "Ton";
|
|
9652
|
-
OtherChain2["Ripple"] = "Ripple";
|
|
9653
|
-
OtherChain2["Tron"] = "Tron";
|
|
9654
|
-
OtherChain2["Cardano"] = "Cardano";
|
|
9655
|
-
OtherChain2["QBTC"] = "QBTC";
|
|
9656
|
-
})(OtherChain || (OtherChain = {}));
|
|
9657
|
-
var Chain8 = {
|
|
9658
|
-
...EvmChain,
|
|
9659
|
-
...UtxoChain,
|
|
9660
|
-
...CosmosChain,
|
|
9661
|
-
...OtherChain
|
|
9662
|
-
};
|
|
9663
|
-
var UtxoBasedChain = [...Object.values(UtxoChain), OtherChain.Cardano];
|
|
9664
|
-
var defaultChains = [Chain8.Bitcoin, Chain8.Ethereum, Chain8.THORChain, Chain8.Solana, Chain8.BSC];
|
|
9665
|
-
|
|
9666
|
-
// ../../packages/core/chain/dist/ChainKind.js
|
|
9667
|
-
var chainKindRecord = {
|
|
9668
|
-
[EvmChain.Arbitrum]: "evm",
|
|
9669
|
-
[EvmChain.Avalanche]: "evm",
|
|
9670
|
-
[EvmChain.Base]: "evm",
|
|
9671
|
-
[EvmChain.CronosChain]: "evm",
|
|
9672
|
-
[EvmChain.BSC]: "evm",
|
|
9673
|
-
[EvmChain.Blast]: "evm",
|
|
9674
|
-
[EvmChain.Ethereum]: "evm",
|
|
9675
|
-
[EvmChain.Optimism]: "evm",
|
|
9676
|
-
[EvmChain.Polygon]: "evm",
|
|
9677
|
-
[EvmChain.Zksync]: "evm",
|
|
9678
|
-
[EvmChain.Mantle]: "evm",
|
|
9679
|
-
[EvmChain.Hyperliquid]: "evm",
|
|
9680
|
-
[EvmChain.Sei]: "evm",
|
|
9681
|
-
[UtxoChain.Bitcoin]: "utxo",
|
|
9682
|
-
[UtxoChain.BitcoinCash]: "utxo",
|
|
9683
|
-
[UtxoChain.Litecoin]: "utxo",
|
|
9684
|
-
[UtxoChain.Dogecoin]: "utxo",
|
|
9685
|
-
[UtxoChain.Dash]: "utxo",
|
|
9686
|
-
[UtxoChain.Zcash]: "utxo",
|
|
9687
|
-
[CosmosChain.THORChain]: "cosmos",
|
|
9688
|
-
[CosmosChain.Cosmos]: "cosmos",
|
|
9689
|
-
[CosmosChain.Osmosis]: "cosmos",
|
|
9690
|
-
[CosmosChain.MayaChain]: "cosmos",
|
|
9691
|
-
[CosmosChain.Dydx]: "cosmos",
|
|
9692
|
-
[CosmosChain.Kujira]: "cosmos",
|
|
9693
|
-
[CosmosChain.Terra]: "cosmos",
|
|
9694
|
-
[CosmosChain.TerraClassic]: "cosmos",
|
|
9695
|
-
[CosmosChain.Noble]: "cosmos",
|
|
9696
|
-
[CosmosChain.Akash]: "cosmos",
|
|
9697
|
-
[OtherChain.Sui]: "sui",
|
|
9698
|
-
[OtherChain.Solana]: "solana",
|
|
9699
|
-
[OtherChain.Polkadot]: "polkadot",
|
|
9700
|
-
[OtherChain.Bittensor]: "bittensor",
|
|
9701
|
-
[OtherChain.Ton]: "ton",
|
|
9702
|
-
[OtherChain.Ripple]: "ripple",
|
|
9703
|
-
[OtherChain.Tron]: "tron",
|
|
9704
|
-
[OtherChain.Cardano]: "cardano",
|
|
9705
|
-
[OtherChain.QBTC]: "qbtc"
|
|
9706
|
-
};
|
|
9707
|
-
function getChainKind(chain) {
|
|
9708
|
-
return chainKindRecord[chain];
|
|
9709
|
-
}
|
|
9710
|
-
|
|
9711
|
-
// ../../packages/lib/utils/dist/record/recordMap.js
|
|
9712
|
-
function recordMap(record, fn) {
|
|
9713
|
-
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, fn(value, key)]));
|
|
9714
|
-
}
|
|
9715
|
-
|
|
9716
|
-
// ../../packages/lib/utils/dist/record/makeRecord/index.js
|
|
9717
|
-
var makeRecord = (keys, getValue) => {
|
|
9718
|
-
const record = {};
|
|
9719
|
-
keys.forEach((key, index) => {
|
|
9720
|
-
record[key] = getValue(key, index);
|
|
9721
|
-
});
|
|
9722
|
-
return record;
|
|
9723
|
-
};
|
|
9724
|
-
|
|
9725
|
-
// ../../packages/core/chain/dist/chains/cosmos/thor/kujira-merge/index.js
|
|
9726
|
-
var kujiraCoinsMigratedToThorChain = ["kuji", "rkuji", "fuzn", "nstk", "wink", "lvn"];
|
|
9727
|
-
var kujiraCoinsMigratedToThorChainMetadata = {
|
|
9728
|
-
kuji: {
|
|
9729
|
-
ticker: "KUJI",
|
|
9730
|
-
logo: "kuji",
|
|
9731
|
-
priceProviderId: "kujira"
|
|
9732
|
-
},
|
|
9733
|
-
rkuji: {
|
|
9734
|
-
ticker: "rKUJI",
|
|
9735
|
-
logo: "rkuji.png",
|
|
9736
|
-
priceProviderId: "kujira"
|
|
9737
|
-
},
|
|
9738
|
-
fuzn: {
|
|
9739
|
-
ticker: "FUZN",
|
|
9740
|
-
logo: "fuzn.png",
|
|
9741
|
-
priceProviderId: "fuzion"
|
|
9742
|
-
},
|
|
9743
|
-
lvn: {
|
|
9744
|
-
ticker: "LVN",
|
|
9745
|
-
logo: "levana",
|
|
9746
|
-
priceProviderId: "levana-protocol"
|
|
9747
|
-
},
|
|
9748
|
-
nstk: {
|
|
9749
|
-
ticker: "NSTK",
|
|
9750
|
-
logo: "nstk.png",
|
|
9751
|
-
priceProviderId: "unstake-fi"
|
|
9752
|
-
},
|
|
9753
|
-
wink: {
|
|
9754
|
-
ticker: "WINK",
|
|
9755
|
-
logo: "wink.png",
|
|
9756
|
-
priceProviderId: "winkhub"
|
|
9757
|
-
}
|
|
9758
|
-
};
|
|
9759
|
-
var kujiraCoinMigratedToThorChainDestinationId = makeRecord(kujiraCoinsMigratedToThorChain, (id) => `thor.${id}`);
|
|
9760
|
-
|
|
9761
|
-
// ../../packages/core/chain/dist/coin/chainFeeCoin.js
|
|
9762
|
-
var ether = {
|
|
9763
|
-
ticker: "ETH",
|
|
9764
|
-
logo: "eth",
|
|
9765
|
-
decimals: 18,
|
|
9766
|
-
priceProviderId: "ethereum"
|
|
9767
|
-
};
|
|
9768
|
-
var leanChainFeeCoin = {
|
|
9769
|
-
[Chain8.Bitcoin]: {
|
|
9770
|
-
ticker: "BTC",
|
|
9771
|
-
logo: "btc",
|
|
9772
|
-
decimals: 8,
|
|
9773
|
-
priceProviderId: "bitcoin"
|
|
9774
|
-
},
|
|
9775
|
-
[Chain8.BitcoinCash]: {
|
|
9776
|
-
ticker: "BCH",
|
|
9777
|
-
logo: "bch",
|
|
9778
|
-
decimals: 8,
|
|
9779
|
-
priceProviderId: "bitcoin-cash"
|
|
9780
|
-
},
|
|
9781
|
-
[Chain8.Litecoin]: {
|
|
9782
|
-
ticker: "LTC",
|
|
9783
|
-
logo: "ltc",
|
|
9784
|
-
decimals: 8,
|
|
9785
|
-
priceProviderId: "litecoin"
|
|
9786
|
-
},
|
|
9787
|
-
[Chain8.Dogecoin]: {
|
|
9788
|
-
ticker: "DOGE",
|
|
9789
|
-
logo: "doge",
|
|
9790
|
-
decimals: 8,
|
|
9791
|
-
priceProviderId: "dogecoin"
|
|
9792
|
-
},
|
|
9793
|
-
[Chain8.Dash]: {
|
|
9794
|
-
ticker: "DASH",
|
|
9795
|
-
logo: "dash",
|
|
9796
|
-
decimals: 8,
|
|
9797
|
-
priceProviderId: "dash"
|
|
9798
|
-
},
|
|
9799
|
-
[Chain8.Ripple]: {
|
|
9800
|
-
ticker: "XRP",
|
|
9801
|
-
logo: "xrp",
|
|
9802
|
-
decimals: 6,
|
|
9803
|
-
priceProviderId: "ripple"
|
|
9804
|
-
},
|
|
9805
|
-
[Chain8.THORChain]: {
|
|
9806
|
-
ticker: "RUNE",
|
|
9807
|
-
logo: "rune",
|
|
9808
|
-
decimals: 8,
|
|
9809
|
-
priceProviderId: "thorchain"
|
|
9810
|
-
},
|
|
9811
|
-
[Chain8.MayaChain]: {
|
|
9812
|
-
ticker: "CACAO",
|
|
9813
|
-
logo: "cacao",
|
|
9814
|
-
decimals: 10,
|
|
9815
|
-
priceProviderId: "cacao"
|
|
9816
|
-
},
|
|
9817
|
-
[Chain8.Solana]: {
|
|
9818
|
-
ticker: "SOL",
|
|
9819
|
-
logo: "solana",
|
|
9820
|
-
decimals: 9,
|
|
9821
|
-
priceProviderId: "solana"
|
|
9822
|
-
},
|
|
9823
|
-
[Chain8.Ton]: {
|
|
9824
|
-
ticker: "GRAM",
|
|
9825
|
-
logo: "gram",
|
|
9826
|
-
decimals: 9,
|
|
9827
|
-
priceProviderId: "the-open-network"
|
|
9828
|
-
},
|
|
9829
|
-
[Chain8.Ethereum]: ether,
|
|
9830
|
-
[Chain8.Avalanche]: {
|
|
9831
|
-
ticker: "AVAX",
|
|
9832
|
-
logo: "avax",
|
|
9833
|
-
decimals: 18,
|
|
9834
|
-
priceProviderId: "avalanche-2"
|
|
9835
|
-
},
|
|
9836
|
-
[Chain8.BSC]: {
|
|
9837
|
-
ticker: "BNB",
|
|
9838
|
-
logo: "bsc",
|
|
9839
|
-
decimals: 18,
|
|
9840
|
-
priceProviderId: "binancecoin"
|
|
9841
|
-
},
|
|
9842
|
-
[Chain8.Polygon]: {
|
|
9843
|
-
ticker: "POL",
|
|
9844
|
-
logo: "polygon",
|
|
9845
|
-
decimals: 18,
|
|
9846
|
-
priceProviderId: "polygon-ecosystem-token"
|
|
9847
|
-
},
|
|
9848
|
-
[Chain8.CronosChain]: {
|
|
9849
|
-
ticker: "CRO",
|
|
9850
|
-
logo: "cro",
|
|
9851
|
-
decimals: 18,
|
|
9852
|
-
priceProviderId: "crypto-com-chain"
|
|
9853
|
-
},
|
|
9854
|
-
[Chain8.Dydx]: {
|
|
9855
|
-
ticker: "DYDX",
|
|
9856
|
-
logo: "dydx",
|
|
9857
|
-
decimals: 18,
|
|
9858
|
-
priceProviderId: "dydx-chain"
|
|
9859
|
-
},
|
|
9860
|
-
[Chain8.Kujira]: {
|
|
9861
|
-
...kujiraCoinsMigratedToThorChainMetadata.kuji,
|
|
9862
|
-
decimals: 6
|
|
9863
|
-
},
|
|
9864
|
-
[Chain8.Terra]: {
|
|
9865
|
-
ticker: "LUNA",
|
|
9866
|
-
logo: "luna",
|
|
9867
|
-
decimals: 6,
|
|
9868
|
-
priceProviderId: "terra-luna-2"
|
|
9869
|
-
},
|
|
9870
|
-
[Chain8.TerraClassic]: {
|
|
9871
|
-
ticker: "LUNC",
|
|
9872
|
-
logo: "lunc",
|
|
9873
|
-
decimals: 6,
|
|
9874
|
-
priceProviderId: "terra-luna"
|
|
9875
|
-
},
|
|
9876
|
-
[Chain8.Sui]: {
|
|
9877
|
-
ticker: "SUI",
|
|
9878
|
-
logo: "sui",
|
|
9879
|
-
decimals: 9,
|
|
9880
|
-
priceProviderId: "sui"
|
|
9881
|
-
},
|
|
9882
|
-
[Chain8.Polkadot]: {
|
|
9883
|
-
ticker: "DOT",
|
|
9884
|
-
logo: "dot",
|
|
9885
|
-
decimals: 10,
|
|
9886
|
-
priceProviderId: "polkadot"
|
|
9887
|
-
},
|
|
9888
|
-
[Chain8.Bittensor]: {
|
|
9889
|
-
ticker: "TAO",
|
|
9890
|
-
logo: "bittensor",
|
|
9891
|
-
decimals: 9,
|
|
9892
|
-
priceProviderId: "bittensor"
|
|
9893
|
-
},
|
|
9894
|
-
[Chain8.Noble]: {
|
|
9895
|
-
ticker: "USDC",
|
|
9896
|
-
logo: "noble",
|
|
9897
|
-
decimals: 6,
|
|
9898
|
-
priceProviderId: "usd-coin"
|
|
9899
|
-
},
|
|
9900
|
-
[Chain8.Akash]: {
|
|
9901
|
-
ticker: "AKT",
|
|
9902
|
-
logo: "akash",
|
|
9903
|
-
decimals: 6,
|
|
9904
|
-
priceProviderId: "akash-network"
|
|
9905
|
-
},
|
|
9906
|
-
[Chain8.Cosmos]: {
|
|
9907
|
-
ticker: "ATOM",
|
|
9908
|
-
logo: "atom",
|
|
9909
|
-
decimals: 6,
|
|
9910
|
-
priceProviderId: "cosmos"
|
|
9911
|
-
},
|
|
9912
|
-
[Chain8.Osmosis]: {
|
|
9913
|
-
ticker: "OSMO",
|
|
9914
|
-
logo: "osmo",
|
|
9915
|
-
decimals: 6,
|
|
9916
|
-
priceProviderId: "osmosis"
|
|
9917
|
-
},
|
|
9918
|
-
[Chain8.Tron]: {
|
|
9919
|
-
ticker: "TRX",
|
|
9920
|
-
logo: "tron",
|
|
9921
|
-
decimals: 6,
|
|
9922
|
-
priceProviderId: "tron"
|
|
9923
|
-
},
|
|
9924
|
-
...recordMap(EthereumL2Chain, () => ether),
|
|
9925
|
-
[Chain8.Zcash]: {
|
|
9926
|
-
ticker: "ZEC",
|
|
9927
|
-
logo: "zec",
|
|
9928
|
-
decimals: 8,
|
|
9929
|
-
priceProviderId: "zcash"
|
|
9930
|
-
},
|
|
9931
|
-
[Chain8.Cardano]: {
|
|
9932
|
-
ticker: "ADA",
|
|
9933
|
-
logo: "ada",
|
|
9934
|
-
decimals: 6,
|
|
9935
|
-
priceProviderId: "cardano"
|
|
9936
|
-
},
|
|
9937
|
-
[Chain8.Mantle]: {
|
|
9938
|
-
ticker: "MNT",
|
|
9939
|
-
logo: "mantle",
|
|
9940
|
-
decimals: 18,
|
|
9941
|
-
priceProviderId: "mantle"
|
|
9942
|
-
},
|
|
9943
|
-
[Chain8.Hyperliquid]: {
|
|
9944
|
-
ticker: "HYPE",
|
|
9945
|
-
logo: "hyperliquid",
|
|
9946
|
-
decimals: 18,
|
|
9947
|
-
priceProviderId: "hyperliquid"
|
|
9948
|
-
},
|
|
9949
|
-
[Chain8.Sei]: {
|
|
9950
|
-
ticker: "SEI",
|
|
9951
|
-
logo: "sei",
|
|
9952
|
-
decimals: 18,
|
|
9953
|
-
priceProviderId: "sei-network"
|
|
9954
|
-
},
|
|
9955
|
-
[Chain8.QBTC]: {
|
|
9956
|
-
ticker: "QBTC",
|
|
9957
|
-
logo: "qbtc",
|
|
9958
|
-
decimals: 8,
|
|
9959
|
-
priceProviderId: "qbtc-testnet"
|
|
9960
|
-
}
|
|
9961
|
-
};
|
|
9962
|
-
var chainFeeCoin = recordMap(leanChainFeeCoin, (coin, chain) => ({
|
|
9963
|
-
...coin,
|
|
9964
|
-
chain
|
|
9965
|
-
}));
|
|
9863
|
+
// src/agent/toolOutputSigning.ts
|
|
9864
|
+
import { getChainKind as getChainKind3 } from "@vultisig/sdk";
|
|
9966
9865
|
|
|
9967
9866
|
// src/agent/executor.ts
|
|
9968
|
-
import {
|
|
9867
|
+
import {
|
|
9868
|
+
Chain as Chain9,
|
|
9869
|
+
chainFeeCoin,
|
|
9870
|
+
getChainKind as getChainKind2,
|
|
9871
|
+
resolveChainReference,
|
|
9872
|
+
VaultError as VaultError3,
|
|
9873
|
+
VaultErrorCode as VaultErrorCode3,
|
|
9874
|
+
Vultisig as VultisigSdk
|
|
9875
|
+
} from "@vultisig/sdk";
|
|
9969
9876
|
|
|
9970
9877
|
// ../../node_modules/viem/_esm/accounts/utils/publicKeyToAddress.js
|
|
9971
9878
|
init_getAddress();
|
|
@@ -10496,6 +10403,14 @@ var AgentExecutor = class {
|
|
|
10496
10403
|
setPassword(password) {
|
|
10497
10404
|
this.password = password;
|
|
10498
10405
|
}
|
|
10406
|
+
/**
|
|
10407
|
+
* Whether a password is already held (set at unlock via the keyring/env chain
|
|
10408
|
+
* or `--password`). The sign gate consults this so a session unlocked
|
|
10409
|
+
* non-interactively doesn't get re-prompted for a secret it already has.
|
|
10410
|
+
*/
|
|
10411
|
+
hasPassword() {
|
|
10412
|
+
return this.password != null;
|
|
10413
|
+
}
|
|
10499
10414
|
/** Opt out of the persistent broadcast-journal duplicate guard (`--force`). */
|
|
10500
10415
|
setForceBroadcast(force) {
|
|
10501
10416
|
this.forceBroadcast = force;
|
|
@@ -10510,6 +10425,7 @@ var AgentExecutor = class {
|
|
|
10510
10425
|
*/
|
|
10511
10426
|
buildBroadcastIntent(payload, chain, overrideTx) {
|
|
10512
10427
|
const source = overrideTx ?? payload;
|
|
10428
|
+
const dataIsEvmCalldata = getChainKind2(chain) === "evm";
|
|
10513
10429
|
const nested = extractNestedTx(source);
|
|
10514
10430
|
if (nested && (nested.to || nested.value || nested.data)) {
|
|
10515
10431
|
return {
|
|
@@ -10517,7 +10433,8 @@ var AgentExecutor = class {
|
|
|
10517
10433
|
chain: chain.toString(),
|
|
10518
10434
|
to: nested.to != null ? String(nested.to) : void 0,
|
|
10519
10435
|
value: nested.value != null ? String(nested.value) : void 0,
|
|
10520
|
-
data: nested.data != null ? String(nested.data) : void 0
|
|
10436
|
+
data: nested.data != null ? String(nested.data) : void 0,
|
|
10437
|
+
dataIsEvmCalldata
|
|
10521
10438
|
};
|
|
10522
10439
|
}
|
|
10523
10440
|
const txArgs = source?.txArgs ?? source;
|
|
@@ -10528,6 +10445,7 @@ var AgentExecutor = class {
|
|
|
10528
10445
|
to: txArgs?.to != null ? String(txArgs.to) : void 0,
|
|
10529
10446
|
value: txArgs?.amount != null ? String(txArgs.amount) : void 0,
|
|
10530
10447
|
data: txArgs?.memo != null ? String(txArgs.memo) : void 0,
|
|
10448
|
+
dataIsEvmCalldata,
|
|
10531
10449
|
asset: asset != null ? String(asset) : void 0
|
|
10532
10450
|
};
|
|
10533
10451
|
}
|
|
@@ -10613,7 +10531,7 @@ var AgentExecutor = class {
|
|
|
10613
10531
|
const txArgs = txReadyData.txArgs;
|
|
10614
10532
|
if (txArgs && typeof txArgs === "object" && typeof txArgs.to === "string" && typeof txArgs.amount === "string") {
|
|
10615
10533
|
const chain2 = resolveChainFromTxReady(txReadyData) || Chain9.Ethereum;
|
|
10616
|
-
if (
|
|
10534
|
+
if (getChainKind2(chain2) !== "evm") {
|
|
10617
10535
|
this.pendingPayloads.clear();
|
|
10618
10536
|
this.pendingLegs = [];
|
|
10619
10537
|
this.pendingPayloads.set("latest", {
|
|
@@ -10624,7 +10542,7 @@ var AgentExecutor = class {
|
|
|
10624
10542
|
});
|
|
10625
10543
|
if (this.verbose)
|
|
10626
10544
|
process.stderr.write(
|
|
10627
|
-
`[executor] Stored non-EVM server tx for chain ${chain2} (kind=${
|
|
10545
|
+
`[executor] Stored non-EVM server tx for chain ${chain2} (kind=${getChainKind2(chain2)})
|
|
10628
10546
|
`
|
|
10629
10547
|
);
|
|
10630
10548
|
return true;
|
|
@@ -10973,7 +10891,7 @@ var AgentExecutor = class {
|
|
|
10973
10891
|
*/
|
|
10974
10892
|
async signServerTx(serverTxData, defaultChain, params) {
|
|
10975
10893
|
const chain = resolveChainFromTxReady(serverTxData) || defaultChain;
|
|
10976
|
-
const chainKind =
|
|
10894
|
+
const chainKind = getChainKind2(chain);
|
|
10977
10895
|
if (chainKind === "evm") {
|
|
10978
10896
|
return this.signEvmServerTx(serverTxData, defaultChain, params);
|
|
10979
10897
|
}
|
|
@@ -11816,41 +11734,7 @@ var AgentExecutor = class {
|
|
|
11816
11734
|
}
|
|
11817
11735
|
};
|
|
11818
11736
|
function resolveChain(name) {
|
|
11819
|
-
|
|
11820
|
-
if (Object.values(Chain9).includes(name)) {
|
|
11821
|
-
return name;
|
|
11822
|
-
}
|
|
11823
|
-
const lower = name.toLowerCase();
|
|
11824
|
-
for (const [, value] of Object.entries(Chain9)) {
|
|
11825
|
-
if (typeof value === "string" && value.toLowerCase() === lower) {
|
|
11826
|
-
return value;
|
|
11827
|
-
}
|
|
11828
|
-
}
|
|
11829
|
-
const aliases = {
|
|
11830
|
-
eth: "Ethereum",
|
|
11831
|
-
btc: "Bitcoin",
|
|
11832
|
-
sol: "Solana",
|
|
11833
|
-
bnb: "BSC",
|
|
11834
|
-
avax: "Avalanche",
|
|
11835
|
-
matic: "Polygon",
|
|
11836
|
-
arb: "Arbitrum",
|
|
11837
|
-
op: "Optimism",
|
|
11838
|
-
ltc: "Litecoin",
|
|
11839
|
-
doge: "Dogecoin",
|
|
11840
|
-
dot: "Polkadot",
|
|
11841
|
-
atom: "Cosmos",
|
|
11842
|
-
rune: "THORChain",
|
|
11843
|
-
thor: "THORChain",
|
|
11844
|
-
sui: "Sui",
|
|
11845
|
-
ton: "Ton",
|
|
11846
|
-
trx: "Tron",
|
|
11847
|
-
xrp: "Ripple"
|
|
11848
|
-
};
|
|
11849
|
-
const aliased = aliases[lower];
|
|
11850
|
-
if (aliased && Object.values(Chain9).includes(aliased)) {
|
|
11851
|
-
return aliased;
|
|
11852
|
-
}
|
|
11853
|
-
return null;
|
|
11737
|
+
return resolveChainReference(name) ?? null;
|
|
11854
11738
|
}
|
|
11855
11739
|
function resolveChainFromTxReady(txReadyData) {
|
|
11856
11740
|
if (txReadyData.chain) {
|
|
@@ -11953,21 +11837,7 @@ function parseThorSwapMemo(memo) {
|
|
|
11953
11837
|
return { destChainCode, destAsset, destAddress };
|
|
11954
11838
|
}
|
|
11955
11839
|
function resolveChainId(chainId) {
|
|
11956
|
-
|
|
11957
|
-
if (isNaN(id)) return null;
|
|
11958
|
-
const chainIdMap = {
|
|
11959
|
-
1: Chain9.Ethereum,
|
|
11960
|
-
56: Chain9.BSC,
|
|
11961
|
-
137: Chain9.Polygon,
|
|
11962
|
-
43114: Chain9.Avalanche,
|
|
11963
|
-
42161: Chain9.Arbitrum,
|
|
11964
|
-
10: Chain9.Optimism,
|
|
11965
|
-
8453: Chain9.Base,
|
|
11966
|
-
81457: Chain9.Blast,
|
|
11967
|
-
324: Chain9.Zksync,
|
|
11968
|
-
25: Chain9.CronosChain
|
|
11969
|
-
};
|
|
11970
|
-
return chainIdMap[id] || null;
|
|
11840
|
+
return resolveChainReference(chainId) ?? null;
|
|
11971
11841
|
}
|
|
11972
11842
|
function computeEIP712Hash(domain, types, primaryType, message) {
|
|
11973
11843
|
const messageTypes = { ...types };
|
|
@@ -12099,7 +11969,7 @@ function resolveStrictEvmChain(chain, chainId) {
|
|
|
12099
11969
|
const byName = resolveChain(chain);
|
|
12100
11970
|
const byId = resolveChainId(chainId);
|
|
12101
11971
|
if (!byName || !byId || byName !== byId) return null;
|
|
12102
|
-
if (
|
|
11972
|
+
if (getChainKind3(byName) !== "evm") return null;
|
|
12103
11973
|
return byName;
|
|
12104
11974
|
}
|
|
12105
11975
|
function asChainString(value) {
|
|
@@ -12752,7 +12622,7 @@ var AgentClient = class {
|
|
|
12752
12622
|
};
|
|
12753
12623
|
|
|
12754
12624
|
// src/agent/context.ts
|
|
12755
|
-
import { Chain as
|
|
12625
|
+
import { Chain as Chain11 } from "@vultisig/sdk";
|
|
12756
12626
|
function applyChainPublicKeys(vault, context) {
|
|
12757
12627
|
const raw = vault.data.chainPublicKeys;
|
|
12758
12628
|
if (!raw) return;
|
|
@@ -12865,57 +12735,57 @@ async function buildMinimalContext(vault) {
|
|
|
12865
12735
|
}
|
|
12866
12736
|
function getNativeTokenTicker(chain) {
|
|
12867
12737
|
const tickers = {
|
|
12868
|
-
[
|
|
12869
|
-
[
|
|
12870
|
-
[
|
|
12871
|
-
[
|
|
12872
|
-
[
|
|
12873
|
-
[
|
|
12874
|
-
[
|
|
12875
|
-
[
|
|
12876
|
-
[
|
|
12877
|
-
[
|
|
12878
|
-
[
|
|
12879
|
-
[
|
|
12880
|
-
[
|
|
12881
|
-
[
|
|
12882
|
-
[
|
|
12883
|
-
[
|
|
12884
|
-
[
|
|
12885
|
-
[
|
|
12886
|
-
[
|
|
12887
|
-
[
|
|
12888
|
-
[
|
|
12889
|
-
[
|
|
12890
|
-
[
|
|
12891
|
-
[
|
|
12892
|
-
[
|
|
12893
|
-
[
|
|
12894
|
-
[
|
|
12895
|
-
[
|
|
12738
|
+
[Chain11.Ethereum]: "ETH",
|
|
12739
|
+
[Chain11.Bitcoin]: "BTC",
|
|
12740
|
+
[Chain11.Solana]: "SOL",
|
|
12741
|
+
[Chain11.THORChain]: "RUNE",
|
|
12742
|
+
[Chain11.Cosmos]: "ATOM",
|
|
12743
|
+
[Chain11.Avalanche]: "AVAX",
|
|
12744
|
+
[Chain11.BSC]: "BNB",
|
|
12745
|
+
[Chain11.Polygon]: "MATIC",
|
|
12746
|
+
[Chain11.Arbitrum]: "ETH",
|
|
12747
|
+
[Chain11.Optimism]: "ETH",
|
|
12748
|
+
[Chain11.Base]: "ETH",
|
|
12749
|
+
[Chain11.Blast]: "ETH",
|
|
12750
|
+
[Chain11.Litecoin]: "LTC",
|
|
12751
|
+
[Chain11.Dogecoin]: "DOGE",
|
|
12752
|
+
[Chain11.Dash]: "DASH",
|
|
12753
|
+
[Chain11.MayaChain]: "CACAO",
|
|
12754
|
+
[Chain11.Polkadot]: "DOT",
|
|
12755
|
+
[Chain11.Sui]: "SUI",
|
|
12756
|
+
[Chain11.Ton]: "TON",
|
|
12757
|
+
[Chain11.Tron]: "TRX",
|
|
12758
|
+
[Chain11.Ripple]: "XRP",
|
|
12759
|
+
[Chain11.Dydx]: "DYDX",
|
|
12760
|
+
[Chain11.Osmosis]: "OSMO",
|
|
12761
|
+
[Chain11.Terra]: "LUNA",
|
|
12762
|
+
[Chain11.Noble]: "USDC",
|
|
12763
|
+
[Chain11.Kujira]: "KUJI",
|
|
12764
|
+
[Chain11.Zksync]: "ETH",
|
|
12765
|
+
[Chain11.CronosChain]: "CRO"
|
|
12896
12766
|
};
|
|
12897
12767
|
return tickers[chain] || chain.toString();
|
|
12898
12768
|
}
|
|
12899
12769
|
function getNativeTokenDecimals(chain) {
|
|
12900
12770
|
const decimals = {
|
|
12901
|
-
[
|
|
12902
|
-
[
|
|
12903
|
-
[
|
|
12904
|
-
[
|
|
12905
|
-
[
|
|
12906
|
-
[
|
|
12907
|
-
[
|
|
12908
|
-
[
|
|
12909
|
-
[
|
|
12910
|
-
[
|
|
12911
|
-
[
|
|
12912
|
-
[
|
|
12913
|
-
[
|
|
12914
|
-
[
|
|
12915
|
-
[
|
|
12916
|
-
[
|
|
12917
|
-
[
|
|
12918
|
-
[
|
|
12771
|
+
[Chain11.Bitcoin]: 8,
|
|
12772
|
+
[Chain11.Litecoin]: 8,
|
|
12773
|
+
[Chain11.Dogecoin]: 8,
|
|
12774
|
+
[Chain11.Dash]: 8,
|
|
12775
|
+
[Chain11.Solana]: 9,
|
|
12776
|
+
[Chain11.Sui]: 9,
|
|
12777
|
+
[Chain11.Ton]: 9,
|
|
12778
|
+
[Chain11.Polkadot]: 10,
|
|
12779
|
+
[Chain11.Cosmos]: 6,
|
|
12780
|
+
[Chain11.THORChain]: 8,
|
|
12781
|
+
[Chain11.MayaChain]: 10,
|
|
12782
|
+
[Chain11.Osmosis]: 6,
|
|
12783
|
+
[Chain11.Dydx]: 18,
|
|
12784
|
+
[Chain11.Tron]: 6,
|
|
12785
|
+
[Chain11.Ripple]: 6,
|
|
12786
|
+
[Chain11.Noble]: 6,
|
|
12787
|
+
[Chain11.Kujira]: 6,
|
|
12788
|
+
[Chain11.Terra]: 6
|
|
12919
12789
|
};
|
|
12920
12790
|
return decimals[chain] || 18;
|
|
12921
12791
|
}
|
|
@@ -13290,6 +13160,16 @@ var AgentSession = class {
|
|
|
13290
13160
|
const conv = await this.withAuthRetry(() => this.client.getConversation(this.conversationId, this.publicKey));
|
|
13291
13161
|
this.historyMessages = conv.messages || [];
|
|
13292
13162
|
} catch (err) {
|
|
13163
|
+
if (this.config.askMode) {
|
|
13164
|
+
this.conversationId = null;
|
|
13165
|
+
this.historyMessages = [];
|
|
13166
|
+
throw Object.assign(
|
|
13167
|
+
new Error(
|
|
13168
|
+
`Session ${this.config.sessionId} could not be resumed (${err?.message ?? "unknown error"}); refusing to execute the request without its conversation context`
|
|
13169
|
+
),
|
|
13170
|
+
{ code: "SESSION_NOT_FOUND" /* SESSION_NOT_FOUND */ }
|
|
13171
|
+
);
|
|
13172
|
+
}
|
|
13293
13173
|
this.conversationId = null;
|
|
13294
13174
|
this.historyMessages = [];
|
|
13295
13175
|
const conv = await this.withAuthRetry(() => this.client.createConversation(this.publicKey));
|
|
@@ -13833,28 +13713,37 @@ var AgentSession = class {
|
|
|
13833
13713
|
}
|
|
13834
13714
|
let promptedPassword;
|
|
13835
13715
|
if (PASSWORD_REQUIRED_TOOLS.has(toolName) && !this.config.password) {
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
|
|
13839
|
-
|
|
13840
|
-
|
|
13841
|
-
|
|
13842
|
-
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13716
|
+
const vaultLocked = this.vault.isEncrypted && !this.vault.isUnlocked();
|
|
13717
|
+
const needsPassword = vaultLocked && !this.executor.hasPassword();
|
|
13718
|
+
if (needsPassword) {
|
|
13719
|
+
const resolved = await resolvePasswordNonInteractive(this.vault.id, this.vault.name);
|
|
13720
|
+
if (resolved) {
|
|
13721
|
+
this.executor.setPassword(resolved);
|
|
13722
|
+
} else {
|
|
13723
|
+
try {
|
|
13724
|
+
promptedPassword = await ui.requestPassword();
|
|
13725
|
+
this.executor.setPassword(promptedPassword);
|
|
13726
|
+
} catch {
|
|
13727
|
+
const failure = {
|
|
13728
|
+
tool: toolName,
|
|
13729
|
+
success: false,
|
|
13730
|
+
data: {
|
|
13731
|
+
error: "Password not provided",
|
|
13732
|
+
code: "PASSWORD_REQUIRED" /* PASSWORD_REQUIRED */
|
|
13733
|
+
}
|
|
13734
|
+
};
|
|
13735
|
+
ui.onToolCall(toolCallId, toolName, input);
|
|
13736
|
+
ui.onToolResult(
|
|
13737
|
+
toolCallId,
|
|
13738
|
+
toolName,
|
|
13739
|
+
false,
|
|
13740
|
+
failure.data,
|
|
13741
|
+
"Password not provided",
|
|
13742
|
+
"PASSWORD_REQUIRED" /* PASSWORD_REQUIRED */
|
|
13743
|
+
);
|
|
13744
|
+
return failure;
|
|
13846
13745
|
}
|
|
13847
|
-
}
|
|
13848
|
-
ui.onToolCall(toolCallId, toolName, input);
|
|
13849
|
-
ui.onToolResult(
|
|
13850
|
-
toolCallId,
|
|
13851
|
-
toolName,
|
|
13852
|
-
false,
|
|
13853
|
-
failure.data,
|
|
13854
|
-
"Password not provided",
|
|
13855
|
-
"PASSWORD_REQUIRED" /* PASSWORD_REQUIRED */
|
|
13856
|
-
);
|
|
13857
|
-
return failure;
|
|
13746
|
+
}
|
|
13858
13747
|
}
|
|
13859
13748
|
}
|
|
13860
13749
|
ui.onToolCall(toolCallId, toolName, input);
|
|
@@ -14437,10 +14326,79 @@ function outputAskError(wantsJson, message, code, conversationId, result) {
|
|
|
14437
14326
|
...Object.keys(data).length > 0 ? { data } : {}
|
|
14438
14327
|
});
|
|
14439
14328
|
} else {
|
|
14329
|
+
if (result) {
|
|
14330
|
+
process.stderr.write(`session:${result.sessionId}
|
|
14331
|
+
`);
|
|
14332
|
+
if (result.outcome) {
|
|
14333
|
+
const { kind, code: outcomeCode } = result.outcome;
|
|
14334
|
+
process.stderr.write(`outcome:${kind}${outcomeCode ? `:${outcomeCode}` : ""}
|
|
14335
|
+
`);
|
|
14336
|
+
}
|
|
14337
|
+
if (result.response) process.stderr.write(`${result.response}
|
|
14338
|
+
`);
|
|
14339
|
+
}
|
|
14440
14340
|
process.stderr.write(`Error: ${message} [${code}]
|
|
14441
14341
|
`);
|
|
14442
14342
|
}
|
|
14443
14343
|
}
|
|
14344
|
+
var BROADCAST_COMMITTED_MESSAGE = "A transaction was broadcast, but the overall agent request may be incomplete. Inspect the transaction status before continuing.";
|
|
14345
|
+
var ACK_FAILED_MESSAGE = "A transaction was broadcast, but its post-broadcast report failed. Inspect the transaction status before continuing.";
|
|
14346
|
+
function hasCommittedBroadcast(result) {
|
|
14347
|
+
return !!result?.transactions.some((tx) => tx.hash.trim().length > 0 && tx.status !== "failed");
|
|
14348
|
+
}
|
|
14349
|
+
var SIGNING_TOOLS = /* @__PURE__ */ new Set(["sign_tx", "sign_typed_data"]);
|
|
14350
|
+
function failedSigningError(result) {
|
|
14351
|
+
const failed = [...result.toolCalls].reverse().find((call) => SIGNING_TOOLS.has(call.action));
|
|
14352
|
+
if (!failed || failed.success) return void 0;
|
|
14353
|
+
const message = failed.error ?? (typeof failed.data?.error === "string" ? failed.data.error : void 0) ?? `${failed.action} failed`;
|
|
14354
|
+
const dataCode = failed.data?.code;
|
|
14355
|
+
const code = failed.code ?? (typeof dataCode === "string" && isAgentErrorCode(dataCode) ? dataCode : inferAgentErrorCodeFromMessage(message));
|
|
14356
|
+
return { message, code };
|
|
14357
|
+
}
|
|
14358
|
+
function outputPostBroadcastFailure(wantsJson, result, conversationId, classification, originalError) {
|
|
14359
|
+
const message = classification === "ACK_FAILED" /* ACK_FAILED */ ? ACK_FAILED_MESSAGE : BROADCAST_COMMITTED_MESSAGE;
|
|
14360
|
+
if (wantsJson) {
|
|
14361
|
+
const data = {
|
|
14362
|
+
transactions: result.transactions,
|
|
14363
|
+
tool_calls: result.toolCalls,
|
|
14364
|
+
response: result.response,
|
|
14365
|
+
...result.outcome ? { outcome: result.outcome } : {},
|
|
14366
|
+
...originalError ? { original_error: originalError } : {}
|
|
14367
|
+
};
|
|
14368
|
+
outputErrorJson({
|
|
14369
|
+
success: false,
|
|
14370
|
+
v: 1,
|
|
14371
|
+
error: { message, code: classification, conversation_id: conversationId },
|
|
14372
|
+
data
|
|
14373
|
+
});
|
|
14374
|
+
return;
|
|
14375
|
+
}
|
|
14376
|
+
const label = classification === "ACK_FAILED" /* ACK_FAILED */ ? "Broadcast acknowledgement failed" : "Broadcast committed";
|
|
14377
|
+
process.stderr.write(`session:${result.sessionId}
|
|
14378
|
+
`);
|
|
14379
|
+
process.stderr.write(`${label}: ${message}
|
|
14380
|
+
`);
|
|
14381
|
+
if (result.outcome) {
|
|
14382
|
+
const { kind, code } = result.outcome;
|
|
14383
|
+
process.stderr.write(`outcome:${kind}${code ? `:${code}` : ""}
|
|
14384
|
+
`);
|
|
14385
|
+
}
|
|
14386
|
+
if (originalError) {
|
|
14387
|
+
process.stderr.write(`backend-error:${originalError.message} [${originalError.code}]
|
|
14388
|
+
`);
|
|
14389
|
+
}
|
|
14390
|
+
for (const tx of result.transactions) {
|
|
14391
|
+
process.stderr.write(`tx:${tx.chain}:${tx.hash}
|
|
14392
|
+
`);
|
|
14393
|
+
process.stderr.write(`status:${tx.status ?? "unknown"}
|
|
14394
|
+
`);
|
|
14395
|
+
if (tx.explorerUrl) process.stderr.write(`explorer:${tx.explorerUrl}
|
|
14396
|
+
`);
|
|
14397
|
+
}
|
|
14398
|
+
process.stderr.write(
|
|
14399
|
+
"WARNING: DO NOT blindly retry. Verify each transaction hash and continue only the incomplete step.\n"
|
|
14400
|
+
);
|
|
14401
|
+
}
|
|
14444
14402
|
function outputAskHuman(result, confirmationRequired, proposed) {
|
|
14445
14403
|
process.stdout.write(`session:${result.sessionId}
|
|
14446
14404
|
`);
|
|
@@ -14494,8 +14452,7 @@ function outputAskSuccess(wantsJson, result, conversationId) {
|
|
|
14494
14452
|
// a2a-02: the typed turn ending (success | blocked | refusal | error) at
|
|
14495
14453
|
// `data.outcome` — the same relative slot as on the error envelope. Present
|
|
14496
14454
|
// only against a backend that honored the advertised turn_outcome surface;
|
|
14497
|
-
// headless callers
|
|
14498
|
-
// (which stays true for a completed-but-blocked/refused turn).
|
|
14455
|
+
// headless callers can inspect it without parsing response prose.
|
|
14499
14456
|
...result.outcome ? { outcome: result.outcome } : {},
|
|
14500
14457
|
...confirmationRequired ? { confirmation_required: true } : {},
|
|
14501
14458
|
...proposed ? { proposed } : {}
|
|
@@ -14504,17 +14461,23 @@ function outputAskSuccess(wantsJson, result, conversationId) {
|
|
|
14504
14461
|
}
|
|
14505
14462
|
outputAskHuman(result, confirmationRequired, proposed);
|
|
14506
14463
|
}
|
|
14507
|
-
function
|
|
14464
|
+
function outcomeError(outcome) {
|
|
14508
14465
|
switch (outcome?.kind) {
|
|
14509
14466
|
case "blocked":
|
|
14510
|
-
return
|
|
14467
|
+
return {
|
|
14468
|
+
message: "The agent request was blocked by a safety guardrail.",
|
|
14469
|
+
code: "AGENT_TURN_BLOCKED" /* AGENT_TURN_BLOCKED */
|
|
14470
|
+
};
|
|
14511
14471
|
case "refusal":
|
|
14512
|
-
return
|
|
14472
|
+
return {
|
|
14473
|
+
message: "The agent did not complete the requested action. Refine or clarify the request.",
|
|
14474
|
+
code: "AGENT_TURN_REFUSAL" /* AGENT_TURN_REFUSAL */
|
|
14475
|
+
};
|
|
14513
14476
|
case "error":
|
|
14514
|
-
return
|
|
14515
|
-
|
|
14516
|
-
|
|
14517
|
-
|
|
14477
|
+
return {
|
|
14478
|
+
message: "The agent could not complete the requested action.",
|
|
14479
|
+
code: "AGENT_TURN_ERROR" /* AGENT_TURN_ERROR */
|
|
14480
|
+
};
|
|
14518
14481
|
default:
|
|
14519
14482
|
return void 0;
|
|
14520
14483
|
}
|
|
@@ -14549,24 +14512,40 @@ async function executeAgentAsk(ctx2, message, options) {
|
|
|
14549
14512
|
const result = await ask.ask(message);
|
|
14550
14513
|
conversationId = result.sessionId;
|
|
14551
14514
|
if (result.error) {
|
|
14552
|
-
|
|
14553
|
-
|
|
14515
|
+
if (hasCommittedBroadcast(result)) {
|
|
14516
|
+
exitCode = 13 /* BROADCAST_COMMITTED */;
|
|
14517
|
+
outputPostBroadcastFailure(wantsJson, result, conversationId, "BROADCAST_COMMITTED" /* BROADCAST_COMMITTED */, result.error);
|
|
14518
|
+
} else {
|
|
14519
|
+
exitCode = agentErrorCodeToExitCode(result.error.code);
|
|
14520
|
+
outputAskError(wantsJson, result.error.message, result.error.code, conversationId, result);
|
|
14521
|
+
}
|
|
14554
14522
|
} else {
|
|
14555
|
-
|
|
14556
|
-
|
|
14523
|
+
const failure = failedSigningError(result) ?? outcomeError(result.outcome);
|
|
14524
|
+
if (failure && hasCommittedBroadcast(result)) {
|
|
14525
|
+
exitCode = 13 /* BROADCAST_COMMITTED */;
|
|
14526
|
+
outputPostBroadcastFailure(wantsJson, result, conversationId, "BROADCAST_COMMITTED" /* BROADCAST_COMMITTED */, failure);
|
|
14527
|
+
} else if (failure) {
|
|
14528
|
+
exitCode = agentErrorCodeToExitCode(failure.code);
|
|
14529
|
+
outputAskError(wantsJson, failure.message, failure.code, conversationId, result);
|
|
14530
|
+
} else {
|
|
14531
|
+
exitCode = 0 /* SUCCESS */;
|
|
14532
|
+
outputAskSuccess(wantsJson, result, conversationId);
|
|
14533
|
+
}
|
|
14557
14534
|
}
|
|
14558
14535
|
} catch (err) {
|
|
14559
14536
|
const normalized = normalizeAgentError(err);
|
|
14560
|
-
|
|
14537
|
+
const code = normalized.code;
|
|
14561
14538
|
const message2 = normalized.message;
|
|
14562
14539
|
const partial = ask?.partialResult();
|
|
14563
14540
|
if (partial && !conversationId) conversationId = partial.sessionId;
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14541
|
+
if (partial && hasCommittedBroadcast(partial)) {
|
|
14542
|
+
const classification = ask?.hasUnacknowledgedBroadcast() ? "ACK_FAILED" /* ACK_FAILED */ : "BROADCAST_COMMITTED" /* BROADCAST_COMMITTED */;
|
|
14543
|
+
exitCode = agentErrorCodeToExitCode(classification);
|
|
14544
|
+
outputPostBroadcastFailure(wantsJson, partial, conversationId, classification, { message: message2, code });
|
|
14545
|
+
} else {
|
|
14546
|
+
exitCode = agentErrorCodeToExitCode(code);
|
|
14547
|
+
outputAskError(wantsJson, message2, code, conversationId, partial);
|
|
14567
14548
|
}
|
|
14568
|
-
exitCode = agentErrorCodeToExitCode(code);
|
|
14569
|
-
outputAskError(wantsJson, message2, code, conversationId, partial);
|
|
14570
14549
|
} finally {
|
|
14571
14550
|
console.log = originalConsoleLog;
|
|
14572
14551
|
setSilentMode(false);
|
|
@@ -14671,7 +14650,7 @@ var cachedVersion = null;
|
|
|
14671
14650
|
function getVersion() {
|
|
14672
14651
|
if (cachedVersion) return cachedVersion;
|
|
14673
14652
|
if (true) {
|
|
14674
|
-
cachedVersion = "2.
|
|
14653
|
+
cachedVersion = "2.20.0";
|
|
14675
14654
|
return cachedVersion;
|
|
14676
14655
|
}
|
|
14677
14656
|
try {
|
|
@@ -14954,7 +14933,7 @@ function readArgValue(args, optionName) {
|
|
|
14954
14933
|
}
|
|
14955
14934
|
|
|
14956
14935
|
// src/interactive/completer.ts
|
|
14957
|
-
import { Chain as
|
|
14936
|
+
import { Chain as Chain12 } from "@vultisig/sdk";
|
|
14958
14937
|
import fs3 from "fs";
|
|
14959
14938
|
import path3 from "path";
|
|
14960
14939
|
var COMMANDS = [
|
|
@@ -15098,7 +15077,7 @@ function completeVaultName(ctx2, partial) {
|
|
|
15098
15077
|
return [show, partial];
|
|
15099
15078
|
}
|
|
15100
15079
|
function completeChainName(partial) {
|
|
15101
|
-
const allChains = Object.values(
|
|
15080
|
+
const allChains = Object.values(Chain12);
|
|
15102
15081
|
const partialLower = partial.toLowerCase();
|
|
15103
15082
|
const matches = allChains.filter((chain) => chain.toLowerCase().startsWith(partialLower));
|
|
15104
15083
|
matches.sort();
|
|
@@ -15106,7 +15085,7 @@ function completeChainName(partial) {
|
|
|
15106
15085
|
return [show, partial];
|
|
15107
15086
|
}
|
|
15108
15087
|
function findChainByName(name) {
|
|
15109
|
-
const allChains = Object.values(
|
|
15088
|
+
const allChains = Object.values(Chain12);
|
|
15110
15089
|
const nameLower = name.toLowerCase();
|
|
15111
15090
|
const found = allChains.find((chain) => chain.toLowerCase() === nameLower);
|
|
15112
15091
|
return found ? found : null;
|
|
@@ -15289,7 +15268,7 @@ var EventBuffer = class {
|
|
|
15289
15268
|
};
|
|
15290
15269
|
|
|
15291
15270
|
// src/interactive/session.ts
|
|
15292
|
-
import { fiatCurrencies as fiatCurrencies3 } from "@vultisig/sdk";
|
|
15271
|
+
import { Chain as Chain13, fiatCurrencies as fiatCurrencies3 } from "@vultisig/sdk";
|
|
15293
15272
|
import chalk14 from "chalk";
|
|
15294
15273
|
import ora3 from "ora";
|
|
15295
15274
|
import * as readline3 from "readline";
|
|
@@ -16115,24 +16094,40 @@ Error: ${error2.message}`));
|
|
|
16115
16094
|
}
|
|
16116
16095
|
async runSend(args) {
|
|
16117
16096
|
if (args.length < 3) {
|
|
16118
|
-
console.log(
|
|
16097
|
+
console.log(
|
|
16098
|
+
chalk14.yellow("Usage: send <chain> <to> <amount> [--token <tokenId>] [--memo <memo>] [--destination-tag <tag>]")
|
|
16099
|
+
);
|
|
16119
16100
|
return;
|
|
16120
16101
|
}
|
|
16121
16102
|
const [chainStr, to, amount, ...rest] = args;
|
|
16122
16103
|
const chain = findChainByName(chainStr) || chainStr;
|
|
16123
16104
|
let tokenId;
|
|
16124
16105
|
let memo;
|
|
16106
|
+
let destinationTag;
|
|
16125
16107
|
for (let i = 0; i < rest.length; i++) {
|
|
16126
16108
|
if (rest[i] === "--token" && i + 1 < rest.length) {
|
|
16127
16109
|
tokenId = rest[i + 1];
|
|
16128
16110
|
i++;
|
|
16129
16111
|
} else if (rest[i] === "--memo" && i + 1 < rest.length) {
|
|
16130
|
-
|
|
16131
|
-
|
|
16112
|
+
const nextOption = rest.findIndex(
|
|
16113
|
+
(arg, index) => index > i && ["--token", "--memo", "--destination-tag"].includes(arg)
|
|
16114
|
+
);
|
|
16115
|
+
memo = rest.slice(i + 1, nextOption === -1 ? void 0 : nextOption).join(" ");
|
|
16116
|
+
i = nextOption === -1 ? rest.length : nextOption - 1;
|
|
16117
|
+
} else if (rest[i] === "--destination-tag") {
|
|
16118
|
+
const tag = rest[i + 1];
|
|
16119
|
+
const parsedTag = Number(tag);
|
|
16120
|
+
if (chain !== Chain13.Ripple || !/^(0|[1-9]\d*)$/.test(tag ?? "") || !Number.isSafeInteger(parsedTag) || parsedTag > 4294967295) {
|
|
16121
|
+
throw new Error("Invalid XRP DestinationTag: expected an integer from 0 to 4294967295");
|
|
16122
|
+
}
|
|
16123
|
+
destinationTag = parsedTag;
|
|
16124
|
+
i++;
|
|
16132
16125
|
}
|
|
16133
16126
|
}
|
|
16134
16127
|
try {
|
|
16135
|
-
await this.withAbortHandler(
|
|
16128
|
+
await this.withAbortHandler(
|
|
16129
|
+
(signal) => executeSend(this.ctx, { chain, to, amount, tokenId, memo, destinationTag, signal })
|
|
16130
|
+
);
|
|
16136
16131
|
} catch (err) {
|
|
16137
16132
|
if (err.message === "Transaction cancelled by user" || err.message === "Operation cancelled" || err.message === "Operation aborted") {
|
|
16138
16133
|
console.log(chalk14.yellow("\nTransaction cancelled"));
|
|
@@ -16718,7 +16713,7 @@ program.name("vultisig").description("Vultisig CLI - Secure multi-party crypto w
|
|
|
16718
16713
|
process.stdout.isTTY ? "table" : "json"
|
|
16719
16714
|
).option("-q, --quiet", "Strip empty/zero fields from output").option("--fields <fields>", "Comma-separated list of fields to include in output").option("--non-interactive", "Disable interactive prompts (fail instead of asking)").option("--ci", "CI/automation mode (equivalent to --output json --non-interactive --quiet)").option("-i, --interactive", "Start interactive shell mode").option("--vault <nameOrId>", "Specify vault by name or ID").option("--server-url <url>", "Base Vultisig API URL for FastVault and relay endpoints").addHelpText(
|
|
16720
16715
|
"after",
|
|
16721
|
-
"\nExit codes:\n" + Object.entries(EXIT_CODE_DESCRIPTIONS).map(([k, v]) => ` ${k} ${v}`).join("\n") + "\n\nEnvironment variables:\n VAULT_PASSWORD
|
|
16716
|
+
"\nExit codes:\n" + Object.entries(EXIT_CODE_DESCRIPTIONS).map(([k, v]) => ` ${k} ${v}`).join("\n") + "\n\nEnvironment variables:\n VAULT_PASSWORD Single fallback; unlocks the vault for reads and signing\n VULTISIG_PASSWORD Alias during normal unlock/signing (not auth setup)\n VAULT_PASSWORDS JSON object or space-separated key:password pairs\n VAULT_DECRYPT_PASSWORD Decrypt an encrypted .vult file during auth setup\n VULTISIG_CREDENTIALS_PASSPHRASE Encrypt credentials on disk without a keyring\n VULTISIG_VAULT Default vault name or ID\n VULTISIG_CONFIG_DIR Override config directory (~/.vultisig)\n VULTISIG_SILENT Set to 1 for silent mode\n VULTISIG_HTTP_TIMEOUT_MS Agent-backend request timeout in ms (default 30000)\n NO_COLOR Disable colored output"
|
|
16722
16717
|
).hook("preAction", (thisCommand) => {
|
|
16723
16718
|
const opts = thisCommand.opts();
|
|
16724
16719
|
if (opts.ci) {
|
|
@@ -16996,7 +16991,7 @@ Examples:
|
|
|
16996
16991
|
});
|
|
16997
16992
|
})
|
|
16998
16993
|
);
|
|
16999
|
-
program.command("send <chain> <to> [amount]").description(descriptions.send.description).option("--max", "Send maximum amount (balance minus fees)").option("--token <tokenId>", "Token to send (default: native)").option("--memo <memo>", "Transaction memo").option("--dry-run", "Preview transaction without signing or broadcasting").option("--confirm", "Confirm and broadcast (without this flag, runs as a preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast tx)").option("--password <password>", "Vault password for signing").addHelpText(
|
|
16994
|
+
program.command("send <chain> <to> [amount]").description(descriptions.send.description).option("--max", "Send maximum amount (balance minus fees)").option("--token <tokenId>", "Token to send (default: native)").option("--memo <memo>", "Transaction memo").option("--destination-tag <tag>", "XRP DestinationTag (0 to 4294967295)").option("--dry-run", "Preview transaction without signing or broadcasting").option("--confirm", "Confirm and broadcast (without this flag, runs as a preview)").option("-y, --yes", "Alias for --confirm").option("--force", "Bypass the duplicate-broadcast guard (re-send an identical, recently-broadcast tx)").option("--password <password>", "Vault password for signing").addHelpText(
|
|
17000
16995
|
"after",
|
|
17001
16996
|
`
|
|
17002
16997
|
Examples:
|
|
@@ -17006,7 +17001,7 @@ Examples:
|
|
|
17006
17001
|
|
|
17007
17002
|
Environment variables:
|
|
17008
17003
|
VAULT_PASSWORD Vault password (bypasses prompt)
|
|
17009
|
-
VAULT_PASSWORDS
|
|
17004
|
+
VAULT_PASSWORDS JSON object or space-separated key:password pairs
|
|
17010
17005
|
|
|
17011
17006
|
See also: balance, tx-status`
|
|
17012
17007
|
).action(
|
|
@@ -17014,14 +17009,23 @@ See also: balance, tx-status`
|
|
|
17014
17009
|
async (chainStr, to, amount, options) => {
|
|
17015
17010
|
if (!amount && !options.max) throw new Error("Provide an amount or use --max");
|
|
17016
17011
|
if (amount && options.max) throw new Error("Cannot specify both amount and --max");
|
|
17012
|
+
const chain = findChainByName(chainStr) || chainStr;
|
|
17013
|
+
if (options.destinationTag !== void 0 && chain !== Chain14.Ripple) {
|
|
17014
|
+
throw new Error("--destination-tag is only supported for XRP");
|
|
17015
|
+
}
|
|
17016
|
+
const destinationTag = options.destinationTag === void 0 ? void 0 : Number(options.destinationTag);
|
|
17017
|
+
if (options.destinationTag !== void 0 && (!/^(0|[1-9]\d*)$/.test(options.destinationTag) || !Number.isSafeInteger(destinationTag) || destinationTag > 4294967295)) {
|
|
17018
|
+
throw new Error("Invalid XRP DestinationTag: expected an integer from 0 to 4294967295");
|
|
17019
|
+
}
|
|
17017
17020
|
const context = await init(program.opts().vault);
|
|
17018
17021
|
try {
|
|
17019
17022
|
await executeSend(context, {
|
|
17020
|
-
chain
|
|
17023
|
+
chain,
|
|
17021
17024
|
to,
|
|
17022
17025
|
amount: amount ?? "max",
|
|
17023
17026
|
tokenId: options.token,
|
|
17024
17027
|
memo: options.memo,
|
|
17028
|
+
destinationTag,
|
|
17025
17029
|
dryRun: options.dryRun,
|
|
17026
17030
|
yes: options.yes || options.confirm,
|
|
17027
17031
|
force: options.force,
|
|
@@ -17087,28 +17091,32 @@ program.command("broadcast").description("Broadcast a pre-signed raw transaction
|
|
|
17087
17091
|
});
|
|
17088
17092
|
})
|
|
17089
17093
|
);
|
|
17090
|
-
program.command("tx-status").description("Check
|
|
17094
|
+
program.command("tx-status").description("Check transaction status (polls until terminal or timeout)").requiredOption("--chain <chain>", "Target blockchain").requiredOption("--tx-hash <hash>", "Transaction hash to check").option("--no-wait", "Return immediately without waiting for confirmation").option("--timeout <seconds>", "Max seconds to poll before giving up (default 120)").addHelpText(
|
|
17091
17095
|
"after",
|
|
17092
17096
|
`
|
|
17097
|
+
Statuses: pending, not_found, confirmed, failed
|
|
17098
|
+
Malformed hashes fail with INVALID_HASH (exit 4).
|
|
17099
|
+
|
|
17093
17100
|
Examples:
|
|
17094
17101
|
vultisig tx-status --chain Ethereum --tx-hash 0xabc...
|
|
17095
17102
|
vultisig tx-status --chain Ethereum --tx-hash 0xabc... --timeout 300
|
|
17096
17103
|
vultisig tx-status --chain Bitcoin --tx-hash abc... --no-wait --output json`
|
|
17097
17104
|
).action(
|
|
17098
17105
|
withExit(async (options) => {
|
|
17099
|
-
const context = await init(program.opts().vault);
|
|
17100
17106
|
const timeoutSec = options.timeout !== void 0 ? Number(options.timeout) : void 0;
|
|
17101
17107
|
if (timeoutSec !== void 0 && (!Number.isFinite(timeoutSec) || timeoutSec < 0)) {
|
|
17102
17108
|
throw new InvalidInputError(
|
|
17103
17109
|
`Invalid --timeout: "${options.timeout}" (expected a non-negative number of seconds)`
|
|
17104
17110
|
);
|
|
17105
17111
|
}
|
|
17106
|
-
|
|
17112
|
+
const params = resolveTxStatusParams({
|
|
17107
17113
|
chain: findChainByName(options.chain) || options.chain,
|
|
17108
17114
|
txHash: options.txHash,
|
|
17109
17115
|
noWait: !options.wait,
|
|
17110
17116
|
timeoutSec
|
|
17111
17117
|
});
|
|
17118
|
+
const context = await init(program.opts().vault);
|
|
17119
|
+
await executeTxStatus(context, params);
|
|
17112
17120
|
})
|
|
17113
17121
|
);
|
|
17114
17122
|
program.command("portfolio").description(descriptions.portfolio.description).option("-c, --currency <currency>", "Fiat currency (usd, eur, gbp, etc.)", "usd").option("--raw", "Show raw values (wei/satoshis) for programmatic use").addHelpText(
|
|
@@ -17465,7 +17473,12 @@ Exit codes:
|
|
|
17465
17473
|
7 unknown/unexpected error
|
|
17466
17474
|
8 ACK_FAILED \u2014 broadcast succeeded but the post-broadcast report failed; the
|
|
17467
17475
|
emitted tx hash IS VALID, do NOT blindly retry (that risks a double-spend)
|
|
17468
|
-
9 duplicate-broadcast refused \u2014 nothing was sent; retry with --force
|
|
17476
|
+
9 duplicate-broadcast refused \u2014 nothing was sent; retry with --force
|
|
17477
|
+
10 agent turn blocked by a fund-safety guardrail
|
|
17478
|
+
11 model refusal or clarifying question; no action taken
|
|
17479
|
+
12 non-interactive confirmation/input required
|
|
17480
|
+
13 BROADCAST_COMMITTED \u2014 a transaction was submitted but the overall request may
|
|
17481
|
+
be incomplete; inspect every emitted hash and DO NOT blindly retry`
|
|
17469
17482
|
).action(
|
|
17470
17483
|
async (message, options) => {
|
|
17471
17484
|
const parentOpts = agentCmd.opts();
|
|
@@ -17537,14 +17550,20 @@ program.command("update").description("Check for updates and show update command
|
|
|
17537
17550
|
}
|
|
17538
17551
|
})
|
|
17539
17552
|
);
|
|
17540
|
-
var authCmd = program.command("auth").description("Manage
|
|
17541
|
-
authCmd.command("setup").description("
|
|
17553
|
+
var authCmd = program.command("auth").description("Manage stored vault credentials");
|
|
17554
|
+
authCmd.command("setup").description("Import a .vult file and store credentials in the OS keyring or encrypted file").option("--vault-file <path>", "Path to a specific .vult file").option("--non-interactive", "Fail instead of prompting (use env vars)").addHelpText(
|
|
17542
17555
|
"after",
|
|
17543
17556
|
`
|
|
17544
17557
|
Examples:
|
|
17545
17558
|
vultisig auth setup
|
|
17546
17559
|
vultisig auth setup --vault-file ~/vault.vult
|
|
17547
|
-
|
|
17560
|
+
|
|
17561
|
+
Keychain-less Docker/CI:
|
|
17562
|
+
VULTISIG_CONFIG_DIR=/data/vultisig \\
|
|
17563
|
+
VAULT_DECRYPT_PASSWORD=backup-password \\
|
|
17564
|
+
VAULT_PASSWORD=server-password \\
|
|
17565
|
+
VULTISIG_CREDENTIALS_PASSPHRASE=file-passphrase \\
|
|
17566
|
+
vultisig auth setup --non-interactive --vault-file /vaults/vault.vult`
|
|
17548
17567
|
).action(
|
|
17549
17568
|
withExit(async (options) => {
|
|
17550
17569
|
const result = await executeAuthSetup({
|