edge-currency-accountbased 0.7.72

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 (58) hide show
  1. package/CHANGELOG.md +713 -0
  2. package/LICENSE +29 -0
  3. package/README.md +63 -0
  4. package/index.js +3 -0
  5. package/lib/binance/bnbEngine.js +591 -0
  6. package/lib/binance/bnbInfo.js +43 -0
  7. package/lib/binance/bnbPlugin.js +168 -0
  8. package/lib/binance/bnbSchema.js +83 -0
  9. package/lib/binance/bnbTypes.js +39 -0
  10. package/lib/common/engine.js +918 -0
  11. package/lib/common/plugin.js +152 -0
  12. package/lib/common/schema.js +108 -0
  13. package/lib/common/types.js +85 -0
  14. package/lib/common/utils.js +378 -0
  15. package/lib/eos/eosEngine.js +1216 -0
  16. package/lib/eos/eosInfo.js +98 -0
  17. package/lib/eos/eosPlugin.js +314 -0
  18. package/lib/eos/eosSchema.js +190 -0
  19. package/lib/eos/eosTypes.js +88 -0
  20. package/lib/eos/telosInfo.js +94 -0
  21. package/lib/eos/waxInfo.js +95 -0
  22. package/lib/ethereum/etcInfo.js +121 -0
  23. package/lib/ethereum/ethEngine.js +832 -0
  24. package/lib/ethereum/ethInfo.js +1300 -0
  25. package/lib/ethereum/ethMiningFees.js +157 -0
  26. package/lib/ethereum/ethNetwork.js +2195 -0
  27. package/lib/ethereum/ethPlugin.js +377 -0
  28. package/lib/ethereum/ethSchema.js +61 -0
  29. package/lib/ethereum/ethTypes.js +461 -0
  30. package/lib/ethereum/ftminfo.js +102 -0
  31. package/lib/ethereum/rskInfo.js +101 -0
  32. package/lib/fio/fioConst.js +38 -0
  33. package/lib/fio/fioEngine.js +1250 -0
  34. package/lib/fio/fioError.js +38 -0
  35. package/lib/fio/fioInfo.js +72 -0
  36. package/lib/fio/fioPlugin.js +486 -0
  37. package/lib/fio/fioSchema.js +56 -0
  38. package/lib/index.js +44 -0
  39. package/lib/pluginError.js +32 -0
  40. package/lib/react-native/edge-currency-accountbased.js +239635 -0
  41. package/lib/react-native/edge-currency-accountbased.js.map +1 -0
  42. package/lib/react-native-io.js +41 -0
  43. package/lib/stellar/stellarEngine.js +563 -0
  44. package/lib/stellar/stellarInfo.js +37 -0
  45. package/lib/stellar/stellarPlugin.js +215 -0
  46. package/lib/stellar/stellarSchema.js +54 -0
  47. package/lib/stellar/stellarTypes.js +66 -0
  48. package/lib/tezos/tezosEngine.js +497 -0
  49. package/lib/tezos/tezosInfo.js +60 -0
  50. package/lib/tezos/tezosPlugin.js +174 -0
  51. package/lib/tezos/tezosTypes.js +110 -0
  52. package/lib/xrp/xrpEngine.js +583 -0
  53. package/lib/xrp/xrpInfo.js +47 -0
  54. package/lib/xrp/xrpPlugin.js +229 -0
  55. package/lib/xrp/xrpSchema.js +74 -0
  56. package/lib/xrp/xrpTypes.js +38 -0
  57. package/package.json +139 -0
  58. package/postinstall.sh +7 -0
@@ -0,0 +1,377 @@
1
+ function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }/**
2
+ * Created by paul on 8/8/17.
3
+ */
4
+ //
5
+
6
+ import { bns } from 'biggystring'
7
+ import { generateMnemonic, mnemonicToSeedSync, validateMnemonic } from 'bip39'
8
+ import { Buffer } from 'buffer'
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+ import EthereumUtil from 'ethereumjs-util'
23
+ import hdKey from 'ethereumjs-wallet/hdkey'
24
+
25
+ import { CurrencyPlugin } from '../common/plugin.js'
26
+ import { biggyScience, getDenomInfo } from '../common/utils.js'
27
+ import { getFetchCors } from '../react-native-io.js'
28
+ import { EthereumEngine } from './ethEngine.js'
29
+
30
+ export { calcMiningFee } from './ethMiningFees.js' // may be tricky for RSK
31
+
32
+ export class EthereumPlugin extends CurrencyPlugin {
33
+ constructor(
34
+ io,
35
+ currencyInfo,
36
+ fetchCors
37
+ ) {
38
+ super(io, currencyInfo.pluginId, currencyInfo)
39
+ }
40
+
41
+ async importPrivateKey(userInput) {
42
+ const { pluginId } = this.currencyInfo
43
+ const { pluginMnemonicKeyName, pluginRegularKeyName } =
44
+ this.currencyInfo.defaultSettings.otherSettings
45
+ if (/^(0x)?[0-9a-fA-F]{64}$/.test(userInput)) {
46
+ // It looks like a private key, so validate the hex:
47
+ const keyBuffer = Buffer.from(userInput.replace(/^0x/, ''), 'hex')
48
+ if (!EthereumUtil.isValidPrivate(keyBuffer)) {
49
+ throw new Error('Invalid private key')
50
+ }
51
+ const hexKey = keyBuffer.toString('hex')
52
+
53
+ // Validate the address derivation:
54
+ const keys = {
55
+ [pluginRegularKeyName]: hexKey
56
+ }
57
+ this.derivePublicKey({
58
+ type: `wallet:${pluginId}`,
59
+ id: 'fake',
60
+ keys
61
+ })
62
+ return keys
63
+ } else {
64
+ // it looks like a mnemonic, so validate that way:
65
+ if (!validateMnemonic(userInput)) {
66
+ // "input" instead of "mnemonic" in case private key
67
+ // was just the wrong length
68
+ throw new Error('Invalid input')
69
+ }
70
+ const hexKey = await this._mnemonicToHex(userInput)
71
+ return {
72
+ [pluginMnemonicKeyName]: userInput,
73
+ [pluginRegularKeyName]: hexKey
74
+ }
75
+ }
76
+ }
77
+
78
+ async createPrivateKey(walletType) {
79
+ const { pluginMnemonicKeyName, pluginRegularKeyName } =
80
+ this.currencyInfo.defaultSettings.otherSettings
81
+ const type = walletType.replace('wallet:', '')
82
+
83
+ if (type !== this.currencyInfo.pluginId) {
84
+ throw new Error('InvalidWalletType')
85
+ }
86
+
87
+ const mnemonicKey = generateMnemonic(128).split(',').join(' ')
88
+
89
+ const hexKey = await this._mnemonicToHex(mnemonicKey) // will not have 0x in it
90
+ return {
91
+ [pluginMnemonicKeyName]: mnemonicKey,
92
+ [pluginRegularKeyName]: hexKey
93
+ }
94
+ }
95
+
96
+ async derivePublicKey(walletInfo) {
97
+ const { pluginId, defaultSettings } = this.currencyInfo
98
+ const { hdPathCoinType, pluginMnemonicKeyName, pluginRegularKeyName } =
99
+ defaultSettings.otherSettings
100
+ if (walletInfo.type !== `wallet:${pluginId}`) {
101
+ throw new Error('Invalid wallet type')
102
+ }
103
+ let address
104
+ if (walletInfo.keys[pluginMnemonicKeyName] != null) {
105
+ // If we have a mnemonic, use that:
106
+ const seedBuffer = mnemonicToSeedSync(
107
+ walletInfo.keys[pluginMnemonicKeyName]
108
+ )
109
+ const hdwallet = hdKey.fromMasterSeed(seedBuffer)
110
+ const walletHdpath = `m/44'/${hdPathCoinType}'/0'/0/`
111
+ const walletPathDerivation = hdwallet.derivePath(walletHdpath + 0)
112
+ const wallet = walletPathDerivation.getWallet()
113
+ const publicKey = wallet.getPublicKey()
114
+ address = `0x${EthereumUtil.pubToAddress(publicKey).toString('hex')}`
115
+ } else {
116
+ // Otherwise, use the private key:
117
+ const keyBuffer = Buffer.from(
118
+ walletInfo.keys[pluginRegularKeyName].replace(/^0x/, ''),
119
+ 'hex'
120
+ )
121
+ if (!EthereumUtil.isValidPrivate(keyBuffer)) {
122
+ throw new Error('Invalid private key')
123
+ }
124
+ address = `0x${EthereumUtil.privateToAddress(keyBuffer).toString('hex')}`
125
+ }
126
+ if (!EthereumUtil.isValidAddress(address)) {
127
+ throw new Error('Invalid address')
128
+ }
129
+ return { publicKey: address }
130
+ }
131
+
132
+ async _mnemonicToHex(mnemonic) {
133
+ const { defaultSettings } = this.currencyInfo
134
+ const { hdPathCoinType } = defaultSettings.otherSettings
135
+ const hdwallet = hdKey.fromMasterSeed(mnemonicToSeedSync(mnemonic))
136
+ const walletHdpath = `m/44'/${hdPathCoinType}'/0'/0/`
137
+ const walletPathDerivation = hdwallet.derivePath(walletHdpath + 0)
138
+ const wallet = walletPathDerivation.getWallet()
139
+ const privKey = wallet.getPrivateKeyString().replace(/^0x/, '')
140
+ return privKey
141
+ }
142
+
143
+ async parseUri(
144
+ uri,
145
+ currencyCode,
146
+ customTokens
147
+ ) {
148
+ const networks = {}
149
+ this.currencyInfo.defaultSettings.otherSettings.uriNetworks.forEach(
150
+ network => {
151
+ networks[network] = true
152
+ }
153
+ )
154
+
155
+ const { parsedUri, edgeParsedUri } = this.parseUriCommon(
156
+ this.currencyInfo,
157
+ uri,
158
+ networks,
159
+ currencyCode || this.currencyInfo.currencyCode,
160
+ customTokens
161
+ )
162
+ let address = ''
163
+ if (edgeParsedUri.publicAddress) {
164
+ address = edgeParsedUri.publicAddress
165
+ edgeParsedUri.publicAddress = edgeParsedUri.publicAddress.toLowerCase()
166
+ }
167
+
168
+ let [prefix, contractAddress] = address.split('-') // Split the address to get the prefix according to EIP-681
169
+ // If contractAddress is null or undefined it means there is no prefix
170
+ if (!contractAddress) {
171
+ contractAddress = prefix // Set the contractAddress to be the prefix when the prefix is missing.
172
+ prefix = 'pay' // The default prefix according to EIP-681 is "pay"
173
+ }
174
+ address = contractAddress
175
+
176
+ // Verify checksum if it's present in the address
177
+ if (
178
+ /[A-F]/.test(address) &&
179
+ !EthereumUtil.isValidChecksumAddress(address)
180
+ ) {
181
+ throw new Error('InvalidPublicAddressError')
182
+ }
183
+
184
+ // Verify address is valid
185
+ address = address.toLowerCase()
186
+ if (!EthereumUtil.isValidAddress(address || '')) {
187
+ throw new Error('InvalidPublicAddressError')
188
+ }
189
+
190
+ // Parse according to EIP-961
191
+ if (prefix === 'token' || prefix === 'token_info') {
192
+ if (!parsedUri.query) throw new Error('InvalidUriError')
193
+
194
+ const currencyCode = parsedUri.query.symbol || 'SYM'
195
+ if (currencyCode.length < 2 || currencyCode.length > 5) {
196
+ throw new Error('Wrong Token symbol')
197
+ }
198
+ const currencyName = parsedUri.query.name || currencyCode
199
+ const decimalsInput = parsedUri.query.decimals || '18'
200
+ let multiplier = '1000000000000000000'
201
+ const decimals = parseInt(decimalsInput)
202
+ if (decimals < 0 || decimals > 18) {
203
+ throw new Error('Wrong number of decimals')
204
+ }
205
+ multiplier = '1' + '0'.repeat(decimals)
206
+
207
+ const type =
208
+ parsedUri.query.type ||
209
+ this.currencyInfo.defaultSettings.otherSettings.ercTokenStandard
210
+
211
+ const edgeParsedUriToken = {
212
+ token: {
213
+ currencyCode,
214
+ contractAddress: contractAddress.toLowerCase(),
215
+ currencyName,
216
+ multiplier,
217
+ denominations: [{ name: currencyCode, multiplier }],
218
+ type: type.toUpperCase()
219
+ }
220
+ }
221
+ return edgeParsedUriToken
222
+ }
223
+
224
+ // Parse according to EIP-681
225
+ if (prefix === 'pay') {
226
+ const targetAddress = address
227
+ const functionName = parsedUri.pathname.split('/')[1]
228
+ const parameters = parsedUri.query
229
+
230
+ // Handle contract function invocations
231
+ // This is a very important measure to prevent accidental payment to contract addresses
232
+ switch (functionName) {
233
+ // ERC-20 token transfer
234
+ case 'transfer': {
235
+ const publicAddress = _nullishCoalesce(parameters.address, () => ( ''))
236
+ const contractAddress = _nullishCoalesce(targetAddress, () => ( ''))
237
+ const nativeAmount =
238
+ parameters.uint256 != null
239
+ ? biggyScience(parameters.uint256)
240
+ : edgeParsedUri.nativeAmount
241
+
242
+ // Get meta token from contract address
243
+ const metaToken = this.currencyInfo.metaTokens.find(
244
+ metaToken => metaToken.contractAddress === contractAddress
245
+ )
246
+
247
+ // If there is a currencyCode param, the metaToken must be found
248
+ // and it's currency code must matching the currencyCode param.
249
+ if (
250
+ currencyCode != null &&
251
+ (metaToken == null || metaToken.currencyCode !== currencyCode)
252
+ ) {
253
+ throw new Error('InternalErrorInvalidCurrencyCode')
254
+ }
255
+
256
+ // Validate addresses
257
+ if (!EthereumUtil.isValidAddress(publicAddress)) {
258
+ throw new Error('InvalidPublicAddressError')
259
+ }
260
+ if (!EthereumUtil.isValidAddress(contractAddress)) {
261
+ throw new Error('InvalidContractAddressError')
262
+ }
263
+
264
+ return {
265
+ ...edgeParsedUri,
266
+ currencyCode: _optionalChain([metaToken, 'optionalAccess', _ => _.currencyCode]),
267
+ nativeAmount,
268
+ publicAddress
269
+ }
270
+ }
271
+ // ETH payment
272
+ case undefined: {
273
+ const publicAddress = targetAddress
274
+ const nativeAmount =
275
+ parameters.value != null
276
+ ? biggyScience(parameters.value)
277
+ : edgeParsedUri.nativeAmount
278
+
279
+ return { ...edgeParsedUri, publicAddress, nativeAmount }
280
+ }
281
+ default: {
282
+ throw new Error('UnsupportedContractFunction')
283
+ }
284
+ }
285
+ }
286
+
287
+ throw new Error('InvalidUriError')
288
+ }
289
+
290
+ async encodeUri(
291
+ obj,
292
+ customTokens
293
+ ) {
294
+ const { publicAddress, nativeAmount, currencyCode } = obj
295
+ const valid = EthereumUtil.isValidAddress(publicAddress)
296
+ if (!valid) {
297
+ throw new Error('InvalidPublicAddressError')
298
+ }
299
+ let amount
300
+ if (typeof nativeAmount === 'string') {
301
+ const denom = getDenomInfo(
302
+ this.currencyInfo,
303
+ currencyCode || this.currencyInfo.currencyCode,
304
+ customTokens
305
+ )
306
+ if (!denom) {
307
+ throw new Error('InternalErrorInvalidCurrencyCode')
308
+ }
309
+ amount = bns.div(nativeAmount, denom.multiplier, 18)
310
+ }
311
+ const encodedUri = this.encodeUriCommon(
312
+ obj,
313
+ this.currencyInfo.pluginId,
314
+ amount
315
+ )
316
+ return encodedUri
317
+ }
318
+ }
319
+
320
+ export function makeEthereumBasedPluginInner(
321
+ opts,
322
+ currencyInfo
323
+ ) {
324
+ const { io, initOptions } = opts
325
+ const fetchCors = getFetchCors(opts)
326
+
327
+ let toolsPromise
328
+ function makeCurrencyTools() {
329
+ if (toolsPromise != null) return toolsPromise
330
+ toolsPromise = Promise.resolve(
331
+ new EthereumPlugin(io, currencyInfo, fetchCors)
332
+ )
333
+ return toolsPromise
334
+ }
335
+
336
+ async function makeCurrencyEngine(
337
+ walletInfo,
338
+ opts
339
+ ) {
340
+ const tools = await makeCurrencyTools()
341
+ const currencyEngine = new EthereumEngine(
342
+ tools,
343
+ walletInfo,
344
+ initOptions,
345
+ opts,
346
+ currencyInfo,
347
+ fetchCors
348
+ )
349
+
350
+ // Do any async initialization necessary for the engine
351
+ await currencyEngine.loadEngine(tools, walletInfo, opts)
352
+
353
+ // This is just to make sure otherData is Flow type checked
354
+ currencyEngine.otherData = currencyEngine.walletLocalData.otherData
355
+
356
+ // Initialize otherData defaults if they weren't on disk
357
+ if (!currencyEngine.otherData.nextNonce) {
358
+ currencyEngine.otherData.nextNonce = '0'
359
+ }
360
+ if (!currencyEngine.otherData.unconfirmedNextNonce) {
361
+ currencyEngine.otherData.unconfirmedNextNonce = '0'
362
+ }
363
+ if (!currencyEngine.otherData.networkFees) {
364
+ currencyEngine.otherData.networkFees =
365
+ currencyInfo.defaultSettings.otherSettings.defaultNetworkFees
366
+ }
367
+
368
+ const out = currencyEngine
369
+ return out
370
+ }
371
+
372
+ return {
373
+ currencyInfo,
374
+ makeCurrencyEngine,
375
+ makeCurrencyTools
376
+ }
377
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Created by paul on 8/27/17.
3
+ */
4
+
5
+ export const EtherscanGetBlockHeight = {
6
+ type: 'object',
7
+ properties: {
8
+ result: { type: 'string' }
9
+ },
10
+ required: ['result']
11
+ }
12
+
13
+ export const EtherscanGetAccountNonce = {
14
+ type: 'object',
15
+ properties: {
16
+ result: { type: 'string' }
17
+ },
18
+ required: ['result']
19
+ }
20
+
21
+ export const EthGasStationSchema = {
22
+ type: 'object',
23
+ properties: {
24
+ safeLow: { type: 'number' },
25
+ average: { type: 'number' },
26
+ fastest: { type: 'number' }
27
+ },
28
+ required: ['safeLow', 'average', 'fastest']
29
+ }
30
+
31
+ export const CustomTokenSchema = {
32
+ type: 'object',
33
+ properties: {
34
+ currencyCode: { type: 'string' },
35
+ currencyName: { type: 'string' },
36
+ multiplier: { type: 'string' },
37
+ contractAddress: { type: 'string' }
38
+ },
39
+ required: ['currencyCode', 'currencyName', 'multiplier', 'contractAddress']
40
+ }
41
+
42
+ export const BlockChairStatsSchema = {
43
+ type: 'object',
44
+ properties: {
45
+ data: {
46
+ type: 'object',
47
+ properties: {
48
+ blocks: { type: 'number' }
49
+ }
50
+ }
51
+ },
52
+ required: ['data']
53
+ }
54
+
55
+ export const AmberdataRpcSchema = {
56
+ type: 'object',
57
+ properties: {
58
+ result: { type: 'string' }
59
+ },
60
+ required: ['result']
61
+ }