@vultisig/cli 0.2.0-beta.8 → 0.2.0-beta.9
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 +28 -0
- package/README.md +198 -0
- package/dist/index.js +149 -18
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @vultisig/cli
|
|
2
2
|
|
|
3
|
+
## 0.2.0-beta.9
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#64](https://github.com/vultisig/vultisig-sdk/pull/64) [`a36a7f6`](https://github.com/vultisig/vultisig-sdk/commit/a36a7f614c03e32ebc7e843cbf1ab30b6be0d4af) Thanks [@bornslippynuxx](https://github.com/bornslippynuxx)! - feat(sdk): add broadcastRawTx() for broadcasting pre-signed transactions
|
|
8
|
+
|
|
9
|
+
Adds `broadcastRawTx()` method supporting all chain families:
|
|
10
|
+
- EVM: Ethereum, Polygon, BSC, Arbitrum, Base, etc. (hex-encoded)
|
|
11
|
+
- UTXO: Bitcoin, Litecoin, Dogecoin, etc. (hex-encoded)
|
|
12
|
+
- Solana: Base58 or Base64 encoded transaction bytes
|
|
13
|
+
- Cosmos: JSON `{tx_bytes}` or raw base64 protobuf (10 chains)
|
|
14
|
+
- TON: BOC as base64 string
|
|
15
|
+
- Polkadot: Hex-encoded extrinsic
|
|
16
|
+
- Ripple: Hex-encoded transaction blob
|
|
17
|
+
- Sui: JSON `{unsignedTx, signature}`
|
|
18
|
+
- Tron: JSON transaction object
|
|
19
|
+
|
|
20
|
+
CLI commands added:
|
|
21
|
+
- `vultisig sign --chain <chain> --bytes <base64>` - sign pre-hashed data
|
|
22
|
+
- `vultisig broadcast --chain <chain> --raw-tx <data>` - broadcast raw tx
|
|
23
|
+
|
|
24
|
+
Documentation updated with complete workflow examples for EVM, UTXO, Solana, and Sui.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`a36a7f6`](https://github.com/vultisig/vultisig-sdk/commit/a36a7f614c03e32ebc7e843cbf1ab30b6be0d4af), [`91990d3`](https://github.com/vultisig/vultisig-sdk/commit/91990d3fc7ef1a8d7068f5cbae8f8f3dda5b68f3)]:
|
|
29
|
+
- @vultisig/sdk@0.2.0-beta.9
|
|
30
|
+
|
|
3
31
|
## 0.2.0-beta.8
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -244,6 +244,204 @@ vultisig swap ethereum bitcoin 0.1 --password mypassword
|
|
|
244
244
|
vultisig swap ethereum bitcoin 0.1 -y --password mypassword
|
|
245
245
|
```
|
|
246
246
|
|
|
247
|
+
### Advanced Operations
|
|
248
|
+
|
|
249
|
+
| Command | Description |
|
|
250
|
+
|---------|-------------|
|
|
251
|
+
| `sign` | Sign pre-hashed bytes for custom transactions |
|
|
252
|
+
| `broadcast` | Broadcast a pre-signed raw transaction |
|
|
253
|
+
|
|
254
|
+
#### Signing Arbitrary Bytes
|
|
255
|
+
|
|
256
|
+
Sign pre-hashed data for externally constructed transactions:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
# Sign a pre-hashed message (base64 encoded)
|
|
260
|
+
vultisig sign --chain ethereum --bytes "aGVsbG8gd29ybGQ="
|
|
261
|
+
|
|
262
|
+
# With password
|
|
263
|
+
vultisig sign --chain bitcoin --bytes "..." --password mypassword
|
|
264
|
+
|
|
265
|
+
# JSON output
|
|
266
|
+
vultisig sign --chain ethereum --bytes "..." -o json
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Output:**
|
|
270
|
+
```
|
|
271
|
+
Signature: <base64-encoded signature>
|
|
272
|
+
Recovery: 0
|
|
273
|
+
Format: ecdsa
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**JSON output:**
|
|
277
|
+
```json
|
|
278
|
+
{
|
|
279
|
+
"signature": "<base64>",
|
|
280
|
+
"recovery": 0,
|
|
281
|
+
"format": "ecdsa"
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Broadcasting Raw Transactions
|
|
286
|
+
|
|
287
|
+
Broadcast pre-signed transactions to the network:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# EVM transaction (hex)
|
|
291
|
+
vultisig broadcast --chain ethereum --raw-tx "0x02f8..."
|
|
292
|
+
|
|
293
|
+
# Bitcoin transaction (hex)
|
|
294
|
+
vultisig broadcast --chain bitcoin --raw-tx "0200000001..."
|
|
295
|
+
|
|
296
|
+
# Solana transaction (base64)
|
|
297
|
+
vultisig broadcast --chain solana --raw-tx "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABAwIAAA..."
|
|
298
|
+
|
|
299
|
+
# Sui transaction (JSON)
|
|
300
|
+
vultisig broadcast --chain sui --raw-tx '{"unsignedTx":"...","signature":"..."}'
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Output:**
|
|
304
|
+
```
|
|
305
|
+
TX Hash: 0x9f8e7d6c...
|
|
306
|
+
Explorer: https://etherscan.io/tx/0x9f8e7d6c...
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Supported broadcast formats by chain:**
|
|
310
|
+
|
|
311
|
+
| Chain | `--raw-tx` Format |
|
|
312
|
+
|-------|-------------------|
|
|
313
|
+
| EVM (Ethereum, Polygon, etc.) | Hex-encoded signed tx |
|
|
314
|
+
| UTXO (Bitcoin, Litecoin, etc.) | Hex-encoded raw tx |
|
|
315
|
+
| Solana | Base64-encoded tx bytes |
|
|
316
|
+
| Sui | JSON: `{"unsignedTx":"...","signature":"..."}` |
|
|
317
|
+
| Cosmos | JSON: `{"tx_bytes":"..."}` or base64 |
|
|
318
|
+
| TON | Base64 BOC |
|
|
319
|
+
| Polkadot | Hex-encoded extrinsic |
|
|
320
|
+
| Ripple | Hex-encoded tx blob |
|
|
321
|
+
| Tron | JSON tx object |
|
|
322
|
+
|
|
323
|
+
#### Example: Custom EVM Transaction
|
|
324
|
+
|
|
325
|
+
Build and sign a transaction with ethers.js, broadcast with CLI:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
# 1. Build transaction externally (save as build-evm-tx.js)
|
|
329
|
+
cat > build-evm-tx.js << 'EOF'
|
|
330
|
+
const { keccak256, Transaction, parseEther } = require('ethers');
|
|
331
|
+
const tx = Transaction.from({
|
|
332
|
+
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
|
|
333
|
+
value: parseEther('0.01'),
|
|
334
|
+
gasLimit: 21000n,
|
|
335
|
+
maxFeePerGas: 50000000000n,
|
|
336
|
+
maxPriorityFeePerGas: 2000000000n,
|
|
337
|
+
nonce: 0,
|
|
338
|
+
chainId: 1,
|
|
339
|
+
type: 2
|
|
340
|
+
});
|
|
341
|
+
const hash = keccak256(tx.unsignedSerialized);
|
|
342
|
+
console.log('HASH:', Buffer.from(hash.slice(2), 'hex').toString('base64'));
|
|
343
|
+
console.log('UNSIGNED:', tx.unsignedSerialized);
|
|
344
|
+
EOF
|
|
345
|
+
node build-evm-tx.js
|
|
346
|
+
|
|
347
|
+
# 2. Sign the hash with Vultisig
|
|
348
|
+
vultisig sign --chain ethereum --bytes "<base64-hash-from-step-1>" -o json > sig.json
|
|
349
|
+
|
|
350
|
+
# 3. Assemble signed transaction (use r,s,v from sig.json)
|
|
351
|
+
# The signature field contains r||s (64 bytes hex), recovery is v
|
|
352
|
+
|
|
353
|
+
# 4. Broadcast the assembled signed transaction
|
|
354
|
+
vultisig broadcast --chain ethereum --raw-tx "0x02f8..."
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### Example: Custom Bitcoin Transaction
|
|
358
|
+
|
|
359
|
+
Build a PSBT with bitcoinjs-lib, sign with CLI:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
# 1. Build PSBT and get sighash (save as build-btc-tx.js)
|
|
363
|
+
cat > build-btc-tx.js << 'EOF'
|
|
364
|
+
const bitcoin = require('bitcoinjs-lib');
|
|
365
|
+
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin });
|
|
366
|
+
// Add your inputs and outputs
|
|
367
|
+
psbt.addInput({
|
|
368
|
+
hash: '<previous-txid>',
|
|
369
|
+
index: 0,
|
|
370
|
+
witnessUtxo: { script: Buffer.from('...'), value: 100000 }
|
|
371
|
+
});
|
|
372
|
+
psbt.addOutput({ address: 'bc1q...', value: 90000 });
|
|
373
|
+
// Get sighash for signing
|
|
374
|
+
const sighash = psbt.getTxForSigning().hashForWitnessV0(0, scriptCode, 100000, 0x01);
|
|
375
|
+
console.log('SIGHASH:', sighash.toString('base64'));
|
|
376
|
+
EOF
|
|
377
|
+
node build-btc-tx.js
|
|
378
|
+
|
|
379
|
+
# 2. Sign with Vultisig
|
|
380
|
+
vultisig sign --chain bitcoin --bytes "<base64-sighash>" -o json > sig.json
|
|
381
|
+
|
|
382
|
+
# 3. Apply signature to PSBT and finalize (use signature from sig.json)
|
|
383
|
+
|
|
384
|
+
# 4. Broadcast
|
|
385
|
+
vultisig broadcast --chain bitcoin --raw-tx "0200000001..."
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### Example: Custom Solana Transaction
|
|
389
|
+
|
|
390
|
+
Build with @solana/web3.js, sign with CLI:
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# 1. Build transaction (save as build-sol-tx.js)
|
|
394
|
+
cat > build-sol-tx.js << 'EOF'
|
|
395
|
+
const { Transaction, SystemProgram, PublicKey, Connection } = require('@solana/web3.js');
|
|
396
|
+
const connection = new Connection('https://api.mainnet-beta.solana.com');
|
|
397
|
+
const fromPubkey = new PublicKey('<your-pubkey>');
|
|
398
|
+
const toPubkey = new PublicKey('<recipient-pubkey>');
|
|
399
|
+
|
|
400
|
+
const tx = new Transaction().add(
|
|
401
|
+
SystemProgram.transfer({ fromPubkey, toPubkey, lamports: 1000000 })
|
|
402
|
+
);
|
|
403
|
+
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
|
|
404
|
+
tx.feePayer = fromPubkey;
|
|
405
|
+
|
|
406
|
+
const message = tx.serializeMessage();
|
|
407
|
+
console.log('MESSAGE:', message.toString('base64'));
|
|
408
|
+
EOF
|
|
409
|
+
node build-sol-tx.js
|
|
410
|
+
|
|
411
|
+
# 2. Sign the message with Vultisig (EdDSA)
|
|
412
|
+
vultisig sign --chain solana --bytes "<base64-message>" -o json > sig.json
|
|
413
|
+
|
|
414
|
+
# 3. Assemble signed transaction (attach signature to message)
|
|
415
|
+
|
|
416
|
+
# 4. Broadcast (base64 encoded signed transaction)
|
|
417
|
+
vultisig broadcast --chain solana --raw-tx "<base64-signed-tx>"
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### Example: Custom Sui Transaction
|
|
421
|
+
|
|
422
|
+
Build with @mysten/sui, sign with CLI:
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# 1. Build transaction (save as build-sui-tx.js)
|
|
426
|
+
cat > build-sui-tx.js << 'EOF'
|
|
427
|
+
const { SuiClient, getFullnodeUrl } = require('@mysten/sui/client');
|
|
428
|
+
const { Transaction } = require('@mysten/sui/transactions');
|
|
429
|
+
|
|
430
|
+
const client = new SuiClient({ url: getFullnodeUrl('mainnet') });
|
|
431
|
+
const tx = new Transaction();
|
|
432
|
+
tx.transferObjects([tx.gas], '<recipient-address>');
|
|
433
|
+
const bytes = await tx.build({ client });
|
|
434
|
+
console.log('TX_BYTES:', Buffer.from(bytes).toString('base64'));
|
|
435
|
+
EOF
|
|
436
|
+
node build-sui-tx.js
|
|
437
|
+
|
|
438
|
+
# 2. Sign the transaction bytes with Vultisig (EdDSA)
|
|
439
|
+
vultisig sign --chain sui --bytes "<base64-tx-bytes>" -o json > sig.json
|
|
440
|
+
|
|
441
|
+
# 3. Broadcast (requires JSON with both unsigned tx and signature)
|
|
442
|
+
vultisig broadcast --chain sui --raw-tx '{"unsignedTx":"<base64-tx-bytes>","signature":"<base64-signature-from-sig.json>"}'
|
|
443
|
+
```
|
|
444
|
+
|
|
247
445
|
### Settings
|
|
248
446
|
|
|
249
447
|
| Command | Description |
|
package/dist/index.js
CHANGED
|
@@ -1042,14 +1042,14 @@ var require_main = __commonJS({
|
|
|
1042
1042
|
cb = opts;
|
|
1043
1043
|
opts = {};
|
|
1044
1044
|
}
|
|
1045
|
-
var
|
|
1046
|
-
|
|
1047
|
-
|
|
1045
|
+
var qrcode4 = new QRCode(-1, this.error);
|
|
1046
|
+
qrcode4.addData(input);
|
|
1047
|
+
qrcode4.make();
|
|
1048
1048
|
var output = "";
|
|
1049
1049
|
if (opts && opts.small) {
|
|
1050
1050
|
var BLACK = true, WHITE = false;
|
|
1051
|
-
var moduleCount =
|
|
1052
|
-
var moduleData =
|
|
1051
|
+
var moduleCount = qrcode4.getModuleCount();
|
|
1052
|
+
var moduleData = qrcode4.modules.slice();
|
|
1053
1053
|
var oddRow = moduleCount % 2 === 1;
|
|
1054
1054
|
if (oddRow) {
|
|
1055
1055
|
moduleData.push(fill(moduleCount, WHITE));
|
|
@@ -1082,9 +1082,9 @@ var require_main = __commonJS({
|
|
|
1082
1082
|
output += borderBottom;
|
|
1083
1083
|
}
|
|
1084
1084
|
} else {
|
|
1085
|
-
var border = repeat(white).times(
|
|
1085
|
+
var border = repeat(white).times(qrcode4.getModuleCount() + 3);
|
|
1086
1086
|
output += border + "\n";
|
|
1087
|
-
|
|
1087
|
+
qrcode4.modules.forEach(function(row2) {
|
|
1088
1088
|
output += white;
|
|
1089
1089
|
output += row2.map(toCell).join("");
|
|
1090
1090
|
output += white + "\n";
|
|
@@ -1103,7 +1103,7 @@ var require_main = __commonJS({
|
|
|
1103
1103
|
|
|
1104
1104
|
// src/index.ts
|
|
1105
1105
|
import "dotenv/config";
|
|
1106
|
-
import { Vultisig as
|
|
1106
|
+
import { Vultisig as Vultisig4 } from "@vultisig/sdk";
|
|
1107
1107
|
import chalk12 from "chalk";
|
|
1108
1108
|
import { program } from "commander";
|
|
1109
1109
|
|
|
@@ -2010,8 +2010,120 @@ Or use this URL: ${qrPayload}
|
|
|
2010
2010
|
}
|
|
2011
2011
|
}
|
|
2012
2012
|
|
|
2013
|
-
// src/commands/
|
|
2013
|
+
// src/commands/sign.ts
|
|
2014
2014
|
var import_qrcode_terminal2 = __toESM(require_main(), 1);
|
|
2015
|
+
import { Chain as Chain2 } from "@vultisig/sdk";
|
|
2016
|
+
async function executeSignBytes(ctx2, params) {
|
|
2017
|
+
const vault = await ctx2.ensureActiveVault();
|
|
2018
|
+
if (!Object.values(Chain2).includes(params.chain)) {
|
|
2019
|
+
throw new Error(`Invalid chain: ${params.chain}`);
|
|
2020
|
+
}
|
|
2021
|
+
return signBytes(vault, params);
|
|
2022
|
+
}
|
|
2023
|
+
async function signBytes(vault, params) {
|
|
2024
|
+
const hashBytes = Buffer.from(params.bytes, "base64");
|
|
2025
|
+
await ensureVaultUnlocked(vault, params.password);
|
|
2026
|
+
const isSecureVault = vault.type === "secure";
|
|
2027
|
+
const signSpinner = createSpinner(isSecureVault ? "Preparing secure signing session..." : "Signing bytes...");
|
|
2028
|
+
vault.on("signingProgress", ({ step }) => {
|
|
2029
|
+
signSpinner.text = `${step.message} (${step.progress}%)`;
|
|
2030
|
+
});
|
|
2031
|
+
if (isSecureVault) {
|
|
2032
|
+
vault.on("qrCodeReady", ({ qrPayload }) => {
|
|
2033
|
+
if (isJsonOutput()) {
|
|
2034
|
+
printResult(JSON.stringify({ qrPayload }));
|
|
2035
|
+
} else if (isSilent()) {
|
|
2036
|
+
printResult(`QR Payload: ${qrPayload}`);
|
|
2037
|
+
} else {
|
|
2038
|
+
signSpinner.stop();
|
|
2039
|
+
info("\nScan this QR code with your Vultisig mobile app to sign:");
|
|
2040
|
+
import_qrcode_terminal2.default.generate(qrPayload, { small: true });
|
|
2041
|
+
info(`
|
|
2042
|
+
Or use this URL: ${qrPayload}
|
|
2043
|
+
`);
|
|
2044
|
+
signSpinner.start("Waiting for devices to join signing session...");
|
|
2045
|
+
}
|
|
2046
|
+
});
|
|
2047
|
+
vault.on(
|
|
2048
|
+
"deviceJoined",
|
|
2049
|
+
({ deviceId, totalJoined, required }) => {
|
|
2050
|
+
if (!isSilent()) {
|
|
2051
|
+
signSpinner.text = `Device joined: ${totalJoined}/${required} (${deviceId})`;
|
|
2052
|
+
} else if (!isJsonOutput()) {
|
|
2053
|
+
printResult(`Device joined: ${totalJoined}/${required}`);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
);
|
|
2057
|
+
}
|
|
2058
|
+
try {
|
|
2059
|
+
const signature = await vault.signBytes(
|
|
2060
|
+
{
|
|
2061
|
+
data: hashBytes,
|
|
2062
|
+
chain: params.chain
|
|
2063
|
+
},
|
|
2064
|
+
{ signal: params.signal }
|
|
2065
|
+
);
|
|
2066
|
+
signSpinner.succeed("Bytes signed");
|
|
2067
|
+
const sigHex = signature.signature.startsWith("0x") ? signature.signature.slice(2) : signature.signature;
|
|
2068
|
+
const sigBase64 = Buffer.from(sigHex, "hex").toString("base64");
|
|
2069
|
+
const result = {
|
|
2070
|
+
signature: sigBase64,
|
|
2071
|
+
recovery: signature.recovery,
|
|
2072
|
+
format: signature.format
|
|
2073
|
+
};
|
|
2074
|
+
if (isJsonOutput()) {
|
|
2075
|
+
outputJson(result);
|
|
2076
|
+
} else {
|
|
2077
|
+
printResult(`Signature: ${result.signature}`);
|
|
2078
|
+
if (result.recovery !== void 0) {
|
|
2079
|
+
printResult(`Recovery: ${result.recovery}`);
|
|
2080
|
+
}
|
|
2081
|
+
printResult(`Format: ${result.format}`);
|
|
2082
|
+
}
|
|
2083
|
+
return result;
|
|
2084
|
+
} finally {
|
|
2085
|
+
vault.removeAllListeners("signingProgress");
|
|
2086
|
+
if (isSecureVault) {
|
|
2087
|
+
vault.removeAllListeners("qrCodeReady");
|
|
2088
|
+
vault.removeAllListeners("deviceJoined");
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
// src/commands/broadcast.ts
|
|
2094
|
+
import { Chain as Chain3, Vultisig as Vultisig3 } from "@vultisig/sdk";
|
|
2095
|
+
async function executeBroadcast(ctx2, params) {
|
|
2096
|
+
const vault = await ctx2.ensureActiveVault();
|
|
2097
|
+
if (!Object.values(Chain3).includes(params.chain)) {
|
|
2098
|
+
throw new Error(`Invalid chain: ${params.chain}`);
|
|
2099
|
+
}
|
|
2100
|
+
const broadcastSpinner = createSpinner("Broadcasting transaction...");
|
|
2101
|
+
try {
|
|
2102
|
+
const txHash = await vault.broadcastRawTx({
|
|
2103
|
+
chain: params.chain,
|
|
2104
|
+
rawTx: params.rawTx
|
|
2105
|
+
});
|
|
2106
|
+
broadcastSpinner.succeed(`Transaction broadcast: ${txHash}`);
|
|
2107
|
+
const result = {
|
|
2108
|
+
txHash,
|
|
2109
|
+
chain: params.chain,
|
|
2110
|
+
explorerUrl: Vultisig3.getTxExplorerUrl(params.chain, txHash)
|
|
2111
|
+
};
|
|
2112
|
+
if (isJsonOutput()) {
|
|
2113
|
+
outputJson(result);
|
|
2114
|
+
} else {
|
|
2115
|
+
printResult(`TX Hash: ${result.txHash}`);
|
|
2116
|
+
printResult(`Explorer: ${result.explorerUrl}`);
|
|
2117
|
+
}
|
|
2118
|
+
return result;
|
|
2119
|
+
} catch (error2) {
|
|
2120
|
+
broadcastSpinner.fail("Broadcast failed");
|
|
2121
|
+
throw error2;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
// src/commands/vault-management.ts
|
|
2126
|
+
var import_qrcode_terminal3 = __toESM(require_main(), 1);
|
|
2015
2127
|
import chalk5 from "chalk";
|
|
2016
2128
|
import { promises as fs } from "fs";
|
|
2017
2129
|
import inquirer4 from "inquirer";
|
|
@@ -2132,7 +2244,7 @@ async function executeCreateSecure(ctx2, options) {
|
|
|
2132
2244
|
} else {
|
|
2133
2245
|
spinner.stop();
|
|
2134
2246
|
info("\nScan this QR code with your Vultisig mobile app:");
|
|
2135
|
-
|
|
2247
|
+
import_qrcode_terminal3.default.generate(qrPayload, { small: true });
|
|
2136
2248
|
info(`
|
|
2137
2249
|
Or use this URL: ${qrPayload}
|
|
2138
2250
|
`);
|
|
@@ -2525,7 +2637,7 @@ async function executeSwap(ctx2, options) {
|
|
|
2525
2637
|
}
|
|
2526
2638
|
|
|
2527
2639
|
// src/commands/settings.ts
|
|
2528
|
-
import { Chain as
|
|
2640
|
+
import { Chain as Chain4, fiatCurrencies as fiatCurrencies2, fiatCurrencyNameRecord as fiatCurrencyNameRecord3 } from "@vultisig/sdk";
|
|
2529
2641
|
import chalk6 from "chalk";
|
|
2530
2642
|
import inquirer5 from "inquirer";
|
|
2531
2643
|
async function executeCurrency(ctx2, newCurrency) {
|
|
@@ -2593,7 +2705,7 @@ async function executeAddressBook(ctx2, options = {}) {
|
|
|
2593
2705
|
type: "list",
|
|
2594
2706
|
name: "chain",
|
|
2595
2707
|
message: "Select chain:",
|
|
2596
|
-
choices: Object.values(
|
|
2708
|
+
choices: Object.values(Chain4)
|
|
2597
2709
|
});
|
|
2598
2710
|
}
|
|
2599
2711
|
if (!address) {
|
|
@@ -2670,7 +2782,7 @@ Address Book${options.chain ? ` (${options.chain})` : ""}:
|
|
|
2670
2782
|
}
|
|
2671
2783
|
|
|
2672
2784
|
// src/interactive/completer.ts
|
|
2673
|
-
import { Chain as
|
|
2785
|
+
import { Chain as Chain5 } from "@vultisig/sdk";
|
|
2674
2786
|
import fs2 from "fs";
|
|
2675
2787
|
import path2 from "path";
|
|
2676
2788
|
var COMMANDS = [
|
|
@@ -2793,7 +2905,7 @@ function completeVaultName(ctx2, partial) {
|
|
|
2793
2905
|
return [show, partial];
|
|
2794
2906
|
}
|
|
2795
2907
|
function completeChainName(partial) {
|
|
2796
|
-
const allChains = Object.values(
|
|
2908
|
+
const allChains = Object.values(Chain5);
|
|
2797
2909
|
const partialLower = partial.toLowerCase();
|
|
2798
2910
|
const matches = allChains.filter((chain) => chain.toLowerCase().startsWith(partialLower));
|
|
2799
2911
|
matches.sort();
|
|
@@ -2801,7 +2913,7 @@ function completeChainName(partial) {
|
|
|
2801
2913
|
return [show, partial];
|
|
2802
2914
|
}
|
|
2803
2915
|
function findChainByName(name) {
|
|
2804
|
-
const allChains = Object.values(
|
|
2916
|
+
const allChains = Object.values(Chain5);
|
|
2805
2917
|
const nameLower = name.toLowerCase();
|
|
2806
2918
|
const found = allChains.find((chain) => chain.toLowerCase() === nameLower);
|
|
2807
2919
|
return found ? found : null;
|
|
@@ -3928,7 +4040,7 @@ var cachedVersion = null;
|
|
|
3928
4040
|
function getVersion() {
|
|
3929
4041
|
if (cachedVersion) return cachedVersion;
|
|
3930
4042
|
if (true) {
|
|
3931
|
-
cachedVersion = "0.2.0-beta.
|
|
4043
|
+
cachedVersion = "0.2.0-beta.9";
|
|
3932
4044
|
return cachedVersion;
|
|
3933
4045
|
}
|
|
3934
4046
|
try {
|
|
@@ -4402,7 +4514,7 @@ async function init(vaultOverride, unlockPassword) {
|
|
|
4402
4514
|
if (unlockPassword && vaultSelector) {
|
|
4403
4515
|
cachePassword(vaultSelector, unlockPassword);
|
|
4404
4516
|
}
|
|
4405
|
-
const sdk = new
|
|
4517
|
+
const sdk = new Vultisig4({
|
|
4406
4518
|
onPasswordRequired: createPasswordCallback()
|
|
4407
4519
|
});
|
|
4408
4520
|
await sdk.initialize();
|
|
@@ -4491,6 +4603,25 @@ program.command("send <chain> <to> <amount>").description("Send tokens to an add
|
|
|
4491
4603
|
}
|
|
4492
4604
|
)
|
|
4493
4605
|
);
|
|
4606
|
+
program.command("sign").description("Sign pre-hashed bytes (for externally constructed transactions)").requiredOption("--chain <chain>", "Target blockchain").requiredOption("--bytes <base64>", "Base64-encoded pre-hashed data to sign").option("--password <password>", "Vault password for signing").action(
|
|
4607
|
+
withExit(async (options) => {
|
|
4608
|
+
const context = await init(program.opts().vault, options.password);
|
|
4609
|
+
await executeSignBytes(context, {
|
|
4610
|
+
chain: findChainByName(options.chain) || options.chain,
|
|
4611
|
+
bytes: options.bytes,
|
|
4612
|
+
password: options.password
|
|
4613
|
+
});
|
|
4614
|
+
})
|
|
4615
|
+
);
|
|
4616
|
+
program.command("broadcast").description("Broadcast a pre-signed raw transaction").requiredOption("--chain <chain>", "Target blockchain").requiredOption("--raw-tx <hex>", "Hex-encoded signed transaction").action(
|
|
4617
|
+
withExit(async (options) => {
|
|
4618
|
+
const context = await init(program.opts().vault);
|
|
4619
|
+
await executeBroadcast(context, {
|
|
4620
|
+
chain: findChainByName(options.chain) || options.chain,
|
|
4621
|
+
rawTx: options.rawTx
|
|
4622
|
+
});
|
|
4623
|
+
})
|
|
4624
|
+
);
|
|
4494
4625
|
program.command("portfolio").description("Show total portfolio value").option("-c, --currency <currency>", "Fiat currency (usd, eur, gbp, etc.)", "usd").action(
|
|
4495
4626
|
withExit(async (options) => {
|
|
4496
4627
|
const context = await init(program.opts().vault);
|
|
@@ -4667,7 +4798,7 @@ program.command("update").description("Check for updates and show update command
|
|
|
4667
4798
|
);
|
|
4668
4799
|
setupCompletionCommand(program);
|
|
4669
4800
|
async function startInteractiveMode() {
|
|
4670
|
-
const sdk = new
|
|
4801
|
+
const sdk = new Vultisig4({
|
|
4671
4802
|
onPasswordRequired: createPasswordCallback()
|
|
4672
4803
|
});
|
|
4673
4804
|
await sdk.initialize();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vultisig/cli",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.9",
|
|
4
4
|
"description": "Command-line wallet for Vultisig - multi-chain MPC wallet management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"homepage": "https://vultisig.com",
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@vultisig/sdk": "^0.2.0-beta.
|
|
51
|
+
"@vultisig/sdk": "^0.2.0-beta.9",
|
|
52
52
|
"chalk": "^5.3.0",
|
|
53
53
|
"cli-table3": "^0.6.5",
|
|
54
54
|
"commander": "^12.0.0",
|