@vultisig/cli 0.19.0 → 0.21.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 +40 -0
- package/dist/index.js +172 -62
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @vultisig/cli
|
|
2
2
|
|
|
3
|
+
## 0.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#350](https://github.com/vultisig/vultisig-sdk/pull/350) [`bad88d8`](https://github.com/vultisig/vultisig-sdk/commit/bad88d8d87229284c739995c027eb33d3ffc19e3) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - feat: cosmos-sdk staking module - generic Delegate/Undelegate/BeginRedelegate/WithdrawDelegatorReward + LCD queries
|
|
8
|
+
|
|
9
|
+
Adds the cosmos-sdk staking + distribution module to the SDK, generic across every ibcEnabled cosmos chain we support (Cosmos Hub, Osmosis, Kujira, Terra, TerraClassic, Akash, Noble, Dydx).
|
|
10
|
+
|
|
11
|
+
**Signing primitives** (`@vultisig/sdk` -> `chains.cosmos.buildCosmosStakingTx`):
|
|
12
|
+
- `MsgDelegate`, `MsgUndelegate`, `MsgBeginRedelegate`, `MsgWithdrawDelegatorReward`
|
|
13
|
+
- Hand-rolled RN-safe protobuf (no cosmjs runtime dep) mirroring the existing `buildCosmosWasmExecuteTx` pattern
|
|
14
|
+
- Multi-msg batch txs supported (e.g. claim rewards from many validators in one tx)
|
|
15
|
+
- Byte-for-byte round-trip verified against `cosmjs-types` canonical decoder
|
|
16
|
+
|
|
17
|
+
**LCD query helpers** (`@vultisig/sdk` top-level + `@vultisig/core-chain/chains/cosmos/staking/lcdQueries`):
|
|
18
|
+
- `getCosmosDelegations(chain, address)` -> per-validator balance + shares
|
|
19
|
+
- `getCosmosUnbondingDelegations(chain, address)` -> pending unbondings with completion time
|
|
20
|
+
- `getCosmosDelegatorRewards(chain, address)` -> per-validator rewards + total
|
|
21
|
+
- `getCosmosVestingAccount(chain, address)` -> Periodic / Continuous / Delayed detection (returns null otherwise)
|
|
22
|
+
|
|
23
|
+
ship-once, unlock-many: adding a future cosmos chain is a config-only change.
|
|
24
|
+
|
|
25
|
+
34 new unit tests including 4 real cosmoshub fixtures captured from `cosmos1a8l3srqyk5krvzhkt7cyzy52yxcght6322w2qy`.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Updated dependencies [[`bad88d8`](https://github.com/vultisig/vultisig-sdk/commit/bad88d8d87229284c739995c027eb33d3ffc19e3)]:
|
|
30
|
+
- @vultisig/sdk@0.21.0
|
|
31
|
+
- @vultisig/client-shared@0.2.5
|
|
32
|
+
- @vultisig/rujira@16.0.0
|
|
33
|
+
|
|
34
|
+
## 0.20.0
|
|
35
|
+
|
|
36
|
+
### Patch Changes
|
|
37
|
+
|
|
38
|
+
- Updated dependencies [[`1d1c02c`](https://github.com/vultisig/vultisig-sdk/commit/1d1c02c37e58340b0617eec3a5e44909efc9b452)]:
|
|
39
|
+
- @vultisig/sdk@0.20.0
|
|
40
|
+
- @vultisig/client-shared@0.2.4
|
|
41
|
+
- @vultisig/rujira@15.0.0
|
|
42
|
+
|
|
3
43
|
## 0.19.0
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1654,7 +1654,7 @@ var thorchainMidgardBaseUrl, POOL_ID_RE, assertValidPoolId, isValidPoolId, norma
|
|
|
1654
1654
|
var init_pools = __esm({
|
|
1655
1655
|
"../../packages/core/chain/dist/chains/cosmos/thor/lp/pools.js"() {
|
|
1656
1656
|
init_queryUrl();
|
|
1657
|
-
thorchainMidgardBaseUrl = "https://midgard.
|
|
1657
|
+
thorchainMidgardBaseUrl = "https://midgard.thorchain.network";
|
|
1658
1658
|
POOL_ID_RE = /^[A-Z0-9]+\.[A-Z0-9]+(-[A-Z0-9]+)?$/;
|
|
1659
1659
|
assertValidPoolId = (pool) => {
|
|
1660
1660
|
if (typeof pool !== "string" || pool.length === 0) {
|
|
@@ -6091,6 +6091,11 @@ var AgentClient = class {
|
|
|
6091
6091
|
}
|
|
6092
6092
|
const toolName = inlineName ?? (callId ? toolNameByCallId.get(callId) : void 0);
|
|
6093
6093
|
const label = typeof parsed.label === "string" ? parsed.label : void 0;
|
|
6094
|
+
if (v1Type === "tool-input-available" && parsed.clientExecuted === true && callId && toolName && callbacks.onClientSideToolCall) {
|
|
6095
|
+
const rawInput = parsed.input;
|
|
6096
|
+
const input = rawInput && typeof rawInput === "object" && !Array.isArray(rawInput) ? rawInput : {};
|
|
6097
|
+
callbacks.onClientSideToolCall(callId, toolName, input);
|
|
6098
|
+
}
|
|
6094
6099
|
if (status && toolName) {
|
|
6095
6100
|
callbacks.onToolProgress?.(toolName, status, label);
|
|
6096
6101
|
}
|
|
@@ -8420,6 +8425,25 @@ import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, wri
|
|
|
8420
8425
|
import { homedir as homedir2 } from "node:os";
|
|
8421
8426
|
import { join as join2 } from "node:path";
|
|
8422
8427
|
import { MemoryStorage, PushNotificationService } from "@vultisig/sdk";
|
|
8428
|
+
var CLIENT_SIDE_TOOL_DISPATCH = {
|
|
8429
|
+
sign_typed_data: "sign_typed_data",
|
|
8430
|
+
add_coin: "add_coin",
|
|
8431
|
+
remove_coin: "remove_coin",
|
|
8432
|
+
add_chain: "add_chain",
|
|
8433
|
+
remove_chain: "remove_chain",
|
|
8434
|
+
address_book_add: "address_book_add",
|
|
8435
|
+
address_book_remove: "address_book_remove"
|
|
8436
|
+
};
|
|
8437
|
+
var MAX_MESSAGE_LOOP_DEPTH = 16;
|
|
8438
|
+
function actionResultToRecentAction(r) {
|
|
8439
|
+
if (r.success) {
|
|
8440
|
+
return { tool: r.action, success: true, data: r.data ?? {} };
|
|
8441
|
+
}
|
|
8442
|
+
const data = { ...r.data ?? {} };
|
|
8443
|
+
if (r.error) data.error = r.error;
|
|
8444
|
+
if (r.code) data.code = r.code;
|
|
8445
|
+
return { tool: r.action, success: false, data };
|
|
8446
|
+
}
|
|
8423
8447
|
var AgentSession = class {
|
|
8424
8448
|
client;
|
|
8425
8449
|
vault;
|
|
@@ -8431,6 +8455,8 @@ var AgentSession = class {
|
|
|
8431
8455
|
abortController = null;
|
|
8432
8456
|
historyMessages = [];
|
|
8433
8457
|
pushService = null;
|
|
8458
|
+
// Flushed into context.recent_actions on the next outbound request.
|
|
8459
|
+
pendingToolResults = [];
|
|
8434
8460
|
constructor(vault, config) {
|
|
8435
8461
|
this.vault = vault;
|
|
8436
8462
|
this.config = config;
|
|
@@ -8552,17 +8578,10 @@ var AgentSession = class {
|
|
|
8552
8578
|
} catch {
|
|
8553
8579
|
}
|
|
8554
8580
|
try {
|
|
8555
|
-
await this.processMessageLoop(content,
|
|
8581
|
+
await this.processMessageLoop(content, ui);
|
|
8556
8582
|
} catch (err) {
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
const auth = await authenticateVault(this.client, this.vault, this.config.password);
|
|
8560
|
-
this.client.setAuthToken(auth.token);
|
|
8561
|
-
saveCachedToken(this.publicKey, auth.token, auth.expiresAt);
|
|
8562
|
-
await this.processMessageLoop(content, null, ui);
|
|
8563
|
-
} else {
|
|
8564
|
-
throw err;
|
|
8565
|
-
}
|
|
8583
|
+
this.pendingToolResults = [];
|
|
8584
|
+
throw err;
|
|
8566
8585
|
} finally {
|
|
8567
8586
|
this.abortController = null;
|
|
8568
8587
|
}
|
|
@@ -8571,11 +8590,20 @@ var AgentSession = class {
|
|
|
8571
8590
|
* Core message processing loop.
|
|
8572
8591
|
* Sends content or action results, executes returned actions, repeats.
|
|
8573
8592
|
*/
|
|
8574
|
-
async processMessageLoop(content,
|
|
8593
|
+
async processMessageLoop(content, ui, depth = 0) {
|
|
8575
8594
|
if (!this.conversationId) return;
|
|
8595
|
+
if (depth > MAX_MESSAGE_LOOP_DEPTH) {
|
|
8596
|
+
process.stderr.write(
|
|
8597
|
+
`[session] processMessageLoop exceeded MAX_MESSAGE_LOOP_DEPTH (${MAX_MESSAGE_LOOP_DEPTH}); stopping. pendingToolResults=${this.pendingToolResults.length}
|
|
8598
|
+
`
|
|
8599
|
+
);
|
|
8600
|
+
this.pendingToolResults = [];
|
|
8601
|
+
ui.onDone();
|
|
8602
|
+
return;
|
|
8603
|
+
}
|
|
8576
8604
|
const request = {
|
|
8577
8605
|
public_key: this.publicKey,
|
|
8578
|
-
context: this.cachedContext
|
|
8606
|
+
context: this.cachedContext ? { ...this.cachedContext } : {}
|
|
8579
8607
|
};
|
|
8580
8608
|
if (this.config.viaAgent || this.config.askMode) {
|
|
8581
8609
|
request.via_agent = true;
|
|
@@ -8583,61 +8611,92 @@ var AgentSession = class {
|
|
|
8583
8611
|
if (content) {
|
|
8584
8612
|
request.content = content;
|
|
8585
8613
|
}
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
...!result.success && result.code ? { code: result.code } : {}
|
|
8595
|
-
};
|
|
8614
|
+
let flushedThisCall = [];
|
|
8615
|
+
if (this.pendingToolResults.length > 0) {
|
|
8616
|
+
flushedThisCall = [...this.pendingToolResults];
|
|
8617
|
+
request.context.recent_actions = this.pendingToolResults.splice(0);
|
|
8618
|
+
if (this.config.verbose) {
|
|
8619
|
+
process.stderr.write(`[session] flushed ${request.context.recent_actions.length} recent_actions into request
|
|
8620
|
+
`);
|
|
8621
|
+
}
|
|
8596
8622
|
}
|
|
8597
8623
|
let serverTxStoredFromStream = 0;
|
|
8598
|
-
const
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
}
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8624
|
+
const pendingDispatches = [];
|
|
8625
|
+
let dispatchChain = Promise.resolve();
|
|
8626
|
+
const callbacks = {
|
|
8627
|
+
onTextDelta: (delta) => ui.onTextDelta(delta),
|
|
8628
|
+
onToolProgress: (tool, status, label) => {
|
|
8629
|
+
if (status === "running") {
|
|
8630
|
+
ui.onToolCall(`mcp-${tool}`, tool);
|
|
8631
|
+
} else {
|
|
8632
|
+
ui.onToolResult(`mcp-${tool}`, tool, true, { label });
|
|
8633
|
+
}
|
|
8634
|
+
},
|
|
8635
|
+
onClientSideToolCall: (toolCallId, toolName, input) => {
|
|
8636
|
+
const dispatch = dispatchChain.then(() => this.dispatchClientSideTool(toolCallId, toolName, input, ui));
|
|
8637
|
+
dispatchChain = dispatch.catch(() => {
|
|
8638
|
+
});
|
|
8639
|
+
pendingDispatches.push(dispatch);
|
|
8640
|
+
},
|
|
8641
|
+
onTitle: (_title) => {
|
|
8642
|
+
},
|
|
8643
|
+
onActions: (_actions) => {
|
|
8644
|
+
},
|
|
8645
|
+
onSuggestions: (suggestions) => {
|
|
8646
|
+
ui.onSuggestions(suggestions);
|
|
8647
|
+
},
|
|
8648
|
+
onTxReady: (tx) => {
|
|
8649
|
+
if (this.executor.storeServerTransaction(tx)) {
|
|
8650
|
+
serverTxStoredFromStream++;
|
|
8651
|
+
if (this.config.password) {
|
|
8652
|
+
this.executor.setPassword(this.config.password);
|
|
8623
8653
|
}
|
|
8624
|
-
},
|
|
8625
|
-
onMessage: (_msg) => {
|
|
8626
|
-
},
|
|
8627
|
-
onError: (error2, code) => {
|
|
8628
|
-
ui.onError(error2, code);
|
|
8629
8654
|
}
|
|
8630
8655
|
},
|
|
8631
|
-
|
|
8632
|
-
|
|
8656
|
+
onMessage: (_msg) => {
|
|
8657
|
+
},
|
|
8658
|
+
onError: (error2, code) => {
|
|
8659
|
+
ui.onError(error2, code);
|
|
8660
|
+
}
|
|
8661
|
+
};
|
|
8662
|
+
let streamResult;
|
|
8663
|
+
let authRetried = false;
|
|
8664
|
+
while (true) {
|
|
8665
|
+
try {
|
|
8666
|
+
streamResult = await this.client.sendMessageStream(
|
|
8667
|
+
this.conversationId,
|
|
8668
|
+
request,
|
|
8669
|
+
callbacks,
|
|
8670
|
+
this.abortController?.signal
|
|
8671
|
+
);
|
|
8672
|
+
break;
|
|
8673
|
+
} catch (err) {
|
|
8674
|
+
const isAuthErr = err.message?.includes("401") || err.message?.includes("403");
|
|
8675
|
+
if (isAuthErr && !authRetried) {
|
|
8676
|
+
authRetried = true;
|
|
8677
|
+
clearCachedToken(this.publicKey);
|
|
8678
|
+
const auth = await authenticateVault(this.client, this.vault, this.config.password);
|
|
8679
|
+
this.client.setAuthToken(auth.token);
|
|
8680
|
+
saveCachedToken(this.publicKey, auth.token, auth.expiresAt);
|
|
8681
|
+
continue;
|
|
8682
|
+
}
|
|
8683
|
+
if (flushedThisCall.length > 0) {
|
|
8684
|
+
this.pendingToolResults = [...flushedThisCall, ...this.pendingToolResults];
|
|
8685
|
+
}
|
|
8686
|
+
throw err;
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8689
|
+
if (pendingDispatches.length > 0) {
|
|
8690
|
+
await Promise.all(pendingDispatches);
|
|
8691
|
+
}
|
|
8633
8692
|
const responseText = streamResult.message?.content || streamResult.fullText || "";
|
|
8634
8693
|
const displayText = stripLeakedToolCallTags(responseText);
|
|
8635
8694
|
if (displayText) {
|
|
8636
8695
|
ui.onAssistantMessage(displayText);
|
|
8637
8696
|
}
|
|
8638
|
-
const
|
|
8639
|
-
if (
|
|
8640
|
-
const results = await this.executeActions(
|
|
8697
|
+
const legacyActions = streamResult.actions.filter((a) => a.type !== "sign_tx");
|
|
8698
|
+
if (legacyActions.length > 0) {
|
|
8699
|
+
const results = await this.executeActions(legacyActions, ui);
|
|
8641
8700
|
const hasBuildSuccess = results.some((r) => r.success && r.action.startsWith("build_"));
|
|
8642
8701
|
if (hasBuildSuccess && this.executor.hasPendingTransaction()) {
|
|
8643
8702
|
if (this.config.verbose)
|
|
@@ -8653,14 +8712,16 @@ var AgentSession = class {
|
|
|
8653
8712
|
const signResults = await this.executeActions([signAction], ui);
|
|
8654
8713
|
const signResult = signResults[0];
|
|
8655
8714
|
if (signResult) {
|
|
8656
|
-
|
|
8715
|
+
this.pendingToolResults.push(actionResultToRecentAction(signResult));
|
|
8716
|
+
await this.processMessageLoop(null, ui, depth + 1);
|
|
8657
8717
|
return;
|
|
8658
8718
|
}
|
|
8659
8719
|
}
|
|
8660
8720
|
if (results.length > 0) {
|
|
8661
8721
|
for (const result of results) {
|
|
8662
|
-
|
|
8722
|
+
this.pendingToolResults.push(actionResultToRecentAction(result));
|
|
8663
8723
|
}
|
|
8724
|
+
await this.processMessageLoop(null, ui, depth + 1);
|
|
8664
8725
|
return;
|
|
8665
8726
|
}
|
|
8666
8727
|
}
|
|
@@ -8680,13 +8741,62 @@ var AgentSession = class {
|
|
|
8680
8741
|
const results = await this.executeActions([signAction], ui);
|
|
8681
8742
|
if (results.length > 0) {
|
|
8682
8743
|
for (const result of results) {
|
|
8683
|
-
|
|
8744
|
+
this.pendingToolResults.push(actionResultToRecentAction(result));
|
|
8684
8745
|
}
|
|
8746
|
+
await this.processMessageLoop(null, ui, depth + 1);
|
|
8685
8747
|
return;
|
|
8686
8748
|
}
|
|
8687
8749
|
}
|
|
8750
|
+
if (this.pendingToolResults.length > 0) {
|
|
8751
|
+
await this.processMessageLoop(null, ui, depth + 1);
|
|
8752
|
+
return;
|
|
8753
|
+
}
|
|
8688
8754
|
ui.onDone();
|
|
8689
8755
|
}
|
|
8756
|
+
// Routes client-side tool calls through executeAction. Missing registry
|
|
8757
|
+
// entries surface as a visible `[cli] unimplemented` warning + failure
|
|
8758
|
+
// RecentAction (never silent).
|
|
8759
|
+
async dispatchClientSideTool(toolCallId, toolName, input, ui) {
|
|
8760
|
+
const actionType = CLIENT_SIDE_TOOL_DISPATCH[toolName];
|
|
8761
|
+
if (!actionType) {
|
|
8762
|
+
process.stderr.write(`[cli] unimplemented client-side tool: ${toolName}
|
|
8763
|
+
`);
|
|
8764
|
+
this.pendingToolResults.push({
|
|
8765
|
+
tool: toolName,
|
|
8766
|
+
success: false,
|
|
8767
|
+
data: { error: `unimplemented in CLI: ${toolName}` }
|
|
8768
|
+
});
|
|
8769
|
+
return;
|
|
8770
|
+
}
|
|
8771
|
+
const action = {
|
|
8772
|
+
id: toolCallId,
|
|
8773
|
+
type: actionType,
|
|
8774
|
+
title: toolName,
|
|
8775
|
+
params: input,
|
|
8776
|
+
auto_execute: true
|
|
8777
|
+
};
|
|
8778
|
+
try {
|
|
8779
|
+
const results = await this.executeActions([action], ui);
|
|
8780
|
+
const result = results[0];
|
|
8781
|
+
if (result) {
|
|
8782
|
+
const recent = actionResultToRecentAction(result);
|
|
8783
|
+
if (recent.data === void 0) recent.data = {};
|
|
8784
|
+
for (const key of Object.keys(input)) {
|
|
8785
|
+
if (key.startsWith("__") || key === "pm_order_ref") {
|
|
8786
|
+
recent.data[key] = input[key];
|
|
8787
|
+
}
|
|
8788
|
+
}
|
|
8789
|
+
this.pendingToolResults.push(recent);
|
|
8790
|
+
}
|
|
8791
|
+
} catch (err) {
|
|
8792
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
8793
|
+
this.pendingToolResults.push({
|
|
8794
|
+
tool: toolName,
|
|
8795
|
+
success: false,
|
|
8796
|
+
data: { error: message }
|
|
8797
|
+
});
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8690
8800
|
/**
|
|
8691
8801
|
* Execute a list of actions, handling password requirements.
|
|
8692
8802
|
*/
|
|
@@ -9343,7 +9453,7 @@ var cachedVersion = null;
|
|
|
9343
9453
|
function getVersion() {
|
|
9344
9454
|
if (cachedVersion) return cachedVersion;
|
|
9345
9455
|
if (true) {
|
|
9346
|
-
cachedVersion = "0.
|
|
9456
|
+
cachedVersion = "0.21.0";
|
|
9347
9457
|
return cachedVersion;
|
|
9348
9458
|
}
|
|
9349
9459
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.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": {
|
|
@@ -73,10 +73,10 @@
|
|
|
73
73
|
"@cosmjs/stargate": "^0.38.1",
|
|
74
74
|
"@napi-rs/keyring": "^1.2.0",
|
|
75
75
|
"@noble/hashes": "^2.0.1",
|
|
76
|
-
"@vultisig/client-shared": "^0.2.
|
|
76
|
+
"@vultisig/client-shared": "^0.2.5",
|
|
77
77
|
"@vultisig/core-chain": "^1.4.1",
|
|
78
|
-
"@vultisig/rujira": "^
|
|
79
|
-
"@vultisig/sdk": "^0.
|
|
78
|
+
"@vultisig/rujira": "^16.0.0",
|
|
79
|
+
"@vultisig/sdk": "^0.21.0",
|
|
80
80
|
"chalk": "^5.6.2",
|
|
81
81
|
"cli-table3": "^0.6.5",
|
|
82
82
|
"commander": "^14.0.3",
|