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.
- package/CHANGELOG.md +713 -0
- package/LICENSE +29 -0
- package/README.md +63 -0
- package/index.js +3 -0
- package/lib/binance/bnbEngine.js +591 -0
- package/lib/binance/bnbInfo.js +43 -0
- package/lib/binance/bnbPlugin.js +168 -0
- package/lib/binance/bnbSchema.js +83 -0
- package/lib/binance/bnbTypes.js +39 -0
- package/lib/common/engine.js +918 -0
- package/lib/common/plugin.js +152 -0
- package/lib/common/schema.js +108 -0
- package/lib/common/types.js +85 -0
- package/lib/common/utils.js +378 -0
- package/lib/eos/eosEngine.js +1216 -0
- package/lib/eos/eosInfo.js +98 -0
- package/lib/eos/eosPlugin.js +314 -0
- package/lib/eos/eosSchema.js +190 -0
- package/lib/eos/eosTypes.js +88 -0
- package/lib/eos/telosInfo.js +94 -0
- package/lib/eos/waxInfo.js +95 -0
- package/lib/ethereum/etcInfo.js +121 -0
- package/lib/ethereum/ethEngine.js +832 -0
- package/lib/ethereum/ethInfo.js +1300 -0
- package/lib/ethereum/ethMiningFees.js +157 -0
- package/lib/ethereum/ethNetwork.js +2195 -0
- package/lib/ethereum/ethPlugin.js +377 -0
- package/lib/ethereum/ethSchema.js +61 -0
- package/lib/ethereum/ethTypes.js +461 -0
- package/lib/ethereum/ftminfo.js +102 -0
- package/lib/ethereum/rskInfo.js +101 -0
- package/lib/fio/fioConst.js +38 -0
- package/lib/fio/fioEngine.js +1250 -0
- package/lib/fio/fioError.js +38 -0
- package/lib/fio/fioInfo.js +72 -0
- package/lib/fio/fioPlugin.js +486 -0
- package/lib/fio/fioSchema.js +56 -0
- package/lib/index.js +44 -0
- package/lib/pluginError.js +32 -0
- package/lib/react-native/edge-currency-accountbased.js +239635 -0
- package/lib/react-native/edge-currency-accountbased.js.map +1 -0
- package/lib/react-native-io.js +41 -0
- package/lib/stellar/stellarEngine.js +563 -0
- package/lib/stellar/stellarInfo.js +37 -0
- package/lib/stellar/stellarPlugin.js +215 -0
- package/lib/stellar/stellarSchema.js +54 -0
- package/lib/stellar/stellarTypes.js +66 -0
- package/lib/tezos/tezosEngine.js +497 -0
- package/lib/tezos/tezosInfo.js +60 -0
- package/lib/tezos/tezosPlugin.js +174 -0
- package/lib/tezos/tezosTypes.js +110 -0
- package/lib/xrp/xrpEngine.js +583 -0
- package/lib/xrp/xrpInfo.js +47 -0
- package/lib/xrp/xrpPlugin.js +229 -0
- package/lib/xrp/xrpSchema.js +74 -0
- package/lib/xrp/xrpTypes.js +38 -0
- package/package.json +139 -0
- package/postinstall.sh +7 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
//
|
|
2
|
+
import { bns } from 'biggystring'
|
|
3
|
+
import {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
InsufficientFundsError,
|
|
10
|
+
NoAmountSpecifiedError
|
|
11
|
+
} from 'edge-core-js/types'
|
|
12
|
+
import { eztz } from 'eztz.js'
|
|
13
|
+
|
|
14
|
+
import { CurrencyEngine } from '../common/engine.js'
|
|
15
|
+
import {
|
|
16
|
+
asyncWaterfall,
|
|
17
|
+
cleanTxLogs,
|
|
18
|
+
getOtherParams,
|
|
19
|
+
makeMutex,
|
|
20
|
+
promiseAny
|
|
21
|
+
} from '../common/utils.js'
|
|
22
|
+
import { TezosPlugin } from '../tezos/tezosPlugin.js'
|
|
23
|
+
import { currencyInfo } from './tezosInfo.js'
|
|
24
|
+
import {
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
asXtzGetTransaction
|
|
30
|
+
} from './tezosTypes.js'
|
|
31
|
+
|
|
32
|
+
const ADDRESS_POLL_MILLISECONDS = 15000
|
|
33
|
+
const BLOCKCHAIN_POLL_MILLISECONDS = 30000
|
|
34
|
+
const TRANSACTION_POLL_MILLISECONDS = 5000
|
|
35
|
+
|
|
36
|
+
const makeSpendMutex = makeMutex()
|
|
37
|
+
|
|
38
|
+
const PRIMARY_CURRENCY = currencyInfo.currencyCode
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
export class TezosEngine extends CurrencyEngine {
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
constructor(
|
|
53
|
+
currencyPlugin,
|
|
54
|
+
walletInfo,
|
|
55
|
+
opts,
|
|
56
|
+
fetchCors
|
|
57
|
+
) {
|
|
58
|
+
super(currencyPlugin, walletInfo, opts)
|
|
59
|
+
this.tezosPlugin = currencyPlugin
|
|
60
|
+
this.fetchCors = fetchCors
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async multicastServers(func, ...params) {
|
|
64
|
+
let out = { result: '', server: 'no server' }
|
|
65
|
+
let funcs
|
|
66
|
+
switch (func) {
|
|
67
|
+
// Functions that should waterfall from top to low priority servers
|
|
68
|
+
case 'getHead': {
|
|
69
|
+
// relevant nodes, disabling first node due to caching / polling issue
|
|
70
|
+
// need to re-enable once that nodes issue is fixed
|
|
71
|
+
const nonCachedNodes = this.tezosPlugin.tezosRpcNodes
|
|
72
|
+
funcs = nonCachedNodes.map(server => async () => {
|
|
73
|
+
const result = await this.io
|
|
74
|
+
.fetch(server + '/chains/main/blocks/head/header')
|
|
75
|
+
.then(function (response) {
|
|
76
|
+
return response.json()
|
|
77
|
+
})
|
|
78
|
+
.then(function (json) {
|
|
79
|
+
return json
|
|
80
|
+
})
|
|
81
|
+
return { server, result }
|
|
82
|
+
})
|
|
83
|
+
out = await asyncWaterfall(funcs)
|
|
84
|
+
break
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case 'getBalance': {
|
|
88
|
+
const usableNodes = this.tezosPlugin.tezosRpcNodes
|
|
89
|
+
funcs = usableNodes.map(server => async () => {
|
|
90
|
+
eztz.node.setProvider(server)
|
|
91
|
+
const result = await eztz.rpc.getBalance(params[0])
|
|
92
|
+
return { server, result }
|
|
93
|
+
})
|
|
94
|
+
out = await asyncWaterfall(funcs)
|
|
95
|
+
break
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
case 'getNumberOfOperations':
|
|
99
|
+
funcs = this.tezosPlugin.tezosApiServers.map(server => async () => {
|
|
100
|
+
const result = await this.fetchCors(
|
|
101
|
+
`${server}/v1/accounts/${params[0]}`
|
|
102
|
+
)
|
|
103
|
+
.then(function (response) {
|
|
104
|
+
return response.json()
|
|
105
|
+
})
|
|
106
|
+
.then(function (json) {
|
|
107
|
+
return json.numTransactions
|
|
108
|
+
})
|
|
109
|
+
return { server, result }
|
|
110
|
+
})
|
|
111
|
+
out = await asyncWaterfall(funcs)
|
|
112
|
+
break
|
|
113
|
+
|
|
114
|
+
case 'getTransactions':
|
|
115
|
+
funcs = this.tezosPlugin.tezosApiServers.map(server => async () => {
|
|
116
|
+
const pagination = /tzkt/.test(server)
|
|
117
|
+
? ''
|
|
118
|
+
: `&p='${params[1]}&number=50`
|
|
119
|
+
const result = await this.fetchCors(
|
|
120
|
+
`${server}/v1/accounts/${params[0]}/operations?type=transaction` +
|
|
121
|
+
pagination
|
|
122
|
+
).then(function (response) {
|
|
123
|
+
return response.json()
|
|
124
|
+
})
|
|
125
|
+
return { server, result }
|
|
126
|
+
})
|
|
127
|
+
out = await asyncWaterfall(funcs)
|
|
128
|
+
break
|
|
129
|
+
|
|
130
|
+
case 'createTransaction':
|
|
131
|
+
funcs = this.tezosPlugin.tezosRpcNodes.map(server => async () => {
|
|
132
|
+
eztz.node.setProvider(server)
|
|
133
|
+
const result = await eztz.rpc
|
|
134
|
+
.transfer(
|
|
135
|
+
params[0],
|
|
136
|
+
params[1],
|
|
137
|
+
params[2],
|
|
138
|
+
params[3],
|
|
139
|
+
params[4],
|
|
140
|
+
null,
|
|
141
|
+
this.currencyInfo.defaultSettings.limit.gas,
|
|
142
|
+
this.currencyInfo.defaultSettings.limit.storage,
|
|
143
|
+
this.currencyInfo.defaultSettings.fee.reveal
|
|
144
|
+
)
|
|
145
|
+
.then(function (response) {
|
|
146
|
+
return response
|
|
147
|
+
})
|
|
148
|
+
return { server, result }
|
|
149
|
+
})
|
|
150
|
+
out = await asyncWaterfall(funcs)
|
|
151
|
+
break
|
|
152
|
+
|
|
153
|
+
// Functions that should multicast to all servers
|
|
154
|
+
case 'injectOperation': {
|
|
155
|
+
let preApplyError = ''
|
|
156
|
+
funcs = this.tezosPlugin.tezosRpcNodes.map(server => async () => {
|
|
157
|
+
eztz.node.setProvider(server)
|
|
158
|
+
const result = await eztz.rpc
|
|
159
|
+
.inject(params[0], params[1])
|
|
160
|
+
.catch((e) => {
|
|
161
|
+
this.log.error(
|
|
162
|
+
'Error when injection operation: ' + e.name + e.message
|
|
163
|
+
)
|
|
164
|
+
const errorMessage = this.formatError(e)
|
|
165
|
+
if (!preApplyError && errorMessage !== '') {
|
|
166
|
+
preApplyError = errorMessage
|
|
167
|
+
}
|
|
168
|
+
throw e
|
|
169
|
+
})
|
|
170
|
+
// Preapply passed -> Broadcast to all remaining nodes in the waterfall
|
|
171
|
+
this.multicastServers('silentInjection', server, params[1])
|
|
172
|
+
return { server, result }
|
|
173
|
+
})
|
|
174
|
+
out = await asyncWaterfall(funcs).catch((e) => {
|
|
175
|
+
this.log.error('Error from waterfall: ' + e.name + e.message)
|
|
176
|
+
if (preApplyError !== '') {
|
|
177
|
+
throw new Error(preApplyError)
|
|
178
|
+
} else {
|
|
179
|
+
throw e
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
break
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
case 'silentInjection': {
|
|
186
|
+
const index = this.tezosPlugin.tezosRpcNodes.indexOf(params[0])
|
|
187
|
+
const remainingRpcNodes = this.tezosPlugin.tezosRpcNodes.slice(
|
|
188
|
+
index + 1
|
|
189
|
+
)
|
|
190
|
+
out = await promiseAny(
|
|
191
|
+
remainingRpcNodes.map(async server => {
|
|
192
|
+
eztz.node.setProvider(server)
|
|
193
|
+
const result = await eztz.rpc.silentInject(params[1])
|
|
194
|
+
this.log.warn('Injected silently to: ' + server)
|
|
195
|
+
return { server, result }
|
|
196
|
+
})
|
|
197
|
+
)
|
|
198
|
+
break
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
this.log(
|
|
202
|
+
`XTZ multicastServers ${func} ${out.server} won with result ${out.result}`
|
|
203
|
+
)
|
|
204
|
+
return out.result
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
formatError(e) {
|
|
208
|
+
if (typeof e === 'string') {
|
|
209
|
+
return e
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
if (
|
|
213
|
+
e.error &&
|
|
214
|
+
e.error === 'Operation Failed' &&
|
|
215
|
+
e.errors &&
|
|
216
|
+
e.errors[0].id
|
|
217
|
+
) {
|
|
218
|
+
return 'Failed in preapply with an error code (' + e.errors[0].id + ')'
|
|
219
|
+
} else if (e[0] && e[0].kind && e[0].kind === 'branch' && e[0].id) {
|
|
220
|
+
return 'Failed in preapply with an error code (' + e[0].id + ')'
|
|
221
|
+
}
|
|
222
|
+
} catch (e) {}
|
|
223
|
+
return ''
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
processTezosTransaction(tx) {
|
|
227
|
+
const transaction = asXtzGetTransaction(tx)
|
|
228
|
+
const pkh = this.walletLocalData.publicKey
|
|
229
|
+
const ourReceiveAddresses = []
|
|
230
|
+
const currencyCode = PRIMARY_CURRENCY
|
|
231
|
+
const date = new Date(transaction.timestamp).getTime() / 1000
|
|
232
|
+
const blockHeight = transaction.level
|
|
233
|
+
let nativeAmount = transaction.amount.toString()
|
|
234
|
+
const networkFee = (
|
|
235
|
+
transaction.bakerFee + transaction.allocationFee
|
|
236
|
+
).toString()
|
|
237
|
+
const failedOperation = transaction.status === 'failed'
|
|
238
|
+
if (pkh === transaction.target.address) {
|
|
239
|
+
ourReceiveAddresses.push(pkh)
|
|
240
|
+
if (transaction.sender.address === pkh) {
|
|
241
|
+
nativeAmount = '-' + networkFee
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
nativeAmount = '-' + bns.add(nativeAmount, networkFee)
|
|
245
|
+
}
|
|
246
|
+
const edgeTransaction = {
|
|
247
|
+
txid: tx.hash,
|
|
248
|
+
date,
|
|
249
|
+
currencyCode,
|
|
250
|
+
blockHeight,
|
|
251
|
+
nativeAmount,
|
|
252
|
+
networkFee,
|
|
253
|
+
ourReceiveAddresses,
|
|
254
|
+
signedTx: '',
|
|
255
|
+
otherParams: {}
|
|
256
|
+
}
|
|
257
|
+
if (!failedOperation) {
|
|
258
|
+
this.addTransaction(currencyCode, edgeTransaction)
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async checkTransactionsInnerLoop() {
|
|
263
|
+
const pkh = this.walletLocalData.publicKey
|
|
264
|
+
if (!this.otherData.numberTransactions) {
|
|
265
|
+
this.otherData.numberTransactions = 0
|
|
266
|
+
}
|
|
267
|
+
const num = await this.multicastServers('getNumberOfOperations', pkh)
|
|
268
|
+
if (num !== this.otherData.numberTransactions) {
|
|
269
|
+
let txs = []
|
|
270
|
+
let page = 0
|
|
271
|
+
let transactions
|
|
272
|
+
this.tokenCheckTransactionsStatus.XTZ = 0.5
|
|
273
|
+
do {
|
|
274
|
+
transactions = await this.multicastServers(
|
|
275
|
+
'getTransactions',
|
|
276
|
+
pkh,
|
|
277
|
+
page++
|
|
278
|
+
)
|
|
279
|
+
txs = txs.concat(transactions)
|
|
280
|
+
} while (transactions.length > 0 && page < 10)
|
|
281
|
+
for (const tx of txs) {
|
|
282
|
+
this.processTezosTransaction(tx)
|
|
283
|
+
}
|
|
284
|
+
if (this.transactionsChangedArray.length > 0) {
|
|
285
|
+
this.currencyEngineCallbacks.onTransactionsChanged(
|
|
286
|
+
this.transactionsChangedArray
|
|
287
|
+
)
|
|
288
|
+
this.transactionsChangedArray = []
|
|
289
|
+
}
|
|
290
|
+
this.otherData.numberTransactions = num
|
|
291
|
+
this.walletLocalDataDirty = true
|
|
292
|
+
}
|
|
293
|
+
this.tokenCheckTransactionsStatus.XTZ = 1
|
|
294
|
+
this.updateOnAddressesChecked()
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async checkUnconfirmedTransactionsFetch() {}
|
|
298
|
+
|
|
299
|
+
// Check all account balance and other relevant info
|
|
300
|
+
async checkAccountInnerLoop() {
|
|
301
|
+
this.tokenCheckBalanceStatus.XTZ = 0
|
|
302
|
+
const currencyCode = PRIMARY_CURRENCY
|
|
303
|
+
const pkh = this.walletLocalData.publicKey
|
|
304
|
+
if (
|
|
305
|
+
typeof this.walletLocalData.totalBalances[currencyCode] === 'undefined'
|
|
306
|
+
) {
|
|
307
|
+
this.walletLocalData.totalBalances[currencyCode] = '0'
|
|
308
|
+
}
|
|
309
|
+
const balance = await this.multicastServers('getBalance', pkh)
|
|
310
|
+
if (this.walletLocalData.totalBalances[currencyCode] !== balance) {
|
|
311
|
+
this.walletLocalData.totalBalances[currencyCode] = balance
|
|
312
|
+
this.log.warn(`Updated ${currencyCode} balance ${balance}`)
|
|
313
|
+
this.currencyEngineCallbacks.onBalanceChanged(currencyCode, balance)
|
|
314
|
+
}
|
|
315
|
+
this.tokenCheckBalanceStatus.XTZ = 1
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async checkBlockchainInnerLoop() {
|
|
319
|
+
const head = await this.multicastServers('getHead')
|
|
320
|
+
const blockHeight = head.level
|
|
321
|
+
if (this.walletLocalData.blockHeight !== blockHeight) {
|
|
322
|
+
this.walletLocalData.blockHeight = blockHeight
|
|
323
|
+
this.walletLocalDataDirty = true
|
|
324
|
+
this.currencyEngineCallbacks.onBlockHeightChanged(
|
|
325
|
+
this.walletLocalData.blockHeight
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async clearBlockchainCache() {
|
|
331
|
+
await super.clearBlockchainCache()
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async isBurn(op) {
|
|
335
|
+
if (op.kind === 'origination') {
|
|
336
|
+
return true
|
|
337
|
+
}
|
|
338
|
+
if (op.kind === 'transaction' && op.destination.slice(0, 2) === 'tz') {
|
|
339
|
+
const balance = await this.multicastServers('getBalance', op.destination)
|
|
340
|
+
if (balance === '0') {
|
|
341
|
+
return true
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return false
|
|
345
|
+
}
|
|
346
|
+
// ****************************************************************************
|
|
347
|
+
// Public methods
|
|
348
|
+
// ****************************************************************************
|
|
349
|
+
|
|
350
|
+
async startEngine() {
|
|
351
|
+
this.engineOn = true
|
|
352
|
+
this.addToLoop('checkBlockchainInnerLoop', BLOCKCHAIN_POLL_MILLISECONDS)
|
|
353
|
+
this.addToLoop('checkAccountInnerLoop', ADDRESS_POLL_MILLISECONDS)
|
|
354
|
+
this.addToLoop('checkTransactionsInnerLoop', TRANSACTION_POLL_MILLISECONDS)
|
|
355
|
+
super.startEngine()
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
async resyncBlockchain() {
|
|
359
|
+
await this.killEngine()
|
|
360
|
+
await this.clearBlockchainCache()
|
|
361
|
+
await this.startEngine()
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async makeSpend(edgeSpendInfoIn) {
|
|
365
|
+
return makeSpendMutex(() => this.makeSpendInner(edgeSpendInfoIn))
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
async makeSpendInner(
|
|
369
|
+
edgeSpendInfoIn
|
|
370
|
+
) {
|
|
371
|
+
const { edgeSpendInfo, currencyCode, nativeBalance, denom } =
|
|
372
|
+
super.makeSpend(edgeSpendInfoIn)
|
|
373
|
+
if (edgeSpendInfo.spendTargets.length !== 1) {
|
|
374
|
+
throw new Error('Error: only one output allowed')
|
|
375
|
+
}
|
|
376
|
+
const publicAddress = edgeSpendInfo.spendTargets[0].publicAddress
|
|
377
|
+
let nativeAmount = '0'
|
|
378
|
+
if (typeof edgeSpendInfo.spendTargets[0].nativeAmount === 'string') {
|
|
379
|
+
nativeAmount = edgeSpendInfo.spendTargets[0].nativeAmount
|
|
380
|
+
} else {
|
|
381
|
+
throw new NoAmountSpecifiedError()
|
|
382
|
+
}
|
|
383
|
+
if (bns.eq(nativeAmount, '0')) {
|
|
384
|
+
throw new NoAmountSpecifiedError()
|
|
385
|
+
}
|
|
386
|
+
const keys = {
|
|
387
|
+
pk: this.walletInfo.keys.publicKeyEd,
|
|
388
|
+
pkh: this.walletInfo.keys.publicKey,
|
|
389
|
+
sk: false
|
|
390
|
+
}
|
|
391
|
+
let ops
|
|
392
|
+
let resendCounter = 0
|
|
393
|
+
let error
|
|
394
|
+
do {
|
|
395
|
+
try {
|
|
396
|
+
ops = await this.multicastServers(
|
|
397
|
+
'createTransaction',
|
|
398
|
+
keys.pkh,
|
|
399
|
+
keys,
|
|
400
|
+
publicAddress,
|
|
401
|
+
bns.div(nativeAmount, denom.multiplier, 6),
|
|
402
|
+
this.currencyInfo.defaultSettings.fee.transaction
|
|
403
|
+
)
|
|
404
|
+
} catch (e) {
|
|
405
|
+
error = e
|
|
406
|
+
}
|
|
407
|
+
} while (
|
|
408
|
+
(typeof ops === 'undefined' || ops.opOb.contents.length > 2) &&
|
|
409
|
+
resendCounter++ < 5
|
|
410
|
+
)
|
|
411
|
+
if (typeof ops === 'undefined') {
|
|
412
|
+
throw error
|
|
413
|
+
}
|
|
414
|
+
let networkFee = '0'
|
|
415
|
+
for (const operation of ops.opOb.contents) {
|
|
416
|
+
networkFee = bns.add(networkFee, operation.fee)
|
|
417
|
+
const burn = await this.isBurn(operation)
|
|
418
|
+
if (burn) {
|
|
419
|
+
networkFee = bns.add(
|
|
420
|
+
networkFee,
|
|
421
|
+
this.currencyInfo.defaultSettings.fee.burn
|
|
422
|
+
)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
nativeAmount = bns.add(nativeAmount, networkFee)
|
|
426
|
+
if (bns.gt(nativeAmount, nativeBalance)) {
|
|
427
|
+
throw new InsufficientFundsError()
|
|
428
|
+
}
|
|
429
|
+
nativeAmount = '-' + nativeAmount
|
|
430
|
+
|
|
431
|
+
const edgeTransaction = {
|
|
432
|
+
txid: '',
|
|
433
|
+
date: 0,
|
|
434
|
+
currencyCode,
|
|
435
|
+
blockHeight: 0,
|
|
436
|
+
nativeAmount,
|
|
437
|
+
networkFee,
|
|
438
|
+
ourReceiveAddresses: [],
|
|
439
|
+
signedTx: '',
|
|
440
|
+
otherParams: {
|
|
441
|
+
idInternal: 0,
|
|
442
|
+
fromAddress: this.walletLocalData.publicKey,
|
|
443
|
+
toAddress: publicAddress,
|
|
444
|
+
fullOp: ops
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return edgeTransaction
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
async signTx(edgeTransaction) {
|
|
451
|
+
const otherParams = getOtherParams(edgeTransaction)
|
|
452
|
+
|
|
453
|
+
if (edgeTransaction.signedTx === '') {
|
|
454
|
+
const sk = this.walletInfo.keys.privateKey
|
|
455
|
+
const signed = eztz.crypto.sign(
|
|
456
|
+
otherParams.fullOp.opbytes,
|
|
457
|
+
sk,
|
|
458
|
+
eztz.watermark.generic
|
|
459
|
+
)
|
|
460
|
+
otherParams.fullOp.opbytes = signed.sbytes
|
|
461
|
+
otherParams.fullOp.opOb.signature = signed.edsig
|
|
462
|
+
edgeTransaction.signedTx = signed.sbytes
|
|
463
|
+
}
|
|
464
|
+
this.log.warn(`signTx\n${cleanTxLogs(edgeTransaction)}`)
|
|
465
|
+
return edgeTransaction
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
async broadcastTx(
|
|
469
|
+
edgeTransaction
|
|
470
|
+
) {
|
|
471
|
+
const otherParams = getOtherParams(edgeTransaction)
|
|
472
|
+
|
|
473
|
+
const opBytes = otherParams.fullOp.opbytes
|
|
474
|
+
const opOb = otherParams.fullOp.opOb
|
|
475
|
+
const result = await this.multicastServers('injectOperation', opOb, opBytes)
|
|
476
|
+
edgeTransaction.txid = result.hash
|
|
477
|
+
edgeTransaction.date = Date.now() / 1000
|
|
478
|
+
this.log.warn(`SUCCESS broadcastTx\n${cleanTxLogs(edgeTransaction)}`)
|
|
479
|
+
return edgeTransaction
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
getDisplayPrivateSeed() {
|
|
483
|
+
if (this.walletInfo.keys && this.walletInfo.keys.mnemonic) {
|
|
484
|
+
return this.walletInfo.keys.mnemonic
|
|
485
|
+
}
|
|
486
|
+
return ''
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
getDisplayPublicSeed() {
|
|
490
|
+
if (this.walletInfo.keys && this.walletInfo.keys.publicKey) {
|
|
491
|
+
return this.walletInfo.keys.publicKey
|
|
492
|
+
}
|
|
493
|
+
return ''
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export { CurrencyEngine }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const otherSettings = {
|
|
7
|
+
// Testnet (alphanet):
|
|
8
|
+
// tezosRpcNodes: [
|
|
9
|
+
// 'https://rpcalpha.tzbeta.net',
|
|
10
|
+
// 'https://alphanet-node.tzscan.io',
|
|
11
|
+
// 'https://alphanet.tezrpc.me'
|
|
12
|
+
// ],
|
|
13
|
+
// tezosApiServers: [
|
|
14
|
+
// 'https://api.alphanet.tzscan.io',
|
|
15
|
+
// 'http://node1.nyc.tezos.org.sg:8091'
|
|
16
|
+
// ]
|
|
17
|
+
|
|
18
|
+
// Mainnet:
|
|
19
|
+
tezosRpcNodes: [
|
|
20
|
+
'https://rpc.tzbeta.net',
|
|
21
|
+
// 'https://teznode.letzbake.com',
|
|
22
|
+
'https://mainnet.tezrpc.me'
|
|
23
|
+
],
|
|
24
|
+
tezosApiServers: ['https://api.tzkt.io']
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const defaultSettings = {
|
|
28
|
+
otherSettings,
|
|
29
|
+
fee: {
|
|
30
|
+
transaction: '1350',
|
|
31
|
+
reveal: '1300',
|
|
32
|
+
burn: '257000'
|
|
33
|
+
},
|
|
34
|
+
limit: {
|
|
35
|
+
gas: '10600',
|
|
36
|
+
storage: '277'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export const currencyInfo = {
|
|
40
|
+
// Basic currency information:
|
|
41
|
+
currencyCode: 'XTZ',
|
|
42
|
+
displayName: 'Tezos',
|
|
43
|
+
pluginId: 'tezos',
|
|
44
|
+
walletType: 'wallet:tezos',
|
|
45
|
+
|
|
46
|
+
defaultSettings,
|
|
47
|
+
|
|
48
|
+
addressExplorer: 'https://tzstats.com/%s',
|
|
49
|
+
transactionExplorer: 'https://tzstats.com/%s',
|
|
50
|
+
|
|
51
|
+
denominations: [
|
|
52
|
+
// An array of Objects of the possible denominations for this currency
|
|
53
|
+
{
|
|
54
|
+
name: 'XTZ',
|
|
55
|
+
multiplier: '1000000',
|
|
56
|
+
symbol: 't'
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
metaTokens: []
|
|
60
|
+
}
|