@toruslabs/ethereum-controllers 5.11.0 → 6.0.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/dist/ethereumControllers.cjs.js +80 -431
- package/dist/ethereumControllers.esm.js +30 -349
- package/dist/ethereumControllers.umd.min.js +1 -1
- package/dist/ethereumControllers.umd.min.js.LICENSE.txt +7 -2
- package/dist/lib.cjs/Account/AccountTrackerController.js +160 -0
- package/dist/lib.cjs/Block/PollingBlockTracker.js +85 -0
- package/dist/lib.cjs/Currency/CurrencyController.js +111 -0
- package/dist/lib.cjs/Gas/GasFeeController.js +214 -0
- package/dist/lib.cjs/Gas/gasUtil.js +148 -0
- package/dist/lib.cjs/Keyring/KeyringController.js +93 -0
- package/dist/lib.cjs/Message/AbstractMessageController.js +107 -0
- package/dist/lib.cjs/Message/AddChainController.js +78 -0
- package/dist/lib.cjs/Message/MessageController.js +77 -0
- package/dist/lib.cjs/Message/PersonalMessageController.js +77 -0
- package/dist/lib.cjs/Message/SwitchChainController.js +78 -0
- package/dist/lib.cjs/Message/TypedMessageController.js +81 -0
- package/dist/lib.cjs/Message/utils.js +112 -0
- package/dist/lib.cjs/Network/NetworkController.js +201 -0
- package/dist/lib.cjs/Network/cacheIdentifier.js +112 -0
- package/dist/lib.cjs/Network/createEthereumMiddleware.js +302 -0
- package/dist/lib.cjs/Network/createJsonRpcClient.js +64 -0
- package/dist/lib.cjs/Nfts/NftHandler.js +180 -0
- package/dist/lib.cjs/Nfts/NftsController.js +213 -0
- package/dist/lib.cjs/Preferences/PreferencesController.js +476 -0
- package/dist/lib.cjs/Tokens/TokenHandler.js +51 -0
- package/dist/lib.cjs/Tokens/TokenRatesController.js +112 -0
- package/dist/lib.cjs/Tokens/TokensController.js +259 -0
- package/dist/lib.cjs/Transaction/NonceTracker.js +150 -0
- package/dist/lib.cjs/Transaction/PendingTransactionTracker.js +222 -0
- package/dist/lib.cjs/Transaction/TransactionController.js +515 -0
- package/dist/lib.cjs/Transaction/TransactionGasUtil.js +81 -0
- package/dist/lib.cjs/Transaction/TransactionStateHistoryHelper.js +42 -0
- package/dist/lib.cjs/Transaction/TransactionStateManager.js +296 -0
- package/dist/lib.cjs/Transaction/TransactionUtils.js +341 -0
- package/dist/lib.cjs/index.js +171 -0
- package/dist/lib.cjs/utils/abis.js +510 -0
- package/dist/lib.cjs/utils/constants.js +362 -0
- package/dist/lib.cjs/utils/contractAddresses.js +16 -0
- package/dist/lib.cjs/utils/conversionUtils.js +232 -0
- package/dist/lib.cjs/utils/helpers.js +244 -0
- package/dist/lib.cjs/utils/lodashUtils.js +25 -0
- package/dist/lib.esm/Account/AccountTrackerController.js +158 -0
- package/dist/lib.esm/Block/PollingBlockTracker.js +83 -0
- package/dist/lib.esm/Currency/CurrencyController.js +109 -0
- package/dist/lib.esm/Gas/GasFeeController.js +212 -0
- package/dist/lib.esm/Gas/gasUtil.js +141 -0
- package/dist/lib.esm/Keyring/KeyringController.js +91 -0
- package/dist/lib.esm/Message/AbstractMessageController.js +105 -0
- package/dist/lib.esm/Message/AddChainController.js +76 -0
- package/dist/lib.esm/Message/MessageController.js +75 -0
- package/dist/lib.esm/Message/PersonalMessageController.js +75 -0
- package/dist/lib.esm/Message/SwitchChainController.js +76 -0
- package/dist/lib.esm/Message/TypedMessageController.js +79 -0
- package/dist/lib.esm/Message/utils.js +105 -0
- package/dist/lib.esm/Network/NetworkController.js +199 -0
- package/dist/lib.esm/Network/cacheIdentifier.js +107 -0
- package/dist/lib.esm/Network/createEthereumMiddleware.js +289 -0
- package/dist/lib.esm/Network/createJsonRpcClient.js +60 -0
- package/dist/lib.esm/Nfts/NftHandler.js +178 -0
- package/dist/lib.esm/Nfts/NftsController.js +211 -0
- package/dist/lib.esm/Preferences/PreferencesController.js +474 -0
- package/dist/lib.esm/Tokens/TokenHandler.js +49 -0
- package/dist/lib.esm/Tokens/TokenRatesController.js +109 -0
- package/dist/lib.esm/Tokens/TokensController.js +257 -0
- package/dist/lib.esm/Transaction/NonceTracker.js +148 -0
- package/dist/lib.esm/Transaction/PendingTransactionTracker.js +220 -0
- package/dist/lib.esm/Transaction/TransactionController.js +513 -0
- package/dist/lib.esm/Transaction/TransactionGasUtil.js +79 -0
- package/dist/lib.esm/Transaction/TransactionStateHistoryHelper.js +38 -0
- package/dist/lib.esm/Transaction/TransactionStateManager.js +294 -0
- package/dist/lib.esm/Transaction/TransactionUtils.js +326 -0
- package/dist/lib.esm/index.js +33 -0
- package/dist/lib.esm/utils/abis.js +505 -0
- package/dist/lib.esm/utils/constants.js +323 -0
- package/dist/lib.esm/utils/contractAddresses.js +14 -0
- package/dist/lib.esm/utils/conversionUtils.js +218 -0
- package/dist/lib.esm/utils/helpers.js +227 -0
- package/dist/lib.esm/utils/lodashUtils.js +21 -0
- package/dist/types/Account/AccountTrackerController.d.ts +5 -5
- package/dist/types/Block/PollingBlockTracker.d.ts +1 -2
- package/dist/types/Currency/CurrencyController.d.ts +1 -1
- package/dist/types/Gas/GasFeeController.d.ts +3 -3
- package/dist/types/Gas/gasUtil.d.ts +1 -1
- package/dist/types/Keyring/KeyringController.d.ts +3 -5
- package/dist/types/Message/AbstractMessageController.d.ts +5 -6
- package/dist/types/Message/AddChainController.d.ts +4 -4
- package/dist/types/Message/MessageController.d.ts +4 -4
- package/dist/types/Message/PersonalMessageController.d.ts +4 -4
- package/dist/types/Message/SwitchChainController.d.ts +4 -4
- package/dist/types/Message/TypedMessageController.d.ts +6 -7
- package/dist/types/Message/utils.d.ts +2 -7
- package/dist/types/Network/NetworkController.d.ts +4 -4
- package/dist/types/Network/cacheIdentifier.d.ts +1 -1
- package/dist/types/Network/createEthereumMiddleware.d.ts +2 -18
- package/dist/types/Network/createJsonRpcClient.d.ts +2 -2
- package/dist/types/Nfts/NftsController.d.ts +2 -2
- package/dist/types/Preferences/PreferencesController.d.ts +4 -4
- package/dist/types/Tokens/TokensController.d.ts +3 -3
- package/dist/types/Transaction/NonceTracker.d.ts +5 -5
- package/dist/types/Transaction/PendingTransactionTracker.d.ts +5 -5
- package/dist/types/Transaction/TransactionController.d.ts +12 -12
- package/dist/types/Transaction/TransactionGasUtil.d.ts +4 -4
- package/dist/types/Transaction/TransactionStateManager.d.ts +3 -3
- package/dist/types/Transaction/TransactionUtils.d.ts +1 -1
- package/dist/types/index.d.ts +12 -14
- package/dist/types/utils/constants.d.ts +1 -5
- package/dist/types/utils/helpers.d.ts +4 -4
- package/dist/types/utils/interfaces.d.ts +43 -23
- package/package.json +7 -7
- package/dist/types/Message/DecryptMessageController.d.ts +0 -20
- package/dist/types/Message/EncryptionPublicKeyController.d.ts +0 -20
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var httpHelpers = require('@toruslabs/http-helpers');
|
|
5
|
+
var BigNumber = require('bignumber.js');
|
|
6
|
+
var constants = require('../utils/constants.js');
|
|
7
|
+
var conversionUtils = require('../utils/conversionUtils.js');
|
|
8
|
+
|
|
9
|
+
function normalizeGWEIDecimalNumbers(n) {
|
|
10
|
+
const numberAsWEIHex = conversionUtils.decGWEIToHexWEI(new BigNumber(n));
|
|
11
|
+
const numberAsGWEI = conversionUtils.hexWEIToDecGWEI(numberAsWEIHex);
|
|
12
|
+
return numberAsGWEI;
|
|
13
|
+
}
|
|
14
|
+
async function fetchGasEstimates(url) {
|
|
15
|
+
const estimates = await httpHelpers.get(url);
|
|
16
|
+
const normalizedEstimates = {
|
|
17
|
+
estimatedBaseFee: normalizeGWEIDecimalNumbers(estimates.estimatedBaseFee).toString(10),
|
|
18
|
+
low: _objectSpread(_objectSpread({}, estimates.low), {}, {
|
|
19
|
+
suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.low.suggestedMaxPriorityFeePerGas).toString(10),
|
|
20
|
+
suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.low.suggestedMaxFeePerGas).toString(10)
|
|
21
|
+
}),
|
|
22
|
+
medium: _objectSpread(_objectSpread({}, estimates.medium), {}, {
|
|
23
|
+
suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.medium.suggestedMaxPriorityFeePerGas).toString(10),
|
|
24
|
+
suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.medium.suggestedMaxFeePerGas).toString(10)
|
|
25
|
+
}),
|
|
26
|
+
high: _objectSpread(_objectSpread({}, estimates.high), {}, {
|
|
27
|
+
suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.high.suggestedMaxPriorityFeePerGas).toString(10),
|
|
28
|
+
suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.high.suggestedMaxFeePerGas).toString(10)
|
|
29
|
+
})
|
|
30
|
+
};
|
|
31
|
+
return normalizedEstimates;
|
|
32
|
+
}
|
|
33
|
+
async function fetchGasEstimatesViaEthFeeHistory(provider) {
|
|
34
|
+
const noOfBlocks = 10;
|
|
35
|
+
const newestBlock = "latest";
|
|
36
|
+
// get the 10, 50 and 95th percentile of the tip fees from the last 10 blocks
|
|
37
|
+
const percentileValues = [10, 50, 95];
|
|
38
|
+
const feeHistory = await provider.request({
|
|
39
|
+
method: "eth_feeHistory",
|
|
40
|
+
params: [noOfBlocks, newestBlock, percentileValues]
|
|
41
|
+
});
|
|
42
|
+
// this is in hex wei
|
|
43
|
+
const finalBaseFeePerGas = feeHistory.baseFeePerGas[feeHistory.baseFeePerGas.length - 1];
|
|
44
|
+
// this is in hex wei
|
|
45
|
+
const priorityFeeCalcs = feeHistory.reward.reduce((acc, curr) => {
|
|
46
|
+
return {
|
|
47
|
+
slow: acc.slow.plus(new BigNumber(curr[0], 16)),
|
|
48
|
+
average: acc.average.plus(new BigNumber(curr[1], 16)),
|
|
49
|
+
fast: acc.fast.plus(new BigNumber(curr[2], 16))
|
|
50
|
+
};
|
|
51
|
+
}, {
|
|
52
|
+
slow: new BigNumber(0),
|
|
53
|
+
average: new BigNumber(0),
|
|
54
|
+
fast: new BigNumber(0)
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
estimatedBaseFee: conversionUtils.hexWEIToDecGWEI(finalBaseFeePerGas).toString(10),
|
|
58
|
+
high: {
|
|
59
|
+
maxWaitTimeEstimate: 30000,
|
|
60
|
+
minWaitTimeEstimate: 15000,
|
|
61
|
+
suggestedMaxFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.fast.plus(finalBaseFeePerGas).toString(16)).toString(),
|
|
62
|
+
suggestedMaxPriorityFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.fast.toString(16)).toString()
|
|
63
|
+
},
|
|
64
|
+
medium: {
|
|
65
|
+
maxWaitTimeEstimate: 45000,
|
|
66
|
+
minWaitTimeEstimate: 15000,
|
|
67
|
+
suggestedMaxFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.average.plus(finalBaseFeePerGas).toString(16)).toString(),
|
|
68
|
+
suggestedMaxPriorityFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.average.toString(16)).toString()
|
|
69
|
+
},
|
|
70
|
+
low: {
|
|
71
|
+
maxWaitTimeEstimate: 60000,
|
|
72
|
+
minWaitTimeEstimate: 15000,
|
|
73
|
+
suggestedMaxFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.slow.plus(finalBaseFeePerGas).toString(16)).toString(),
|
|
74
|
+
suggestedMaxPriorityFeePerGas: conversionUtils.hexWEIToDecGWEI(priorityFeeCalcs.slow.toString(16)).toString()
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Hit the legacy MetaSwaps gasPrices estimate api and return the low, medium
|
|
81
|
+
* high values from that API.
|
|
82
|
+
*/
|
|
83
|
+
async function fetchLegacyGasPriceEstimates(url) {
|
|
84
|
+
const result = await httpHelpers.get(url, {
|
|
85
|
+
referrer: url,
|
|
86
|
+
referrerPolicy: "no-referrer-when-downgrade",
|
|
87
|
+
method: "GET"
|
|
88
|
+
});
|
|
89
|
+
// this returns decimal gwei
|
|
90
|
+
return {
|
|
91
|
+
low: result.SafeGasPrice,
|
|
92
|
+
medium: result.ProposeGasPrice,
|
|
93
|
+
high: result.FastGasPrice
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async function fetchEthGasPriceEstimate(provider) {
|
|
97
|
+
const gasPrice = await provider.request({
|
|
98
|
+
method: constants.METHOD_TYPES.ETH_GET_GAS_PRICE
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
gasPrice: conversionUtils.hexWEIToDecGWEI(gasPrice).toString()
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function calculateTimeEstimate(maxPriorityFeePerGas, maxFeePerGas, gasFeeEstimates) {
|
|
105
|
+
// all are in dec gwei
|
|
106
|
+
const {
|
|
107
|
+
low,
|
|
108
|
+
medium,
|
|
109
|
+
high,
|
|
110
|
+
estimatedBaseFee
|
|
111
|
+
} = gasFeeEstimates;
|
|
112
|
+
const maxPriorityFeePerGasInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(maxPriorityFeePerGas)), 16);
|
|
113
|
+
const maxFeePerGasInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(maxFeePerGas)), 16);
|
|
114
|
+
const estimatedBaseFeeInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(estimatedBaseFee)), 16);
|
|
115
|
+
const effectiveMaxPriorityFee = BigNumber.min(maxPriorityFeePerGasInWEI, maxFeePerGasInWEI.minus(estimatedBaseFeeInWEI));
|
|
116
|
+
const lowMaxPriorityFeeInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(low.suggestedMaxPriorityFeePerGas)), 16);
|
|
117
|
+
const mediumMaxPriorityFeeInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(medium.suggestedMaxPriorityFeePerGas)), 16);
|
|
118
|
+
const highMaxPriorityFeeInWEI = new BigNumber(conversionUtils.decGWEIToHexWEI(new BigNumber(high.suggestedMaxPriorityFeePerGas)), 16);
|
|
119
|
+
let lowerTimeBound;
|
|
120
|
+
let upperTimeBound;
|
|
121
|
+
if (effectiveMaxPriorityFee.lt(lowMaxPriorityFeeInWEI)) {
|
|
122
|
+
lowerTimeBound = null;
|
|
123
|
+
upperTimeBound = "unknown";
|
|
124
|
+
} else if (effectiveMaxPriorityFee.gte(lowMaxPriorityFeeInWEI) && effectiveMaxPriorityFee.lt(mediumMaxPriorityFeeInWEI)) {
|
|
125
|
+
lowerTimeBound = low.minWaitTimeEstimate;
|
|
126
|
+
upperTimeBound = low.maxWaitTimeEstimate;
|
|
127
|
+
} else if (effectiveMaxPriorityFee.gte(mediumMaxPriorityFeeInWEI) && effectiveMaxPriorityFee.lt(highMaxPriorityFeeInWEI)) {
|
|
128
|
+
lowerTimeBound = medium.minWaitTimeEstimate;
|
|
129
|
+
upperTimeBound = medium.maxWaitTimeEstimate;
|
|
130
|
+
} else if (effectiveMaxPriorityFee.eq(highMaxPriorityFeeInWEI)) {
|
|
131
|
+
lowerTimeBound = high.minWaitTimeEstimate;
|
|
132
|
+
upperTimeBound = high.maxWaitTimeEstimate;
|
|
133
|
+
} else {
|
|
134
|
+
lowerTimeBound = 0;
|
|
135
|
+
upperTimeBound = high.maxWaitTimeEstimate;
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
lowerTimeBound,
|
|
139
|
+
upperTimeBound
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
exports.calculateTimeEstimate = calculateTimeEstimate;
|
|
144
|
+
exports.fetchEthGasPriceEstimate = fetchEthGasPriceEstimate;
|
|
145
|
+
exports.fetchGasEstimates = fetchGasEstimates;
|
|
146
|
+
exports.fetchGasEstimatesViaEthFeeHistory = fetchGasEstimatesViaEthFeeHistory;
|
|
147
|
+
exports.fetchLegacyGasPriceEstimates = fetchLegacyGasPriceEstimates;
|
|
148
|
+
exports.normalizeGWEIDecimalNumbers = normalizeGWEIDecimalNumbers;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var util = require('@ethereumjs/util');
|
|
4
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
5
|
+
var ethers = require('ethers');
|
|
6
|
+
|
|
7
|
+
class KeyringController extends baseControllers.BaseKeyringController {
|
|
8
|
+
constructor({
|
|
9
|
+
config,
|
|
10
|
+
state
|
|
11
|
+
}) {
|
|
12
|
+
super({
|
|
13
|
+
config,
|
|
14
|
+
state
|
|
15
|
+
});
|
|
16
|
+
this.defaultState = {
|
|
17
|
+
wallets: []
|
|
18
|
+
};
|
|
19
|
+
this.initialize();
|
|
20
|
+
}
|
|
21
|
+
async signTransaction(tx, address) {
|
|
22
|
+
const txPayload = tx;
|
|
23
|
+
const wallet = this._getWalletForAccount(address);
|
|
24
|
+
const privKey = this.getBufferPrivateKey(wallet.privateKey);
|
|
25
|
+
const signedTx = txPayload.sign(privKey);
|
|
26
|
+
// Newer versions of Ethereumjs-tx are immutable and return a new tx object
|
|
27
|
+
return signedTx === undefined ? tx : signedTx;
|
|
28
|
+
}
|
|
29
|
+
getAccounts() {
|
|
30
|
+
return this.state.wallets.map(w => w.publicKey);
|
|
31
|
+
}
|
|
32
|
+
importAccount(accountPrivateKey) {
|
|
33
|
+
const hexPrivateKey = accountPrivateKey.padStart(64, "0");
|
|
34
|
+
const bufferPrivKey = Buffer.from(hexPrivateKey, "hex");
|
|
35
|
+
const publicKey = util.bytesToHex(util.privateToPublic(bufferPrivKey));
|
|
36
|
+
const address = util.toChecksumAddress(util.bytesToHex(util.privateToAddress(bufferPrivKey)));
|
|
37
|
+
const existingWallet = this.state.wallets.find(w => w.address === address);
|
|
38
|
+
if (existingWallet) return existingWallet.address;
|
|
39
|
+
this.update({
|
|
40
|
+
wallets: [...this.state.wallets, {
|
|
41
|
+
publicKey,
|
|
42
|
+
privateKey: accountPrivateKey,
|
|
43
|
+
address
|
|
44
|
+
}]
|
|
45
|
+
});
|
|
46
|
+
return address;
|
|
47
|
+
}
|
|
48
|
+
removeAccount(address) {
|
|
49
|
+
const newWallets = [...this.state.wallets];
|
|
50
|
+
const idx = newWallets.findIndex(w => w.address === address);
|
|
51
|
+
if (idx !== -1) {
|
|
52
|
+
newWallets.splice(idx, 1);
|
|
53
|
+
this.update({
|
|
54
|
+
wallets: newWallets
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
getBufferPrivateKey(privateKey) {
|
|
59
|
+
const stripped = util.stripHexPrefix(privateKey);
|
|
60
|
+
return Buffer.from(stripped, "hex");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// For eth_sign, we need to sign arbitrary data:
|
|
64
|
+
async signMessage(data, address) {
|
|
65
|
+
const wallet = this._getWalletForAccount(address);
|
|
66
|
+
const privKey = this.getBufferPrivateKey(wallet.privateKey);
|
|
67
|
+
const messageSig = util.ecsign(Buffer.from(util.stripHexPrefix(data), "hex"), privKey);
|
|
68
|
+
const sig = baseControllers.concatSig(Buffer.from(util.bigIntToBytes(messageSig.v)), Buffer.from(messageSig.r), Buffer.from(messageSig.s));
|
|
69
|
+
return sig;
|
|
70
|
+
}
|
|
71
|
+
async signPersonalMessage(data, address) {
|
|
72
|
+
const wallet = this._getWalletForAccount(address);
|
|
73
|
+
const privKey = new ethers.SigningKey(util.addHexPrefix(wallet.privateKey));
|
|
74
|
+
const signature = privKey.sign(ethers.hashMessage(data)).serialized;
|
|
75
|
+
return signature;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// personal_signTypedData, signs data along with the schema
|
|
79
|
+
async signTypedData(typedData, address) {
|
|
80
|
+
const wallet = this._getWalletForAccount(address);
|
|
81
|
+
const privKey = new ethers.SigningKey(util.addHexPrefix(wallet.privateKey));
|
|
82
|
+
const signature = privKey.sign(ethers.TypedDataEncoder.hash(typedData.domain, typedData.types, typedData.message)).serialized;
|
|
83
|
+
return signature;
|
|
84
|
+
}
|
|
85
|
+
_getWalletForAccount(account) {
|
|
86
|
+
const address = account.toLowerCase();
|
|
87
|
+
const wallet = this.state.wallets.find(w => w.address.toLowerCase() === address);
|
|
88
|
+
if (!wallet) throw new Error("Torus Keyring - Unable to find matching address.");
|
|
89
|
+
return wallet;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
exports.KeyringController = KeyringController;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
4
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
5
|
+
var auth = require('@web3auth/auth');
|
|
6
|
+
var constants = require('../utils/constants.js');
|
|
7
|
+
|
|
8
|
+
class AbstractMessageController extends baseControllers.BaseController {
|
|
9
|
+
/**
|
|
10
|
+
* Controller in charge of managing - storing, adding, removing, updating - Messages.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
constructor({
|
|
14
|
+
config,
|
|
15
|
+
state,
|
|
16
|
+
getNetworkIdentifier
|
|
17
|
+
}) {
|
|
18
|
+
super({
|
|
19
|
+
config,
|
|
20
|
+
state
|
|
21
|
+
});
|
|
22
|
+
_defineProperty(this, "messages", void 0);
|
|
23
|
+
_defineProperty(this, "getNetworkIdentifier", void 0);
|
|
24
|
+
this.defaultState = {
|
|
25
|
+
unapprovedMessages: {},
|
|
26
|
+
unapprovedMessagesCount: 0
|
|
27
|
+
};
|
|
28
|
+
this.messages = [];
|
|
29
|
+
this.defaultConfig = {};
|
|
30
|
+
this.getNetworkIdentifier = getNetworkIdentifier;
|
|
31
|
+
super.initialize();
|
|
32
|
+
}
|
|
33
|
+
getMessage(messageId) {
|
|
34
|
+
return this.messages.find(message => message.id === messageId);
|
|
35
|
+
}
|
|
36
|
+
getAllMessages() {
|
|
37
|
+
return this.messages;
|
|
38
|
+
}
|
|
39
|
+
setMetadata(messageId, metadata) {
|
|
40
|
+
const message = this.getMessage(messageId);
|
|
41
|
+
if (!message) {
|
|
42
|
+
throw new Error(`${this.name}: Message not found for id: ${messageId}.`);
|
|
43
|
+
}
|
|
44
|
+
message.metadata = metadata;
|
|
45
|
+
this.updateMessage(message);
|
|
46
|
+
}
|
|
47
|
+
getUnapprovedMessages() {
|
|
48
|
+
return this.messages.filter(message => message.status === constants.MessageStatus.UNAPPROVED).reduce((result, message) => {
|
|
49
|
+
result[message.id] = message;
|
|
50
|
+
return result;
|
|
51
|
+
}, {});
|
|
52
|
+
}
|
|
53
|
+
async addMessage(message) {
|
|
54
|
+
this.messages.push(message);
|
|
55
|
+
this.saveMessageList();
|
|
56
|
+
}
|
|
57
|
+
approveMessage(messageId, messageParams) {
|
|
58
|
+
this.setMessageStatus(messageId, constants.MessageStatus.APPROVED);
|
|
59
|
+
return this.prepMessageForSigning(messageParams);
|
|
60
|
+
}
|
|
61
|
+
setMessageStatus(messageId, status) {
|
|
62
|
+
const message = this.getMessage(messageId);
|
|
63
|
+
if (!message) {
|
|
64
|
+
throw new Error(`${this.name}: Message not found for id: ${messageId}.`);
|
|
65
|
+
}
|
|
66
|
+
message.status = status;
|
|
67
|
+
this.updateMessage(message);
|
|
68
|
+
this.emit(`${messageId}:${status}`, message);
|
|
69
|
+
if (status === constants.MessageStatus.REJECTED || status === constants.MessageStatus.SIGNED || status === constants.MessageStatus.FAILED) {
|
|
70
|
+
this.emit(`${messageId}:finished`, message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async waitForFinishStatus(msgParams, messageName) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const handleFinished = msg => {
|
|
76
|
+
if (msg.status === constants.MessageStatus.REJECTED) {
|
|
77
|
+
return reject(auth.providerErrors.userRejectedRequest(`${messageName} Signature: User denied message signature`));
|
|
78
|
+
}
|
|
79
|
+
if (msg.status === constants.MessageStatus.FAILED) {
|
|
80
|
+
return reject(auth.rpcErrors.internal(`${messageName} Signature: failed to sign message ${msg.error}`));
|
|
81
|
+
}
|
|
82
|
+
if (msg.status === constants.MessageStatus.SIGNED) {
|
|
83
|
+
return resolve(msg.rawSig);
|
|
84
|
+
}
|
|
85
|
+
return reject(auth.rpcErrors.internal(`${messageName} Signature: Unknown problem: ${JSON.stringify(msgParams)}`));
|
|
86
|
+
};
|
|
87
|
+
this.once(`${msgParams.id}:finished`, handleFinished);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
updateMessage(message) {
|
|
91
|
+
const index = this.messages.findIndex(msg => message.id === msg.id);
|
|
92
|
+
if (index !== -1) {
|
|
93
|
+
this.messages[index] = message;
|
|
94
|
+
}
|
|
95
|
+
this.saveMessageList();
|
|
96
|
+
}
|
|
97
|
+
saveMessageList() {
|
|
98
|
+
const unapprovedMessages = this.getUnapprovedMessages();
|
|
99
|
+
const unapprovedMessagesCount = Object.keys(unapprovedMessages).length;
|
|
100
|
+
this.update({
|
|
101
|
+
unapprovedMessages,
|
|
102
|
+
unapprovedMessagesCount
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
exports.AbstractMessageController = AbstractMessageController;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
5
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
6
|
+
var log = require('loglevel');
|
|
7
|
+
var constants = require('../utils/constants.js');
|
|
8
|
+
var AbstractMessageController = require('./AbstractMessageController.js');
|
|
9
|
+
var utils = require('./utils.js');
|
|
10
|
+
|
|
11
|
+
class AddChainController extends AbstractMessageController.AbstractMessageController {
|
|
12
|
+
constructor({
|
|
13
|
+
config,
|
|
14
|
+
state,
|
|
15
|
+
getNetworkIdentifier,
|
|
16
|
+
addChain
|
|
17
|
+
}) {
|
|
18
|
+
super({
|
|
19
|
+
config,
|
|
20
|
+
state,
|
|
21
|
+
getNetworkIdentifier
|
|
22
|
+
});
|
|
23
|
+
_defineProperty(this, "name", "AddChainController");
|
|
24
|
+
_defineProperty(this, "addChain", void 0);
|
|
25
|
+
this.addChain = addChain;
|
|
26
|
+
this.initialize();
|
|
27
|
+
}
|
|
28
|
+
async processAddChain(messageId) {
|
|
29
|
+
const msgObject = this.getMessage(messageId);
|
|
30
|
+
if (!msgObject) {
|
|
31
|
+
throw new Error("Message not found");
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
await this.approveMessage(messageId, msgObject.messageParams);
|
|
35
|
+
await this.addChain(msgObject.messageParams);
|
|
36
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
37
|
+
rawSig: JSON.stringify(msgObject.messageParams)
|
|
38
|
+
}));
|
|
39
|
+
this.setMessageStatus(messageId, constants.MessageStatus.SIGNED);
|
|
40
|
+
return null;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log.error(error);
|
|
43
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
44
|
+
this.setMessageStatus(messageId, constants.MessageStatus.FAILED);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
48
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
49
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
50
|
+
}
|
|
51
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
52
|
+
// set message params origin first to satisfy the eslint rule (origin won't be checked by validateAddChainData)
|
|
53
|
+
// for "Possible race condition: `messageParams.origin` might be assigned based on an outdated state of `messageParams`"
|
|
54
|
+
if (req) {
|
|
55
|
+
messageParams.origin = req.origin;
|
|
56
|
+
}
|
|
57
|
+
await utils.validateAddChainData(messageParams);
|
|
58
|
+
const messageId = messageParams.id || baseControllers.randomId();
|
|
59
|
+
const messageData = {
|
|
60
|
+
id: messageId,
|
|
61
|
+
messageParams,
|
|
62
|
+
status: constants.MessageStatus.UNAPPROVED,
|
|
63
|
+
time: Date.now(),
|
|
64
|
+
type: constants.METHOD_TYPES.ADD_CHAIN
|
|
65
|
+
};
|
|
66
|
+
await this.addMessage(messageData);
|
|
67
|
+
this.emit(constants.MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
68
|
+
messageData,
|
|
69
|
+
req
|
|
70
|
+
});
|
|
71
|
+
return messageId;
|
|
72
|
+
}
|
|
73
|
+
prepMessageForSigning(messageParams) {
|
|
74
|
+
return Promise.resolve(messageParams);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
exports.AddChainController = AddChainController;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
5
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
6
|
+
var log = require('loglevel');
|
|
7
|
+
var constants = require('../utils/constants.js');
|
|
8
|
+
var AbstractMessageController = require('./AbstractMessageController.js');
|
|
9
|
+
var utils = require('./utils.js');
|
|
10
|
+
|
|
11
|
+
class MessageController extends AbstractMessageController.AbstractMessageController {
|
|
12
|
+
constructor({
|
|
13
|
+
config,
|
|
14
|
+
state,
|
|
15
|
+
signMessage,
|
|
16
|
+
getNetworkIdentifier
|
|
17
|
+
}) {
|
|
18
|
+
super({
|
|
19
|
+
config,
|
|
20
|
+
state,
|
|
21
|
+
getNetworkIdentifier
|
|
22
|
+
});
|
|
23
|
+
_defineProperty(this, "name", "MessageController");
|
|
24
|
+
_defineProperty(this, "signMessage", void 0);
|
|
25
|
+
this.signMessage = signMessage;
|
|
26
|
+
this.initialize();
|
|
27
|
+
}
|
|
28
|
+
async processSignMessage(messageId) {
|
|
29
|
+
const msgObject = this.getMessage(messageId);
|
|
30
|
+
if (!msgObject) {
|
|
31
|
+
throw new Error(`Message not found`);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const cleanMsgParams = await this.approveMessage(messageId, msgObject.messageParams);
|
|
35
|
+
const rawSig = await this.signMessage(cleanMsgParams.data, cleanMsgParams.from);
|
|
36
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
37
|
+
rawSig
|
|
38
|
+
}));
|
|
39
|
+
this.setMessageStatus(messageId, constants.MessageStatus.SIGNED);
|
|
40
|
+
return rawSig;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log.error(error);
|
|
43
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
44
|
+
this.setMessageStatus(messageId, constants.MessageStatus.FAILED);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
48
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
49
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
50
|
+
}
|
|
51
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
52
|
+
utils.validateSignMessageData(messageParams);
|
|
53
|
+
if (req) {
|
|
54
|
+
messageParams.origin = req.origin;
|
|
55
|
+
}
|
|
56
|
+
messageParams.data = utils.normalizeMessageData(messageParams.data);
|
|
57
|
+
const messageId = messageParams.id || baseControllers.randomId();
|
|
58
|
+
const messageData = {
|
|
59
|
+
id: messageId,
|
|
60
|
+
messageParams,
|
|
61
|
+
status: constants.MessageStatus.UNAPPROVED,
|
|
62
|
+
time: Date.now(),
|
|
63
|
+
type: constants.METHOD_TYPES.ETH_SIGN
|
|
64
|
+
};
|
|
65
|
+
await this.addMessage(messageData);
|
|
66
|
+
this.emit(constants.MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
67
|
+
messageData,
|
|
68
|
+
req
|
|
69
|
+
});
|
|
70
|
+
return messageId;
|
|
71
|
+
}
|
|
72
|
+
prepMessageForSigning(messageParams) {
|
|
73
|
+
return Promise.resolve(messageParams);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exports.MessageController = MessageController;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
5
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
6
|
+
var log = require('loglevel');
|
|
7
|
+
var constants = require('../utils/constants.js');
|
|
8
|
+
var AbstractMessageController = require('./AbstractMessageController.js');
|
|
9
|
+
var utils = require('./utils.js');
|
|
10
|
+
|
|
11
|
+
class PersonalMessageController extends AbstractMessageController.AbstractMessageController {
|
|
12
|
+
constructor({
|
|
13
|
+
config,
|
|
14
|
+
state,
|
|
15
|
+
signPersonalMessage,
|
|
16
|
+
getNetworkIdentifier
|
|
17
|
+
}) {
|
|
18
|
+
super({
|
|
19
|
+
config,
|
|
20
|
+
state,
|
|
21
|
+
getNetworkIdentifier
|
|
22
|
+
});
|
|
23
|
+
_defineProperty(this, "name", "PersonalMessageController");
|
|
24
|
+
_defineProperty(this, "signPersonalMessage", void 0);
|
|
25
|
+
this.signPersonalMessage = signPersonalMessage;
|
|
26
|
+
this.initialize();
|
|
27
|
+
}
|
|
28
|
+
async processSignPersonalMessage(messageId) {
|
|
29
|
+
const msgObject = this.getMessage(messageId);
|
|
30
|
+
if (!msgObject) {
|
|
31
|
+
throw new Error(`Message not found`);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const cleanMsgParams = await this.approveMessage(messageId, msgObject.messageParams);
|
|
35
|
+
const rawSig = await this.signPersonalMessage(cleanMsgParams.data, cleanMsgParams.from);
|
|
36
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
37
|
+
rawSig
|
|
38
|
+
}));
|
|
39
|
+
this.setMessageStatus(messageId, constants.MessageStatus.SIGNED);
|
|
40
|
+
return rawSig;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log.error(error);
|
|
43
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
44
|
+
this.setMessageStatus(messageId, constants.MessageStatus.FAILED);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
48
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
49
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
50
|
+
}
|
|
51
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
52
|
+
utils.validateSignMessageData(messageParams);
|
|
53
|
+
if (req) {
|
|
54
|
+
messageParams.origin = req.origin;
|
|
55
|
+
}
|
|
56
|
+
messageParams.data = utils.normalizeMessageData(messageParams.data);
|
|
57
|
+
const messageId = messageParams.id || baseControllers.randomId();
|
|
58
|
+
const messageData = {
|
|
59
|
+
id: messageId,
|
|
60
|
+
messageParams,
|
|
61
|
+
status: constants.MessageStatus.UNAPPROVED,
|
|
62
|
+
time: Date.now(),
|
|
63
|
+
type: constants.METHOD_TYPES.PERSONAL_SIGN
|
|
64
|
+
};
|
|
65
|
+
await this.addMessage(messageData);
|
|
66
|
+
this.emit(constants.MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
67
|
+
messageData,
|
|
68
|
+
req
|
|
69
|
+
});
|
|
70
|
+
return messageId;
|
|
71
|
+
}
|
|
72
|
+
prepMessageForSigning(messageParams) {
|
|
73
|
+
return Promise.resolve(messageParams);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
exports.PersonalMessageController = PersonalMessageController;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
4
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
5
|
+
var baseControllers = require('@toruslabs/base-controllers');
|
|
6
|
+
var log = require('loglevel');
|
|
7
|
+
var constants = require('../utils/constants.js');
|
|
8
|
+
var AbstractMessageController = require('./AbstractMessageController.js');
|
|
9
|
+
var utils = require('./utils.js');
|
|
10
|
+
|
|
11
|
+
class SwitchChainController extends AbstractMessageController.AbstractMessageController {
|
|
12
|
+
constructor({
|
|
13
|
+
config,
|
|
14
|
+
state,
|
|
15
|
+
getNetworkIdentifier,
|
|
16
|
+
switchChain
|
|
17
|
+
}) {
|
|
18
|
+
super({
|
|
19
|
+
config,
|
|
20
|
+
state,
|
|
21
|
+
getNetworkIdentifier
|
|
22
|
+
});
|
|
23
|
+
_defineProperty(this, "name", "SwitchChainController");
|
|
24
|
+
_defineProperty(this, "switchChain", void 0);
|
|
25
|
+
this.switchChain = switchChain;
|
|
26
|
+
this.initialize();
|
|
27
|
+
}
|
|
28
|
+
async processSwitchChain(messageId) {
|
|
29
|
+
const msgObject = this.getMessage(messageId);
|
|
30
|
+
if (!msgObject) {
|
|
31
|
+
throw new Error(`Message not found`);
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
await this.approveMessage(messageId, msgObject.messageParams);
|
|
35
|
+
this.switchChain({
|
|
36
|
+
chainId: msgObject.messageParams.chainId
|
|
37
|
+
});
|
|
38
|
+
this.updateMessage(_objectSpread(_objectSpread({}, msgObject), {}, {
|
|
39
|
+
rawSig: JSON.stringify(msgObject.messageParams)
|
|
40
|
+
}));
|
|
41
|
+
this.setMessageStatus(messageId, constants.MessageStatus.SIGNED);
|
|
42
|
+
return null;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
log.error(error);
|
|
45
|
+
msgObject.error = (error === null || error === void 0 ? void 0 : error.message) || (error === null || error === void 0 ? void 0 : error.toString());
|
|
46
|
+
this.setMessageStatus(messageId, constants.MessageStatus.FAILED);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async addNewUnapprovedMessage(messageParams, req) {
|
|
50
|
+
await this.addUnapprovedMessage(messageParams, req);
|
|
51
|
+
return this.waitForFinishStatus(messageParams, this.name);
|
|
52
|
+
}
|
|
53
|
+
async addUnapprovedMessage(messageParams, req) {
|
|
54
|
+
utils.validateSwitchChainData(messageParams);
|
|
55
|
+
if (req) {
|
|
56
|
+
messageParams.origin = req.origin;
|
|
57
|
+
}
|
|
58
|
+
const messageId = messageParams.id || baseControllers.randomId();
|
|
59
|
+
const messageData = {
|
|
60
|
+
id: messageId,
|
|
61
|
+
messageParams,
|
|
62
|
+
status: constants.MessageStatus.UNAPPROVED,
|
|
63
|
+
time: Date.now(),
|
|
64
|
+
type: constants.METHOD_TYPES.SWITCH_CHAIN
|
|
65
|
+
};
|
|
66
|
+
await this.addMessage(messageData);
|
|
67
|
+
this.emit(constants.MESSAGE_EVENTS.UNAPPROVED_MESSAGE, {
|
|
68
|
+
messageData,
|
|
69
|
+
req
|
|
70
|
+
});
|
|
71
|
+
return messageId;
|
|
72
|
+
}
|
|
73
|
+
prepMessageForSigning(messageParams) {
|
|
74
|
+
return Promise.resolve(messageParams);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
exports.SwitchChainController = SwitchChainController;
|