ethershell 0.1.2-beta.0 → 0.1.4-beta.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ethershell",
3
3
  "license": "MIT",
4
- "version": "0.1.2-beta.0",
4
+ "version": "0.1.4-beta.0",
5
5
  "description": "Interactive JavaScript console for Ethereum smart contract management",
6
6
  "author": "Alireza Kiakojouri (alirezaethdev@gmail.com)",
7
7
  "repository": {
@@ -8,12 +8,13 @@
8
8
 
9
9
  import { ethers } from 'ethers';
10
10
  import fs from 'fs';
11
- import { provider } from './network.js';
12
- import { allAccounts, accounts, hdAccounts } from './wallet.js';
11
+ import { provider } from './config.js';
12
+ import { allAccounts } from './wallet.js';
13
13
  import { LocalStorage } from 'node-localstorage';
14
14
  import { r } from '../../bin/cli.js';
15
- import { configFile } from './build.js';
15
+ import { configFile } from './config.js';
16
16
  import { createContractProxy } from '../utils/contractProxy.js';
17
+ import { eventOf } from '../utils/event.js';
17
18
 
18
19
  /**
19
20
  * Local storage instance for persisting contract metadata
@@ -88,16 +89,6 @@ export async function deploy(contractName, args, accIndex, chain, abiLoc, byteco
88
89
  }
89
90
 
90
91
  allAccounts[accIndex].contracts.push(contSpec);
91
-
92
- const accountsIndex = accounts.findIndex(wallet => wallet.index == accIndex);
93
- if(accountsIndex >= 0) {
94
- accounts[accountsIndex].contracts.push(contSpec);
95
- }
96
-
97
- const hdIndex = hdAccounts.findIndex(wallet => wallet.index == accIndex);
98
- if(hdIndex >= 0) {
99
- hdAccounts[hdIndex].contracts.push(contSpec);
100
- }
101
92
 
102
93
  // Extend contract object
103
94
  deployTx.index = Array.from(contracts.values()).length;
@@ -117,6 +108,13 @@ export async function deploy(contractName, args, accIndex, chain, abiLoc, byteco
117
108
  // Wrap the contract instace with proxy
118
109
  const proxiedContract = createContractProxy(contractInstance, currentProvider, allAccounts);
119
110
 
111
+ proxiedContract.index = Array.from(contracts.values()).length;
112
+ proxiedContract.name = contractName;
113
+ proxiedContract.chain = connectedChain.name;
114
+ proxiedContract.chainId = connectedChain.chainId;
115
+ proxiedContract.deployType = 'ethershell-deployed';
116
+ proxiedContract.provider = currentProvider;
117
+
120
118
  // Add to REPL context with proxy
121
119
  r.context[contractName] = proxiedContract;
122
120
  contracts.set(contractName, proxiedContract);
@@ -127,14 +125,22 @@ export async function deploy(contractName, args, accIndex, chain, abiLoc, byteco
127
125
  const tx = await provider.getTransaction(deployHash);
128
126
  delete tx.data;
129
127
 
128
+ // Get event values
129
+ const tx1 = await provider.getTransactionReceipt(deployHash);
130
+ const eventValues = eventOf(contractInstance, tx1);
131
+
130
132
  // Extend transaction object
131
133
  tx.ethershellIndex = deployTx.index;
132
134
  tx.address = deployTx.target;
133
135
  tx.name = deployTx.name;
134
136
  tx.chain = deployTx.chain;
135
137
  tx.deployType = deployTx.deployType;
138
+
139
+ if(eventValues) {
140
+ tx.eventValues = eventValues;
141
+ }
136
142
 
137
- console.log(tx);
143
+ return tx;
138
144
  } catch(err) {
139
145
  console.error(err);
140
146
  }
@@ -185,6 +191,13 @@ export async function add(contractName, contractAddr, accIndex, abiLoc, chain) {
185
191
  // Wrap the contract instace with proxy
186
192
  const proxiedContract = createContractProxy(newContract, currentProvider, allAccounts);
187
193
 
194
+ proxiedContract.index = Array.from(contracts.values()).length;
195
+ proxiedContract.name = contractName;
196
+ proxiedContract.chain = connectedChain.name;
197
+ proxiedContract.chainId = connectedChain.chainId;
198
+ proxiedContract.deployType = 'ethershell-deployed';
199
+ proxiedContract.provider = currentProvider;
200
+
188
201
  // Add to REPL context with proxy
189
202
  r.context[contractName] = proxiedContract;
190
203
  contracts.set(contractName, proxiedContract);
@@ -197,16 +210,6 @@ export async function add(contractName, contractAddr, accIndex, abiLoc, chain) {
197
210
  }
198
211
 
199
212
  allAccounts[accIndex].contracts.push(contSpec);
200
-
201
- const accountsIndex = accounts.findIndex(wallet => wallet.index == accIndex);
202
- if(accountsIndex >= 0) {
203
- accounts[accountsIndex].contracts.push(contSpec);
204
- }
205
-
206
- const hdIndex = hdAccounts.findIndex(wallet => wallet.index == accIndex);
207
- if(hdIndex >= 0) {
208
- hdAccounts[hdIndex].contracts.push(contSpec);
209
- }
210
213
 
211
214
  // Extend contract object
212
215
  newContract.index = Array.from(contracts.values()).length;
@@ -227,7 +230,7 @@ export async function add(contractName, contractAddr, accIndex, abiLoc, chain) {
227
230
  provider: newContract.provider
228
231
  }
229
232
 
230
- console.log(result);
233
+ return result;
231
234
  } catch(err) {
232
235
  console.error(err);
233
236
  }
@@ -6,92 +6,21 @@
6
6
  */
7
7
 
8
8
  import path from 'path';
9
- import solc from 'solc';
10
9
  import { check, collectSolFiles } from '../utils/dir.js';
11
10
  import {
12
11
  setVersion,
13
12
  build,
14
- loadSolcVersion,
15
13
  extractLoadableVersion
16
14
  } from '../utils/builder.js';
17
15
  import fs from 'fs';
18
16
  import {
19
17
  generateAllTypes,
20
18
  } from '../utils/typeGenerator.js';
21
-
22
- /**
23
- * Stored config path
24
- * @type {string}
25
- */
26
- export const configPath = './ethershell/config.json';
27
-
28
- /**
29
- * Global compiler configuration state
30
- * @type {Object}
31
- * @property {Object} currentSolcInstance - Current Solidity compiler instance
32
- * @property {boolean} optimizer - Whether gas optimizer is enabled
33
- * @property {number} optimizerRuns - Number of optimizer runs
34
- * @property {boolean} viaIR - Whether to use IR-based code generation
35
- */
36
- let compConfig = {};
37
-
38
- /**
39
- * JSON file fields of compiler configuration
40
- * @type {Object}
41
- * @property {string} version - Current Solidity compiler version
42
- * @property {boolean} optimizer - Whether gas optimizer is enabled
43
- * @property {number} optimizerRuns - Number of optimizer runs
44
- * @property {boolean} viaIR - Whether to use IR-based code generation
45
- */
46
- export let configFile = {
47
- providerEndpoint: '',
48
- defaultWallet: {},
49
- compiler: {}
50
- };
51
-
52
- /**
53
- * Global compiler configuration state
54
- * @type {Object}
55
- * @property {boolean} optimizer - Whether gas optimizer is enabled
56
- * @property {number} optimizerRuns - Number of optimizer runs
57
- * @property {boolean} viaIR - Whether to use IR-based code generation
58
- */
59
- let storedCompConfig;
60
-
61
- // Load config file
62
- if(fs.existsSync(configPath)){
63
- storedCompConfig = JSON.parse(fs.readFileSync(configPath));
64
- } else {
65
- storedCompConfig = null;
66
- }
67
-
68
- // Initialize global configuration of compiler
69
- if(storedCompConfig){
70
- configFile.compiler = storedCompConfig.compiler;
71
- console.info(`Compiler is loading ...`);
72
- compConfig.currentSolcInstance = await loadSolcVersion(configFile.compiler.version);
73
- console.info(`Loading done!`);
74
- compConfig.optimizer = configFile.compiler.optimizer;
75
- compConfig.viaIR = configFile.compiler.viaIR;
76
- compConfig.optimizerRuns = configFile.compiler.optimizerRuns;
77
- compConfig.compilePath = configFile.compiler.compilePath;
78
- } else {
79
- compConfig = {
80
- currentSolcInstance: solc, // default local compiler
81
- optimizer: false,
82
- viaIR: false,
83
- optimizerRuns: 200,
84
- compilePath: './build'
85
- }
86
- configFile.compiler.version = extractLoadableVersion(compConfig.currentSolcInstance.version());
87
- configFile.compiler.optimizer = compConfig.optimizer;
88
- configFile.compiler.viaIR = compConfig.viaIR;
89
- configFile.compiler.optimizerRuns = compConfig.optimizerRuns;
90
- configFile.compiler.compilePath = compConfig.compilePath;
91
-
92
- // Update config file
93
- fs.writeFileSync(configPath, JSON.stringify(configFile, null, 2));
94
- }
19
+ import {
20
+ configPath,
21
+ configFile,
22
+ compConfig
23
+ } from './config.js';
95
24
 
96
25
  /**
97
26
  * Update the Solidity compiler to a specific version
@@ -1,15 +1,175 @@
1
- import { configFile } from './build.js';
1
+ import {
2
+ loadSolcVersion,
3
+ extractLoadableVersion
4
+ } from '../utils/builder.js';
5
+ import { allAccounts } from './wallet.js';
6
+ import { serializeBigInts } from '../utils/serialize.js';
7
+ import fs from 'fs';
8
+ import { ethers } from 'ethers';
9
+
10
+ // Sync Config Memory with Storage Config:
11
+ /**
12
+ * Default JSON-RPC URL for local Ethereum node
13
+ * @constant {string}
14
+ */
15
+ export const defaultUrl = 'http://127.0.0.1:8545' ;
16
+
17
+ /**
18
+ * Currently active network URL
19
+ * @type {string}
20
+ */
21
+ export let currentUrl;
22
+
23
+ /**
24
+ * Ethers.js JSON-RPC provider instance
25
+ * @type {ethers.JsonRpcProvider}
26
+ */
27
+ export let provider
28
+
29
+ /**
30
+ * Stored config path
31
+ * @type {string}
32
+ */
33
+ export const configPath = './ethershell/config.json';
34
+
35
+ /**
36
+ * Global compiler configuration state
37
+ * @type {Object}
38
+ * @property {Object} currentSolcInstance - Current Solidity compiler instance
39
+ * @property {boolean} optimizer - Whether gas optimizer is enabled
40
+ * @property {number} optimizerRuns - Number of optimizer runs
41
+ * @property {boolean} viaIR - Whether to use IR-based code generation
42
+ */
43
+ export let compConfig = {};
44
+
45
+ /**
46
+ * JSON file fields of compiler configuration
47
+ * @type {Object}
48
+ * @property {string} version - Current Solidity compiler version
49
+ * @property {boolean} optimizer - Whether gas optimizer is enabled
50
+ * @property {number} optimizerRuns - Number of optimizer runs
51
+ * @property {boolean} viaIR - Whether to use IR-based code generation
52
+ */
53
+ export let configFile = {
54
+ providerEndpoint: '',
55
+ defaultWallet: {},
56
+ compiler: {}
57
+ };
58
+
59
+ /**
60
+ * Global compiler configuration state
61
+ * @type {Object}
62
+ * @property {boolean} optimizer - Whether gas optimizer is enabled
63
+ * @property {number} optimizerRuns - Number of optimizer runs
64
+ * @property {boolean} viaIR - Whether to use IR-based code generation
65
+ */
66
+ let storedCompConfig;
67
+
68
+ /**
69
+ * Object containing properties of config file
70
+ * @type {Object}
71
+ */
72
+ let configObj;
73
+
74
+ // 1) Load config file
75
+ if(!fs.existsSync(configPath)){
76
+ storedCompConfig = null;
77
+ } else {
78
+ configObj = JSON.parse(fs.readFileSync(configPath));
79
+ storedCompConfig = configObj;
80
+ }
81
+
82
+ // 2) Set Provider to Memory:
83
+ // Initialize provider with default URL
84
+ /**
85
+ * The specific RPC endpoint URL saved on storage before.
86
+ * @type {string}
87
+ */
88
+ const storedUrl = configObj.providerEndpoint;
89
+ if(storedUrl) {
90
+ provider = new ethers.JsonRpcProvider(storedUrl);
91
+ currentUrl = storedUrl;
92
+ configFile.providerEndpoint = storedUrl;
93
+ } else {
94
+ provider = new ethers.JsonRpcProvider(defaultUrl);
95
+ currentUrl = defaultUrl;
96
+ configFile.providerEndpoint = defaultUrl;
97
+ }
98
+
99
+ // 3) Set Compiler to Memeory:
100
+ // Initialize global configuration of compiler
101
+ if(storedCompConfig){
102
+ configFile.compiler = storedCompConfig.compiler;
103
+ console.info(`Compiler is loading ...`);
104
+ compConfig.currentSolcInstance = await loadSolcVersion(configFile.compiler.version);
105
+ console.info(`Loading done!`);
106
+ compConfig.optimizer = configFile.compiler.optimizer;
107
+ compConfig.viaIR = configFile.compiler.viaIR;
108
+ compConfig.optimizerRuns = configFile.compiler.optimizerRuns;
109
+ compConfig.compilePath = configFile.compiler.compilePath;
110
+ } else {
111
+ compConfig = {
112
+ currentSolcInstance: solc, // default local compiler
113
+ optimizer: false,
114
+ viaIR: false,
115
+ optimizerRuns: 200,
116
+ compilePath: './build'
117
+ }
118
+ configFile.compiler.version = extractLoadableVersion(compConfig.currentSolcInstance.version());
119
+ configFile.compiler.optimizer = compConfig.optimizer;
120
+ configFile.compiler.viaIR = compConfig.viaIR;
121
+ configFile.compiler.optimizerRuns = compConfig.optimizerRuns;
122
+ configFile.compiler.compilePath = compConfig.compilePath;
123
+ }
124
+
125
+ // 4) Set Default Account:
126
+ // Set the default account from stored wallets
127
+ const defWallet = configObj.defaultWallet;
128
+ if(defWallet.address) {
129
+ configFile.defaultWallet = serializeBigInts(defWallet);
130
+ } else {
131
+ if(allAccounts && allAccounts.length > 0) {
132
+ configFile.defaultWallet = serializeBigInts(allAccounts[0]);
133
+ }
134
+ }
135
+
136
+ // 5) Update config file
137
+ fs.writeFileSync(configPath, JSON.stringify(configFile, null, 2));
138
+
139
+ /**
140
+ * Changes provider just in memory
141
+ * @param {Object} newProvider
142
+ */
143
+ export function setProvider(newProvider) {
144
+ provider = new ethers.JsonRpcProvider(newProvider);
145
+ }
146
+
147
+ /**
148
+ * Changes provider just in memory
149
+ * @param {String} newUrl
150
+ */
151
+ export function setCurrentUrl(newUrl) {
152
+ currentUrl = newUrl;
153
+ }
154
+
155
+ /**
156
+ * Changes configFile in memory
157
+ * @param {Object} newConfig
158
+ */
159
+ export function setConfigFile(newConfig) {
160
+ configFile = newConfig;
161
+ }
2
162
 
3
163
  /**
4
164
  * Gets all fields of config file
5
165
  */
6
166
  export function getConfigInfo() {
7
- console.log(configFile);
167
+ return configFile;
8
168
  }
9
169
 
10
170
  /**
11
171
  * Gets just default account of config file
12
172
  */
13
173
  export function getDefaultAccount() {
14
- console.log(configFile.defaultWallet);
174
+ return configFile.defaultWallet;
15
175
  }
@@ -39,5 +39,5 @@ export async function getContracts(contPointer) {
39
39
  throw new Error('Input is NOT valid!');
40
40
  }
41
41
 
42
- console.log(result);
42
+ return result;
43
43
  }
@@ -23,17 +23,17 @@ export function deleteDirectory(dirPath){
23
23
  }
24
24
  // Check if the directory exists
25
25
  if(!fs.existsSync(dirPath)){
26
- console.log('Path is not a directory');
26
+ console.info('Path is not a directory');
27
27
  return;
28
28
  }
29
29
 
30
30
  // For Node.js 14.14.0+ (recommended)
31
31
  fs.rmSync(dirPath, { recursive: true, force: true });
32
32
 
33
- console.log('Directory deleted successfully');
33
+ console.info('Directory deleted successfully');
34
34
  } catch (err) {
35
35
  if (err.code === 'ENOENT') {
36
- console.log('Directory does not exist');
36
+ console.info('Directory does not exist');
37
37
  } else {
38
38
  console.error('Error deleting directory:', err);
39
39
  }
@@ -5,44 +5,14 @@
5
5
  * @module network
6
6
  */
7
7
 
8
- import { ethers } from 'ethers';
9
- import { configPath } from './build.js';
10
- import fs from 'fs';
11
8
  import { changeProvider } from '../utils/configFileUpdate.js';
12
-
13
- /**
14
- * Default JSON-RPC URL for local Ethereum node
15
- * @constant {string}
16
- */
17
- const defaultUrl = 'http://127.0.0.1:8545' ;
18
-
19
- /**
20
- * Currently active network URL
21
- * @type {string}
22
- */
23
- export let currentUrl;
24
-
25
- /**
26
- * Ethers.js JSON-RPC provider instance
27
- * @type {ethers.JsonRpcProvider}
28
- */
29
- export let provider
30
-
31
- // Initialize provider with default URL
32
- /**
33
- * The specific RPC endpoint URL saved on storage before.
34
- * @type {string}
35
- */
36
- const storedUrl = JSON.parse(fs.readFileSync(configPath)).providerEndpoint;
37
- if(storedUrl) {
38
- provider = new ethers.JsonRpcProvider(storedUrl);
39
- currentUrl = storedUrl;
40
- } else {
41
- provider = new ethers.JsonRpcProvider(defaultUrl);
42
- currentUrl = defaultUrl;
43
- changeProvider(currentUrl);
44
- }
45
-
9
+ import {
10
+ currentUrl,
11
+ setCurrentUrl,
12
+ provider,
13
+ setProvider,
14
+ defaultUrl
15
+ } from './config.js';
46
16
 
47
17
  /**
48
18
  * Set a new network provider
@@ -55,8 +25,8 @@ if(storedUrl) {
55
25
  */
56
26
  export async function set(url){
57
27
  try{
58
- provider = new ethers.JsonRpcProvider(url);
59
- currentUrl = url;
28
+ setProvider(url);
29
+ setCurrentUrl(url);
60
30
  const result = await provider.getNetwork();
61
31
  const network = {
62
32
  URL: currentUrl,
@@ -64,7 +34,7 @@ export async function set(url){
64
34
  chainId: result.chainId
65
35
  }
66
36
  changeProvider(currentUrl);
67
- console.log(network);
37
+ return network;
68
38
  }catch(err){
69
39
  console.error(err);
70
40
  }
@@ -86,7 +56,7 @@ export async function get(){
86
56
  name: result.name,
87
57
  chainId: result.chainId
88
58
  }
89
- console.log(network);
59
+ return network;
90
60
  }catch(err){
91
61
  console.error(err);
92
62
  }
@@ -103,7 +73,7 @@ export function getDefault(){
103
73
  const result = {
104
74
  URL: defaultUrl
105
75
  }
106
- console.log(result);
76
+ return result;
107
77
  }catch(err){
108
78
  console.error(err);
109
79
  }
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { ethers } from 'ethers';
10
- import { provider } from './network.js';
10
+ import { provider } from './config.js';
11
11
  import {
12
12
  deleteByIndex,
13
13
  deleteByIndexArr,
@@ -18,8 +18,6 @@ import {
18
18
  updateAccountMemory,
19
19
  setDefaultAccount
20
20
  } from '../utils/accounter.js';
21
- import { configPath } from './build.js';
22
- import fs from 'fs';
23
21
 
24
22
  /**
25
23
  * Array containing all accounts (imported, generated, HD, and node-managed)
@@ -27,17 +25,6 @@ import {
27
25
  */
28
26
  export let allAccounts = getWalletJSON();
29
27
 
30
- // Set the default account from stored wallets
31
- const defWallet = JSON.parse(fs.readFileSync(configPath)).defaultWallet;
32
- if(defWallet.address) {
33
- setDefaultAccount(defWallet);
34
- } else {
35
- if(allAccounts && allAccounts.length > 0) {
36
- setDefaultAccount(allAccounts[0]);
37
- }
38
- }
39
-
40
-
41
28
  /**
42
29
  * Array containing only regular accounts (imported and generated)
43
30
  * @type {Array<Object>}
@@ -94,7 +81,7 @@ export function addAccounts(privKeyArr) {
94
81
  updateWalletJSON(allAccounts);
95
82
  newAccObj.index = allAccounts.length - 1;
96
83
  accounts.push(newAccObj);
97
- console.log(allAccounts[newFrom]);
84
+ return allAccounts[newFrom];
98
85
  }
99
86
 
100
87
  if(Array.isArray(privKeyArr)){
@@ -112,7 +99,7 @@ export function addAccounts(privKeyArr) {
112
99
  accounts.push(newAccObj);
113
100
  });
114
101
 
115
- console.log(allAccounts.slice(newFrom));
102
+ return allAccounts.slice(newFrom);
116
103
  }
117
104
  setDefaultAccount(allAccounts[0]);
118
105
  }
@@ -157,8 +144,8 @@ export function addHD(phrase, count = 10) {
157
144
  }
158
145
  updateWalletJSON(allAccounts);
159
146
  setDefaultAccount(allAccounts[0]);
160
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
161
- console.log(allAccounts.slice(newFrom));
147
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
148
+ return allAccounts.slice(newFrom);
162
149
  }
163
150
 
164
151
  /**
@@ -187,8 +174,8 @@ export function createAccounts(count = 1) {
187
174
  }
188
175
  updateWalletJSON(allAccounts);
189
176
  setDefaultAccount(allAccounts[0]);
190
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
191
- console.log(allAccounts.slice(newFrom));
177
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
178
+ return allAccounts.slice(newFrom);
192
179
  }
193
180
 
194
181
  /**
@@ -222,8 +209,8 @@ export function createHD(count = 10) {
222
209
  }
223
210
  updateWalletJSON(allAccounts);
224
211
  setDefaultAccount(allAccounts[0]);
225
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
226
- console.log(allAccounts.slice(newFrom));
212
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
213
+ return allAccounts.slice(newFrom);
227
214
  }
228
215
 
229
216
  /**
@@ -232,8 +219,8 @@ export function createHD(count = 10) {
232
219
  * getAllAccounts();
233
220
  */
234
221
  export function getAllAccounts() {
235
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
236
- console.log(allAccounts);
222
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
223
+ return allAccounts;
237
224
  }
238
225
 
239
226
  /**
@@ -242,8 +229,8 @@ export function getAllAccounts() {
242
229
  * getAccounts();
243
230
  */
244
231
  export function getAccounts() {
245
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
246
- console.log(accounts);
232
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
233
+ return accounts;
247
234
  }
248
235
 
249
236
  /**
@@ -252,8 +239,8 @@ export function getAccounts() {
252
239
  * getHDAccounts();
253
240
  */
254
241
  export function getHDAccounts() {
255
- console.log(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
256
- console.log(hdAccounts);
242
+ console.info(`!WARNING!\n The generated accounts are NOT safe. Do NOT use them on main net!`);
243
+ return hdAccounts;
257
244
  }
258
245
 
259
246
  /**
@@ -267,14 +254,14 @@ export function getHDAccounts() {
267
254
  * deleteAccount(); // Delete all accounts
268
255
  */
269
256
  export function deleteAccount(accPointer) {
270
- if(!accPointer) {
257
+ if(!accPointer && accPointer !== 0) {
271
258
  deleteByIndex(null);
272
- console.log(allAccounts);
259
+ return allAccounts;
273
260
  }
274
261
 
275
262
  if(typeof accPointer === 'number') {
276
263
  deleteByIndex(accPointer);
277
- console.log(allAccounts);
264
+ return allAccounts;
278
265
  }
279
266
 
280
267
  if(ethers.isAddress(accPointer)) {
@@ -283,11 +270,12 @@ export function deleteAccount(accPointer) {
283
270
  if(index !== -1) {
284
271
  deleteByIndex(index);
285
272
  }
286
- console.log(allAccounts);
273
+ return allAccounts;
287
274
  }
288
275
 
289
276
  if(Array.isArray(accPointer)) {
290
277
  deleteByIndexArr(accPointer);
278
+ return allAccounts;
291
279
  }
292
280
 
293
281
  if(ethers.Mnemonic.isValidMnemonic(accPointer)) {
@@ -309,7 +297,7 @@ export function deleteAccount(accPointer) {
309
297
  deleteByIndex(indicesToDelete[i]);
310
298
  }
311
299
 
312
- console.log(allAccounts);
300
+ return allAccounts;
313
301
  return;
314
302
  }
315
303
  }
@@ -363,16 +351,16 @@ export async function getWalletInfo(accPointer) {
363
351
 
364
352
  if(typeof accPointer === 'number') {
365
353
  const index = allAccounts.findIndex(wallet => wallet.index == accPointer);
366
- await getAccountInfo(index);
354
+ return await getAccountInfo(index);
367
355
  }
368
356
 
369
357
  if(ethers.isAddress(accPointer)) {
370
358
  const index = allAccounts.findIndex(wallet => wallet.address == accPointer);
371
- await getAccountInfo(index);
359
+ return await getAccountInfo(index);
372
360
  }
373
361
 
374
362
  if(Array.isArray(accPointer)) {
375
- await getAccountInfo(accPointer);
363
+ return await getAccountInfo(accPointer);
376
364
  }
377
365
 
378
366
  } catch(err) {
@@ -402,6 +390,10 @@ export function changeDefaultAccount(accPointer) {
402
390
  }
403
391
 
404
392
  if(ethers.isHexString(accPointer, 32)) {
393
+ const dupWallet = detectDupWallet(accPointer);
394
+ if(dupWallet.status) {
395
+ throw `Wallets may NOT be duplicated! You are adding wallet index ${dupWallet.index} again!`
396
+ }
405
397
  const newAccount = new ethers.Wallet(accPointer, provider);
406
398
  const newAccObj = {
407
399
  index: allAccounts.length,
@@ -6,9 +6,9 @@
6
6
  */
7
7
 
8
8
  import { allAccounts, accounts, hdAccounts } from '../services/wallet.js';
9
- import { provider } from '../services/network.js';
9
+ import { provider } from '../services/config.js';
10
10
  import fs from 'fs';
11
- import { configFile, configPath } from '../services/build.js';
11
+ import { configFile, configPath } from '../services/config.js';
12
12
  import { serializeBigInts } from './serialize.js';
13
13
 
14
14
  /**
@@ -69,9 +69,9 @@ export function deleteByIndexArr(indices) {
69
69
  */
70
70
  export async function getAccountInfo(index) {
71
71
  if (Array.isArray(index)) {
72
- await _getAccArrInfo(index);
72
+ return await _getAccArrInfo(index);
73
73
  } else if (typeof index === 'number') {
74
- await _getAccountInfo(index);
74
+ return await _getAccountInfo(index);
75
75
  }
76
76
  }
77
77
 
@@ -182,7 +182,7 @@ async function _getAccountInfo(_index) {
182
182
  accInfo.nonce = await provider.getTransactionCount(accInfo.address);
183
183
  accInfo.balance = await provider.getBalance(accInfo.address);
184
184
 
185
- console.log(accInfo);
185
+ return accInfo;
186
186
  }
187
187
 
188
188
  /**
@@ -227,6 +227,11 @@ function _deleteBySingIndex(_index) {
227
227
  _index++;
228
228
  }
229
229
  }
230
+
231
+ // Remove from config file if it is default wallet
232
+ if(accountIndex == configFile.defaultWallet.index) {
233
+ deleteDefaultAccount();
234
+ }
230
235
  }
231
236
  }
232
237
 
@@ -282,6 +287,7 @@ function _deleteAll() {
282
287
  allAccounts.splice(0);
283
288
  accounts.splice(0);
284
289
  hdAccounts.splice(0);
290
+ deleteDefaultAccount();
285
291
  fs.writeFileSync(walletJSONPath, JSON.stringify([], null, 2));
286
292
  return;
287
293
  }
@@ -294,3 +300,11 @@ export function setDefaultAccount(account) {
294
300
  configFile.defaultWallet = serializeBigInts(account);
295
301
  fs.writeFileSync(configPath, JSON.stringify(configFile, null, 2));
296
302
  }
303
+
304
+ /**
305
+ * Deletes default account from config file
306
+ */
307
+ export function deleteDefaultAccount() {
308
+ configFile.defaultWallet = {};
309
+ fs.writeFileSync(configPath, JSON.stringify(configFile, null, 2));
310
+ }
@@ -1,4 +1,7 @@
1
- import { configFile, configPath } from '../services/build.js';
1
+ import {
2
+ configFile,
3
+ configPath
4
+ } from '../services/config.js';
2
5
  import fs from 'fs';
3
6
 
4
7
  export function changeProvider(url) {
@@ -1,5 +1,6 @@
1
1
  // src/utils/contractProxy.js
2
2
  import { ethers } from 'ethers';
3
+ import { eventOf } from './event.js';
3
4
 
4
5
  /**
5
6
  * Creates a proxy wrapper for ethers.js Contract objects
@@ -25,6 +26,10 @@ import { ethers } from 'ethers';
25
26
  export function createContractProxy(contract, provider, allAccounts) {
26
27
  return new Proxy(contract, {
27
28
  get(target, prop) {
29
+ if (prop === 'provider') {
30
+ return provider;
31
+ }
32
+
28
33
  // Pass through non-function properties
29
34
  if (typeof target[prop] !== 'function') {
30
35
  return target[prop];
@@ -155,7 +160,27 @@ export function createContractProxy(contract, provider, allAccounts) {
155
160
  }
156
161
 
157
162
  // Call the method with remaining args and tx options
158
- return method.apply(method, args);
163
+ const result = await method.apply(method, args);
164
+
165
+ // Check if result is a transaction response (has wait method)
166
+ if (result && typeof result.wait === 'function') {
167
+ // This is a transaction - wait for mining
168
+ const receipt = await result.wait();
169
+
170
+ // Get event values
171
+ const tx = await provider.getTransactionReceipt(receipt.hash);
172
+ const eventValues = eventOf(contract, tx);
173
+
174
+ // Extend transaction receipt with event values
175
+ if(eventValues) {
176
+ receipt.eventValues = eventValues;
177
+ }
178
+
179
+ return receipt;
180
+ }
181
+
182
+ // This is a view/pure function result - return as-is
183
+ return result;
159
184
  };
160
185
  }
161
186
  });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Returns event values
3
+ * @param {Object} contract
4
+ * @param {Object} tx
5
+ * @returns {Array<Object>}
6
+ */
7
+
8
+ export function eventOf(contract, tx){
9
+ const events = tx.logs.map(log => {
10
+ try {
11
+ return contract.interface.parseLog(log);
12
+ } catch (e) {
13
+ return null;
14
+ }
15
+ }).filter(log => log !== null);
16
+
17
+ const parsedEvents = events.map(e => ({
18
+ name: e.name,
19
+ values: e.args,
20
+ }));
21
+ return parsedEvents;
22
+ }