@acala-network/chopsticks 0.9.13 → 0.10.0-2

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.
Files changed (27) hide show
  1. package/dist/cjs/cli.js +4 -4
  2. package/dist/cjs/plugins/index.js +2 -1
  3. package/dist/cjs/plugins/trace-transaction/README.md +12 -0
  4. package/dist/cjs/plugins/trace-transaction/__tests__/__snapshots__/trace-call.test.ts.snap +365 -0
  5. package/dist/cjs/plugins/trace-transaction/index.d.ts +2 -0
  6. package/dist/cjs/plugins/trace-transaction/index.js +66 -0
  7. package/dist/cjs/plugins/trace-transaction/table.d.ts +148 -0
  8. package/dist/cjs/plugins/trace-transaction/table.js +168 -0
  9. package/dist/cjs/plugins/trace-transaction/types.d.ts +30 -0
  10. package/dist/cjs/plugins/trace-transaction/types.js +64 -0
  11. package/dist/cjs/plugins/trace-transaction/utils.d.ts +40 -0
  12. package/dist/cjs/plugins/trace-transaction/utils.js +207 -0
  13. package/dist/cjs/utils/tunnel.js +2 -1
  14. package/dist/esm/cli.js +5 -5
  15. package/dist/esm/plugins/index.js +2 -1
  16. package/dist/esm/plugins/trace-transaction/README.md +12 -0
  17. package/dist/esm/plugins/trace-transaction/__tests__/__snapshots__/trace-call.test.ts.snap +365 -0
  18. package/dist/esm/plugins/trace-transaction/index.d.ts +2 -0
  19. package/dist/esm/plugins/trace-transaction/index.js +56 -0
  20. package/dist/esm/plugins/trace-transaction/table.d.ts +148 -0
  21. package/dist/esm/plugins/trace-transaction/table.js +150 -0
  22. package/dist/esm/plugins/trace-transaction/types.d.ts +30 -0
  23. package/dist/esm/plugins/trace-transaction/types.js +54 -0
  24. package/dist/esm/plugins/trace-transaction/utils.d.ts +40 -0
  25. package/dist/esm/plugins/trace-transaction/utils.js +199 -0
  26. package/dist/esm/utils/tunnel.js +2 -1
  27. package/package.json +3 -3
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ TABLE: function() {
13
+ return TABLE;
14
+ },
15
+ opName: function() {
16
+ return opName;
17
+ }
18
+ });
19
+ const TABLE = {
20
+ '0x00': 'STOP',
21
+ '0x01': 'ADD',
22
+ '0x02': 'MUL',
23
+ '0x03': 'SUB',
24
+ '0x04': 'DIV',
25
+ '0x05': 'SDIV',
26
+ '0x06': 'MOD',
27
+ '0x07': 'SMOD',
28
+ '0x08': 'ADDMOD',
29
+ '0x09': 'MULMOD',
30
+ '0x0a': 'EXP',
31
+ '0x0b': 'SIGNEXTEND',
32
+ '0x10': 'LT',
33
+ '0x11': 'GT',
34
+ '0x12': 'SLT',
35
+ '0x13': 'SGT',
36
+ '0x14': 'EQ',
37
+ '0x15': 'ISZERO',
38
+ '0x16': 'AND',
39
+ '0x17': 'OR',
40
+ '0x18': 'XOR',
41
+ '0x19': 'NOT',
42
+ '0x1a': 'BYTE',
43
+ '0x35': 'CALLDATALOAD',
44
+ '0x36': 'CALLDATASIZE',
45
+ '0x37': 'CALLDATACOPY',
46
+ '0x38': 'CODESIZE',
47
+ '0x39': 'CODECOPY',
48
+ '0x1b': 'SHL',
49
+ '0x1c': 'SHR',
50
+ '0x1d': 'SAR',
51
+ '0x50': 'POP',
52
+ '0x51': 'MLOAD',
53
+ '0x52': 'MSTORE',
54
+ '0x53': 'MSTORE8',
55
+ '0x56': 'JUMP',
56
+ '0x57': 'JUMPI',
57
+ '0x58': 'PC',
58
+ '0x59': 'MSIZE',
59
+ '0x5b': 'JUMPDEST',
60
+ '0x5f': 'PUSH0',
61
+ '0x60': 'PUSH1',
62
+ '0x61': 'PUSH2',
63
+ '0x62': 'PUSH3',
64
+ '0x63': 'PUSH4',
65
+ '0x64': 'PUSH5',
66
+ '0x65': 'PUSH6',
67
+ '0x66': 'PUSH7',
68
+ '0x67': 'PUSH8',
69
+ '0x68': 'PUSH9',
70
+ '0x69': 'PUSH10',
71
+ '0x6a': 'PUSH11',
72
+ '0x6b': 'PUSH12',
73
+ '0x6c': 'PUSH13',
74
+ '0x6d': 'PUSH14',
75
+ '0x6e': 'PUSH15',
76
+ '0x6f': 'PUSH16',
77
+ '0x70': 'PUSH17',
78
+ '0x71': 'PUSH18',
79
+ '0x72': 'PUSH19',
80
+ '0x73': 'PUSH20',
81
+ '0x74': 'PUSH21',
82
+ '0x75': 'PUSH22',
83
+ '0x76': 'PUSH23',
84
+ '0x77': 'PUSH24',
85
+ '0x78': 'PUSH25',
86
+ '0x79': 'PUSH26',
87
+ '0x7a': 'PUSH27',
88
+ '0x7b': 'PUSH28',
89
+ '0x7c': 'PUSH29',
90
+ '0x7d': 'PUSH30',
91
+ '0x7e': 'PUSH31',
92
+ '0x7f': 'PUSH32',
93
+ '0x80': 'DUP1',
94
+ '0x81': 'DUP2',
95
+ '0x82': 'DUP3',
96
+ '0x83': 'DUP4',
97
+ '0x84': 'DUP5',
98
+ '0x85': 'DUP6',
99
+ '0x86': 'DUP7',
100
+ '0x87': 'DUP8',
101
+ '0x88': 'DUP9',
102
+ '0x89': 'DUP10',
103
+ '0x8a': 'DUP11',
104
+ '0x8b': 'DUP12',
105
+ '0x8c': 'DUP13',
106
+ '0x8d': 'DUP14',
107
+ '0x8e': 'DUP15',
108
+ '0x8f': 'DUP16',
109
+ '0x90': 'SWAP1',
110
+ '0x91': 'SWAP2',
111
+ '0x92': 'SWAP3',
112
+ '0x93': 'SWAP4',
113
+ '0x94': 'SWAP5',
114
+ '0x95': 'SWAP6',
115
+ '0x96': 'SWAP7',
116
+ '0x97': 'SWAP8',
117
+ '0x98': 'SWAP9',
118
+ '0x99': 'SWAP10',
119
+ '0x9a': 'SWAP11',
120
+ '0x9b': 'SWAP12',
121
+ '0x9c': 'SWAP13',
122
+ '0x9d': 'SWAP14',
123
+ '0x9e': 'SWAP15',
124
+ '0x9f': 'SWAP16',
125
+ '0xf3': 'RETURN',
126
+ '0xfd': 'REVERT',
127
+ '0xfe': 'INVALID',
128
+ '0xef': 'EOFMAGIC',
129
+ '0x20': 'SHA3',
130
+ '0x30': 'ADDRESS',
131
+ '0x31': 'BALANCE',
132
+ '0x47': 'SELFBALANCE',
133
+ '0x48': 'BASEFEE',
134
+ '0x32': 'ORIGIN',
135
+ '0x33': 'CALLER',
136
+ '0x34': 'CALLVALUE',
137
+ '0x3a': 'GASPRICE',
138
+ '0x3b': 'EXTCODESIZE',
139
+ '0x3c': 'EXTCODECOPY',
140
+ '0x3f': 'EXTCODEHASH',
141
+ '0x3d': 'RETURNDATASIZE',
142
+ '0x3e': 'RETURNDATACOPY',
143
+ '0x40': 'BLOCKHASH',
144
+ '0x41': 'COINBASE',
145
+ '0x42': 'TIMESTAMP',
146
+ '0x43': 'NUMBER',
147
+ '0x44': 'DIFFICULTY',
148
+ '0x45': 'GASLIMIT',
149
+ '0x54': 'SLOAD',
150
+ '0x55': 'SSTORE',
151
+ '0x5a': 'GAS',
152
+ '0xa0': 'LOG0',
153
+ '0xa1': 'LOG1',
154
+ '0xa2': 'LOG2',
155
+ '0xa3': 'LOG3',
156
+ '0xa4': 'LOG4',
157
+ '0xf0': 'CREATE',
158
+ '0xf5': 'CREATE2',
159
+ '0xf1': 'CALL',
160
+ '0xf2': 'CALLCODE',
161
+ '0xf4': 'DELEGATECALL',
162
+ '0xfa': 'STATICCALL',
163
+ '0xff': 'SUICIDE',
164
+ '0x46': 'CHAINID'
165
+ };
166
+ const opName = (op)=>{
167
+ return TABLE[`0x${op.toString(16).padStart(2, '0')}`] || `0x${op.toString(16).padStart(2, '0')}`;
168
+ };
@@ -0,0 +1,30 @@
1
+ import { HexString } from '@polkadot/util/types';
2
+ import { Registry } from '@polkadot/types/types';
3
+ export type CallTrace = {
4
+ type: 'CALL' | 'CALLCODE' | 'STATICCALL' | 'DELEGATECALL' | 'CREATE' | 'SUICIDE';
5
+ from: HexString;
6
+ to: HexString;
7
+ input: HexString;
8
+ value: HexString;
9
+ gas: number;
10
+ gasUsed: number;
11
+ output: HexString | null;
12
+ error: string | null;
13
+ revertReason: string | null;
14
+ depth: number;
15
+ calls: CallTrace[];
16
+ };
17
+ export type Step = {
18
+ op: number;
19
+ pc: number;
20
+ depth: number;
21
+ gas: number;
22
+ stack: HexString[];
23
+ memory: string[] | null;
24
+ };
25
+ export type TraceOutcome = {
26
+ steps: Step[];
27
+ } | {
28
+ calls: CallTrace[];
29
+ };
30
+ export declare const registerTypes: (registry: Registry) => void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "registerTypes", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return registerTypes;
9
+ }
10
+ });
11
+ const registerTypes = (registry)=>{
12
+ registry.register({
13
+ Step: {
14
+ op: 'u8',
15
+ pc: 'Compact<u32>',
16
+ depth: 'Compact<u32>',
17
+ gas: 'Compact<u64>',
18
+ stack: 'Vec<Bytes>',
19
+ memory: 'Option<Vec<Bytes>>'
20
+ },
21
+ CallType: {
22
+ _enum: {
23
+ CALL: null,
24
+ CALLCODE: null,
25
+ STATICCALL: null,
26
+ DELEGATECALL: null,
27
+ CREATE: null,
28
+ SUICIDE: null
29
+ }
30
+ },
31
+ CallTrace: {
32
+ type: 'CallType',
33
+ from: 'H160',
34
+ to: 'H160',
35
+ input: 'Bytes',
36
+ value: 'U256',
37
+ gas: 'Compact<u64>',
38
+ gasUsed: 'Compact<u64>',
39
+ output: 'Option<Bytes>',
40
+ error: 'Option<String>',
41
+ revertReason: 'Option<String>',
42
+ depth: 'Compact<u32>',
43
+ calls: 'Vec<CallTrace>'
44
+ },
45
+ TraceOutcome: {
46
+ _enum: {
47
+ Calls: 'Vec<CallTrace>',
48
+ Steps: 'Vec<Step>'
49
+ }
50
+ },
51
+ OpcodeConfig: {
52
+ page: 'u32',
53
+ pageSize: 'u32',
54
+ disableStack: 'bool',
55
+ enableMemory: 'bool'
56
+ },
57
+ TracerConfig: {
58
+ _enum: {
59
+ CallTracer: null,
60
+ OpcodeTracer: 'OpcodeConfig'
61
+ }
62
+ }
63
+ });
64
+ };
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { Block, Blockchain, RuntimeVersion } from '@acala-network/chopsticks-core';
3
+ import { HexString } from '@polkadot/util/types';
4
+ import { Step } from './types.js';
5
+ /**
6
+ * Fetches the runtime with tracing feature from Github releases.
7
+ * @param runtimeVersion - The version of the runtime.
8
+ * @returns A Promise that resolves to the fetched runtime as a Buffer.
9
+ */
10
+ export declare const fetchRuntime: (runtimeVersion: RuntimeVersion) => Promise<Buffer | undefined>;
11
+ export declare const fetchEVMTransaction: (runtimeVersion: RuntimeVersion, txHash: string) => Promise<any>;
12
+ /**
13
+ * Traces the execution of a transaction in the VM.
14
+ * @param block - The block to trace the extrinsic in.
15
+ * @param extrinsic - The extrinsic to trace.
16
+ * @returns An array of VM steps.
17
+ * @throws Error if the trace outcome is invalid.
18
+ */
19
+ export declare const traceVM: (block: Block, extrinsic: HexString, pageSize?: number, disableStack?: boolean, enableMemory?: boolean) => Promise<Step[]>;
20
+ /**
21
+ * Traces the calls made by an extrinsic in a block.
22
+ * @param block - The block to trace the extrinsic in.
23
+ * @param extrinsic - The extrinsic to trace.
24
+ * @returns An array of calls made by the extrinsic.
25
+ * @throws Error if the trace outcome is invalid.
26
+ */
27
+ export declare const traceCalls: (block: Block, extrinsic: HexString) => Promise<import("./types.js").CallTrace[]>;
28
+ /**
29
+ * Prepares a block for tracing a transaction.
30
+ * @param chain The blockchain instance.
31
+ * @param blockHashNumber The block hash or block number.
32
+ * @param txHash The transaction hash.
33
+ * @param wasmPath The path to the runtime wasm file.
34
+ * @returns An object containing the tracing block and the transaction extrinsic.
35
+ * @throws Error if the block or parent block is not found, or if the runtime wasm with tracing feature cannot be found.
36
+ */
37
+ export declare const prepareBlock: (chain: Blockchain, blockHashNumber: HexString | number, txHash: string, wasmPath?: string) => Promise<{
38
+ tracingBlock: Block;
39
+ extrinsic: `0x${string}`;
40
+ }>;
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ fetchEVMTransaction: function() {
13
+ return fetchEVMTransaction;
14
+ },
15
+ fetchRuntime: function() {
16
+ return fetchRuntime;
17
+ },
18
+ prepareBlock: function() {
19
+ return prepareBlock;
20
+ },
21
+ traceCalls: function() {
22
+ return traceCalls;
23
+ },
24
+ traceVM: function() {
25
+ return traceVM;
26
+ }
27
+ });
28
+ const _chopstickscore = require("@acala-network/chopsticks-core");
29
+ const _utilcrypto = require("@polkadot/util-crypto");
30
+ const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
31
+ const _types = require("./types.js");
32
+ const _table = require("./table.js");
33
+ const _override = require("../../utils/override.js");
34
+ function _interop_require_default(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
39
+ const fetchRuntime = async (runtimeVersion)=>{
40
+ const GIHTUB_RELEASES_API = 'https://api.github.com/repos/AcalaNetwork/Acala/releases';
41
+ const assetName = `${runtimeVersion.specName}_runtime_tracing_${runtimeVersion.specVersion}.compact.compressed.wasm`;
42
+ _chopstickscore.pinoLogger.info({
43
+ assetName
44
+ }, 'Search for runtime with tracing feature from Github releases ...');
45
+ const releases = await fetch(GIHTUB_RELEASES_API).then((res)=>res.json());
46
+ for (const release of releases){
47
+ if (release.assets) {
48
+ for (const asset of release.assets){
49
+ if (asset.name === assetName) {
50
+ _chopstickscore.pinoLogger.info({
51
+ url: asset.browser_download_url
52
+ }, 'Downloading ...');
53
+ const runtime = await fetch(asset.browser_download_url).then((x)=>x.arrayBuffer());
54
+ return Buffer.from(runtime);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ };
60
+ const fetchEVMTransaction = async (runtimeVersion, txHash)=>{
61
+ const ACALA_ETH_RPC = 'https://eth-rpc-acala.aca-api.network';
62
+ const KARURA_ETH_RPC = 'https://eth-rpc-karura.aca-api.network';
63
+ let ethRpc;
64
+ if (runtimeVersion.specName.includes('acala')) {
65
+ ethRpc = ACALA_ETH_RPC;
66
+ } else if (runtimeVersion.specName.includes('karura')) {
67
+ ethRpc = KARURA_ETH_RPC;
68
+ } else {
69
+ throw new Error(`Unsupported chain. Only Acala and Karura are supported`);
70
+ }
71
+ _chopstickscore.pinoLogger.info(`Fetching EVM transaction ...`);
72
+ const response = await fetch(ethRpc, {
73
+ headers: [
74
+ [
75
+ 'Content-Type',
76
+ 'application/json'
77
+ ],
78
+ [
79
+ 'Accept',
80
+ 'application/json'
81
+ ]
82
+ ],
83
+ method: 'POST',
84
+ body: JSON.stringify({
85
+ jsonrpc: '2.0',
86
+ id: 1,
87
+ method: 'eth_getTransactionByHash',
88
+ params: [
89
+ txHash
90
+ ]
91
+ })
92
+ });
93
+ const data = await response.json();
94
+ if (data.error) {
95
+ throw new Error(data.error.message);
96
+ }
97
+ return data.result;
98
+ };
99
+ const traceVM = async (block, extrinsic, pageSize = 50_000, disableStack = false, enableMemory = true)=>{
100
+ const meta = await block.meta;
101
+ (0, _types.registerTypes)(meta.registry);
102
+ let page = 0;
103
+ let traceNextPage = true;
104
+ let steps = [];
105
+ while(traceNextPage){
106
+ _chopstickscore.pinoLogger.info(`VM trace page ${page} ...`);
107
+ const tracerConfig = meta.registry.createType('TracerConfig', {
108
+ OpcodeTracer: {
109
+ page,
110
+ pageSize,
111
+ disableStack,
112
+ enableMemory
113
+ }
114
+ }).toHex();
115
+ const taskResponse = await block.call('EVMTraceApi_trace_extrinsic', [
116
+ extrinsic,
117
+ tracerConfig
118
+ ]);
119
+ const outcome = meta.registry.createType('Result<TraceOutcome, TransactionValidityError>', taskResponse.result).asOk.toJSON();
120
+ if (!('steps' in outcome)) {
121
+ throw new Error('Invalid trace outcome');
122
+ }
123
+ steps = steps.concat(outcome.steps.map((step)=>({
124
+ ...step,
125
+ op: (0, _table.opName)(step.op),
126
+ // transform memory to 64 bytes chunks
127
+ memory: step.memory ? step.memory.map((chunk, idx)=>{
128
+ // remove 0x prefix
129
+ const slice = chunk.slice(2);
130
+ // make sure each chunk is 64 bytes
131
+ if (slice.length < 64 && idx + 1 < step.memory.length) {
132
+ return slice.padStart(64, '0');
133
+ }
134
+ return slice;
135
+ }) : null
136
+ })));
137
+ page += 1;
138
+ traceNextPage = outcome.steps.length == pageSize;
139
+ }
140
+ return steps;
141
+ };
142
+ const traceCalls = async (block, extrinsic)=>{
143
+ const meta = await block.meta;
144
+ (0, _types.registerTypes)(meta.registry);
145
+ const tracerConfig = meta.registry.createType('TracerConfig', {
146
+ CallTracer: null
147
+ }).toHex();
148
+ const taskResponse = await block.call('EVMTraceApi_trace_extrinsic', [
149
+ extrinsic,
150
+ tracerConfig
151
+ ]);
152
+ const outcome = meta.registry.createType('Result<TraceOutcome, TransactionValidityError>', taskResponse.result).asOk.toJSON();
153
+ if (!('calls' in outcome)) {
154
+ throw new Error('Invalid trace outcome');
155
+ }
156
+ return outcome.calls;
157
+ };
158
+ const prepareBlock = async (chain, blockHashNumber, txHash, wasmPath)=>{
159
+ let wasm = wasmPath;
160
+ const block = typeof blockHashNumber == 'number' ? await chain.getBlockAt(blockHashNumber) : await chain.getBlock(blockHashNumber);
161
+ if (!block) {
162
+ throw new Error(`Block not found ${blockHashNumber}`);
163
+ }
164
+ const header = await block.header;
165
+ const parent = await chain.getBlock(header.parentHash.toHex());
166
+ if (!parent) {
167
+ throw new Error(`Block not found ${blockHashNumber}`);
168
+ }
169
+ await chain.setHead(parent);
170
+ // override wasm with tracing feature
171
+ if (typeof wasm === 'string') {
172
+ await (0, _override.overrideWasm)(chain, wasm);
173
+ } else {
174
+ // Fetch runtime wasm with tracing feature from Github releases
175
+ if (!wasm) {
176
+ wasm = await fetchRuntime(await chain.head.runtimeVersion);
177
+ if (!wasm) {
178
+ throw new Error('Could not find runtime with tracing feature from Github releasesw. Make sure to manually override runtime wasm built with `tracing` feature enabled.');
179
+ }
180
+ }
181
+ chain.head.setWasm(`0x${wasm.toString('hex')}`);
182
+ }
183
+ const runtimeVersion = await chain.head.runtimeVersion;
184
+ _chopstickscore.pinoLogger.info(`${_lodash.default.capitalize(runtimeVersion.specName)} specVersion: ${runtimeVersion.specVersion}`);
185
+ const extrinsics = await block.extrinsics;
186
+ const txIndex = extrinsics.findIndex((tx)=>(0, _utilcrypto.blake2AsHex)(tx) === txHash);
187
+ const tracingBlock = new _chopstickscore.Block(chain, block.number, block.hash, parent, {
188
+ header,
189
+ extrinsics: [],
190
+ storage: parent.storage
191
+ });
192
+ _chopstickscore.pinoLogger.info(`Preparing block ${chain.head.number + 1} ...`);
193
+ const { storageDiff } = await tracingBlock.call('Core_initialize_block', [
194
+ header.toHex()
195
+ ]);
196
+ tracingBlock.pushStorageLayer().setAll(storageDiff);
197
+ for (const extrinsic of extrinsics.slice(0, txIndex)){
198
+ const { storageDiff } = await tracingBlock.call('BlockBuilder_apply_extrinsic', [
199
+ extrinsic
200
+ ]);
201
+ tracingBlock.pushStorageLayer().setAll(storageDiff);
202
+ }
203
+ return {
204
+ tracingBlock,
205
+ extrinsic: extrinsics[txIndex]
206
+ };
207
+ };
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  const _globalagent = require("global-agent");
6
+ const _chopstickscore = require("@acala-network/chopsticks-core");
6
7
  const _npmconf = /*#__PURE__*/ _interop_require_default(require("@pnpm/npm-conf"));
7
8
  function _interop_require_default(obj) {
8
9
  return obj && obj.__esModule ? obj : {
@@ -11,4 +12,4 @@ function _interop_require_default(obj) {
11
12
  }
12
13
  (0, _globalagent.bootstrap)();
13
14
  const npmConfig = (0, _npmconf.default)().config;
14
- global.GLOBAL_AGENT.HTTP_PROXY = process.env.HTTP_PROXY || process.env.http_proxy || process.env.HTTPS_PROXY || process.env.https_proxy || npmConfig.get('proxy') || npmConfig.get('https-proxy') || global.GLOBAL_AGENT.HTTP_PROXY;
15
+ global.GLOBAL_AGENT.HTTP_PROXY = _chopstickscore.environment.HTTP_PROXY || _chopstickscore.environment.http_proxy || _chopstickscore.environment.HTTPS_PROXY || _chopstickscore.environment.https_proxy || npmConfig.get('proxy') || npmConfig.get('https-proxy') || global.GLOBAL_AGENT.HTTP_PROXY;
package/dist/esm/cli.js CHANGED
@@ -2,7 +2,7 @@ import { config as dotenvConfig } from 'dotenv';
2
2
  import { hideBin } from 'yargs/helpers';
3
3
  import _ from 'lodash';
4
4
  import yargs from 'yargs';
5
- import { connectParachains, connectVertical } from '@acala-network/chopsticks-core';
5
+ import { connectParachains, connectVertical, environment } from '@acala-network/chopsticks-core';
6
6
  import { configSchema, fetchConfig, getYargsOptions } from './schema/index.js';
7
7
  import { pluginExtendCli } from './plugins/index.js';
8
8
  import { setupWithServer } from './index.js';
@@ -11,8 +11,8 @@ const processArgv = async (argv)=>{
11
11
  if (argv.config) {
12
12
  Object.assign(argv, _.defaults(argv, await fetchConfig(argv.config)));
13
13
  }
14
- if (process.env.PORT) {
15
- argv.port = Number(process.env.PORT);
14
+ if (environment.PORT) {
15
+ argv.port = Number(environment.PORT);
16
16
  }
17
17
  };
18
18
  const commands = yargs(hideBin(process.argv)).scriptName('chopsticks').middleware(processArgv, false).command('*', 'Dev mode, fork off a chain', (yargs)=>yargs.config('config', 'Path to config file with default options', ()=>({})).options(getYargsOptions(configSchema.shape)), async (argv)=>{
@@ -35,7 +35,7 @@ const commands = yargs(hideBin(process.argv)).scriptName('chopsticks').middlewar
35
35
  parachains.push(chain);
36
36
  }
37
37
  if (parachains.length > 1) {
38
- await connectParachains(parachains);
38
+ await connectParachains(parachains, environment.DISABLE_AUTO_HRMP);
39
39
  }
40
40
  if (argv.relaychain) {
41
41
  const { chain: relaychain } = await setupWithServer(await fetchConfig(argv.relaychain));
@@ -44,7 +44,7 @@ const commands = yargs(hideBin(process.argv)).scriptName('chopsticks').middlewar
44
44
  }
45
45
  }
46
46
  }).strict().help().alias('help', 'h').alias('version', 'v').alias('config', 'c').alias('endpoint', 'e').alias('port', 'p').alias('block', 'b').alias('import-storage', 's').alias('wasm-override', 'w').usage('Usage: $0 <command> [options]').example('$0', '-c acala');
47
- if (!process.env.DISABLE_PLUGINS) {
47
+ if (!environment.DISABLE_PLUGINS) {
48
48
  pluginExtendCli(commands.config('config', 'Path to config file with default options', ()=>({}))).then(()=>commands.parse());
49
49
  } else {
50
50
  commands.parse();
@@ -1,3 +1,4 @@
1
+ import { environment } from '@acala-network/chopsticks-core';
1
2
  import { lstatSync, readdirSync } from 'fs';
2
3
  import _ from 'lodash';
3
4
  import { defaultLogger } from '../logger.js';
@@ -10,7 +11,7 @@ const plugins = readdirSync(new URL('.', import.meta.url)).filter((file)=>lstatS
10
11
  // find all rpc methods
11
12
  export const rpcPluginMethods = plugins.filter((name)=>readdirSync(new URL(name, import.meta.url)).some((file)=>file.startsWith('rpc'))).map((name)=>`dev_${_.camelCase(name)}`);
12
13
  export const loadRpcPlugin = async (method)=>{
13
- if (process.env.DISABLE_PLUGINS) {
14
+ if (environment.DISABLE_PLUGINS) {
14
15
  return undefined;
15
16
  }
16
17
  if (rpcPluginHandlers[method]) return rpcPluginHandlers[method];
@@ -0,0 +1,12 @@
1
+ # EVM+ trace transaction plugin
2
+
3
+ This plugin allows you to trace the execution of a transaction on the Acala & Karura EVM+. The plugin will take a transaction hash as input and will look up the mainnet for transaction details and perform a trace call for the transaction. You can do either call trace or VM trace
4
+
5
+ Example usage:
6
+ To trace transaction calls, you can use the following command:
7
+
8
+ ```bash
9
+ npx @acala-network/chopsticks trace-transaction <tx-hash> --config acala --output trace.json
10
+ ```
11
+
12
+ VM trace can be enabled by add `--vm` flag to the command