rocketh 0.4.41 → 0.5.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.
- package/.prettierignore +3 -0
- package/.prettierrc +7 -0
- package/CHANGELOG.md +13 -0
- package/README.md +1 -21
- package/dist/chunk-INGRKRCC.js +648 -0
- package/dist/chunk-INGRKRCC.js.map +1 -0
- package/dist/cli.cjs +697 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +66 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +684 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +186 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -20
- package/src/cli.ts +37 -0
- package/src/environment/deployments.ts +79 -0
- package/src/environment/index.ts +392 -0
- package/src/environment/types.ts +158 -0
- package/src/executor/index.ts +302 -0
- package/src/executor/types.ts +42 -0
- package/src/index.ts +5 -0
- package/src/internal/types.ts +6 -0
- package/src/utils/fs.ts +70 -0
- package/src/utils/json.ts +26 -0
- package/tsconfig.json +15 -0
- package/tsup.config.ts +5 -0
- package/.gitattributes +0 -1
- package/bitski_subprovider.js +0 -148
- package/geth_test_server.js +0 -194
- package/index.js +0 -424
- package/provider.js +0 -58
- package/providerengine.js +0 -128
- package/run.js +0 -1575
- package/run_ganache.js +0 -27
- package/utils.js +0 -188
- package/walletprovider.js +0 -232
package/run_ganache.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const {requireLocal, executeServer} = require('./utils');
|
|
3
|
-
const {log} = require('./utils');
|
|
4
|
-
|
|
5
|
-
async function runGanache(port, wsPort, ganacheOptions) {
|
|
6
|
-
let ganache;
|
|
7
|
-
try{
|
|
8
|
-
ganache = requireLocal('ganache-core');
|
|
9
|
-
log.green('using ganache-core from dependencies');
|
|
10
|
-
}catch(e){}
|
|
11
|
-
|
|
12
|
-
if(!ganache) {
|
|
13
|
-
try{
|
|
14
|
-
ganache = requireLocal('ganache-cli');
|
|
15
|
-
log.green('using ganache-cli from dependencies');
|
|
16
|
-
} catch(e) {
|
|
17
|
-
log.red(e);
|
|
18
|
-
reject('you need to install your desired ganache-core version in your own project: "npm install ganache-core')
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const server = ganache.server(ganacheOptions);
|
|
23
|
-
// log.log('execute server on port ' + port);
|
|
24
|
-
await executeServer(server, port);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
module.exports = runGanache;
|
package/utils.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const colors = require('colors/safe');
|
|
4
|
-
const ethers = require('ethers');
|
|
5
|
-
const deepmerge = require('deepmerge');
|
|
6
|
-
|
|
7
|
-
function pause(s) {
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
setTimeout(resolve, s*1000);
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function requireLocal(moduleName) {
|
|
14
|
-
// TODO if all else fails. rocketh could provide a default
|
|
15
|
-
let currentFolder = path.resolve('./')
|
|
16
|
-
do {
|
|
17
|
-
try{
|
|
18
|
-
const nodeModule = path.join(currentFolder,'node_modules', moduleName);
|
|
19
|
-
// console.log('trying ' + nodeModule + '...');
|
|
20
|
-
return require(nodeModule);
|
|
21
|
-
} catch(e) {
|
|
22
|
-
// console.error(e);
|
|
23
|
-
}
|
|
24
|
-
currentFolder = path.resolve(currentFolder, '..');
|
|
25
|
-
} while (path.resolve(currentFolder, '..') != currentFolder);
|
|
26
|
-
|
|
27
|
-
throw(new Error("can't find module " + moduleName));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function executeServer(server, port) {
|
|
31
|
-
return new Promise((resolve, reject) => {
|
|
32
|
-
server.listen(port, function(err, blockchain) {
|
|
33
|
-
if(err) {
|
|
34
|
-
reject(err);
|
|
35
|
-
} else {
|
|
36
|
-
resolve(blockchain)
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getAccountsFromMnemonic(mnemonic, num) {
|
|
43
|
-
const accounts = [];
|
|
44
|
-
for(let i = 0; i < num; i++) { // TODO 10 is config of number of accounts
|
|
45
|
-
const wallet = ethers.Wallet.fromMnemonic(mnemonic, "m/44'/60'/0'/0/"+i);
|
|
46
|
-
accounts.push(wallet.address);
|
|
47
|
-
}
|
|
48
|
-
return accounts;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function onExit(childProcess) {
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
childProcess.once('exit', (code, signal) => {
|
|
54
|
-
if (code === 0) {
|
|
55
|
-
resolve();
|
|
56
|
-
} else {
|
|
57
|
-
reject({error: new Error('Exit with error code: '+code), code});
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
childProcess.once('error', (err) => {
|
|
61
|
-
reject(err);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function fetchTransaction(url, hash) {
|
|
67
|
-
const provider = new ethers.providers.JsonRpcProvider(url);
|
|
68
|
-
return provider.send('eth_getTransactionByHash',[hash]);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function fetchTransactionViaWeb3Provider(provider, hash) { // TODO remove
|
|
72
|
-
return new Promise((resolve, reject) => {
|
|
73
|
-
provider.send({id:1, method: 'eth_getTransactionByHash', params:[hash], jsonrpc: '2.0'}, (error, json) => {
|
|
74
|
-
if (error) {
|
|
75
|
-
reject(error);
|
|
76
|
-
} else {
|
|
77
|
-
resolve(json.result);
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function fetchReceiptViaWeb3Provider(provider, hash) { // TODO remove
|
|
84
|
-
return new Promise((resolve, reject) => {
|
|
85
|
-
provider.send({id:1, method: 'eth_getTransactionReceipt', params:[hash], jsonrpc: '2.0'}, (error, json) => {
|
|
86
|
-
if (error) {
|
|
87
|
-
reject(error);
|
|
88
|
-
} else {
|
|
89
|
-
resolve(json.result);
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function fetchAccounts(url) {
|
|
96
|
-
const provider = new ethers.providers.JsonRpcProvider(url);
|
|
97
|
-
return provider.send('eth_accounts',[]);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function parseChainId(chainId) {
|
|
101
|
-
if (typeof chainId === 'string') {
|
|
102
|
-
if(chainId.startsWith('0x') || chainId.startsWith('0X')) {
|
|
103
|
-
return '' + parseInt(chainId.substr(2),16);
|
|
104
|
-
} else {
|
|
105
|
-
return chainId;
|
|
106
|
-
}
|
|
107
|
-
} else if(typeof chainId === 'number') {
|
|
108
|
-
return '' + chainId;
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function fetchChainId(url, use_net_version) {
|
|
114
|
-
const method = use_net_version ? 'net_version' : 'eth_chainId';
|
|
115
|
-
const provider = new ethers.providers.JsonRpcProvider(url);
|
|
116
|
-
return provider.send(method,[]).then((chainId) => {
|
|
117
|
-
return parseChainId(chainId);
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function fetchChainIdViaWeb3Provider(provider, use_net_version) { // TODO remove
|
|
122
|
-
const method = use_net_version ? 'net_version' : 'eth_chainId';
|
|
123
|
-
return new Promise((resolve, reject) => {
|
|
124
|
-
provider.send({id:1, method, params:[], jsonrpc: '2.0'}, (error, json) => {
|
|
125
|
-
if (error) {
|
|
126
|
-
reject(error);
|
|
127
|
-
} else {
|
|
128
|
-
const result = parseChainId(json.result);
|
|
129
|
-
if(result) {
|
|
130
|
-
resolve(result);
|
|
131
|
-
} else {
|
|
132
|
-
reject({message: 'could not decode chainId'});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
})
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const traverse = function(dir, result = [], topDir, filter) {
|
|
140
|
-
fs.readdirSync(dir).forEach((name) => {
|
|
141
|
-
const fPath = path.resolve(dir, name);
|
|
142
|
-
const stats = fs.statSync(fPath);
|
|
143
|
-
if(!filter || filter(name, stats)) {
|
|
144
|
-
const fileStats = { name, path: fPath, relativePath: path.relative(topDir || dir, fPath), mtimeMs: stats.mtimeMs, directory: stats.isDirectory() };
|
|
145
|
-
if (fileStats.directory) {
|
|
146
|
-
result.push(fileStats);
|
|
147
|
-
return traverse(fPath, result, topDir || dir)
|
|
148
|
-
}
|
|
149
|
-
result.push(fileStats);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
return result;
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
let silent = false;
|
|
156
|
-
function log(...args) {
|
|
157
|
-
if(silent) { return; }
|
|
158
|
-
console.log.apply(console, args);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
|
|
162
|
-
|
|
163
|
-
module.exports = {
|
|
164
|
-
onExit,
|
|
165
|
-
traverse,
|
|
166
|
-
requireLocal,
|
|
167
|
-
executeServer,
|
|
168
|
-
fetchAccounts,
|
|
169
|
-
fetchChainId,
|
|
170
|
-
fetchChainIdViaWeb3Provider,
|
|
171
|
-
fetchTransaction,
|
|
172
|
-
fetchTransactionViaWeb3Provider,
|
|
173
|
-
fetchReceiptViaWeb3Provider,
|
|
174
|
-
getAccountsFromMnemonic,
|
|
175
|
-
pause,
|
|
176
|
-
mergeConfig: (base, extra) => deepmerge(base, extra, { arrayMerge: overwriteMerge }),
|
|
177
|
-
log : {
|
|
178
|
-
setSlient: (s) => silent = s,
|
|
179
|
-
log : (...args) => log(...args),
|
|
180
|
-
error: (...args) => console.error(...args),
|
|
181
|
-
red : (message) => console.error(colors.red(message)),
|
|
182
|
-
green : (message) => log(colors.green(message)),
|
|
183
|
-
blue : (message) => log(colors.blue(message)),
|
|
184
|
-
cyan : (message) => log(colors.cyan(message)),
|
|
185
|
-
yellow : (message) => log(colors.yellow(message)),
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
}
|
package/walletprovider.js
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
const ethers = require('ethers');
|
|
2
|
-
// const {Logger} = require('@ethersproject/logger');
|
|
3
|
-
// Logger.globalLogger().setLogLevel('error');
|
|
4
|
-
const {BigNumber} = ethers;
|
|
5
|
-
|
|
6
|
-
const WalletSubProvider = function(privateKeys, config) {
|
|
7
|
-
this.lastId = 0;
|
|
8
|
-
this.config = config;
|
|
9
|
-
|
|
10
|
-
if(privateKeys){
|
|
11
|
-
this.accounts = [];
|
|
12
|
-
this.wallets = {};
|
|
13
|
-
for(let i = 0; i < privateKeys.length; i++) {
|
|
14
|
-
const wallet = new ethers.Wallet(privateKeys[i]);
|
|
15
|
-
this.wallets[wallet.address.toLowerCase()] = wallet;
|
|
16
|
-
this.accounts.push(wallet.address);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
WalletSubProvider.prototype.setEngine = function(engine) {
|
|
22
|
-
this.engine = engine;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
WalletSubProvider.prototype.fetchGasPrice = function() {
|
|
26
|
-
const self = this;
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
self.engine.sendAsync({id: ++this.lastId, method: 'eth_gasPrice', jsonrpc: '2.0'}, (error, json) =>{
|
|
29
|
-
if(error) {
|
|
30
|
-
reject(error);
|
|
31
|
-
} else {
|
|
32
|
-
resolve(json.result);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
WalletSubProvider.prototype.fetchNonce = function(from) {
|
|
39
|
-
const self = this;
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
self.engine.sendAsync({ id: ++this.lastId, method: 'eth_getTransactionCount', params: [from, 'latest'], jsonrpc: '2.0'}, (error, json) =>{
|
|
42
|
-
if(error) {
|
|
43
|
-
reject(error);
|
|
44
|
-
} else {
|
|
45
|
-
resolve(json.result);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
WalletSubProvider.prototype.fetchBalance = function(from) {
|
|
52
|
-
const self = this;
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
self.engine.sendAsync({ id: ++self.lastId, method: 'eth_getBalance', params: [from, 'latest'], jsonrpc: '2.0'}, (error, json) =>{
|
|
55
|
-
if(error) {
|
|
56
|
-
reject(error);
|
|
57
|
-
} else {
|
|
58
|
-
resolve(json.result);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
WalletSubProvider.prototype.estimateGas = function(data) {
|
|
65
|
-
const self = this;
|
|
66
|
-
return new Promise((resolve, reject) => {
|
|
67
|
-
self.engine.sendAsync({ id: ++self.lastId, method: 'eth_estimateGas', params: [data], jsonrpc: '2.0'}, (error, json) =>{
|
|
68
|
-
if(error) {
|
|
69
|
-
reject(error);
|
|
70
|
-
} else {
|
|
71
|
-
resolve(json.result);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
function ensureEvenLength(hexString, debug) {
|
|
80
|
-
const l = hexString.length - 2;
|
|
81
|
-
if(debug) {
|
|
82
|
-
console.log(debug, {l})
|
|
83
|
-
}
|
|
84
|
-
if(l)
|
|
85
|
-
if(l % 2 === 1) {
|
|
86
|
-
return ethers.utils.hexZeroPad(hexString, (l+1) / 2);
|
|
87
|
-
}
|
|
88
|
-
return hexString;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
WalletSubProvider.prototype.handleRequest = async function(payload, next, end) {
|
|
92
|
-
const self = this;
|
|
93
|
-
if (payload.method === 'eth_accounts' && this.accounts) {
|
|
94
|
-
return end(null, this.accounts);
|
|
95
|
-
} else if (payload.method === 'eth_sendTransaction') {
|
|
96
|
-
const rawTx = payload.params[0];
|
|
97
|
-
const from = rawTx.from;
|
|
98
|
-
|
|
99
|
-
const wallet = this.wallets[from];
|
|
100
|
-
if (!wallet) {
|
|
101
|
-
return end(new Error('Account unknown ' +from));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// // TODO remove ?
|
|
105
|
-
// if(!rawTx.gas) {
|
|
106
|
-
// return end(new Error('gas not specified'));
|
|
107
|
-
// }
|
|
108
|
-
|
|
109
|
-
let nonce = rawTx.nonce;
|
|
110
|
-
if (typeof nonce === 'undefined') {
|
|
111
|
-
nonce = await this.fetchNonce(from);
|
|
112
|
-
}
|
|
113
|
-
const nonceBN = BigNumber.from(nonce);
|
|
114
|
-
|
|
115
|
-
let value
|
|
116
|
-
if(typeof rawTx.value === 'undefined') {
|
|
117
|
-
value = '0x00'; // TODO fix ethers
|
|
118
|
-
} else {
|
|
119
|
-
value = rawTx.value;
|
|
120
|
-
}
|
|
121
|
-
const valueBN = BigNumber.from(value);
|
|
122
|
-
|
|
123
|
-
let gas;
|
|
124
|
-
if(rawTx.gas) {
|
|
125
|
-
gas = rawTx.gas;
|
|
126
|
-
} else {
|
|
127
|
-
gas = await this.estimateGas({
|
|
128
|
-
from,
|
|
129
|
-
to: rawTx.to,
|
|
130
|
-
nonce: nonceBN.toHexString(),
|
|
131
|
-
data: rawTx.data,
|
|
132
|
-
value: valueBN.toHexString(),
|
|
133
|
-
chainId: rawTx.chainId,
|
|
134
|
-
gas: rawTx.estimateGasLimit,
|
|
135
|
-
});
|
|
136
|
-
if (rawTx.estimateGasExtra) {
|
|
137
|
-
gas += rawTx.estimateGasExtra;
|
|
138
|
-
if (rawTx.estimateGasLimit) {
|
|
139
|
-
gas = Math.min(gas, rawTx.estimateGasLimit);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// return end(new Error('gas not specified'));
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const gasPriceSpecified = !!rawTx.gasPrice;
|
|
146
|
-
let gasPriceBN;
|
|
147
|
-
if (!gasPriceSpecified) {
|
|
148
|
-
if (this.config.fixedGasPrice) {
|
|
149
|
-
gasPriceBN = BigNumber.from(this.config.fixedGasPrice);
|
|
150
|
-
} else {
|
|
151
|
-
const currentGasPrice = await this.fetchGasPrice();
|
|
152
|
-
gasPriceBN = BigNumber.from(currentGasPrice);
|
|
153
|
-
}
|
|
154
|
-
} else {
|
|
155
|
-
gasPriceBN = BigNumber.from(rawTx.gasPrice);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (this.config.extraGasPrice) {
|
|
159
|
-
let extraGasPriceBN;
|
|
160
|
-
if (this.config.extraGasPrice.endsWith('%')) {
|
|
161
|
-
extraGasPriceBN = gasPriceBN.mul(this.config.extraGasPrice.slice(0,this.config.extraGasPrice.length-1)).div(100);
|
|
162
|
-
} else {
|
|
163
|
-
extraGasPriceBN = BigNumber.from(this.config.extraGasPrice);
|
|
164
|
-
}
|
|
165
|
-
gasPriceBN = gasPriceBN.add(extraGasPriceBN);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const gasBN = BigNumber.from(gas);
|
|
169
|
-
|
|
170
|
-
const balance = await this.fetchBalance(from);
|
|
171
|
-
const balanceBN = BigNumber.from(balance);
|
|
172
|
-
const balanceRequiredBN = gasPriceBN.mul(gasBN);
|
|
173
|
-
|
|
174
|
-
if(balanceBN.lt(balanceRequiredBN)) {
|
|
175
|
-
return end(new Error('Not enough balance: '
|
|
176
|
-
+ balanceRequiredBN.toString()
|
|
177
|
-
+ '( ' + gasBN.toString() + ' gas x ' + gasPriceBN.toString() + ' gasPrice'
|
|
178
|
-
+ ' ) > ' + balanceBN.toString()));
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const forEthers = {
|
|
182
|
-
to: rawTx.to,
|
|
183
|
-
gasLimit: gasBN.toHexString(),
|
|
184
|
-
gasPrice: gasPriceBN.toHexString(),
|
|
185
|
-
nonce: nonceBN.toHexString(),
|
|
186
|
-
data: rawTx.data,// ? (rawTx.data[1].toLowerCase() == 'x' ? rawTx.data : '0x' + rawTx.data) : undefined,
|
|
187
|
-
value: valueBN.toHexString(),
|
|
188
|
-
chainId: rawTx.chainId
|
|
189
|
-
}
|
|
190
|
-
const signedTx = await this.signTransaction(from, forEthers);
|
|
191
|
-
|
|
192
|
-
return this.engine.sendAsync({
|
|
193
|
-
id: payload.id,
|
|
194
|
-
jsonrpc: payload.jsonrpc,
|
|
195
|
-
method: 'eth_sendRawTransaction',
|
|
196
|
-
params: [signedTx],
|
|
197
|
-
jsonrpc: '2.0',
|
|
198
|
-
}, function(error, json) {
|
|
199
|
-
if(error) {
|
|
200
|
-
return end(error);
|
|
201
|
-
}
|
|
202
|
-
return end(null, json.result);
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
} else if(payload.method == 'eth_sign') {
|
|
206
|
-
const wallet = this.wallets[payload.params[0]];
|
|
207
|
-
if (!wallet) {
|
|
208
|
-
return end(new Error('Account unknown ' + payload.params[0]));
|
|
209
|
-
}
|
|
210
|
-
const signedMessage = await this.signMessage(payload.params[0], payload.params[1]);
|
|
211
|
-
// console.log(payload.params, signedMessage);
|
|
212
|
-
return end(null, signedMessage);
|
|
213
|
-
} else {
|
|
214
|
-
next();
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
WalletSubProvider.prototype.signTransaction = function(from, rawTx) {
|
|
219
|
-
// console.log('rawTx', rawTx);
|
|
220
|
-
const wallet = this.wallets[from.toLowerCase()];
|
|
221
|
-
return wallet.signTransaction(rawTx);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
WalletSubProvider.prototype.signMessage = function(from, message) {
|
|
225
|
-
if(message[0] == '0' && message[1] == 'x') { // work arround : if start with 0x interpret it as binary data
|
|
226
|
-
message = ethers.utils.arrayify(message);
|
|
227
|
-
}
|
|
228
|
-
const wallet = this.wallets[from.toLowerCase()];
|
|
229
|
-
return wallet.signMessage(message);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
module.exports = WalletSubProvider;
|