@shield3/sky-safe-cli 0.1.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/README.md +79 -0
- package/dist/commands/verify.d.ts +9 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +255 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/formatters/output.d.ts +56 -0
- package/dist/formatters/output.d.ts.map +1 -0
- package/dist/formatters/output.js +342 -0
- package/dist/formatters/output.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @shield3/sky-safe-cli
|
|
2
|
+
|
|
3
|
+
Command-line tool for verifying Safe multisig transaction hashes.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @shield3/sky-safe-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run directly:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @shield3/sky-safe-cli verify --address 0x... --nonce 520
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Ethereum mainnet (default)
|
|
21
|
+
sky-safe verify \
|
|
22
|
+
--address 0xf65475e74C1Ed6d004d5240b06E3088724dFDA5d \
|
|
23
|
+
--nonce 520
|
|
24
|
+
|
|
25
|
+
# Sepolia testnet
|
|
26
|
+
sky-safe verify \
|
|
27
|
+
--address 0x384937B93ca0dB13f5bC62450f309b31CC48D278 \
|
|
28
|
+
--nonce 8 \
|
|
29
|
+
--network sepolia
|
|
30
|
+
|
|
31
|
+
# From local JSON file
|
|
32
|
+
sky-safe verify --file examples/gas-token-attack.json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Options
|
|
36
|
+
|
|
37
|
+
| Option | Description | Default |
|
|
38
|
+
|--------|-------------|---------|
|
|
39
|
+
| `--address <address>` | Safe contract address | - |
|
|
40
|
+
| `--nonce <nonce>` | Transaction nonce | - |
|
|
41
|
+
| `--network <network>` | Network (`ethereum`, `sepolia`) | `ethereum` |
|
|
42
|
+
| `--file <path>` | Load from JSON file instead of API | - |
|
|
43
|
+
|
|
44
|
+
## Output
|
|
45
|
+
|
|
46
|
+
The tool displays:
|
|
47
|
+
|
|
48
|
+
1. **Transaction data** - All parameters with known address labels
|
|
49
|
+
2. **Decoded data** - Method and parameters with verification status
|
|
50
|
+
3. **Custom decoder analysis** - Protocol-specific explanations (when available)
|
|
51
|
+
4. **Security analysis** - Delegate call, gas token, and owner modification warnings
|
|
52
|
+
5. **Hash verification** - Independently calculated EIP-712 hashes compared against the API
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Computed Hashes
|
|
56
|
+
|
|
57
|
+
Domain Hash: 0xabcd...
|
|
58
|
+
Message Hash: 0x1234...
|
|
59
|
+
Safe TX Hash: 0x5678...
|
|
60
|
+
|
|
61
|
+
Safe Transaction Hash (API): 0x5678...
|
|
62
|
+
|
|
63
|
+
HASH VERIFIED: Calculated hash matches API hash
|
|
64
|
+
This is the hash you should see on your hardware wallet.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Development
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# From the monorepo root
|
|
71
|
+
pnpm --filter @shield3/sky-safe-cli dev verify --address 0x... --nonce 42
|
|
72
|
+
|
|
73
|
+
# Build
|
|
74
|
+
pnpm --filter @shield3/sky-safe-cli build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
AGPL-3.0-only
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify command - Fetch and display Safe transaction from API
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* sky-safe verify --address 0x... --nonce 123 [--network ethereum]
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare function createVerifyCommand(): Command;
|
|
9
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAiCnC,wBAAgB,mBAAmB,IAAI,OAAO,CAoS7C"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify command - Fetch and display Safe transaction from API
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* sky-safe verify --address 0x... --nonce 123 [--network ethereum]
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import inquirer from 'inquirer';
|
|
12
|
+
import { createSafeApiClient, SafeApiError, isNetworkSupported, decoderRegistry, LockstakeEngineDecoder, calculateSafeTxHash, verifySafeTxHash, analyzeSecurity, decodeMultiSend, isMultiSend, verifyDecodedData, } from '@shield3/sky-safe-core';
|
|
13
|
+
import { printNetworkConfig, printTransactionData, printDecodedData, printCustomDecodedData, printNestedTransactionData, printHashVerification, printSecurityWarnings, } from '../formatters/output.js';
|
|
14
|
+
// Register custom decoders
|
|
15
|
+
decoderRegistry.register(new LockstakeEngineDecoder());
|
|
16
|
+
export function createVerifyCommand() {
|
|
17
|
+
const command = new Command('verify');
|
|
18
|
+
command
|
|
19
|
+
.description('Fetch and verify a Safe transaction from the Safe Transaction Service or local file')
|
|
20
|
+
.option('-a, --address <address>', 'Safe multisig address')
|
|
21
|
+
.option('-n, --nonce <nonce>', 'Transaction nonce', parseNonce)
|
|
22
|
+
.option('--network <network>', 'Network name (e.g., ethereum, sepolia)', 'ethereum')
|
|
23
|
+
.option('-f, --file <file>', 'Read transaction from JSON file instead of API')
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
try {
|
|
26
|
+
// Validate mode
|
|
27
|
+
if (options.file && (options.address || options.nonce !== undefined)) {
|
|
28
|
+
console.error(chalk.red('✗ Cannot use both --file and --address/--nonce'));
|
|
29
|
+
console.error(chalk.dim(' Use --file for local mode OR --address/--nonce for API mode'));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
if (!options.file && (!options.address || options.nonce === undefined)) {
|
|
33
|
+
console.error(chalk.red('✗ Missing required options'));
|
|
34
|
+
console.error(chalk.dim(' Use either:'));
|
|
35
|
+
console.error(chalk.dim(' --file <file> (local mode)'));
|
|
36
|
+
console.error(chalk.dim(' --address <address> --nonce <nonce> (API mode)'));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
// Validate network
|
|
40
|
+
if (!isNetworkSupported(options.network)) {
|
|
41
|
+
console.error(chalk.red(`✗ Unsupported network: ${options.network}`));
|
|
42
|
+
console.error(chalk.dim(' Run `sky-safe networks` to see supported networks'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
// Create API client for network info
|
|
46
|
+
const client = createSafeApiClient(options.network);
|
|
47
|
+
// Show network config
|
|
48
|
+
printNetworkConfig(client.getNetworkName(), client.getChainId());
|
|
49
|
+
let tx;
|
|
50
|
+
let version;
|
|
51
|
+
if (options.file) {
|
|
52
|
+
// Local mode: read from file
|
|
53
|
+
const spinner = ora('Reading transaction from file...').start();
|
|
54
|
+
try {
|
|
55
|
+
const fileContent = readFileSync(options.file, 'utf-8');
|
|
56
|
+
const jsonData = JSON.parse(fileContent);
|
|
57
|
+
tx = jsonData.transaction;
|
|
58
|
+
version = jsonData.version || '1.3.0'; // Default to 1.3.0 if not specified
|
|
59
|
+
if (!tx) {
|
|
60
|
+
throw new Error('Invalid JSON: missing "transaction" field');
|
|
61
|
+
}
|
|
62
|
+
spinner.succeed('Transaction loaded from file');
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
spinner.fail('Failed to read transaction file');
|
|
66
|
+
if (error instanceof Error) {
|
|
67
|
+
console.error(chalk.red(` ${error.message}`));
|
|
68
|
+
}
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// API mode: fetch from Safe API
|
|
74
|
+
// Validate address format (basic check)
|
|
75
|
+
if (!options.address.match(/^0x[a-fA-F0-9]{40}$/)) {
|
|
76
|
+
console.error(chalk.red(`✗ Invalid address format: ${options.address}`));
|
|
77
|
+
console.error(chalk.dim(' Address must be a 40-character hex string starting with 0x'));
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const spinner = ora('Fetching transaction(s) from Safe API...').start();
|
|
81
|
+
try {
|
|
82
|
+
// Fetch all transactions with this nonce
|
|
83
|
+
const transactions = await client.fetchTransactionsByNonce(options.address, options.nonce);
|
|
84
|
+
spinner.stop();
|
|
85
|
+
// If multiple transactions found, let user select
|
|
86
|
+
if (transactions.length > 1) {
|
|
87
|
+
console.log(chalk.yellow(`\n⚠️ Found ${transactions.length} transactions with nonce ${options.nonce}`));
|
|
88
|
+
console.log(chalk.dim(' This can happen when transactions are replaced or cancelled.\n'));
|
|
89
|
+
const choices = transactions.map((t, idx) => {
|
|
90
|
+
const submissionDate = t.submissionDate ? new Date(t.submissionDate).toLocaleString() : 'Unknown';
|
|
91
|
+
const status = t.isExecuted
|
|
92
|
+
? (t.isSuccessful ? '✅ Executed' : '❌ Failed')
|
|
93
|
+
: `⏳ Pending (${t.confirmations?.length || 0}/${t.confirmationsRequired} sigs)`;
|
|
94
|
+
return {
|
|
95
|
+
name: `[${idx + 1}] ${status} | Submitted: ${submissionDate} | Hash: ${t.safeTxHash.slice(0, 10)}...`,
|
|
96
|
+
value: idx,
|
|
97
|
+
short: `Transaction ${idx + 1}`
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
const answer = await inquirer.prompt([
|
|
101
|
+
{
|
|
102
|
+
type: 'list',
|
|
103
|
+
name: 'txIndex',
|
|
104
|
+
message: 'Select which transaction to analyze:',
|
|
105
|
+
choices: choices,
|
|
106
|
+
}
|
|
107
|
+
]);
|
|
108
|
+
tx = transactions[answer.txIndex];
|
|
109
|
+
console.log(chalk.green(`\n✓ Selected transaction ${answer.txIndex + 1}\n`));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
tx = transactions[0];
|
|
113
|
+
}
|
|
114
|
+
const spinner2 = ora('Fetching Safe version...').start();
|
|
115
|
+
version = await client.fetchSafeVersion(options.address);
|
|
116
|
+
spinner2.succeed('Transaction fetched successfully');
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
spinner.fail('Failed to fetch transaction');
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Display transaction data
|
|
124
|
+
console.log(chalk.bold('\n========================================'));
|
|
125
|
+
console.log(chalk.bold('= Transaction Data and Decoded Info ='));
|
|
126
|
+
console.log(chalk.bold('========================================'));
|
|
127
|
+
printTransactionData(tx);
|
|
128
|
+
// Verify decoded data if available
|
|
129
|
+
let apiDecodedVerification = null;
|
|
130
|
+
if (tx.data && tx.data !== '0x' && tx.dataDecoded) {
|
|
131
|
+
apiDecodedVerification = verifyDecodedData(tx.data, tx.dataDecoded);
|
|
132
|
+
}
|
|
133
|
+
printDecodedData(tx, apiDecodedVerification);
|
|
134
|
+
// Try custom decoder if available OR decode MultiSend
|
|
135
|
+
if (tx.data && tx.data !== '0x') {
|
|
136
|
+
// Check if this is a MultiSend transaction
|
|
137
|
+
if (isMultiSend(tx.data)) {
|
|
138
|
+
console.log(chalk.bold('\n========================================'));
|
|
139
|
+
console.log(chalk.bold('= MultiSend Batched Transactions ='));
|
|
140
|
+
console.log(chalk.bold('========================================'));
|
|
141
|
+
// Verify the outer MultiSend transaction itself
|
|
142
|
+
if (tx.dataDecoded) {
|
|
143
|
+
const multiSendVerification = verifyDecodedData(tx.data, tx.dataDecoded);
|
|
144
|
+
if (multiSendVerification.verified) {
|
|
145
|
+
console.log(chalk.green('\n✓ MultiSend outer transaction verified'));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.log(chalk.red('\n⚠ MultiSend outer transaction verification failed'));
|
|
149
|
+
if (multiSendVerification.error) {
|
|
150
|
+
console.log(chalk.red(` ${multiSendVerification.error}`));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const nestedTxs = decodeMultiSend(tx.data);
|
|
155
|
+
// Get Safe API decoded nested transactions from valueDecoded
|
|
156
|
+
let apiNestedTxs = null;
|
|
157
|
+
if (tx.dataDecoded?.parameters) {
|
|
158
|
+
const transactionsParam = tx.dataDecoded.parameters.find(p => p.name === 'transactions');
|
|
159
|
+
if (transactionsParam?.valueDecoded && Array.isArray(transactionsParam.valueDecoded)) {
|
|
160
|
+
apiNestedTxs = transactionsParam.valueDecoded;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (nestedTxs) {
|
|
164
|
+
console.log(chalk.dim(`\nFound ${nestedTxs.length} nested transaction(s)\n`));
|
|
165
|
+
for (let i = 0; i < nestedTxs.length; i++) {
|
|
166
|
+
const nestedTx = nestedTxs[i];
|
|
167
|
+
// Try to decode with custom decoder
|
|
168
|
+
let customDecoded = null;
|
|
169
|
+
if (nestedTx.data && nestedTx.data !== '0x') {
|
|
170
|
+
customDecoded = decoderRegistry.decode(nestedTx.to, nestedTx.data, options.network);
|
|
171
|
+
}
|
|
172
|
+
// Get Safe API decoded data for this nested transaction
|
|
173
|
+
const apiDecoded = apiNestedTxs?.[i]?.dataDecoded || null;
|
|
174
|
+
// Verify Safe API decoded data
|
|
175
|
+
let verification = null;
|
|
176
|
+
if (apiDecoded && nestedTx.data && nestedTx.data !== '0x') {
|
|
177
|
+
verification = verifyDecodedData(nestedTx.data, apiDecoded);
|
|
178
|
+
}
|
|
179
|
+
// Print using the new formatter
|
|
180
|
+
printNestedTransactionData(i, nestedTxs.length, nestedTx.to, nestedTx.value.toString(), nestedTx.operation, nestedTx.data, apiDecoded, customDecoded, verification);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
// Try direct custom decoder
|
|
186
|
+
const customDecoded = decoderRegistry.decode(tx.to, tx.data, options.network);
|
|
187
|
+
if (customDecoded) {
|
|
188
|
+
printCustomDecodedData(customDecoded);
|
|
189
|
+
}
|
|
190
|
+
else if (decoderRegistry.hasDecoder(tx.to, options.network)) {
|
|
191
|
+
// Decoder exists but couldn't decode - might be unsupported function
|
|
192
|
+
console.log(chalk.yellow('\n⚠️ This contract has a custom decoder, but the function is not yet supported.'));
|
|
193
|
+
console.log(chalk.dim(' Please verify the transaction carefully.'));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Perform security analysis
|
|
198
|
+
const txData = {
|
|
199
|
+
to: tx.to,
|
|
200
|
+
value: tx.value,
|
|
201
|
+
data: (tx.data || '0x'),
|
|
202
|
+
operation: tx.operation,
|
|
203
|
+
safeTxGas: String(tx.safeTxGas),
|
|
204
|
+
baseGas: String(tx.baseGas),
|
|
205
|
+
gasPrice: tx.gasPrice,
|
|
206
|
+
gasToken: tx.gasToken,
|
|
207
|
+
refundReceiver: tx.refundReceiver,
|
|
208
|
+
nonce: String(tx.nonce),
|
|
209
|
+
};
|
|
210
|
+
const securityAnalysis = analyzeSecurity(txData);
|
|
211
|
+
printSecurityWarnings(securityAnalysis);
|
|
212
|
+
// Calculate Safe transaction hash
|
|
213
|
+
console.log(chalk.bold('\n========================================'));
|
|
214
|
+
console.log(chalk.bold('= Hash Calculation & Verification ='));
|
|
215
|
+
console.log(chalk.bold('========================================'));
|
|
216
|
+
try {
|
|
217
|
+
const safeAddress = options.file ? tx.safe : options.address;
|
|
218
|
+
const hashResult = calculateSafeTxHash(client.getChainId(), safeAddress, txData, version);
|
|
219
|
+
// Verify the calculated hash matches the API hash
|
|
220
|
+
const isValid = verifySafeTxHash(hashResult.safeTxHash, tx.safeTxHash);
|
|
221
|
+
printHashVerification(hashResult.domainHash, hashResult.messageHash, hashResult.safeTxHash, tx.safeTxHash, isValid, version);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.log(chalk.red('\n✗ Hash calculation failed'));
|
|
225
|
+
console.log(chalk.dim(` Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
226
|
+
console.log(chalk.yellow('\n⚠️ Cannot verify transaction hash - proceed with caution!'));
|
|
227
|
+
}
|
|
228
|
+
console.log(); // Empty line at end
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
if (error instanceof SafeApiError) {
|
|
232
|
+
console.error(chalk.red(`\n✗ ${error.message}`));
|
|
233
|
+
if (error.statusCode === 404) {
|
|
234
|
+
console.error(chalk.dim(' Make sure the Safe address exists on this network and the transaction has been proposed.'));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
console.error(chalk.red(`\n✗ Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
239
|
+
}
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return command;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Parse nonce from string to number
|
|
247
|
+
*/
|
|
248
|
+
function parseNonce(value) {
|
|
249
|
+
const nonce = parseInt(value, 10);
|
|
250
|
+
if (isNaN(nonce) || nonce < 0) {
|
|
251
|
+
throw new Error(`Invalid nonce: ${value}. Must be a non-negative integer.`);
|
|
252
|
+
}
|
|
253
|
+
return nonce;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for CLI
|
|
3
|
+
* Port of bash script lines 404-563 (formatting functions)
|
|
4
|
+
*/
|
|
5
|
+
import type { SafeApiMultisigTransaction, DecodedTransactionData, SecurityAnalysisResult, SafeApiDataDecoded } from '@shield3/sky-safe-core';
|
|
6
|
+
/**
|
|
7
|
+
* Print a section header
|
|
8
|
+
*/
|
|
9
|
+
export declare function printHeader(text: string): void;
|
|
10
|
+
/**
|
|
11
|
+
* Print a labeled field
|
|
12
|
+
*/
|
|
13
|
+
export declare function printField(label: string, value: string | number): void;
|
|
14
|
+
/**
|
|
15
|
+
* Print transaction data from Safe API
|
|
16
|
+
*/
|
|
17
|
+
export declare function printTransactionData(tx: SafeApiMultisigTransaction): void;
|
|
18
|
+
/**
|
|
19
|
+
* Print decoded transaction data (if available)
|
|
20
|
+
* @param tx - Transaction data
|
|
21
|
+
* @param verification - Optional verification result to display
|
|
22
|
+
*/
|
|
23
|
+
export declare function printDecodedData(tx: SafeApiMultisigTransaction, verification?: {
|
|
24
|
+
verified: boolean;
|
|
25
|
+
error?: string;
|
|
26
|
+
} | null): void;
|
|
27
|
+
/**
|
|
28
|
+
* Print nested transaction data with Safe API decoding and verification
|
|
29
|
+
*/
|
|
30
|
+
export declare function printNestedTransactionData(index: number, total: number, to: string, value: string, operation: number, data: string, apiDecoded?: SafeApiDataDecoded | null, customDecoded?: DecodedTransactionData | null, verification?: {
|
|
31
|
+
verified: boolean;
|
|
32
|
+
error?: string;
|
|
33
|
+
} | null): void;
|
|
34
|
+
/**
|
|
35
|
+
* Print custom decoded data with explanations
|
|
36
|
+
*/
|
|
37
|
+
export declare function printCustomDecodedData(decoded: DecodedTransactionData): void;
|
|
38
|
+
/**
|
|
39
|
+
* Print network configuration
|
|
40
|
+
*/
|
|
41
|
+
export declare function printNetworkConfig(network: string, chainId: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* Print safe transaction hash
|
|
44
|
+
*/
|
|
45
|
+
export declare function printSafeTxHash(hash: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Print hash calculation results and verification
|
|
48
|
+
* Reference: bash script lines 480-485, 664-673
|
|
49
|
+
*/
|
|
50
|
+
export declare function printHashVerification(domainHash: string, messageHash: string, calculatedHash: string, apiHash: string, isValid: boolean, version: string): void;
|
|
51
|
+
/**
|
|
52
|
+
* Print security analysis warnings
|
|
53
|
+
* Reference: bash script lines 789-853 (security checks)
|
|
54
|
+
*/
|
|
55
|
+
export declare function printSecurityWarnings(analysis: SecurityAnalysisResult): void;
|
|
56
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/formatters/output.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,0BAA0B,EAC1B,sBAAsB,EAEtB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,wBAAwB,CAAA;AAI/B;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,0BAA0B,GAAG,IAAI,CAmCzE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,0BAA0B,EAAE,YAAY,CAAC,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,IAAI,CAgDlI;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,kBAAkB,GAAG,IAAI,EACtC,aAAa,CAAC,EAAE,sBAAsB,GAAG,IAAI,EAC7C,YAAY,CAAC,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC1D,IAAI,CAoDN;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CA0B5E;AAmCD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGlD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,GACd,IAAI,CAgCN;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAqF5E"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting utilities for CLI
|
|
3
|
+
* Port of bash script lines 404-563 (formatting functions)
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { getAddressTag } from '@shield3/sky-safe-core';
|
|
7
|
+
/**
|
|
8
|
+
* Print a section header
|
|
9
|
+
*/
|
|
10
|
+
export function printHeader(text) {
|
|
11
|
+
console.log(`\n${chalk.underline(text)}`);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Print a labeled field
|
|
15
|
+
*/
|
|
16
|
+
export function printField(label, value) {
|
|
17
|
+
console.log(`${label}: ${chalk.green(value)}`);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Print transaction data from Safe API
|
|
21
|
+
*/
|
|
22
|
+
export function printTransactionData(tx) {
|
|
23
|
+
printHeader('Transaction Data');
|
|
24
|
+
printField('Safe address', tx.safe);
|
|
25
|
+
// Print 'To' field with address tag if available
|
|
26
|
+
const tag = getAddressTag(tx.to);
|
|
27
|
+
if (tag) {
|
|
28
|
+
console.log(`To: ${chalk.green(tx.to)} ${chalk.blue(`[${tag.label}]`)}`);
|
|
29
|
+
console.log(` ${chalk.dim(tag.description)}`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
printField('To', tx.to);
|
|
33
|
+
}
|
|
34
|
+
printField('Value', `${tx.value} wei`);
|
|
35
|
+
printField('Data', tx.data || '0x');
|
|
36
|
+
// Operation type
|
|
37
|
+
const operationType = tx.operation === 0 ? 'Call' : tx.operation === 1 ? 'DelegateCall' : 'Unknown';
|
|
38
|
+
printField('Operation', operationType);
|
|
39
|
+
printField('Safe Transaction Gas', tx.safeTxGas);
|
|
40
|
+
printField('Base Gas', tx.baseGas);
|
|
41
|
+
printField('Gas Price', tx.gasPrice);
|
|
42
|
+
printField('Gas Token', tx.gasToken);
|
|
43
|
+
printField('Refund Receiver', tx.refundReceiver);
|
|
44
|
+
printField('Nonce', tx.nonce);
|
|
45
|
+
// Status
|
|
46
|
+
printField('Executed', tx.isExecuted ? 'Yes' : 'No');
|
|
47
|
+
if (tx.isExecuted && tx.isSuccessful !== null) {
|
|
48
|
+
printField('Successful', tx.isSuccessful ? 'Yes' : 'No');
|
|
49
|
+
}
|
|
50
|
+
// Confirmations
|
|
51
|
+
printField('Confirmations', `${tx.confirmations.length}/${tx.confirmationsRequired}`);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Print decoded transaction data (if available)
|
|
55
|
+
* @param tx - Transaction data
|
|
56
|
+
* @param verification - Optional verification result to display
|
|
57
|
+
*/
|
|
58
|
+
export function printDecodedData(tx, verification) {
|
|
59
|
+
if (!tx.dataDecoded) {
|
|
60
|
+
// Check for special cases
|
|
61
|
+
if (!tx.data || tx.data === '0x') {
|
|
62
|
+
const method = tx.to === tx.safe && tx.value === '0'
|
|
63
|
+
? '0x (On-Chain Rejection)'
|
|
64
|
+
: tx.to === tx.safe && tx.value !== '0'
|
|
65
|
+
? '0x (ETH Self-Transfer)'
|
|
66
|
+
: tx.to !== tx.safe && tx.value === '0'
|
|
67
|
+
? '0x (Zero-Value ETH Transfer)'
|
|
68
|
+
: '0x (ETH Transfer)';
|
|
69
|
+
printHeader('Decoded Data');
|
|
70
|
+
printField('Method', method);
|
|
71
|
+
printField('Parameters', '[]');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
printHeader('Decoded Data');
|
|
75
|
+
printField('Method', 'Unknown');
|
|
76
|
+
printField('Parameters', 'Unknown (no decoding available from API)');
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
printHeader('Decoded Data');
|
|
81
|
+
// Print method with verification status
|
|
82
|
+
if (verification) {
|
|
83
|
+
const verificationBadge = verification.verified
|
|
84
|
+
? chalk.green('✓ Verified')
|
|
85
|
+
: chalk.red('⚠ Mismatch');
|
|
86
|
+
console.log(`Method: ${chalk.green(tx.dataDecoded.method)} ${verificationBadge}`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
printField('Method', tx.dataDecoded.method);
|
|
90
|
+
}
|
|
91
|
+
// Show verification error if failed
|
|
92
|
+
if (verification && !verification.verified && verification.error) {
|
|
93
|
+
console.log(chalk.red(` ⚠️ Warning: ${verification.error}`));
|
|
94
|
+
}
|
|
95
|
+
if (tx.dataDecoded.parameters.length > 0) {
|
|
96
|
+
console.log('Parameters:');
|
|
97
|
+
for (const param of tx.dataDecoded.parameters) {
|
|
98
|
+
console.log(` ${chalk.dim(param.name)} (${chalk.dim(param.type)}): ${chalk.cyan(param.value)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
printField('Parameters', '[]');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Print nested transaction data with Safe API decoding and verification
|
|
107
|
+
*/
|
|
108
|
+
export function printNestedTransactionData(index, total, to, value, operation, data, apiDecoded, customDecoded, verification) {
|
|
109
|
+
console.log(chalk.bold.cyan(`\n[Transaction ${index + 1}/${total}]`));
|
|
110
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
111
|
+
// Print nested transaction details
|
|
112
|
+
console.log(`${chalk.dim('To')}: ${chalk.green(to)}`);
|
|
113
|
+
const tag = getAddressTag(to);
|
|
114
|
+
if (tag) {
|
|
115
|
+
console.log(` ${chalk.blue(`[${tag.label}]`)} ${chalk.dim(tag.description)}`);
|
|
116
|
+
}
|
|
117
|
+
console.log(`${chalk.dim('Value')}: ${chalk.green(value)} wei`);
|
|
118
|
+
console.log(`${chalk.dim('Operation')}: ${chalk.green(operation === 0 ? 'Call' : operation === 1 ? 'DelegateCall' : 'Unknown')}`);
|
|
119
|
+
// Print custom decoded data if available
|
|
120
|
+
if (customDecoded) {
|
|
121
|
+
console.log(chalk.dim('\nCustom Decoder Analysis:'));
|
|
122
|
+
printCustomDecodedData(customDecoded);
|
|
123
|
+
}
|
|
124
|
+
// Otherwise print Safe API decoded data with verification
|
|
125
|
+
else if (apiDecoded) {
|
|
126
|
+
console.log(chalk.dim('\nSafe API Decoded Data:'));
|
|
127
|
+
// Print method with verification status
|
|
128
|
+
if (verification) {
|
|
129
|
+
const verificationBadge = verification.verified
|
|
130
|
+
? chalk.green('✓ Verified')
|
|
131
|
+
: chalk.red('⚠ Mismatch');
|
|
132
|
+
console.log(` Method: ${chalk.green(apiDecoded.method)} ${verificationBadge}`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
console.log(` Method: ${chalk.green(apiDecoded.method)}`);
|
|
136
|
+
}
|
|
137
|
+
// Show verification error if failed
|
|
138
|
+
if (verification && !verification.verified && verification.error) {
|
|
139
|
+
console.log(chalk.red(` ⚠️ Warning: ${verification.error}`));
|
|
140
|
+
}
|
|
141
|
+
// Print parameters
|
|
142
|
+
if (apiDecoded.parameters.length > 0) {
|
|
143
|
+
console.log(' Parameters:');
|
|
144
|
+
for (const param of apiDecoded.parameters) {
|
|
145
|
+
console.log(` ${chalk.dim(param.name)} (${chalk.dim(param.type)}): ${chalk.cyan(param.value)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log(' Parameters: []');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Just show raw data if no decoding available
|
|
153
|
+
else if (data && data !== '0x') {
|
|
154
|
+
console.log(chalk.dim(`\nData: ${data.slice(0, 66)}${data.length > 66 ? '...' : ''}`));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Print custom decoded data with explanations
|
|
159
|
+
*/
|
|
160
|
+
export function printCustomDecodedData(decoded) {
|
|
161
|
+
printHeader('Custom Decoder Analysis');
|
|
162
|
+
if (decoded.isMulticall) {
|
|
163
|
+
// Print multicall header
|
|
164
|
+
printDecodedFunction(decoded.main, 0);
|
|
165
|
+
// Print nested calls
|
|
166
|
+
if (decoded.nested && decoded.nested.length > 0) {
|
|
167
|
+
console.log(chalk.dim('\nNested calls:'));
|
|
168
|
+
for (let i = 0; i < decoded.nested.length; i++) {
|
|
169
|
+
printDecodedFunction(decoded.nested[i], i + 1);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// Single function call
|
|
175
|
+
printDecodedFunction(decoded.main, 0);
|
|
176
|
+
}
|
|
177
|
+
// Print general warnings
|
|
178
|
+
if (decoded.generalWarnings && decoded.generalWarnings.length > 0) {
|
|
179
|
+
console.log(chalk.yellow('\n⚠️ General Warnings:'));
|
|
180
|
+
for (const warning of decoded.generalWarnings) {
|
|
181
|
+
console.log(chalk.yellow(` • ${warning}`));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Print a single decoded function
|
|
187
|
+
*/
|
|
188
|
+
function printDecodedFunction(func, index) {
|
|
189
|
+
const prefix = index > 0 ? ` [${index}] ` : '';
|
|
190
|
+
console.log(`\n${prefix}${chalk.bold(func.name)}${chalk.dim(` (${func.signature})`)}`);
|
|
191
|
+
console.log(`${prefix}${chalk.italic(func.explanation)}`);
|
|
192
|
+
// Print parameters
|
|
193
|
+
if (func.parameters.length > 0) {
|
|
194
|
+
console.log(`${prefix}${chalk.dim('Parameters:')}`);
|
|
195
|
+
for (const param of func.parameters) {
|
|
196
|
+
console.log(`${prefix} ${chalk.dim(param.name)} (${chalk.dim(param.type)}): ${chalk.cyan(String(param.value))}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Print function-specific warnings
|
|
200
|
+
if (func.warnings && func.warnings.length > 0) {
|
|
201
|
+
for (const warning of func.warnings) {
|
|
202
|
+
console.log(`${prefix}${chalk.yellow(`⚠️ ${warning}`)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// Print risk level
|
|
206
|
+
if (func.riskLevel && func.riskLevel !== 'none') {
|
|
207
|
+
const riskColor = func.riskLevel === 'high' ? chalk.red
|
|
208
|
+
: func.riskLevel === 'medium' ? chalk.yellow
|
|
209
|
+
: chalk.blue;
|
|
210
|
+
console.log(`${prefix}${riskColor(`Risk: ${func.riskLevel}`)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Print network configuration
|
|
215
|
+
*/
|
|
216
|
+
export function printNetworkConfig(network, chainId) {
|
|
217
|
+
console.log(chalk.bold('\n==================================='));
|
|
218
|
+
console.log(chalk.bold('= Selected Network Configuration ='));
|
|
219
|
+
console.log(chalk.bold('===================================\n'));
|
|
220
|
+
printField('Network', network);
|
|
221
|
+
printField('Chain ID', chainId);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Print safe transaction hash
|
|
225
|
+
*/
|
|
226
|
+
export function printSafeTxHash(hash) {
|
|
227
|
+
printHeader('Safe Transaction Hash');
|
|
228
|
+
console.log(chalk.green(hash));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Print hash calculation results and verification
|
|
232
|
+
* Reference: bash script lines 480-485, 664-673
|
|
233
|
+
*/
|
|
234
|
+
export function printHashVerification(domainHash, messageHash, calculatedHash, apiHash, isValid, version) {
|
|
235
|
+
console.log(`\n${chalk.dim('Safe Version')}: ${chalk.cyan(version)}`);
|
|
236
|
+
printHeader('Computed Hashes');
|
|
237
|
+
// Format hashes in Ledger-style (matching hardware wallet display)
|
|
238
|
+
console.log(chalk.dim('Domain Hash:'));
|
|
239
|
+
console.log(chalk.green(domainHash));
|
|
240
|
+
console.log(chalk.dim('\nMessage Hash:'));
|
|
241
|
+
console.log(chalk.green(messageHash));
|
|
242
|
+
console.log(chalk.dim('\nSafe Transaction Hash (Calculated):'));
|
|
243
|
+
console.log(chalk.green(calculatedHash));
|
|
244
|
+
console.log(chalk.dim('\nSafe Transaction Hash (API):'));
|
|
245
|
+
console.log(chalk.green(apiHash));
|
|
246
|
+
// Verification result
|
|
247
|
+
console.log();
|
|
248
|
+
if (isValid) {
|
|
249
|
+
console.log(chalk.bold.green('✓ HASH VERIFIED: Calculated hash matches API hash'));
|
|
250
|
+
console.log(chalk.dim(' This is the hash you should see on your hardware wallet (e.g., Ledger).'));
|
|
251
|
+
console.log(chalk.dim(' It is safe to sign this transaction if all parameters are correct.'));
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
console.log(chalk.bold.red('✗ HASH MISMATCH: Calculated hash does NOT match API hash'));
|
|
255
|
+
console.log(chalk.red(' DO NOT SIGN THIS TRANSACTION!'));
|
|
256
|
+
console.log(chalk.yellow(' This indicates a potential issue with:'));
|
|
257
|
+
console.log(chalk.yellow(' - Transaction data from the API'));
|
|
258
|
+
console.log(chalk.yellow(' - Safe version mismatch'));
|
|
259
|
+
console.log(chalk.yellow(' - Hash calculation implementation'));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Print security analysis warnings
|
|
264
|
+
* Reference: bash script lines 789-853 (security checks)
|
|
265
|
+
*/
|
|
266
|
+
export function printSecurityWarnings(analysis) {
|
|
267
|
+
// Overall risk header
|
|
268
|
+
if (analysis.overallRisk === 'none') {
|
|
269
|
+
console.log(chalk.green('\n✓ No security risks detected'));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
console.log(chalk.bold('\n========================================'));
|
|
273
|
+
console.log(chalk.bold('= Security Analysis ='));
|
|
274
|
+
console.log(chalk.bold('========================================'));
|
|
275
|
+
// Overall risk level
|
|
276
|
+
const riskColor = analysis.overallRisk === 'critical'
|
|
277
|
+
? chalk.bold.red
|
|
278
|
+
: analysis.overallRisk === 'high'
|
|
279
|
+
? chalk.red
|
|
280
|
+
: analysis.overallRisk === 'medium'
|
|
281
|
+
? chalk.yellow
|
|
282
|
+
: chalk.blue;
|
|
283
|
+
console.log(riskColor(`\nOverall Risk Level: ${analysis.overallRisk.toUpperCase()}`));
|
|
284
|
+
// Delegate call warnings
|
|
285
|
+
if (analysis.delegateCall.warning) {
|
|
286
|
+
console.log(chalk.bold.red('\n⚠️ DELEGATE CALL WARNING'));
|
|
287
|
+
console.log(chalk.red(analysis.delegateCall.warning));
|
|
288
|
+
console.log(chalk.dim(' Target: ' + analysis.delegateCall.targetAddress));
|
|
289
|
+
}
|
|
290
|
+
else if (analysis.delegateCall.isDelegateCall && analysis.delegateCall.isTrusted) {
|
|
291
|
+
console.log(chalk.blue('\nℹ️ This transaction uses a trusted delegate call'));
|
|
292
|
+
console.log(chalk.dim(' Target: ' + analysis.delegateCall.targetAddress));
|
|
293
|
+
}
|
|
294
|
+
// Gas token warnings
|
|
295
|
+
if (analysis.gasToken.warnings.length > 0) {
|
|
296
|
+
console.log(chalk.bold.red('\n⚠️ GAS TOKEN WARNINGS'));
|
|
297
|
+
for (const warning of analysis.gasToken.warnings) {
|
|
298
|
+
console.log(chalk.red(' • ' + warning));
|
|
299
|
+
}
|
|
300
|
+
if (analysis.gasToken.usesCustomGasToken) {
|
|
301
|
+
console.log(chalk.dim(' Gas Token: ' + analysis.gasToken.gasToken));
|
|
302
|
+
}
|
|
303
|
+
if (analysis.gasToken.usesCustomRefundReceiver) {
|
|
304
|
+
console.log(chalk.dim(' Refund Receiver: ' + analysis.gasToken.refundReceiver));
|
|
305
|
+
}
|
|
306
|
+
if (analysis.gasToken.hasNonZeroGasPrice) {
|
|
307
|
+
console.log(chalk.dim(' Gas Price: ' + analysis.gasToken.gasPrice));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// Owner modification warnings
|
|
311
|
+
if (analysis.ownerModification.warning) {
|
|
312
|
+
console.log(chalk.bold.red('\n⚠️ OWNER/THRESHOLD MODIFICATION WARNING'));
|
|
313
|
+
console.log(chalk.red(analysis.ownerModification.warning));
|
|
314
|
+
console.log(chalk.dim('\n Detected modifications:'));
|
|
315
|
+
for (const mod of analysis.ownerModification.modifications) {
|
|
316
|
+
const nestedTag = mod.isNested ? ' (nested in MultiSend)' : ' (direct call)';
|
|
317
|
+
console.log(chalk.red(` • ${mod.functionName}${nestedTag}`));
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Module/Guard warnings
|
|
321
|
+
if (analysis.moduleGuard.warnings && analysis.moduleGuard.warnings.length > 0) {
|
|
322
|
+
console.log(chalk.bold.red('\n⚠️ MODULE/GUARD SECURITY WARNING'));
|
|
323
|
+
for (const warning of analysis.moduleGuard.warnings) {
|
|
324
|
+
console.log(chalk.red(warning));
|
|
325
|
+
}
|
|
326
|
+
if (analysis.moduleGuard.detections.length > 0) {
|
|
327
|
+
console.log(chalk.dim('\n Detected operations:'));
|
|
328
|
+
for (const detection of analysis.moduleGuard.detections) {
|
|
329
|
+
const nestedTag = detection.isNested ? ' (nested in MultiSend)' : ' (direct call)';
|
|
330
|
+
const trustTag = detection.isTrusted ? ' [TRUSTED]' : ' [UNTRUSTED]';
|
|
331
|
+
const targetInfo = detection.targetAddress ? ` → ${detection.targetAddress}` : '';
|
|
332
|
+
console.log(chalk.red(` • ${detection.functionName}${targetInfo}${trustTag}${nestedTag}`));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Final warning if requires careful review
|
|
337
|
+
if (analysis.requiresCarefulReview) {
|
|
338
|
+
console.log(chalk.bold.red('\n⚠️ This transaction requires CAREFUL REVIEW before signing!'));
|
|
339
|
+
console.log(chalk.yellow(' Please verify all parameters and ensure you understand the implications.'));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/formatters/output.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sky Safe Transaction Decoder CLI
|
|
4
|
+
*
|
|
5
|
+
* CLI tool for calculating and verifying Safe multisig transaction hashes.
|
|
6
|
+
* TypeScript port of safe-tx-hashes-util bash script.
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/pcaversaccio/safe-tx-hashes-util
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sky Safe Transaction Decoder CLI
|
|
4
|
+
*
|
|
5
|
+
* CLI tool for calculating and verifying Safe multisig transaction hashes.
|
|
6
|
+
* TypeScript port of safe-tx-hashes-util bash script.
|
|
7
|
+
*
|
|
8
|
+
* @see https://github.com/pcaversaccio/safe-tx-hashes-util
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { createVerifyCommand } from './commands/verify.js';
|
|
12
|
+
const program = new Command();
|
|
13
|
+
program
|
|
14
|
+
.name('sky-safe')
|
|
15
|
+
.description('Safe multisig transaction hash calculator and decoder')
|
|
16
|
+
.version('0.1.0');
|
|
17
|
+
// Verify command - Fetch and display transaction
|
|
18
|
+
program.addCommand(createVerifyCommand());
|
|
19
|
+
// Show help if no command provided
|
|
20
|
+
if (process.argv.length === 2) {
|
|
21
|
+
program.help();
|
|
22
|
+
}
|
|
23
|
+
// Parse arguments
|
|
24
|
+
program.parse();
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,uDAAuD,CAAC;KACpE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,iDAAiD;AACjD,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAA;AAEzC,mCAAmC;AACnC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC9B,OAAO,CAAC,IAAI,EAAE,CAAA;AAChB,CAAC;AAED,kBAAkB;AAClB,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shield3/sky-safe-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for Safe transaction hash calculation and verification",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"sky-safe": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsx src/index.ts",
|
|
15
|
+
"test": "vitest run --passWithNoTests",
|
|
16
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
17
|
+
"prepublishOnly": "pnpm run build && pnpm run test"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"safe",
|
|
21
|
+
"gnosis-safe",
|
|
22
|
+
"multisig",
|
|
23
|
+
"cli",
|
|
24
|
+
"transaction-decoder",
|
|
25
|
+
"eip-712"
|
|
26
|
+
],
|
|
27
|
+
"license": "AGPL-3.0-only",
|
|
28
|
+
"author": "Security Alliance",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/securityalliance/sky-safe-tx-decoder",
|
|
32
|
+
"directory": "packages/cli"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/securityalliance/sky-safe-tx-decoder#readme",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@shield3/sky-safe-core": "workspace:*",
|
|
40
|
+
"@types/inquirer": "9.0.9",
|
|
41
|
+
"chalk": "5.3.0",
|
|
42
|
+
"commander": "11.1.0",
|
|
43
|
+
"inquirer": "12.11.1",
|
|
44
|
+
"ora": "8.0.1",
|
|
45
|
+
"viem": "2.7.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "20.19.0",
|
|
49
|
+
"tsx": "4.7.0",
|
|
50
|
+
"typescript": "5.3.3",
|
|
51
|
+
"vitest": "2.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|