@vultisig/cli 4.1.0 → 4.3.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 +59 -0
- package/dist/index.js +140 -26
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# @vultisig/cli
|
|
2
2
|
|
|
3
|
+
## 4.3.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`c0ff9b5`](https://github.com/vultisig/vultisig-sdk/commit/c0ff9b5f8fe477df10850b25cc0def27ee31b6b4)]:
|
|
8
|
+
- @vultisig/core-chain@2.34.0
|
|
9
|
+
- @vultisig/sdk@4.3.0
|
|
10
|
+
- @vultisig/rujira@62.0.0
|
|
11
|
+
|
|
12
|
+
## 4.2.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#1605](https://github.com/vultisig/vultisig-sdk/pull/1605) [`1a23da3`](https://github.com/vultisig/vultisig-sdk/commit/1a23da39c7b50649b213efab13e02590d35db1a1) Thanks [@neavra](https://github.com/neavra)! - fix(agent): `agent ask` without `--yes` now reports the proposed transaction instead of a failure
|
|
17
|
+
|
|
18
|
+
`agent ask --help` documents the no-`--yes` path as read-safe: "it reports the
|
|
19
|
+
proposed transaction so a read-only prompt can't move funds." It did not. The
|
|
20
|
+
transaction built fine, the confirm gate correctly denied signing, and the
|
|
21
|
+
refusal was then fed back into the model loop — which retried, failed, and ended
|
|
22
|
+
the turn with `transactions: []`, `cards: []`, no proposed transaction, and a
|
|
23
|
+
stated cause that was wrong: that the build had errored, that there was no send
|
|
24
|
+
tool, or that a broadcast could not be confirmed. Nothing had ever been
|
|
25
|
+
authorized to broadcast.
|
|
26
|
+
|
|
27
|
+
Refusing to sign without `--yes` was always right. Discarding the built
|
|
28
|
+
transaction and reporting the refusal as a failed build was the defect.
|
|
29
|
+
|
|
30
|
+
In ask mode a declined signing now ENDS the turn — the gate there is a fixed
|
|
31
|
+
policy, not something a retry can satisfy — and the built, unsigned transaction
|
|
32
|
+
is surfaced as the turn's result: `proposed_transaction` (tool, summary, chain)
|
|
33
|
+
plus `confirmation_required` on the JSON envelope, and `proposed:` /
|
|
34
|
+
`confirmation-required:` lines on the human output. The exit code stays 12
|
|
35
|
+
(`CONFIRMATION_REQUIRED`), the same slot `send` and `swap` already use for
|
|
36
|
+
"needs `--yes`", and the error message now states what actually happened. This
|
|
37
|
+
covers `sign_typed_data` (e.g. a Polymarket bet) as well as `sign_tx`.
|
|
38
|
+
|
|
39
|
+
Results of client-side tools that already RAN in the same turn (`vault_chain`,
|
|
40
|
+
`vault_coin`, `address_book`) stay queued across the decline, so a committed
|
|
41
|
+
local mutation is still reported to the backend on the next request.
|
|
42
|
+
|
|
43
|
+
The TUI and pipe mode are unchanged: the discriminator is policy-vs-decision, not
|
|
44
|
+
headless-vs-interactive. Ask mode's gate is a constant; the TUI prompts a live
|
|
45
|
+
user and pipe mode blocks on a live host answer over stdin — there a decline is a
|
|
46
|
+
real decision the model should still get to acknowledge.
|
|
47
|
+
|
|
48
|
+
Also maps a backend turn outcome of `confirmation_required` onto exit 12 rather
|
|
49
|
+
than the generic safety-block exit 10.
|
|
50
|
+
|
|
51
|
+
- [#1604](https://github.com/vultisig/vultisig-sdk/pull/1604) [`9e88dcf`](https://github.com/vultisig/vultisig-sdk/commit/9e88dcf4875ebccfc7ea021707d99ec728a41eea) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Export `DEFAULT_CHAINS` and `defaultChains` from the root and React Native SDK entrypoints so consumers can reuse the canonical onboarding/import default-chain set instead of maintaining local mirrors.
|
|
52
|
+
|
|
53
|
+
- [#1613](https://github.com/vultisig/vultisig-sdk/pull/1613) [`68f8899`](https://github.com/vultisig/vultisig-sdk/commit/68f8899f6545b3876703e7a56b43d73a64217da2) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Export canonical `ChainKind` helpers from the React Native SDK entrypoint.
|
|
54
|
+
|
|
55
|
+
- [#1783](https://github.com/vultisig/vultisig-sdk/pull/1783) [`59c4b6d`](https://github.com/vultisig/vultisig-sdk/commit/59c4b6dcda667cf8f7e482ab1ec9666723d7f5c8) Thanks [@neavra](https://github.com/neavra)! - Emit an auditable signing summary in agent output after --yes approves signing
|
|
56
|
+
|
|
57
|
+
- Updated dependencies [[`5ce75b5`](https://github.com/vultisig/vultisig-sdk/commit/5ce75b53c527b373eb9ccacceac6edbaacf4ebec), [`eb7d862`](https://github.com/vultisig/vultisig-sdk/commit/eb7d86260a2ea5cdd661951d15677ec4db3517b0), [`9e88dcf`](https://github.com/vultisig/vultisig-sdk/commit/9e88dcf4875ebccfc7ea021707d99ec728a41eea), [`68f8899`](https://github.com/vultisig/vultisig-sdk/commit/68f8899f6545b3876703e7a56b43d73a64217da2), [`80b19bd`](https://github.com/vultisig/vultisig-sdk/commit/80b19bdbfbcb6af875a0b145bb02306552adac27), [`a812367`](https://github.com/vultisig/vultisig-sdk/commit/a812367923ac3781dc240d00124232c6f0cc3348)]:
|
|
58
|
+
- @vultisig/sdk@4.2.0
|
|
59
|
+
- @vultisig/core-chain@2.33.0
|
|
60
|
+
- @vultisig/rujira@61.0.0
|
|
61
|
+
|
|
3
62
|
## 4.1.0
|
|
4
63
|
|
|
5
64
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -10186,6 +10186,8 @@ var AskInterface = class {
|
|
|
10186
10186
|
polymarketCards = [];
|
|
10187
10187
|
warnings = [];
|
|
10188
10188
|
outcome;
|
|
10189
|
+
proposedTransaction;
|
|
10190
|
+
signingRecords = [];
|
|
10189
10191
|
error;
|
|
10190
10192
|
// Tracks whether the currently-latched `error` is a terminal one (e.g. the
|
|
10191
10193
|
// depth cap). A terminal error may overwrite a prior non-terminal one; once a
|
|
@@ -10245,6 +10247,12 @@ var AskInterface = class {
|
|
|
10245
10247
|
onTurnOutcome: (outcome) => {
|
|
10246
10248
|
this.outcome = outcome;
|
|
10247
10249
|
},
|
|
10250
|
+
onProposedTransaction: (proposed) => {
|
|
10251
|
+
this.proposedTransaction = proposed;
|
|
10252
|
+
},
|
|
10253
|
+
onSigningRecord: (record) => {
|
|
10254
|
+
this.signingRecords.push(record);
|
|
10255
|
+
},
|
|
10248
10256
|
onSuggestions: (_suggestions) => {
|
|
10249
10257
|
},
|
|
10250
10258
|
onTxStatus: (txHash, chain, status, explorerUrl) => {
|
|
@@ -10304,6 +10312,8 @@ var AskInterface = class {
|
|
|
10304
10312
|
this.polymarketCards = [];
|
|
10305
10313
|
this.warnings = [];
|
|
10306
10314
|
this.outcome = void 0;
|
|
10315
|
+
this.proposedTransaction = void 0;
|
|
10316
|
+
this.signingRecords = [];
|
|
10307
10317
|
this.error = void 0;
|
|
10308
10318
|
this.errorIsTerminal = false;
|
|
10309
10319
|
const callbacks = this.getCallbacks();
|
|
@@ -10328,8 +10338,10 @@ var AskInterface = class {
|
|
|
10328
10338
|
yieldCards: this.yieldCards,
|
|
10329
10339
|
polymarketCards: this.polymarketCards,
|
|
10330
10340
|
warnings: this.warnings,
|
|
10341
|
+
signingRecords: this.signingRecords,
|
|
10331
10342
|
error: this.error,
|
|
10332
|
-
...this.outcome ? { outcome: this.outcome } : {}
|
|
10343
|
+
...this.outcome ? { outcome: this.outcome } : {},
|
|
10344
|
+
...this.proposedTransaction ? { proposedTransaction: this.proposedTransaction } : {}
|
|
10333
10345
|
};
|
|
10334
10346
|
}
|
|
10335
10347
|
};
|
|
@@ -11103,6 +11115,16 @@ var AgentExecutor = class {
|
|
|
11103
11115
|
this.pendingPayloads.clear();
|
|
11104
11116
|
this.pendingLegs = [];
|
|
11105
11117
|
}
|
|
11118
|
+
/**
|
|
11119
|
+
* The chain the currently-buffered server tx targets, or null when nothing is
|
|
11120
|
+
* buffered. Read alongside {@link getPendingSummary} so a declined signing can
|
|
11121
|
+
* report the proposed transaction as a machine-readable surface — a read-safe
|
|
11122
|
+
* `agent ask` (no `--yes`) is documented to REPORT the proposed transaction,
|
|
11123
|
+
* and a prose summary alone is not something an integrator can branch on.
|
|
11124
|
+
*/
|
|
11125
|
+
getPendingChain() {
|
|
11126
|
+
return this.pendingPayloads.get("latest")?.chain ?? null;
|
|
11127
|
+
}
|
|
11106
11128
|
/**
|
|
11107
11129
|
* Human-readable one-line summary of the currently-buffered server tx
|
|
11108
11130
|
* (set by storeServerTransaction), for the pre-sign confirmation prompt.
|
|
@@ -11140,7 +11162,11 @@ var AgentExecutor = class {
|
|
|
11140
11162
|
const symbol = labels.token_resolved || labels.token_symbol || "";
|
|
11141
11163
|
const amountWithSymbol = symbol && !amount.endsWith(` ${symbol}`) ? `${amount} ${symbol}` : amount;
|
|
11142
11164
|
const to = p?.txArgs?.to || labels.recipient_echo || "?";
|
|
11143
|
-
|
|
11165
|
+
const contractTo = typeof p?.txArgs?.tx?.to === "string" ? p.txArgs.tx.to : "";
|
|
11166
|
+
const calldata = typeof p?.txArgs?.tx?.data === "string" ? p.txArgs.tx.data : "";
|
|
11167
|
+
const isContractSend = !!contractTo && calldata !== "" && calldata !== "0x";
|
|
11168
|
+
const contractPart = isContractSend && contractTo.toLowerCase() !== to.toLowerCase() ? ` (token contract ${contractTo})` : "";
|
|
11169
|
+
return `send ${amountWithSymbol} on ${stored.chain} to ${to}${contractPart}`;
|
|
11144
11170
|
}
|
|
11145
11171
|
/**
|
|
11146
11172
|
* Wrap a per-tool handler body with normalised success/failure → RecentAction
|
|
@@ -13697,6 +13723,9 @@ var PipeInterface = class {
|
|
|
13697
13723
|
explorer_url: explorerUrl
|
|
13698
13724
|
});
|
|
13699
13725
|
},
|
|
13726
|
+
onSigningRecord: (record) => {
|
|
13727
|
+
this.emit({ type: "signing_record", record });
|
|
13728
|
+
},
|
|
13700
13729
|
onError: (message, code) => {
|
|
13701
13730
|
this.emit({ type: "error", message, code });
|
|
13702
13731
|
},
|
|
@@ -13960,6 +13989,10 @@ var CLIENT_SIDE_DISPATCH_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
13960
13989
|
...Object.keys(CLIENT_SIDE_TOOL_DISPATCH)
|
|
13961
13990
|
]);
|
|
13962
13991
|
var MAX_MESSAGE_LOOP_DEPTH = 16;
|
|
13992
|
+
var PROPOSED_SUMMARY_MAX_CHARS = 500;
|
|
13993
|
+
function capSigningSummary(summary) {
|
|
13994
|
+
return summary.length > PROPOSED_SUMMARY_MAX_CHARS ? `${summary.slice(0, PROPOSED_SUMMARY_MAX_CHARS)}\u2026` : summary;
|
|
13995
|
+
}
|
|
13963
13996
|
var RECOVERY_POLL_INTERVAL_MS = 2e3;
|
|
13964
13997
|
var RECOVERY_MAX_POLLS = 90;
|
|
13965
13998
|
var TX_CONFIRM_POLL_INTERVAL_MS = 3e3;
|
|
@@ -13971,6 +14004,55 @@ function hasUnacknowledgedBroadcastResult(results) {
|
|
|
13971
14004
|
return typeof hash === "string" && hash.length > 0;
|
|
13972
14005
|
});
|
|
13973
14006
|
}
|
|
14007
|
+
function reportDeclinedSigning(executor, toolName, toolCallId, summary, input, ui) {
|
|
14008
|
+
const proposedChain = toolName === "sign_tx" ? executor.getPendingChain() : null;
|
|
14009
|
+
if (toolName === "sign_tx") executor.clearPendingTransaction();
|
|
14010
|
+
const proposed = capSigningSummary(summary);
|
|
14011
|
+
const declined = {
|
|
14012
|
+
tool: toolName,
|
|
14013
|
+
success: false,
|
|
14014
|
+
data: {
|
|
14015
|
+
error: "Transaction not confirmed",
|
|
14016
|
+
code: "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */,
|
|
14017
|
+
proposed,
|
|
14018
|
+
...proposedChain ? { proposed_chain: proposedChain } : {}
|
|
14019
|
+
}
|
|
14020
|
+
};
|
|
14021
|
+
ui.onProposedTransaction?.({
|
|
14022
|
+
tool: toolName,
|
|
14023
|
+
summary: proposed,
|
|
14024
|
+
...proposedChain ? { chain: proposedChain } : {}
|
|
14025
|
+
});
|
|
14026
|
+
ui.onToolCall(toolCallId, toolName, input);
|
|
14027
|
+
ui.onToolResult(
|
|
14028
|
+
toolCallId,
|
|
14029
|
+
toolName,
|
|
14030
|
+
false,
|
|
14031
|
+
declined.data,
|
|
14032
|
+
"Transaction not confirmed",
|
|
14033
|
+
"CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */
|
|
14034
|
+
);
|
|
14035
|
+
return declined;
|
|
14036
|
+
}
|
|
14037
|
+
function isAskModeDecline(askMode, recent) {
|
|
14038
|
+
return !!askMode && !!recent && !recent.success && recent.data?.code === "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */;
|
|
14039
|
+
}
|
|
14040
|
+
function takeQueuedAskModeDeclines(askMode, pending) {
|
|
14041
|
+
if (!askMode) return false;
|
|
14042
|
+
const kept = pending.filter((r) => !isAskModeDecline(askMode, r));
|
|
14043
|
+
if (kept.length === pending.length) return false;
|
|
14044
|
+
pending.splice(0, pending.length, ...kept);
|
|
14045
|
+
return true;
|
|
14046
|
+
}
|
|
14047
|
+
function finishDeclinedTurn(verbose, pendingCount, ui) {
|
|
14048
|
+
if (verbose) {
|
|
14049
|
+
process.stderr.write(
|
|
14050
|
+
`[session] signing declined and ask mode is non-interactive; ending turn with the proposed transaction (${pendingCount} already-executed result(s) stay queued)
|
|
14051
|
+
`
|
|
14052
|
+
);
|
|
14053
|
+
}
|
|
14054
|
+
ui.onDone();
|
|
14055
|
+
}
|
|
13974
14056
|
var AgentSession = class {
|
|
13975
14057
|
client;
|
|
13976
14058
|
vault;
|
|
@@ -14412,10 +14494,16 @@ var AgentSession = class {
|
|
|
14412
14494
|
ui,
|
|
14413
14495
|
() => this.executor.signTxFromBuffer(signToolCallId)
|
|
14414
14496
|
);
|
|
14415
|
-
this.
|
|
14497
|
+
const declinedInAskMode = isAskModeDecline(this.config.askMode, recent);
|
|
14498
|
+
if (!declinedInAskMode) this.pendingToolResults.push(recent);
|
|
14416
14499
|
if (!recent.success && recent.data?.code === "DUPLICATE_BROADCAST" /* DUPLICATE_BROADCAST */) {
|
|
14417
14500
|
ui.onError(String(recent.data.error ?? "duplicate broadcast refused"), "DUPLICATE_BROADCAST" /* DUPLICATE_BROADCAST */);
|
|
14418
14501
|
}
|
|
14502
|
+
if (declinedInAskMode) {
|
|
14503
|
+
takeQueuedAskModeDeclines(this.config.askMode, this.pendingToolResults);
|
|
14504
|
+
finishDeclinedTurn(this.config.verbose, this.pendingToolResults.length, ui);
|
|
14505
|
+
return;
|
|
14506
|
+
}
|
|
14419
14507
|
if (recent.success && recent.data) {
|
|
14420
14508
|
const txHash = recent.data.tx_hash;
|
|
14421
14509
|
const chain = recent.data.chain;
|
|
@@ -14427,6 +14515,10 @@ var AgentSession = class {
|
|
|
14427
14515
|
await this.processMessageLoop(null, ui, depth + 1);
|
|
14428
14516
|
return;
|
|
14429
14517
|
}
|
|
14518
|
+
if (takeQueuedAskModeDeclines(this.config.askMode, this.pendingToolResults)) {
|
|
14519
|
+
finishDeclinedTurn(this.config.verbose, this.pendingToolResults.length, ui);
|
|
14520
|
+
return;
|
|
14521
|
+
}
|
|
14430
14522
|
if (this.pendingToolResults.length > 0) {
|
|
14431
14523
|
await this.processMessageLoop(null, ui, depth + 1);
|
|
14432
14524
|
return;
|
|
@@ -14696,33 +14788,15 @@ var AgentSession = class {
|
|
|
14696
14788
|
* prompt was declined).
|
|
14697
14789
|
*/
|
|
14698
14790
|
async runPasswordGatedTool(toolName, toolCallId, ui, body, input) {
|
|
14791
|
+
let signingRecord;
|
|
14699
14792
|
if (PASSWORD_REQUIRED_TOOLS.has(toolName)) {
|
|
14700
14793
|
const summary = (toolName === "sign_tx" ? this.executor.getPendingSummary() : null) ?? `${toolName}${input ? ` ${JSON.stringify(input)}` : ""}`;
|
|
14701
14794
|
const approved = await ui.requestConfirmation(summary);
|
|
14702
14795
|
if (!approved) {
|
|
14703
|
-
|
|
14704
|
-
this.executor.clearPendingTransaction();
|
|
14705
|
-
}
|
|
14706
|
-
const declined = {
|
|
14707
|
-
tool: toolName,
|
|
14708
|
-
success: false,
|
|
14709
|
-
data: {
|
|
14710
|
-
error: "Transaction not confirmed",
|
|
14711
|
-
code: "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */,
|
|
14712
|
-
proposed: summary
|
|
14713
|
-
}
|
|
14714
|
-
};
|
|
14715
|
-
ui.onToolCall(toolCallId, toolName, input);
|
|
14716
|
-
ui.onToolResult(
|
|
14717
|
-
toolCallId,
|
|
14718
|
-
toolName,
|
|
14719
|
-
false,
|
|
14720
|
-
declined.data,
|
|
14721
|
-
"Transaction not confirmed",
|
|
14722
|
-
"CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */
|
|
14723
|
-
);
|
|
14724
|
-
return declined;
|
|
14796
|
+
return reportDeclinedSigning(this.executor, toolName, toolCallId, summary, input, ui);
|
|
14725
14797
|
}
|
|
14798
|
+
const chain = ui.onSigningRecord && toolName === "sign_tx" ? this.executor.getPendingChain() : null;
|
|
14799
|
+
signingRecord = { tool: toolName, summary: capSigningSummary(summary), ...chain ? { chain } : {} };
|
|
14726
14800
|
}
|
|
14727
14801
|
let promptedPassword;
|
|
14728
14802
|
if (PASSWORD_REQUIRED_TOOLS.has(toolName) && !this.config.password) {
|
|
@@ -14767,6 +14841,7 @@ var AgentSession = class {
|
|
|
14767
14841
|
const message = err instanceof Error ? err.message : String(err);
|
|
14768
14842
|
recent = { tool: toolName, success: false, data: { error: message } };
|
|
14769
14843
|
}
|
|
14844
|
+
if (signingRecord) ui.onSigningRecord?.({ ...signingRecord, success: recent.success });
|
|
14770
14845
|
const errorMsg = recent.data?.error ?? void 0;
|
|
14771
14846
|
const errorCode = recent.data?.code ?? void 0;
|
|
14772
14847
|
ui.onToolResult(toolCallId, toolName, recent.success, recent.data, errorMsg, errorCode);
|
|
@@ -15049,6 +15124,13 @@ var ChatTUI = class {
|
|
|
15049
15124
|
console.log(` ${chalk9.blue.underline(explorerUrl)}`);
|
|
15050
15125
|
}
|
|
15051
15126
|
},
|
|
15127
|
+
onSigningRecord: (record) => {
|
|
15128
|
+
if (record.success) {
|
|
15129
|
+
console.log(` ${chalk9.green("\u2713")} ${chalk9.bold("Signing approved")}: ${record.summary}`);
|
|
15130
|
+
} else {
|
|
15131
|
+
console.log(` ${chalk9.red("\u2717")} ${chalk9.bold("Signing approved but not completed")}: ${record.summary}`);
|
|
15132
|
+
}
|
|
15133
|
+
},
|
|
15052
15134
|
onError: (message, code) => {
|
|
15053
15135
|
if (this.isStreaming) {
|
|
15054
15136
|
process.stdout.write("\n");
|
|
@@ -15297,14 +15379,29 @@ async function executeAgent(ctx2, options) {
|
|
|
15297
15379
|
}
|
|
15298
15380
|
}
|
|
15299
15381
|
}
|
|
15382
|
+
function signingRecordsField(result) {
|
|
15383
|
+
return result?.signingRecords?.length ? { signing_records: result.signingRecords } : {};
|
|
15384
|
+
}
|
|
15385
|
+
function writeSigningRecordLines(records, write) {
|
|
15386
|
+
for (const record of records ?? []) {
|
|
15387
|
+
write(`signing-record:${record.success ? "signed" : "not-signed"}:${record.summary}
|
|
15388
|
+
`);
|
|
15389
|
+
}
|
|
15390
|
+
}
|
|
15300
15391
|
function outputAskError(wantsJson, message, code, conversationId, result) {
|
|
15301
15392
|
if (wantsJson) {
|
|
15302
15393
|
const data = {};
|
|
15303
15394
|
if (result?.transactions.length) data.transactions = result.transactions;
|
|
15395
|
+
Object.assign(data, signingRecordsField(result));
|
|
15304
15396
|
if (result?.toolCalls.length) data.tool_calls = result.toolCalls;
|
|
15305
15397
|
if (result?.response) data.response = result.response;
|
|
15306
15398
|
if (result?.warnings.length) data.warnings = result.warnings;
|
|
15307
15399
|
if (result?.outcome) data.outcome = result.outcome;
|
|
15400
|
+
if (result?.proposedTransaction) {
|
|
15401
|
+
data.confirmation_required = true;
|
|
15402
|
+
data.proposed_transaction = result.proposedTransaction;
|
|
15403
|
+
data.proposed = result.proposedTransaction.summary;
|
|
15404
|
+
}
|
|
15308
15405
|
outputErrorJson({
|
|
15309
15406
|
success: false,
|
|
15310
15407
|
v: 1,
|
|
@@ -15322,6 +15419,12 @@ function outputAskError(wantsJson, message, code, conversationId, result) {
|
|
|
15322
15419
|
}
|
|
15323
15420
|
if (result.response) process.stderr.write(`${result.response}
|
|
15324
15421
|
`);
|
|
15422
|
+
if (result.proposedTransaction) {
|
|
15423
|
+
process.stderr.write("confirmation-required:pass --yes to authorize signing\n");
|
|
15424
|
+
process.stderr.write(`proposed:${result.proposedTransaction.summary}
|
|
15425
|
+
`);
|
|
15426
|
+
}
|
|
15427
|
+
writeSigningRecordLines(result.signingRecords, (line) => process.stderr.write(line));
|
|
15325
15428
|
}
|
|
15326
15429
|
process.stderr.write(`Error: ${message} [${code}]
|
|
15327
15430
|
`);
|
|
@@ -15333,12 +15436,16 @@ function hasCommittedBroadcast(result) {
|
|
|
15333
15436
|
return !!result?.transactions.some((tx) => tx.hash.trim().length > 0 && tx.status !== "failed");
|
|
15334
15437
|
}
|
|
15335
15438
|
var SIGNING_TOOLS = /* @__PURE__ */ new Set(["sign_tx", "sign_typed_data"]);
|
|
15439
|
+
var CONFIRMATION_REQUIRED_MESSAGE = "The transaction was built but signing was not authorized, so nothing was signed or broadcast. Re-run with --yes to authorize signing.";
|
|
15336
15440
|
function failedSigningError(result) {
|
|
15337
15441
|
const failed = [...result.toolCalls].reverse().find((call) => SIGNING_TOOLS.has(call.action));
|
|
15338
15442
|
if (!failed || failed.success) return void 0;
|
|
15339
15443
|
const message = failed.error ?? (typeof failed.data?.error === "string" ? failed.data.error : void 0) ?? `${failed.action} failed`;
|
|
15340
15444
|
const dataCode = failed.data?.code;
|
|
15341
15445
|
const code = failed.code ?? (typeof dataCode === "string" && isAgentErrorCode(dataCode) ? dataCode : inferAgentErrorCodeFromMessage(message));
|
|
15446
|
+
if (code === "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */) {
|
|
15447
|
+
return { message: CONFIRMATION_REQUIRED_MESSAGE, code };
|
|
15448
|
+
}
|
|
15342
15449
|
return { message, code };
|
|
15343
15450
|
}
|
|
15344
15451
|
function outputPostBroadcastFailure(wantsJson, result, conversationId, classification, originalError) {
|
|
@@ -15346,6 +15453,7 @@ function outputPostBroadcastFailure(wantsJson, result, conversationId, classific
|
|
|
15346
15453
|
if (wantsJson) {
|
|
15347
15454
|
const data = {
|
|
15348
15455
|
transactions: result.transactions,
|
|
15456
|
+
...signingRecordsField(result),
|
|
15349
15457
|
tool_calls: result.toolCalls,
|
|
15350
15458
|
response: result.response,
|
|
15351
15459
|
...result.warnings.length ? { warnings: result.warnings } : {},
|
|
@@ -15382,6 +15490,7 @@ function outputPostBroadcastFailure(wantsJson, result, conversationId, classific
|
|
|
15382
15490
|
if (tx.explorerUrl) process.stderr.write(`explorer:${tx.explorerUrl}
|
|
15383
15491
|
`);
|
|
15384
15492
|
}
|
|
15493
|
+
writeSigningRecordLines(result.signingRecords, (line) => process.stderr.write(line));
|
|
15385
15494
|
process.stderr.write(
|
|
15386
15495
|
"WARNING: DO NOT blindly retry. Verify each transaction hash and continue only the incomplete step.\n"
|
|
15387
15496
|
);
|
|
@@ -15402,6 +15511,7 @@ function outputAskHuman(result, confirmationRequired, proposed) {
|
|
|
15402
15511
|
`);
|
|
15403
15512
|
}
|
|
15404
15513
|
}
|
|
15514
|
+
writeSigningRecordLines(result.signingRecords, (line) => process.stdout.write(line));
|
|
15405
15515
|
for (const card of result.cards) {
|
|
15406
15516
|
process.stdout.write(`
|
|
15407
15517
|
${renderBalanceSummaryCard(card)}
|
|
@@ -15445,6 +15555,7 @@ function outputAskSuccess(wantsJson, result, conversationId) {
|
|
|
15445
15555
|
response: result.response,
|
|
15446
15556
|
tool_calls: result.toolCalls,
|
|
15447
15557
|
transactions: result.transactions,
|
|
15558
|
+
...signingRecordsField(result),
|
|
15448
15559
|
...result.cards.length > 0 ? { cards: result.cards } : {},
|
|
15449
15560
|
...result.yieldCards.length > 0 ? { yield_cards: result.yieldCards } : {},
|
|
15450
15561
|
...result.polymarketCards.length > 0 ? { polymarket_cards: result.polymarketCards } : {},
|
|
@@ -15462,6 +15573,9 @@ function outputAskSuccess(wantsJson, result, conversationId) {
|
|
|
15462
15573
|
outputAskHuman(result, confirmationRequired, proposed);
|
|
15463
15574
|
}
|
|
15464
15575
|
function outcomeError(outcome) {
|
|
15576
|
+
if (outcome?.code === "confirmation_required") {
|
|
15577
|
+
return { message: CONFIRMATION_REQUIRED_MESSAGE, code: "CONFIRMATION_REQUIRED" /* CONFIRMATION_REQUIRED */ };
|
|
15578
|
+
}
|
|
15465
15579
|
switch (outcome?.kind) {
|
|
15466
15580
|
case "blocked":
|
|
15467
15581
|
return {
|
|
@@ -15651,7 +15765,7 @@ var cachedVersion = null;
|
|
|
15651
15765
|
function getVersion() {
|
|
15652
15766
|
if (cachedVersion) return cachedVersion;
|
|
15653
15767
|
if (true) {
|
|
15654
|
-
cachedVersion = "4.
|
|
15768
|
+
cachedVersion = "4.3.0";
|
|
15655
15769
|
return cachedVersion;
|
|
15656
15770
|
}
|
|
15657
15771
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "The self-custody MPC wallet CLI for AI coding agents (Claude Code, Cursor, OpenCode). Natural-language agent mode, 36+ chains, DKLS23 threshold signatures. Seedless.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
"@napi-rs/keyring": "^1.3.0",
|
|
75
75
|
"@noble/hashes": "^2.2.0",
|
|
76
76
|
"@vultisig/client-shared": "^0.3.3",
|
|
77
|
-
"@vultisig/core-chain": "^2.
|
|
78
|
-
"@vultisig/rujira": "^
|
|
79
|
-
"@vultisig/sdk": "^4.
|
|
77
|
+
"@vultisig/core-chain": "^2.34.0",
|
|
78
|
+
"@vultisig/rujira": "^62.0.0",
|
|
79
|
+
"@vultisig/sdk": "^4.3.0",
|
|
80
80
|
"chalk": "^5.6.2",
|
|
81
81
|
"cli-table3": "^0.6.5",
|
|
82
82
|
"commander": "^15.0.0",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@types/node": "^26.1.1",
|
|
95
95
|
"@types/tabtab": "^3.0.4",
|
|
96
96
|
"@types/ws": "^8.18.1",
|
|
97
|
-
"@vultisig/core-mpc": "^1.
|
|
97
|
+
"@vultisig/core-mpc": "^1.19.0",
|
|
98
98
|
"esbuild": "^0.28.1",
|
|
99
99
|
"ethers": "^6.17.0",
|
|
100
100
|
"node-pty": "^1.1.0",
|