@pioneer-platform/eth-network 8.4.8 → 8.5.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/lib/constant.d.ts +3 -3
- package/lib/constant.js +1 -0
- package/lib/constant.js.map +1 -0
- package/lib/etherscan-api.d.ts +4 -4
- package/lib/etherscan-api.js +49 -116
- package/lib/etherscan-api.js.map +1 -0
- package/lib/index.js +1102 -1529
- package/lib/index.js.map +1 -0
- package/lib/types/client-types.d.ts +10 -3
- package/lib/types/client-types.js +1 -0
- package/lib/types/client-types.js.map +1 -0
- package/lib/types/etherscan-api-types.js +1 -0
- package/lib/types/etherscan-api-types.js.map +1 -0
- package/lib/types/index.js +1 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils.d.ts +5 -5
- package/lib/utils.js +46 -48
- package/lib/utils.js.map +1 -0
- package/package.json +18 -14
- package/tsconfig.json +27 -9
- package/tsconfig.json.bak +27 -0
- package/tsconfig.tsbuildinfo +1 -0
package/lib/index.js
CHANGED
@@ -25,102 +25,78 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
25
25
|
}) : function(o, v) {
|
26
26
|
o["default"] = v;
|
27
27
|
});
|
28
|
-
var __importStar = (this && this.__importStar) || function (
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
};
|
35
|
-
|
36
|
-
|
37
|
-
return
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
};
|
44
|
-
|
45
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
46
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
47
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
48
|
-
function step(op) {
|
49
|
-
if (f) throw new TypeError("Generator is already executing.");
|
50
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
51
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
52
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
53
|
-
switch (op[0]) {
|
54
|
-
case 0: case 1: t = op; break;
|
55
|
-
case 4: _.label++; return { value: op[1], done: false };
|
56
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
57
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
58
|
-
default:
|
59
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
60
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
61
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
62
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
63
|
-
if (t[2]) _.ops.pop();
|
64
|
-
_.trys.pop(); continue;
|
65
|
-
}
|
66
|
-
op = body.call(thisArg, _);
|
67
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
68
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
69
|
-
}
|
70
|
-
};
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
29
|
+
var ownKeys = function(o) {
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
31
|
+
var ar = [];
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
33
|
+
return ar;
|
34
|
+
};
|
35
|
+
return ownKeys(o);
|
36
|
+
};
|
37
|
+
return function (mod) {
|
38
|
+
if (mod && mod.__esModule) return mod;
|
39
|
+
var result = {};
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
41
|
+
__setModuleDefault(result, mod);
|
42
|
+
return result;
|
43
|
+
};
|
44
|
+
})();
|
71
45
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
72
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
73
47
|
};
|
74
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
75
|
-
|
76
|
-
|
77
|
-
|
49
|
+
const TAG = " | eth-network | ";
|
50
|
+
let Web3 = require('web3');
|
51
|
+
// @ts-ignore
|
52
|
+
const ethers = __importStar(require("ethers"));
|
78
53
|
// @ts-ignore
|
79
|
-
|
54
|
+
const BigNumber = require('bignumber.js');
|
80
55
|
//
|
81
|
-
|
82
|
-
|
83
|
-
|
56
|
+
const Axios = require('axios');
|
57
|
+
const https = require('https');
|
58
|
+
const axios = Axios.create({
|
84
59
|
httpsAgent: new https.Agent({
|
85
60
|
rejectUnauthorized: false
|
86
61
|
})
|
87
62
|
});
|
88
|
-
|
63
|
+
const request = require("request-promise");
|
89
64
|
//blockbook
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
65
|
+
let blockbook = require("@pioneer-platform/blockbook");
|
66
|
+
const Web3Utils = require('web3-utils');
|
67
|
+
const providers_1 = require("@ethersproject/providers");
|
68
|
+
const abi_1 = require("@ethersproject/abi");
|
69
|
+
const utils_1 = require("./utils");
|
70
|
+
const xchain_util_1 = require("@xchainjs/xchain-util");
|
71
|
+
const etherscanAPI = __importStar(require("./etherscan-api"));
|
72
|
+
const log = require('@pioneer-platform/loggerdog')();
|
73
|
+
let ETHPLORER_API_KEY = process.env['ETHPLORER_API_KEY'] || 'freekey';
|
74
|
+
const nodes_1 = __importDefault(require("@pioneer-platform/nodes"));
|
75
|
+
let wait = require('wait-promise');
|
76
|
+
let sleep = wait.sleep;
|
102
77
|
//
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
78
|
+
let web3;
|
79
|
+
let web3Base;
|
80
|
+
let ETHERSCAN;
|
81
|
+
let ETHPLORER;
|
82
|
+
let PROVIDER;
|
83
|
+
let NODE_URL;
|
109
84
|
//TODO precision module
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
85
|
+
let BASE = 1000000000000000000;
|
86
|
+
// Remove deprecated import
|
87
|
+
// import { Interface } from '@ethersproject/abi'
|
88
|
+
const constant_1 = require("./constant"); // Replace with your actual module file path
|
89
|
+
const BASE_NODE = 'https://base.llamarpc.com';
|
90
|
+
const NODES = [];
|
115
91
|
module.exports = {
|
116
92
|
init: function (settings) {
|
117
93
|
//blockbook.init()
|
118
94
|
//log.debug("node: ",process.env['PARITY_ARCHIVE_NODE'])
|
119
95
|
//load
|
120
96
|
// @ts-ignore
|
121
|
-
|
122
|
-
for (
|
123
|
-
|
97
|
+
let web3nodes = nodes_1.default.getWeb3Nodes();
|
98
|
+
for (let i = 0; i < web3nodes.length; i++) {
|
99
|
+
let node = web3nodes[i];
|
124
100
|
if (!node.networkId)
|
125
101
|
throw Error('missing networkId');
|
126
102
|
if (!node.service)
|
@@ -132,7 +108,7 @@ module.exports = {
|
|
132
108
|
web3 = new Web3(process.env['PARITY_ARCHIVE_NODE']);
|
133
109
|
web3Base = new Web3(process.env['BASE_NODE'] || 'https://base.llamarpc.com');
|
134
110
|
ETHERSCAN = new providers_1.EtherscanProvider('mainnet', process.env['ETHERSCAN_API_KEY']);
|
135
|
-
PROVIDER = new
|
111
|
+
PROVIDER = new ethers.providers.InfuraProvider('mainnet', process.env['INFURA_API_KEY']);
|
136
112
|
NODE_URL = process.env['PARITY_ARCHIVE_NODE'];
|
137
113
|
}
|
138
114
|
else if (settings.testnet) {
|
@@ -144,7 +120,7 @@ module.exports = {
|
|
144
120
|
web3 = new Web3(process.env['INFURA_TESTNET_ROPSTEN']);
|
145
121
|
NODE_URL = process.env['INFURA_TESTNET_ROPSTEN'];
|
146
122
|
ETHERSCAN = new providers_1.EtherscanProvider('ropsten', process.env['ETHERSCAN_API_KEY']);
|
147
|
-
PROVIDER = new
|
123
|
+
PROVIDER = new ethers.providers.InfuraProvider('ropsten', process.env['INFURA_API_KEY']);
|
148
124
|
}
|
149
125
|
else if (settings.network) {
|
150
126
|
//force a network setting
|
@@ -166,8 +142,8 @@ module.exports = {
|
|
166
142
|
return NODES.push(node);
|
167
143
|
},
|
168
144
|
addNodes: function (nodes) {
|
169
|
-
for (
|
170
|
-
|
145
|
+
for (let i = 0; i < nodes.length; i++) {
|
146
|
+
let node = nodes[i];
|
171
147
|
if (!node.networkId)
|
172
148
|
throw Error('missing networkId');
|
173
149
|
if (!node.service)
|
@@ -193,8 +169,56 @@ module.exports = {
|
|
193
169
|
getFees: function (params) {
|
194
170
|
return get_fees(params);
|
195
171
|
},
|
196
|
-
estimateFee: function (
|
197
|
-
|
172
|
+
estimateFee: async function (asset, params) {
|
173
|
+
if (!params)
|
174
|
+
throw Error("params required");
|
175
|
+
if (!params.asset && !asset)
|
176
|
+
throw Error("Asset or params.asset required");
|
177
|
+
//create asset locally with correct types
|
178
|
+
let assetForEstimate = asset ? asset : params.asset;
|
179
|
+
const { average: averageGP, fast: fastGP, fastest: fastestGP } = (0, utils_1.getDefaultGasPrices)();
|
180
|
+
let assetAddress;
|
181
|
+
// @ts-ignore
|
182
|
+
if (assetForEstimate && (0, xchain_util_1.assetToString)(assetForEstimate) !== (0, xchain_util_1.assetToString)(xchain_util_1.AssetETH)) {
|
183
|
+
// @ts-ignore
|
184
|
+
assetAddress = (0, utils_1.getTokenAddress)(assetForEstimate);
|
185
|
+
}
|
186
|
+
let gasLimit;
|
187
|
+
if (assetAddress && assetAddress !== utils_1.ETHAddress) {
|
188
|
+
if (!params.sender || !params.recipient)
|
189
|
+
throw Error("missing params! need sender and recipient on token tx!");
|
190
|
+
let contract = new ethers.Contract(assetAddress, constant_1.ERC20ABI, PROVIDER);
|
191
|
+
gasLimit = params.data
|
192
|
+
? await contract.estimateGas.transfer(params.recipient, params.data, { from: params.sender })
|
193
|
+
: await contract.estimateGas.transfer(params.recipient, 1, { from: params.sender }); // amount = 1 as a dummy value
|
194
|
+
}
|
195
|
+
else {
|
196
|
+
// ETH transfer
|
197
|
+
if (!params.sender || !params.recipient)
|
198
|
+
throw Error("missing params! need sender and recipient");
|
199
|
+
const gasEstimate = await PROVIDER.estimateGas({
|
200
|
+
from: params.sender,
|
201
|
+
to: params.recipient,
|
202
|
+
value: ethers.utils.parseEther('0.000001') // using dummy ETH amount for gas calculation
|
203
|
+
});
|
204
|
+
gasLimit = gasEstimate.add(0); // Add extra gas as buffer
|
205
|
+
console.log("ETH gasEstimate: ", gasEstimate.toString());
|
206
|
+
console.log("ETH gasEstimate + buffer: ", gasLimit.toString());
|
207
|
+
}
|
208
|
+
return {
|
209
|
+
gasPrices: {
|
210
|
+
average: averageGP,
|
211
|
+
fast: fastGP,
|
212
|
+
fastest: fastestGP
|
213
|
+
},
|
214
|
+
gasLimit,
|
215
|
+
fees: {
|
216
|
+
type: 'byte',
|
217
|
+
average: (0, utils_1.getFee)({ gasPrice: averageGP, gasLimit }),
|
218
|
+
fast: (0, utils_1.getFee)({ gasPrice: fastGP, gasLimit }),
|
219
|
+
fastest: (0, utils_1.getFee)({ gasPrice: fastestGP, gasLimit })
|
220
|
+
}
|
221
|
+
};
|
198
222
|
},
|
199
223
|
getMemoEncoded: function (params) {
|
200
224
|
return get_memo_data(params);
|
@@ -293,542 +317,375 @@ module.exports = {
|
|
293
317
|
broadcastByNetwork: function (networkId, tx) {
|
294
318
|
return broadcast_transaction_by_network(networkId, tx);
|
295
319
|
},
|
296
|
-
blockHeight: function (networkId) {
|
297
|
-
return get_blockheight(networkId);
|
298
|
-
},
|
299
320
|
broadcast: function (tx) {
|
300
321
|
return broadcast_transaction(tx);
|
301
322
|
}
|
302
323
|
};
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
checksumAddress = web3_2.utils.toChecksumAddress(address);
|
351
|
-
return [4 /*yield*/, web3_2.eth.getBlockNumber()];
|
352
|
-
case 2:
|
353
|
-
currentBlockHeight = _f.sent();
|
354
|
-
fromBlock = (options === null || options === void 0 ? void 0 : options.fromBlock) || 0;
|
355
|
-
toBlock = (options === null || options === void 0 ? void 0 : options.toBlock) || "latest";
|
356
|
-
if (toBlock === "latest") {
|
357
|
-
toBlock = currentBlockHeight;
|
358
|
-
}
|
359
|
-
if (fromBlock === "latest") {
|
360
|
-
fromBlock = currentBlockHeight;
|
361
|
-
}
|
362
|
-
// Adjust the range to ensure it scans only the last 100 blocks if the range is too large
|
363
|
-
if (fromBlock < toBlock - 100) {
|
364
|
-
fromBlock = toBlock - 100;
|
324
|
+
const get_transactions_by_network = async function (networkId, address, options = { fromBlock: 'latest', toBlock: 'latest' }) {
|
325
|
+
let tag = TAG + " | get_transactions_by_network | ";
|
326
|
+
try {
|
327
|
+
// Find the node in the NODES array
|
328
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
329
|
+
if (!node)
|
330
|
+
throw new Error("101: Missing node for network " + networkId);
|
331
|
+
// Initialize a new web3 instance
|
332
|
+
let web3 = new Web3(node.service);
|
333
|
+
const checksumAddress = web3.utils.toChecksumAddress(address);
|
334
|
+
// Get the current block height
|
335
|
+
const currentBlockHeight = await web3.eth.getBlockNumber();
|
336
|
+
// Define the block range
|
337
|
+
let fromBlock = options?.fromBlock || 0;
|
338
|
+
let toBlock = options?.toBlock || "latest";
|
339
|
+
if (toBlock === "latest") {
|
340
|
+
toBlock = currentBlockHeight;
|
341
|
+
}
|
342
|
+
if (fromBlock === "latest") {
|
343
|
+
fromBlock = currentBlockHeight;
|
344
|
+
}
|
345
|
+
// Adjust the range to ensure it scans only the last 100 blocks if the range is too large
|
346
|
+
if (fromBlock < toBlock - 100) {
|
347
|
+
fromBlock = toBlock - 100;
|
348
|
+
}
|
349
|
+
log.debug(tag, `Scanning from block ${fromBlock} to block ${toBlock}`);
|
350
|
+
let transactions = [];
|
351
|
+
// Loop through each block in the range
|
352
|
+
for (let blockNumber = fromBlock; blockNumber <= toBlock; blockNumber++) {
|
353
|
+
let block = await web3.eth.getBlock(blockNumber, true); // Retrieve block with full transactions
|
354
|
+
log.debug(tag, "block ", block.transactions.length);
|
355
|
+
if (block && block.transactions) {
|
356
|
+
for (let tx of block.transactions) {
|
357
|
+
// Check if the transaction is initiated by the specified address
|
358
|
+
if (tx.from?.toLowerCase() === checksumAddress.toLowerCase()) {
|
359
|
+
// Collect detailed transaction info
|
360
|
+
let receipt = await web3.eth.getTransactionReceipt(tx.hash);
|
361
|
+
transactions.push({
|
362
|
+
txHash: tx.hash,
|
363
|
+
from: tx.from,
|
364
|
+
to: tx.to,
|
365
|
+
value: tx.value,
|
366
|
+
gas: tx.gas,
|
367
|
+
gasPrice: tx.gasPrice,
|
368
|
+
blockNumber: tx.blockNumber,
|
369
|
+
receipt,
|
370
|
+
});
|
365
371
|
}
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
if (
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
});
|
396
|
-
_f.label = 7;
|
397
|
-
case 7:
|
398
|
-
_i++;
|
399
|
-
return [3 /*break*/, 5];
|
400
|
-
case 8:
|
401
|
-
blockNumber++;
|
402
|
-
return [3 /*break*/, 3];
|
403
|
-
case 9: return [4 /*yield*/, web3_2.eth.getTransactionCount(checksumAddress, "pending")];
|
404
|
-
case 10:
|
405
|
-
currentNonce = _f.sent();
|
406
|
-
return [4 /*yield*/, web3_2.eth.getTransactionCount(checksumAddress, "latest")];
|
407
|
-
case 11:
|
408
|
-
confirmedNonce = _f.sent();
|
409
|
-
log.info(tag, "Current Nonce: ".concat(currentNonce, ", Confirmed Nonce: ").concat(confirmedNonce));
|
410
|
-
hasPendingTransactions = currentNonce > confirmedNonce;
|
411
|
-
if (!hasPendingTransactions) return [3 /*break*/, 13];
|
412
|
-
log.info(tag, "Pending transactions detected");
|
413
|
-
return [4 /*yield*/, web3_2.eth.getBlock("pending", true)];
|
414
|
-
case 12:
|
415
|
-
pendingBlock = _f.sent();
|
416
|
-
if (pendingBlock && pendingBlock.transactions) {
|
417
|
-
for (_d = 0, _e = pendingBlock.transactions; _d < _e.length; _d++) {
|
418
|
-
tx = _e[_d];
|
419
|
-
if (((_b = tx.from) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === checksumAddress.toLowerCase()) {
|
420
|
-
// Collect detailed transaction info
|
421
|
-
transactions.push({
|
422
|
-
txHash: tx.hash,
|
423
|
-
from: tx.from,
|
424
|
-
to: tx.to,
|
425
|
-
value: tx.value,
|
426
|
-
gas: tx.gas,
|
427
|
-
gasPrice: tx.gasPrice,
|
428
|
-
blockNumber: tx.blockNumber, // This will be null for pending transactions
|
429
|
-
receipt: null, // Receipt is not available for pending transactions
|
430
|
-
pending: true,
|
431
|
-
});
|
432
|
-
}
|
433
|
-
}
|
372
|
+
}
|
373
|
+
}
|
374
|
+
}
|
375
|
+
// Fetch current and pending nonces for the address
|
376
|
+
let currentNonce = await web3.eth.getTransactionCount(checksumAddress, "pending");
|
377
|
+
let confirmedNonce = await web3.eth.getTransactionCount(checksumAddress, "latest");
|
378
|
+
log.debug(tag, `Current Nonce: ${currentNonce}, Confirmed Nonce: ${confirmedNonce}`);
|
379
|
+
// Determine if there are pending transactions
|
380
|
+
const hasPendingTransactions = currentNonce > confirmedNonce;
|
381
|
+
if (hasPendingTransactions) {
|
382
|
+
log.debug(tag, "Pending transactions detected");
|
383
|
+
// Fetch the pending transactions from the transaction pool
|
384
|
+
// Note: This requires access to the node's txpool, which may not be available on all nodes
|
385
|
+
let pendingBlock = await web3.eth.getBlock("pending", true);
|
386
|
+
if (pendingBlock && pendingBlock.transactions) {
|
387
|
+
for (let tx of pendingBlock.transactions) {
|
388
|
+
if (tx.from?.toLowerCase() === checksumAddress.toLowerCase()) {
|
389
|
+
// Collect detailed transaction info
|
390
|
+
transactions.push({
|
391
|
+
txHash: tx.hash,
|
392
|
+
from: tx.from,
|
393
|
+
to: tx.to,
|
394
|
+
value: tx.value,
|
395
|
+
gas: tx.gas,
|
396
|
+
gasPrice: tx.gasPrice,
|
397
|
+
blockNumber: tx.blockNumber, // This will be null for pending transactions
|
398
|
+
receipt: null, // Receipt is not available for pending transactions
|
399
|
+
pending: true,
|
400
|
+
});
|
434
401
|
}
|
435
|
-
|
436
|
-
case 13:
|
437
|
-
log.info(tag, "No pending transactions detected");
|
438
|
-
_f.label = 14;
|
439
|
-
case 14: return [2 /*return*/, {
|
440
|
-
address: address,
|
441
|
-
networkId: networkId,
|
442
|
-
fromBlock: fromBlock,
|
443
|
-
toBlock: toBlock,
|
444
|
-
currentBlockHeight: currentBlockHeight,
|
445
|
-
currentNonce: currentNonce,
|
446
|
-
hasPendingTransactions: hasPendingTransactions,
|
447
|
-
transactions: transactions,
|
448
|
-
}];
|
449
|
-
case 15:
|
450
|
-
e_2 = _f.sent();
|
451
|
-
console.error(tag, e_2);
|
452
|
-
throw e_2; // Rethrow the error to handle it upstream
|
453
|
-
case 16: return [2 /*return*/];
|
402
|
+
}
|
454
403
|
}
|
455
|
-
}
|
456
|
-
|
404
|
+
}
|
405
|
+
else {
|
406
|
+
log.debug(tag, "No pending transactions detected");
|
407
|
+
}
|
408
|
+
return {
|
409
|
+
address,
|
410
|
+
networkId,
|
411
|
+
fromBlock,
|
412
|
+
toBlock,
|
413
|
+
currentBlockHeight,
|
414
|
+
currentNonce,
|
415
|
+
hasPendingTransactions,
|
416
|
+
transactions,
|
417
|
+
};
|
418
|
+
}
|
419
|
+
catch (e) {
|
420
|
+
console.error(tag, e);
|
421
|
+
throw e; // Rethrow the error to handle it upstream
|
422
|
+
}
|
457
423
|
};
|
458
424
|
// Broadcast transaction by network
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
})
|
485
|
-
.on('error', function (error) {
|
486
|
-
console.error("Broadcast Error:", error);
|
487
|
-
throw error;
|
488
|
-
})];
|
489
|
-
case 2:
|
490
|
-
result = _a.sent();
|
491
|
-
return [2 /*return*/, result];
|
492
|
-
case 3:
|
493
|
-
e_3 = _a.sent();
|
494
|
-
console.error(tag, e_3);
|
495
|
-
throw e_3;
|
496
|
-
case 4: return [2 /*return*/];
|
497
|
-
}
|
425
|
+
const broadcast_transaction_by_network = async function (networkId, tx) {
|
426
|
+
let tag = TAG + " | broadcast_transaction_by_network | ";
|
427
|
+
try {
|
428
|
+
if (!tx)
|
429
|
+
throw Error("Transaction data required!");
|
430
|
+
// Find the node in the NODES array by networkId
|
431
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
432
|
+
if (!node)
|
433
|
+
throw Error("101: missing node! for network " + networkId);
|
434
|
+
// Initialize new web3 instance with the node's service URL
|
435
|
+
let web3 = new Web3(node.service);
|
436
|
+
// Broadcast transaction and handle transaction lifecycle events
|
437
|
+
let result = await web3.eth.sendSignedTransaction(tx)
|
438
|
+
.on('transactionHash', function (hash) {
|
439
|
+
console.log("Transaction Hash:", hash);
|
440
|
+
})
|
441
|
+
.on('receipt', function (receipt) {
|
442
|
+
console.log("Receipt:", receipt);
|
443
|
+
})
|
444
|
+
.on('confirmation', function (confirmationNumber, receipt) {
|
445
|
+
console.log("Confirmation Number:", confirmationNumber, "Receipt:", receipt);
|
446
|
+
})
|
447
|
+
.on('error', function (error) {
|
448
|
+
console.error("Broadcast Error:", error);
|
449
|
+
throw error;
|
498
450
|
});
|
499
|
-
|
451
|
+
return result;
|
452
|
+
}
|
453
|
+
catch (e) {
|
454
|
+
console.error(tag, e);
|
455
|
+
throw e;
|
456
|
+
}
|
500
457
|
};
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
];
|
521
|
-
case 2:
|
522
|
-
//normal tx info
|
523
|
-
_a.txInfo = _c.sent();
|
524
|
-
//if contract
|
525
|
-
_b = output;
|
526
|
-
return [4 /*yield*/, web3_4.eth.getTransactionReceipt(txid)];
|
527
|
-
case 3:
|
528
|
-
//if contract
|
529
|
-
_b.receipt = _c.sent();
|
530
|
-
return [2 /*return*/, output];
|
531
|
-
case 4:
|
532
|
-
e_4 = _c.sent();
|
533
|
-
console.error(tag, e_4);
|
534
|
-
return [3 /*break*/, 5];
|
535
|
-
case 5: return [2 /*return*/];
|
536
|
-
}
|
537
|
-
});
|
538
|
-
});
|
458
|
+
const get_transaction_by_network = async function (networkId, txid) {
|
459
|
+
let tag = TAG + " | get_transaction | ";
|
460
|
+
try {
|
461
|
+
// Find the node in NODES array
|
462
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
463
|
+
if (!node)
|
464
|
+
throw Error("101: missing node! for network " + networkId);
|
465
|
+
// Initialize new web3 instance
|
466
|
+
let web3 = new Web3(node.service);
|
467
|
+
let output = {};
|
468
|
+
//normal tx info
|
469
|
+
output.txInfo = await web3.eth.getTransaction(txid);
|
470
|
+
//if contract
|
471
|
+
output.receipt = await web3.eth.getTransactionReceipt(txid);
|
472
|
+
return output;
|
473
|
+
}
|
474
|
+
catch (e) {
|
475
|
+
console.error(tag, e);
|
476
|
+
}
|
539
477
|
};
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
return [2 /*return*/, gasPrice];
|
558
|
-
case 3:
|
559
|
-
e_5 = _a.sent();
|
560
|
-
console.error(tag, e_5);
|
561
|
-
throw e_5;
|
562
|
-
case 4: return [2 /*return*/];
|
563
|
-
}
|
564
|
-
});
|
565
|
-
});
|
478
|
+
const get_gas_price_by_network = async function (networkId) {
|
479
|
+
let tag = TAG + " | get_gas_price_by_network | ";
|
480
|
+
try {
|
481
|
+
// Find the node in NODES array
|
482
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
483
|
+
if (!node)
|
484
|
+
throw Error("101: missing node! for network " + networkId);
|
485
|
+
// Initialize new web3 instance
|
486
|
+
let web3 = new Web3(node.service);
|
487
|
+
// Get gas price
|
488
|
+
let gasPrice = await web3.eth.getGasPrice();
|
489
|
+
return gasPrice;
|
490
|
+
}
|
491
|
+
catch (e) {
|
492
|
+
console.error(tag, e);
|
493
|
+
throw e;
|
494
|
+
}
|
566
495
|
};
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
return [2 /*return*/, nonce];
|
587
|
-
case 3:
|
588
|
-
e_6 = _a.sent();
|
589
|
-
console.error(tag, e_6);
|
590
|
-
throw e_6;
|
591
|
-
case 4: return [2 /*return*/];
|
592
|
-
}
|
593
|
-
});
|
594
|
-
});
|
496
|
+
const get_nonce_by_network = async function (networkId, address) {
|
497
|
+
let tag = TAG + " | get_nonce_by_network | ";
|
498
|
+
try {
|
499
|
+
if (!address)
|
500
|
+
throw Error("Address required!");
|
501
|
+
// Find the node in NODES array
|
502
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
503
|
+
if (!node)
|
504
|
+
throw Error("101: missing node! for network " + networkId);
|
505
|
+
// Initialize new web3 instance
|
506
|
+
let web3 = new Web3(node.service);
|
507
|
+
// Get nonce (transaction count)
|
508
|
+
let nonce = await web3.eth.getTransactionCount(address, 'pending');
|
509
|
+
return nonce;
|
510
|
+
}
|
511
|
+
catch (e) {
|
512
|
+
console.error(tag, e);
|
513
|
+
throw e;
|
514
|
+
}
|
595
515
|
};
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
return [2 /*return*/, gas];
|
616
|
-
case 3:
|
617
|
-
e_7 = _a.sent();
|
618
|
-
console.error(tag, e_7);
|
619
|
-
throw e_7;
|
620
|
-
case 4: return [2 /*return*/];
|
621
|
-
}
|
622
|
-
});
|
623
|
-
});
|
516
|
+
const estimate_gas_by_network = async function (networkId, transaction) {
|
517
|
+
let tag = TAG + " | estimate_gas_by_network | ";
|
518
|
+
try {
|
519
|
+
if (!transaction)
|
520
|
+
throw Error("Transaction object required!");
|
521
|
+
// Find the node in NODES array
|
522
|
+
let node = NODES.find((n) => n.networkId === networkId);
|
523
|
+
if (!node)
|
524
|
+
throw Error("101: missing node! for network " + networkId);
|
525
|
+
// Initialize new web3 instance
|
526
|
+
let web3 = new Web3(node.service);
|
527
|
+
// Estimate gas
|
528
|
+
let gas = await web3.eth.estimateGas(transaction);
|
529
|
+
return gas;
|
530
|
+
}
|
531
|
+
catch (e) {
|
532
|
+
console.error(tag, e);
|
533
|
+
throw e;
|
534
|
+
}
|
624
535
|
};
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
owner = _a.sent();
|
655
|
-
log.debug(tag, "owner: ", owner);
|
656
|
-
output['owners'].push(owner.toLowerCase());
|
657
|
-
return [4 /*yield*/, metadataContract.methods.getAttributes(i).call()];
|
658
|
-
case 6:
|
659
|
-
imageInfo = _a.sent();
|
660
|
-
imageName = JSON.parse(imageInfo['0'])["0-backgrounds"];
|
661
|
-
baseImageUrl = "https://ipfs.io/ipfs/bafybeiezdzjofkcpiwy5hlvxwzkgcztxc6xtodh3q7eddfjmqsguqs47aa/0-backgrounds/";
|
662
|
-
fullImageUrl = baseImageUrl + imageName + ".png";
|
663
|
-
// Add this image URL to the images array in output
|
664
|
-
output['images'].push({ address: owner.toLowerCase(), image: fullImageUrl });
|
665
|
-
return [3 /*break*/, 8];
|
666
|
-
case 7:
|
667
|
-
e_8 = _a.sent();
|
668
|
-
log.debug("no image for: ", i);
|
669
|
-
return [3 /*break*/, 8];
|
670
|
-
case 8:
|
671
|
-
i++;
|
672
|
-
return [3 /*break*/, 3];
|
673
|
-
case 9: return [2 /*return*/, output];
|
674
|
-
case 10:
|
675
|
-
e_9 = _a.sent();
|
676
|
-
console.error(tag, e_9);
|
677
|
-
return [3 /*break*/, 11];
|
678
|
-
case 11: return [2 /*return*/];
|
536
|
+
const get_all_pioneers = async function () {
|
537
|
+
let tag = TAG + " | get_all_pioneers | ";
|
538
|
+
try {
|
539
|
+
let output = {};
|
540
|
+
const nftContract = new web3.eth.Contract(constant_1.ERC721_ABI, constant_1.PIONEER_CONTRACT_ADDRESS);
|
541
|
+
const metadataContract = new web3.eth.Contract(constant_1.METADATA_ABI, constant_1.PIONEER_METADATA_CONTRACT_ADDRESS);
|
542
|
+
// Fetch the total supply of the NFTs
|
543
|
+
const totalSupply = await nftContract.methods.totalSupply().call();
|
544
|
+
log.debug("totalSupply: ", totalSupply);
|
545
|
+
output['totalSupply'] = totalSupply;
|
546
|
+
output['owners'] = [];
|
547
|
+
output['images'] = []; // add an images array to output
|
548
|
+
for (let i = 0; i < totalSupply; i++) {
|
549
|
+
//slow down
|
550
|
+
// await sleep(1000);
|
551
|
+
try {
|
552
|
+
const owner = await nftContract.methods.ownerOf(i).call();
|
553
|
+
log.debug(tag, "owner: ", owner);
|
554
|
+
output['owners'].push(owner.toLowerCase());
|
555
|
+
//get images
|
556
|
+
const imageInfo = await metadataContract.methods.getAttributes(i).call();
|
557
|
+
//log.debug(tag,"imageInfo: ",imageInfo)
|
558
|
+
// Parse the JSON string and get the image name
|
559
|
+
const imageName = JSON.parse(imageInfo['0'])["0-backgrounds"];
|
560
|
+
// Build the full image URL by replacing the image name in the base URL
|
561
|
+
const baseImageUrl = "https://ipfs.io/ipfs/bafybeiezdzjofkcpiwy5hlvxwzkgcztxc6xtodh3q7eddfjmqsguqs47aa/0-backgrounds/";
|
562
|
+
const fullImageUrl = baseImageUrl + imageName + ".png";
|
563
|
+
// Add this image URL to the images array in output
|
564
|
+
output['images'].push({ address: owner.toLowerCase(), image: fullImageUrl });
|
679
565
|
}
|
680
|
-
|
681
|
-
|
682
|
-
};
|
683
|
-
var get_all_pioneers_base = function () {
|
684
|
-
return __awaiter(this, void 0, void 0, function () {
|
685
|
-
var tag, output, nftContract, metadataContract, totalSupply, i, owner, imageInfo, imageName, baseImageUrl, fullImageUrl, e_10, e_11;
|
686
|
-
return __generator(this, function (_a) {
|
687
|
-
switch (_a.label) {
|
688
|
-
case 0:
|
689
|
-
tag = TAG + " | get_all_pioneers_base | ";
|
690
|
-
_a.label = 1;
|
691
|
-
case 1:
|
692
|
-
_a.trys.push([1, 10, , 11]);
|
693
|
-
output = {};
|
694
|
-
log.info(tag, "PIONEER_CONTRACT_ADDRESS_BASE: ", constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
695
|
-
nftContract = new web3Base.eth.Contract(constant_1.ERC721_ABI, constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
696
|
-
metadataContract = new web3Base.eth.Contract(constant_1.METADATA_ABI, constant_1.PIONEER_METADATA_CONTRACT_ADDRESS_BASE);
|
697
|
-
return [4 /*yield*/, nftContract.methods.totalSupply().call()];
|
698
|
-
case 2:
|
699
|
-
totalSupply = _a.sent();
|
700
|
-
log.info("totalSupply: ", totalSupply);
|
701
|
-
output['totalSupply'] = totalSupply;
|
702
|
-
output['owners'] = [];
|
703
|
-
output['images'] = []; // add an images array to output
|
704
|
-
i = 0;
|
705
|
-
_a.label = 3;
|
706
|
-
case 3:
|
707
|
-
if (!(i < totalSupply)) return [3 /*break*/, 9];
|
708
|
-
_a.label = 4;
|
709
|
-
case 4:
|
710
|
-
_a.trys.push([4, 7, , 8]);
|
711
|
-
return [4 /*yield*/, nftContract.methods.ownerOf(i).call()];
|
712
|
-
case 5:
|
713
|
-
owner = _a.sent();
|
714
|
-
log.info(tag, "owner: ", owner);
|
715
|
-
output['owners'].push(owner.toLowerCase());
|
716
|
-
return [4 /*yield*/, metadataContract.methods.getAttributes(i).call()];
|
717
|
-
case 6:
|
718
|
-
imageInfo = _a.sent();
|
719
|
-
log.info(tag, "imageInfo: ", imageInfo);
|
720
|
-
imageName = JSON.parse(imageInfo['0'])["0-backgrounds"];
|
721
|
-
baseImageUrl = "https://ipfs.io/ipfs/bafybeiezdzjofkcpiwy5hlvxwzkgcztxc6xtodh3q7eddfjmqsguqs47aa/0-backgrounds/";
|
722
|
-
fullImageUrl = baseImageUrl + imageName + ".png";
|
723
|
-
// Add this image URL to the images array in output
|
724
|
-
output['images'].push({ address: owner.toLowerCase(), image: fullImageUrl });
|
725
|
-
return [3 /*break*/, 8];
|
726
|
-
case 7:
|
727
|
-
e_10 = _a.sent();
|
728
|
-
log.debug("no image for: ", i);
|
729
|
-
return [3 /*break*/, 8];
|
730
|
-
case 8:
|
731
|
-
i++;
|
732
|
-
return [3 /*break*/, 3];
|
733
|
-
case 9: return [2 /*return*/, output];
|
734
|
-
case 10:
|
735
|
-
e_11 = _a.sent();
|
736
|
-
console.error(tag, e_11);
|
737
|
-
return [3 /*break*/, 11];
|
738
|
-
case 11: return [2 /*return*/];
|
566
|
+
catch (e) {
|
567
|
+
log.debug("no image for: ", i);
|
739
568
|
}
|
740
|
-
}
|
741
|
-
|
569
|
+
}
|
570
|
+
return output;
|
571
|
+
}
|
572
|
+
catch (e) {
|
573
|
+
console.error(tag, e);
|
574
|
+
}
|
742
575
|
};
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
576
|
+
const get_all_pioneers_base = async function () {
|
577
|
+
let tag = TAG + " | get_all_pioneers_base | ";
|
578
|
+
try {
|
579
|
+
let output = {};
|
580
|
+
log.debug(tag, "PIONEER_CONTRACT_ADDRESS_BASE: ", constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
581
|
+
const nftContract = new web3Base.eth.Contract(constant_1.ERC721_ABI, constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
582
|
+
const metadataContract = new web3Base.eth.Contract(constant_1.METADATA_ABI, constant_1.PIONEER_METADATA_CONTRACT_ADDRESS_BASE);
|
583
|
+
// Fetch the total supply of the NFTs
|
584
|
+
const totalSupply = await nftContract.methods.totalSupply().call();
|
585
|
+
log.debug("totalSupply: ", totalSupply);
|
586
|
+
output['totalSupply'] = totalSupply;
|
587
|
+
output['owners'] = [];
|
588
|
+
output['images'] = []; // add an images array to output
|
589
|
+
for (let i = 0; i < totalSupply; i++) {
|
590
|
+
//slow down
|
591
|
+
// await sleep(1000);
|
748
592
|
try {
|
749
|
-
|
750
|
-
|
593
|
+
const owner = await nftContract.methods.ownerOf(i).call();
|
594
|
+
log.debug(tag, "owner: ", owner);
|
595
|
+
output['owners'].push(owner.toLowerCase());
|
596
|
+
//get images
|
597
|
+
const imageInfo = await metadataContract.methods.getAttributes(i).call();
|
598
|
+
log.debug(tag, "imageInfo: ", imageInfo);
|
599
|
+
// Parse the JSON string and get the image name
|
600
|
+
const imageName = JSON.parse(imageInfo['0'])["0-backgrounds"];
|
601
|
+
// Build the full image URL by replacing the image name in the base URL
|
602
|
+
const baseImageUrl = "https://ipfs.io/ipfs/bafybeiezdzjofkcpiwy5hlvxwzkgcztxc6xtodh3q7eddfjmqsguqs47aa/0-backgrounds/";
|
603
|
+
const fullImageUrl = baseImageUrl + imageName + ".png";
|
604
|
+
// Add this image URL to the images array in output
|
605
|
+
output['images'].push({ address: owner.toLowerCase(), image: fullImageUrl });
|
751
606
|
}
|
752
607
|
catch (e) {
|
753
|
-
|
608
|
+
log.debug("no image for: ", i);
|
754
609
|
}
|
755
|
-
|
756
|
-
|
757
|
-
}
|
610
|
+
}
|
611
|
+
return output;
|
612
|
+
}
|
613
|
+
catch (e) {
|
614
|
+
console.error(tag, e);
|
615
|
+
}
|
758
616
|
};
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
_a.trys.push([1, 3, , 4]);
|
769
|
-
airdropContract = new web3.eth.Contract(constant_1.AIRDROP_ABI, constant_1.AIRDROP_CONTRACT);
|
770
|
-
return [4 /*yield*/, axios({ method: 'GET', url: constant_1.CLAIM_URL + '/' + address })
|
771
|
-
//console.log("accountInfo: ",accountInfo)
|
772
|
-
];
|
773
|
-
case 2:
|
774
|
-
accountInfo = _a.sent();
|
775
|
-
//console.log("accountInfo: ",accountInfo)
|
776
|
-
if (!accountInfo.data.index)
|
777
|
-
throw Error("Not found in db! ");
|
778
|
-
AirDropInterface = new abi_1.Interface(constant_1.AIRDROP_ABI);
|
779
|
-
data = AirDropInterface.encodeFunctionData('claim', [
|
780
|
-
accountInfo.data.index,
|
781
|
-
address,
|
782
|
-
'0x0821ab0d4414980000',
|
783
|
-
accountInfo.data.proof
|
784
|
-
]);
|
785
|
-
return [2 /*return*/, data];
|
786
|
-
case 3:
|
787
|
-
e_12 = _a.sent();
|
788
|
-
console.error(tag, e_12);
|
789
|
-
return [3 /*break*/, 4];
|
790
|
-
case 4: return [2 /*return*/];
|
791
|
-
}
|
792
|
-
});
|
793
|
-
});
|
617
|
+
const decode_tx = async function (tx) {
|
618
|
+
let tag = TAG + " | decode_tx | ";
|
619
|
+
try {
|
620
|
+
const data = ethers.utils.parseTransaction(tx);
|
621
|
+
return data;
|
622
|
+
}
|
623
|
+
catch (e) {
|
624
|
+
console.error(tag, e);
|
625
|
+
}
|
794
626
|
};
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
627
|
+
const build_airdrop_claim = async function (address) {
|
628
|
+
let tag = TAG + " | build_airdrop_claim | ";
|
629
|
+
try {
|
630
|
+
const airdropContract = new web3.eth.Contract(constant_1.AIRDROP_ABI, constant_1.AIRDROP_CONTRACT);
|
631
|
+
let accountInfo = await axios({ method: 'GET', url: constant_1.CLAIM_URL + '/' + address });
|
632
|
+
//console.log("accountInfo: ",accountInfo)
|
633
|
+
if (!accountInfo.data.index)
|
634
|
+
throw Error("Not found in db! ");
|
635
|
+
//
|
636
|
+
//console.log("airdropContract: ",accountInfo.data.contract)
|
637
|
+
const AirDropInterface = new abi_1.Interface(constant_1.AIRDROP_ABI);
|
638
|
+
// const data = airdropContract.methods.claim(
|
639
|
+
// accountInfo.data.index,
|
640
|
+
// address,
|
641
|
+
// 150,
|
642
|
+
// accountInfo.data.proof
|
643
|
+
// )
|
644
|
+
// console.log("airdropContract: ",[
|
645
|
+
// accountInfo.data.index as number,
|
646
|
+
// address,
|
647
|
+
// '0x0821ab0d4414980000',
|
648
|
+
// accountInfo.data.proof
|
649
|
+
// ])
|
650
|
+
const data = AirDropInterface.encodeFunctionData('claim', [
|
651
|
+
accountInfo.data.index,
|
652
|
+
address,
|
653
|
+
'0x0821ab0d4414980000',
|
654
|
+
accountInfo.data.proof
|
655
|
+
]);
|
656
|
+
return data;
|
657
|
+
}
|
658
|
+
catch (e) {
|
659
|
+
console.error(tag, e);
|
660
|
+
}
|
661
|
+
};
|
662
|
+
const check_airdrop_claim = async function (address) {
|
663
|
+
let tag = TAG + " | check_airdrop_claim | ";
|
664
|
+
try {
|
665
|
+
//
|
666
|
+
let accountInfo = await axios({ method: 'GET', url: constant_1.CLAIM_URL + '/' + address });
|
667
|
+
//console.log("accountInfo: ",accountInfo)
|
668
|
+
let output = {};
|
669
|
+
if (accountInfo.data.index) {
|
670
|
+
output.isElgible = true;
|
671
|
+
output.contract = accountInfo.data.contractAddress;
|
672
|
+
//get index?
|
673
|
+
//check contract
|
674
|
+
//const AirDropInterface = new Interface(AirDropABI)
|
675
|
+
const airdropContract = new web3.eth.Contract(constant_1.AIRDROP_ABI, accountInfo.data.contractAddress);
|
676
|
+
//get index by address?
|
677
|
+
//log.debug("index: ",accountInfo.data.index)
|
678
|
+
let isClaimed = await airdropContract.methods.isClaimed(accountInfo.data.index).call();
|
679
|
+
output.isClaimed = isClaimed;
|
680
|
+
}
|
681
|
+
else {
|
682
|
+
output.isElgible = false;
|
683
|
+
}
|
684
|
+
return output;
|
685
|
+
}
|
686
|
+
catch (e) {
|
687
|
+
console.error(tag, e);
|
688
|
+
}
|
832
689
|
};
|
833
690
|
// const get_token_transfer_data = async function(toAddress: string, amount: string, contract: string) {
|
834
691
|
// const tag = TAG + " | get_token_transfer_data | ";
|
@@ -940,64 +797,56 @@ var check_airdrop_claim = function (address) {
|
|
940
797
|
// console.error(tag, e);
|
941
798
|
// }
|
942
799
|
// }
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
// decimals
|
963
|
-
{
|
964
|
-
"constant": true,
|
965
|
-
"inputs": [],
|
966
|
-
"name": "decimals",
|
967
|
-
"outputs": [{ "name": "", "type": "uint8" }],
|
968
|
-
"type": "function"
|
969
|
-
}
|
970
|
-
];
|
971
|
-
newContract = new web3.eth.Contract(minABI, contract);
|
972
|
-
return [4 /*yield*/, newContract.methods.decimals().call()];
|
973
|
-
case 2:
|
974
|
-
decimalPlaces = _a.sent();
|
975
|
-
amountInSmallestUnit = web3.utils.toBN(parseFloat(amount) * Math.pow(10, decimalPlaces));
|
976
|
-
amountHex = amountInSmallestUnit.toString(16);
|
977
|
-
amountHexPadded = amountHex.padStart(64, '0');
|
978
|
-
tokenData = web3.eth.abi.encodeFunctionCall({
|
979
|
-
name: 'transfer',
|
980
|
-
type: 'function',
|
981
|
-
inputs: [
|
982
|
-
{
|
983
|
-
type: 'address',
|
984
|
-
name: '_to'
|
985
|
-
},
|
986
|
-
{
|
987
|
-
type: 'uint256',
|
988
|
-
name: '_value'
|
989
|
-
}
|
990
|
-
]
|
991
|
-
}, [toAddress, amountInSmallestUnit.toString()]);
|
992
|
-
return [2 /*return*/, tokenData];
|
993
|
-
case 3:
|
994
|
-
e_14 = _a.sent();
|
995
|
-
console.error(tag, e_14);
|
996
|
-
return [3 /*break*/, 4];
|
997
|
-
case 4: return [2 /*return*/];
|
800
|
+
const get_token_transfer_data = async function (toAddress, amount, contract) {
|
801
|
+
const tag = TAG + " | get_token_transfer_data | ";
|
802
|
+
try {
|
803
|
+
const minABI = [
|
804
|
+
// balanceOf
|
805
|
+
{
|
806
|
+
"constant": true,
|
807
|
+
"inputs": [{ "name": "_owner", "type": "address" }],
|
808
|
+
"name": "balanceOf",
|
809
|
+
"outputs": [{ "name": "balance", "type": "uint256" }],
|
810
|
+
"type": "function"
|
811
|
+
},
|
812
|
+
// decimals
|
813
|
+
{
|
814
|
+
"constant": true,
|
815
|
+
"inputs": [],
|
816
|
+
"name": "decimals",
|
817
|
+
"outputs": [{ "name": "", "type": "uint8" }],
|
818
|
+
"type": "function"
|
998
819
|
}
|
999
|
-
|
1000
|
-
|
820
|
+
];
|
821
|
+
const newContract = new web3.eth.Contract(minABI, contract);
|
822
|
+
const decimalPlaces = await newContract.methods.decimals().call();
|
823
|
+
// Convert amount to the appropriate number of decimal places
|
824
|
+
// Note: we're assuming 'amount' is a string representing a decimal number
|
825
|
+
const amountInSmallestUnit = web3.utils.toBN(parseFloat(amount) * Math.pow(10, decimalPlaces));
|
826
|
+
// Convert the amount to a hexadecimal string
|
827
|
+
const amountHex = amountInSmallestUnit.toString(16);
|
828
|
+
// Pad the hexadecimal string with zeros to 64 characters
|
829
|
+
const amountHexPadded = amountHex.padStart(64, '0');
|
830
|
+
// Parse the token data
|
831
|
+
const tokenData = web3.eth.abi.encodeFunctionCall({
|
832
|
+
name: 'transfer',
|
833
|
+
type: 'function',
|
834
|
+
inputs: [
|
835
|
+
{
|
836
|
+
type: 'address',
|
837
|
+
name: '_to'
|
838
|
+
},
|
839
|
+
{
|
840
|
+
type: 'uint256',
|
841
|
+
name: '_value'
|
842
|
+
}
|
843
|
+
]
|
844
|
+
}, [toAddress, amountInSmallestUnit.toString()]);
|
845
|
+
return tokenData;
|
846
|
+
}
|
847
|
+
catch (e) {
|
848
|
+
console.error(tag, e);
|
849
|
+
}
|
1001
850
|
};
|
1002
851
|
// //get_token_transfer_data
|
1003
852
|
// const get_token_transfer_data = async function(toAddress:string, amount:string, contract:string){
|
@@ -1063,330 +912,207 @@ var get_token_transfer_data = function (toAddress, amount, contract) {
|
|
1063
912
|
// console.error(tag,e)
|
1064
913
|
// }
|
1065
914
|
// }
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
case 2:
|
1081
|
-
tokenName = _a.sent();
|
1082
|
-
//log.debug(tag,"tokenName: ",tokenName)
|
1083
|
-
return [2 /*return*/, tokenName];
|
1084
|
-
case 3:
|
1085
|
-
e_15 = _a.sent();
|
1086
|
-
console.error(tag, e_15);
|
1087
|
-
return [3 /*break*/, 4];
|
1088
|
-
case 4: return [2 /*return*/];
|
1089
|
-
}
|
1090
|
-
});
|
1091
|
-
});
|
915
|
+
const get_symbol_from_contract = async function (address) {
|
916
|
+
let tag = TAG + " | get_symbol_from_contract | ";
|
917
|
+
try {
|
918
|
+
//get total LP tokens
|
919
|
+
//LP token
|
920
|
+
const contract = new web3.eth.Contract(constant_1.ERC20ABI, address);
|
921
|
+
//log.debug(tag,"contract: ",contract)
|
922
|
+
let tokenName = await contract.methods.name().call();
|
923
|
+
//log.debug(tag,"tokenName: ",tokenName)
|
924
|
+
return tokenName;
|
925
|
+
}
|
926
|
+
catch (e) {
|
927
|
+
console.error(tag, e);
|
928
|
+
}
|
1092
929
|
};
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
];
|
1110
|
-
case 2:
|
1111
|
-
totalFox = _a.sent();
|
1112
|
-
//log.debug(tag,"totalFox: ",totalFox)
|
1113
|
-
return [2 /*return*/, totalFox];
|
1114
|
-
case 3:
|
1115
|
-
e_16 = _a.sent();
|
1116
|
-
console.error(tag, e_16);
|
1117
|
-
return [3 /*break*/, 4];
|
1118
|
-
case 4: return [2 /*return*/];
|
1119
|
-
}
|
1120
|
-
});
|
1121
|
-
});
|
930
|
+
const get_stream = async function (streamId) {
|
931
|
+
let tag = TAG + " | get_stream | ";
|
932
|
+
try {
|
933
|
+
//get total LP tokens
|
934
|
+
//LP token
|
935
|
+
const sablierContract = new web3.eth.Contract(constant_1.SABLIER_ABI, constant_1.PROXY_CONTRACT_SABLIER);
|
936
|
+
//log.debug(tag,"sablierContract: ",sablierContract)
|
937
|
+
//log.debug(tag,"streamId: ",streamId)
|
938
|
+
streamId = parseInt(streamId);
|
939
|
+
let totalFox = await sablierContract.methods.getSalary(streamId).call();
|
940
|
+
//log.debug(tag,"totalFox: ",totalFox)
|
941
|
+
return totalFox;
|
942
|
+
}
|
943
|
+
catch (e) {
|
944
|
+
console.error(tag, e);
|
945
|
+
}
|
1122
946
|
};
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
case 3:
|
1145
|
-
txsWithPending = _a.sent();
|
1146
|
-
pending = txsConfirmed - txsWithPending;
|
1147
|
-
return [2 /*return*/, {
|
1148
|
-
confirmed: txsConfirmed,
|
1149
|
-
total: txsWithPending,
|
1150
|
-
pending: pending
|
1151
|
-
}];
|
1152
|
-
case 4:
|
1153
|
-
e_17 = _a.sent();
|
1154
|
-
console.error(tag, e_17);
|
1155
|
-
return [3 /*break*/, 5];
|
1156
|
-
case 5: return [2 /*return*/];
|
1157
|
-
}
|
1158
|
-
});
|
1159
|
-
});
|
947
|
+
const get_tx_count = async function (address, options) {
|
948
|
+
let tag = TAG + " | get_tx_count | ";
|
949
|
+
try {
|
950
|
+
log.debug(tag, "address: ", address);
|
951
|
+
if (!address)
|
952
|
+
throw Error("102: address required!");
|
953
|
+
//confirmed
|
954
|
+
let txsConfirmed = await web3.eth.getTransactionCount(address);
|
955
|
+
//pending
|
956
|
+
let txsWithPending = await web3.eth.getTransactionCount(address, 'pending');
|
957
|
+
//count pending
|
958
|
+
let pending = txsConfirmed - txsWithPending;
|
959
|
+
return {
|
960
|
+
confirmed: txsConfirmed,
|
961
|
+
total: txsWithPending,
|
962
|
+
pending
|
963
|
+
};
|
964
|
+
}
|
965
|
+
catch (e) {
|
966
|
+
console.error(tag, e);
|
967
|
+
}
|
1160
968
|
};
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
case 5:
|
1197
|
-
e_18 = _a.sent();
|
1198
|
-
console.error(tag, e_18);
|
1199
|
-
return [3 /*break*/, 6];
|
1200
|
-
case 6: return [2 /*return*/];
|
1201
|
-
}
|
1202
|
-
});
|
1203
|
-
});
|
969
|
+
const get_pool_percent = async function (amountFox, amountEth, poolAddress) {
|
970
|
+
let tag = TAG + " | get_pool_percent | ";
|
971
|
+
try {
|
972
|
+
//get total LP tokens
|
973
|
+
//LP token
|
974
|
+
const lpContract = new web3.eth.Contract(constant_1.ERC20ABI, constant_1.UNISWAP_V2_WETH_FOX_POOL_ADDRESS);
|
975
|
+
const foxContract = new web3.eth.Contract(constant_1.ERC20ABI, constant_1.FOX_TOKEN_CONTRACT_ADDRESS);
|
976
|
+
const wethContract = new web3.eth.Contract(constant_1.ERC20ABI, constant_1.WETH_TOKEN_CONTRACT_ADDRESS);
|
977
|
+
//log.debug("lpContract: ",lpContract)
|
978
|
+
let totalSupply = await lpContract.methods.totalSupply().call();
|
979
|
+
totalSupply = totalSupply / BASE;
|
980
|
+
log.debug("LP totalSupply: ", totalSupply);
|
981
|
+
//get total fox in pool
|
982
|
+
let totalFox = await foxContract.methods.balanceOf(constant_1.UNISWAP_V2_WETH_FOX_POOL_ADDRESS).call();
|
983
|
+
totalFox = totalFox / BASE;
|
984
|
+
log.debug("totalFox: ", totalFox / BASE);
|
985
|
+
//get total eth in pool
|
986
|
+
let totalEth = await wethContract.methods.balanceOf(constant_1.UNISWAP_V2_WETH_FOX_POOL_ADDRESS).call();
|
987
|
+
totalEth = totalEth / BASE;
|
988
|
+
log.debug("totalEth: ", totalEth);
|
989
|
+
//token math
|
990
|
+
let result = totalFox / totalEth;
|
991
|
+
log.debug("result: ", result);
|
992
|
+
//balance
|
993
|
+
let lpTokens = (amountFox * totalSupply) / totalFox;
|
994
|
+
log.debug("lpTokens: ", lpTokens);
|
995
|
+
//total LP tokens
|
996
|
+
//liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
|
997
|
+
let percent = (lpTokens / totalSupply) * 100;
|
998
|
+
log.debug("percent: ", percent);
|
999
|
+
return percent;
|
1000
|
+
}
|
1001
|
+
catch (e) {
|
1002
|
+
console.error(tag, e);
|
1003
|
+
}
|
1204
1004
|
};
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
balance = entry.result;
|
1233
|
-
balance = Web3Utils.hexToNumberString(balance);
|
1234
|
-
balance = balance / BASE;
|
1235
|
-
output.push(balance);
|
1236
|
-
}
|
1237
|
-
return [2 /*return*/, output];
|
1238
|
-
case 3:
|
1239
|
-
e_19 = _a.sent();
|
1240
|
-
console.error(tag, e_19);
|
1241
|
-
return [3 /*break*/, 4];
|
1242
|
-
case 4: return [2 /*return*/];
|
1243
|
-
}
|
1244
|
-
});
|
1245
|
-
});
|
1005
|
+
const get_balances = async function (addresses) {
|
1006
|
+
let tag = TAG + " | get_balances | ";
|
1007
|
+
try {
|
1008
|
+
let actions = [];
|
1009
|
+
for (let i = 0; i < addresses.length; i++) {
|
1010
|
+
let address = addresses[i];
|
1011
|
+
let action = {
|
1012
|
+
method: "eth_getBalance",
|
1013
|
+
params: [address]
|
1014
|
+
};
|
1015
|
+
actions.push(action);
|
1016
|
+
}
|
1017
|
+
let result = await rpcCallBatch(actions);
|
1018
|
+
//covert
|
1019
|
+
let output = [];
|
1020
|
+
for (let i = 0; i < result.length; i++) {
|
1021
|
+
let entry = result[i];
|
1022
|
+
let balance = entry.result;
|
1023
|
+
balance = Web3Utils.hexToNumberString(balance);
|
1024
|
+
balance = balance / BASE;
|
1025
|
+
output.push(balance);
|
1026
|
+
}
|
1027
|
+
return output;
|
1028
|
+
}
|
1029
|
+
catch (e) {
|
1030
|
+
console.error(tag, e);
|
1031
|
+
}
|
1246
1032
|
};
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
"jsonrpc": "2.0",
|
1261
|
-
"method": action.method,
|
1262
|
-
"params": action.params,
|
1263
|
-
"id": 1
|
1264
|
-
};
|
1265
|
-
body.push(req);
|
1266
|
-
}
|
1267
|
-
options = {
|
1268
|
-
method: "POST",
|
1269
|
-
url: NODE_URL,
|
1270
|
-
headers: { 'content-type': 'application/json' },
|
1271
|
-
body: JSON.stringify(body)
|
1272
|
-
};
|
1273
|
-
return [4 /*yield*/, request(options)];
|
1274
|
-
case 2:
|
1275
|
-
result = _a.sent();
|
1276
|
-
//console.log("result: ",result)
|
1277
|
-
result = JSON.parse(result);
|
1278
|
-
if (result.error)
|
1279
|
-
throw JSON.stringify(result.error);
|
1280
|
-
return [2 /*return*/, result];
|
1281
|
-
case 3:
|
1282
|
-
err_1 = _a.sent();
|
1283
|
-
throw new Error(err_1);
|
1284
|
-
case 4: return [2 /*return*/];
|
1033
|
+
const rpcCallBatch = async (actions) => {
|
1034
|
+
let tag = TAG + " | post_request | ";
|
1035
|
+
try {
|
1036
|
+
let body = [];
|
1037
|
+
for (let i = 0; i < actions.length; i++) {
|
1038
|
+
let action = actions[i];
|
1039
|
+
let req = {
|
1040
|
+
"jsonrpc": "2.0",
|
1041
|
+
"method": action.method,
|
1042
|
+
"params": action.params,
|
1043
|
+
"id": 1
|
1044
|
+
};
|
1045
|
+
body.push(req);
|
1285
1046
|
}
|
1286
|
-
|
1287
|
-
|
1047
|
+
let options = {
|
1048
|
+
method: "POST",
|
1049
|
+
url: NODE_URL,
|
1050
|
+
headers: { 'content-type': 'application/json' },
|
1051
|
+
body: JSON.stringify(body)
|
1052
|
+
};
|
1053
|
+
//console.log("options: ",options)
|
1054
|
+
let result = await request(options);
|
1055
|
+
//console.log("result: ",result)
|
1056
|
+
result = JSON.parse(result);
|
1057
|
+
if (result.error)
|
1058
|
+
throw JSON.stringify(result.error);
|
1059
|
+
return result;
|
1060
|
+
}
|
1061
|
+
catch (err) {
|
1062
|
+
throw new Error(err);
|
1063
|
+
}
|
1064
|
+
};
|
1288
1065
|
//get_approval_status
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
contract = new web3.eth.Contract(constant_1.ERC20ABI, tokenAddress);
|
1300
|
-
return [4 /*yield*/, contract.methods.allowance(spender, sender).call()];
|
1301
|
-
case 2:
|
1302
|
-
allowance = _a.sent();
|
1303
|
-
return [2 /*return*/, allowance];
|
1304
|
-
case 3:
|
1305
|
-
e_20 = _a.sent();
|
1306
|
-
console.error(tag, e_20);
|
1307
|
-
return [3 /*break*/, 4];
|
1308
|
-
case 4: return [2 /*return*/];
|
1309
|
-
}
|
1310
|
-
});
|
1311
|
-
});
|
1066
|
+
const get_allowance = async function (tokenAddress, spender, sender) {
|
1067
|
+
let tag = TAG + " | get_allowance | ";
|
1068
|
+
try {
|
1069
|
+
let contract = new web3.eth.Contract(constant_1.ERC20ABI, tokenAddress);
|
1070
|
+
let allowance = await contract.methods.allowance(spender, sender).call();
|
1071
|
+
return allowance;
|
1072
|
+
}
|
1073
|
+
catch (e) {
|
1074
|
+
console.error(tag, e);
|
1075
|
+
}
|
1312
1076
|
};
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
case 2:
|
1325
|
-
ethInto = _a.sent();
|
1326
|
-
log.debug(tag, "ethInto: ", ethInto);
|
1327
|
-
return [2 /*return*/, true];
|
1328
|
-
case 3:
|
1329
|
-
e_21 = _a.sent();
|
1330
|
-
console.error(tag, e_21);
|
1331
|
-
return [3 /*break*/, 4];
|
1332
|
-
case 4: return [2 /*return*/];
|
1333
|
-
}
|
1334
|
-
});
|
1335
|
-
});
|
1077
|
+
const get_all_tokens_blockbook = async function (address) {
|
1078
|
+
let tag = TAG + " | get_all_tokens_blockbook | ";
|
1079
|
+
try {
|
1080
|
+
//
|
1081
|
+
let ethInto = await blockbook.getEthInfo(address);
|
1082
|
+
log.debug(tag, "ethInto: ", ethInto);
|
1083
|
+
return true;
|
1084
|
+
}
|
1085
|
+
catch (e) {
|
1086
|
+
console.error(tag, e);
|
1087
|
+
}
|
1336
1088
|
};
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
case 2:
|
1351
|
-
ethInfo = _a.sent();
|
1352
|
-
//TODO filter by LP contracts
|
1353
|
-
log.debug(tag, "ethInfo: ", ethInfo);
|
1354
|
-
return [2 /*return*/, ethInfo];
|
1355
|
-
case 3:
|
1356
|
-
e_22 = _a.sent();
|
1357
|
-
console.error(tag, e_22);
|
1358
|
-
return [3 /*break*/, 4];
|
1359
|
-
case 4: return [2 /*return*/];
|
1360
|
-
}
|
1361
|
-
});
|
1362
|
-
});
|
1089
|
+
const get_nfts = async function (address) {
|
1090
|
+
let tag = TAG + " | get_nfts | ";
|
1091
|
+
try {
|
1092
|
+
//get nfts from etherscan (v3 uniswap)
|
1093
|
+
//
|
1094
|
+
let ethInfo = await blockbook.getAddressInfo('ETH', address);
|
1095
|
+
//TODO filter by LP contracts
|
1096
|
+
log.debug(tag, "ethInfo: ", ethInfo);
|
1097
|
+
return ethInfo;
|
1098
|
+
}
|
1099
|
+
catch (e) {
|
1100
|
+
console.error(tag, e);
|
1101
|
+
}
|
1363
1102
|
};
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
case 2:
|
1378
|
-
ethInfo = _a.sent();
|
1379
|
-
//TODO filter by LP contracts
|
1380
|
-
log.debug(tag, "ethInfo: ", ethInfo);
|
1381
|
-
return [2 /*return*/, ethInfo];
|
1382
|
-
case 3:
|
1383
|
-
e_23 = _a.sent();
|
1384
|
-
console.error(tag, e_23);
|
1385
|
-
return [3 /*break*/, 4];
|
1386
|
-
case 4: return [2 /*return*/];
|
1387
|
-
}
|
1388
|
-
});
|
1389
|
-
});
|
1103
|
+
const get_pool_positions = async function (address) {
|
1104
|
+
let tag = TAG + " | get_pool_positions | ";
|
1105
|
+
try {
|
1106
|
+
//get nfts from etherscan (v3 uniswap)
|
1107
|
+
//
|
1108
|
+
let ethInfo = await blockbook.getAddressInfo('ETH', address);
|
1109
|
+
//TODO filter by LP contracts
|
1110
|
+
log.debug(tag, "ethInfo: ", ethInfo);
|
1111
|
+
return ethInfo;
|
1112
|
+
}
|
1113
|
+
catch (e) {
|
1114
|
+
console.error(tag, e);
|
1115
|
+
}
|
1390
1116
|
};
|
1391
1117
|
/*
|
1392
1118
|
let swap = {
|
@@ -1407,588 +1133,435 @@ let swap = {
|
|
1407
1133
|
amount: "0.1"
|
1408
1134
|
}
|
1409
1135
|
*/
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
throw e;
|
1430
|
-
}
|
1431
|
-
return [2 /*return*/];
|
1432
|
-
});
|
1433
|
-
});
|
1136
|
+
let get_memo_data = async function (swap) {
|
1137
|
+
let tag = TAG + " | get_memo_data | ";
|
1138
|
+
try {
|
1139
|
+
const web3 = new Web3();
|
1140
|
+
if (!swap.inboundAddress.router)
|
1141
|
+
throw Error("Router required!");
|
1142
|
+
const routerContract = new web3.eth.Contract(constant_1.TCRopstenAbi, swap.inboundAddress.router);
|
1143
|
+
const memo = swap.memo;
|
1144
|
+
//TODO support tokens?
|
1145
|
+
const data = routerContract.methods
|
1146
|
+
.deposit(swap.inboundAddress.address, '0x0000000000000000000000000000000000000000', // 0 = ETH
|
1147
|
+
web3.utils.toBN(swap.amount * BASE), memo)
|
1148
|
+
.encodeABI();
|
1149
|
+
return data;
|
1150
|
+
}
|
1151
|
+
catch (e) {
|
1152
|
+
log.error(tag, e);
|
1153
|
+
throw e;
|
1154
|
+
}
|
1434
1155
|
};
|
1435
1156
|
/*
|
1436
1157
|
X-chain compatible call
|
1437
1158
|
*/
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1159
|
+
let estimate_fee = async function (sourceAsset, params) {
|
1160
|
+
let tag = TAG + " | estimate_fee | ";
|
1161
|
+
try {
|
1162
|
+
let checkSummedAddress;
|
1163
|
+
let decimal;
|
1164
|
+
if (sourceAsset.symbol === 'ETH') {
|
1165
|
+
checkSummedAddress = '0x0000000000000000000000000000000000000000';
|
1166
|
+
decimal = utils_1.ETH_DECIMAL;
|
1167
|
+
}
|
1168
|
+
else {
|
1169
|
+
throw Error("TODO");
|
1170
|
+
// const assetAddress = sourceAsset.symbol.slice(sourceAsset.ticker.length + 1);
|
1171
|
+
// const strip0x = assetAddress.substr(2);
|
1172
|
+
// checkSummedAddress = ethers.utils.getAddress(strip0x);
|
1173
|
+
//
|
1174
|
+
// const tokenContract = new ethers.Contract(checkSummedAddress, erc20ABI, wallet);
|
1175
|
+
// const tokenDecimals = await tokenContract.decimals();
|
1176
|
+
// decimal = tokenDecimals.toNumber();
|
1177
|
+
}
|
1178
|
+
// Connect to the network
|
1179
|
+
let provider = PROVIDER;
|
1180
|
+
// Get the current block
|
1181
|
+
let block = await provider.getBlockNumber();
|
1182
|
+
log.debug(tag, "block: ", block);
|
1183
|
+
const { average: averageGP, fast: fastGP, fastest: fastestGP } = (0, utils_1.getDefaultGasPrices)();
|
1184
|
+
let assetAddress;
|
1185
|
+
// @ts-ignore
|
1186
|
+
if (sourceAsset && (0, xchain_util_1.assetToString)(sourceAsset) !== (0, xchain_util_1.assetToString)(xchain_util_1.AssetETH)) {
|
1187
|
+
// @ts-ignore
|
1188
|
+
assetAddress = (0, utils_1.getTokenAddress)(sourceAsset);
|
1189
|
+
}
|
1190
|
+
let gasLimit;
|
1191
|
+
if (assetAddress && assetAddress !== utils_1.ETHAddress) {
|
1192
|
+
if (!params.sender || !params.recipient)
|
1193
|
+
throw Error("missing params! need sender and recipient on token tx!");
|
1194
|
+
let contract = new ethers.Contract(assetAddress, constant_1.ERC20ABI, provider);
|
1195
|
+
gasLimit = params.data
|
1196
|
+
? await contract.estimateGas.transfer(params.recipient, params.data, { from: params.sender })
|
1197
|
+
: await contract.estimateGas.transfer(params.recipient, 1, { from: params.sender }); // amount = 1 as a dummy value
|
1198
|
+
}
|
1199
|
+
else {
|
1200
|
+
// ETH transfer
|
1201
|
+
if (!params.sender || !params.recipient)
|
1202
|
+
throw Error("missing params! need sender and recipient");
|
1203
|
+
const gasEstimate = await provider.estimateGas({
|
1204
|
+
from: params.sender,
|
1205
|
+
to: params.recipient,
|
1206
|
+
value: ethers.utils.parseEther('0.000001') // using dummy ETH amount for gas calculation
|
1207
|
+
});
|
1208
|
+
gasLimit = gasEstimate.add(0); // Add extra gas as buffer
|
1209
|
+
console.log("ETH gasEstimate: ", gasEstimate.toString());
|
1210
|
+
console.log("ETH gasEstimate + buffer: ", gasLimit.toString());
|
1211
|
+
}
|
1212
|
+
return {
|
1213
|
+
gasPrices: {
|
1214
|
+
average: averageGP,
|
1215
|
+
fast: fastGP,
|
1216
|
+
fastest: fastestGP
|
1217
|
+
},
|
1218
|
+
gasLimit,
|
1219
|
+
fees: {
|
1220
|
+
type: 'byte',
|
1221
|
+
average: (0, utils_1.getFee)({ gasPrice: averageGP, gasLimit }),
|
1222
|
+
fast: (0, utils_1.getFee)({ gasPrice: fastGP, gasLimit }),
|
1223
|
+
fastest: (0, utils_1.getFee)({ gasPrice: fastestGP, gasLimit })
|
1493
1224
|
}
|
1494
|
-
}
|
1495
|
-
}
|
1225
|
+
};
|
1226
|
+
}
|
1227
|
+
catch (e) {
|
1228
|
+
console.error(tag, "Error: ", e);
|
1229
|
+
throw e;
|
1230
|
+
}
|
1496
1231
|
};
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
case 5: return [2 /*return*/, estimate];
|
1535
|
-
case 6:
|
1536
|
-
e_25 = _b.sent();
|
1537
|
-
log.error(tag, e_25);
|
1538
|
-
throw e_25;
|
1539
|
-
case 7: return [2 /*return*/];
|
1540
|
-
}
|
1541
|
-
});
|
1542
|
-
});
|
1232
|
+
let get_gas_limit = async function ({ asset, recipient, amount, memo }) {
|
1233
|
+
let tag = TAG + " | get_gas_limit | ";
|
1234
|
+
try {
|
1235
|
+
log.debug(tag, "input: ", { asset, recipient, amount, memo });
|
1236
|
+
const txAmount = BigNumber.from(amount?.amount().toFixed());
|
1237
|
+
let assetAddress;
|
1238
|
+
// @ts-ignore
|
1239
|
+
if (asset && (0, xchain_util_1.assetToString)(asset) !== (0, xchain_util_1.assetToString)(xchain_util_1.AssetETH)) {
|
1240
|
+
// @ts-ignore
|
1241
|
+
assetAddress = (0, utils_1.getTokenAddress)(asset);
|
1242
|
+
}
|
1243
|
+
let estimate;
|
1244
|
+
//NOTE: I changed the from to recipient because this module has no context to address of the sender.
|
1245
|
+
// I hope I dont skrew the pooch and the differnce +-1 byte between addresses actually matter
|
1246
|
+
if (assetAddress && assetAddress !== utils_1.ETHAddress) {
|
1247
|
+
// ERC20 gas estimate
|
1248
|
+
const contract = new ethers.Contract(assetAddress, utils_1.erc20ABI, PROVIDER);
|
1249
|
+
estimate = await contract.estimateGas.transfer(recipient, txAmount, {
|
1250
|
+
from: recipient,
|
1251
|
+
});
|
1252
|
+
}
|
1253
|
+
else {
|
1254
|
+
// ETH gas estimate
|
1255
|
+
const transactionRequest = {
|
1256
|
+
from: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", //address with lots of eth
|
1257
|
+
to: recipient,
|
1258
|
+
value: txAmount,
|
1259
|
+
data: memo ? toUtf8Bytes(memo) : undefined,
|
1260
|
+
};
|
1261
|
+
estimate = await PROVIDER.estimateGas(transactionRequest);
|
1262
|
+
}
|
1263
|
+
return estimate;
|
1264
|
+
}
|
1265
|
+
catch (e) {
|
1266
|
+
log.error(tag, e);
|
1267
|
+
throw e;
|
1268
|
+
}
|
1543
1269
|
};
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
// @ts-ignore
|
1571
|
-
params.amount = {
|
1572
|
-
// @ts-ignore
|
1573
|
-
amount: function () { return .98; }
|
1574
|
-
};
|
1575
|
-
}
|
1576
|
-
log.debug(tag, "get_gas_limit: ", {
|
1577
|
-
asset: params.asset,
|
1578
|
-
amount: params.amount,
|
1579
|
-
recipient: params.recipient,
|
1580
|
-
memo: params.memo,
|
1581
|
-
});
|
1582
|
-
return [4 /*yield*/, get_gas_limit({
|
1583
|
-
asset: params.asset,
|
1584
|
-
amount: params.amount,
|
1585
|
-
recipient: params.recipient,
|
1586
|
-
memo: params.memo,
|
1587
|
-
})];
|
1588
|
-
case 3:
|
1589
|
-
gasLimit = _b.sent();
|
1590
|
-
output = {
|
1591
|
-
gasPrices: gasPrices,
|
1592
|
-
fees: {
|
1593
|
-
type: 'byte',
|
1594
|
-
average: (0, utils_1.getFee)({ gasPrice: averageGP, gasLimit: gasLimit }).amount().toString(),
|
1595
|
-
fast: (0, utils_1.getFee)({ gasPrice: fastGP, gasLimit: gasLimit }).amount().toString(),
|
1596
|
-
fastest: (0, utils_1.getFee)({ gasPrice: fastestGP, gasLimit: gasLimit }).amount().toString(),
|
1597
|
-
},
|
1598
|
-
gasLimit: gasLimit,
|
1599
|
-
};
|
1600
|
-
return [2 /*return*/, output];
|
1601
|
-
case 4:
|
1602
|
-
e_26 = _b.sent();
|
1603
|
-
log.error(tag, e_26);
|
1604
|
-
throw e_26;
|
1605
|
-
case 5: return [2 /*return*/];
|
1606
|
-
}
|
1270
|
+
let get_fees = async function (params) {
|
1271
|
+
let tag = TAG + " | get_fees | ";
|
1272
|
+
try {
|
1273
|
+
const response = await etherscanAPI.getGasOracle(ETHERSCAN.baseUrl, ETHERSCAN.apiKey);
|
1274
|
+
// Convert result of gas prices: `Gwei` -> `Wei`
|
1275
|
+
const averageWei = parseUnits(response.SafeGasPrice, 'gwei');
|
1276
|
+
const fastWei = parseUnits(response.ProposeGasPrice, 'gwei');
|
1277
|
+
const fastestWei = parseUnits(response.FastGasPrice, 'gwei');
|
1278
|
+
let gasPrices = {
|
1279
|
+
average: (0, xchain_util_1.baseAmount)(averageWei.toString(), utils_1.ETH_DECIMAL),
|
1280
|
+
fast: (0, xchain_util_1.baseAmount)(fastWei.toString(), utils_1.ETH_DECIMAL),
|
1281
|
+
fastest: (0, xchain_util_1.baseAmount)(fastestWei.toString(), utils_1.ETH_DECIMAL),
|
1282
|
+
};
|
1283
|
+
const { fast: fastGP, fastest: fastestGP, average: averageGP } = gasPrices;
|
1284
|
+
if (!params.amount || !params?.amount?.amount) {
|
1285
|
+
// @ts-ignore
|
1286
|
+
params.amount = {
|
1287
|
+
// @ts-ignore
|
1288
|
+
amount: function () { return .98; }
|
1289
|
+
};
|
1290
|
+
}
|
1291
|
+
log.debug(tag, "get_gas_limit: ", {
|
1292
|
+
asset: params.asset,
|
1293
|
+
amount: params.amount,
|
1294
|
+
recipient: params.recipient,
|
1295
|
+
memo: params.memo,
|
1607
1296
|
});
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
return __generator(this, function (_a) {
|
1614
|
-
switch (_a.label) {
|
1615
|
-
case 0:
|
1616
|
-
tag = TAG + " | broadcast_transaction | ";
|
1617
|
-
_a.label = 1;
|
1618
|
-
case 1:
|
1619
|
-
_a.trys.push([1, 3, , 4]);
|
1620
|
-
output = {};
|
1621
|
-
output.success = false;
|
1622
|
-
log.debug(tag, "tx: ", tx);
|
1623
|
-
if (!tx)
|
1624
|
-
throw Error("101: missing tx!");
|
1625
|
-
return [4 /*yield*/, axios({
|
1626
|
-
method: 'GET',
|
1627
|
-
url: 'https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=' + tx + '&apikey=' + process.env['ETHERSCAN_API_KEY']
|
1628
|
-
})];
|
1629
|
-
case 2:
|
1630
|
-
resp = _a.sent();
|
1631
|
-
resp = resp.data;
|
1632
|
-
console.log(resp);
|
1633
|
-
//push blockbook
|
1634
|
-
//TODO lifecycle hook?
|
1635
|
-
// let resp2 = await web3.eth.sendSignedTransaction(tx)
|
1636
|
-
// .on('transactionHash', function(hash:any){
|
1637
|
-
// console.log("hash: ",hash)
|
1638
|
-
// })
|
1639
|
-
// .on('receipt', function(receipt:any){
|
1640
|
-
// console.log("receipt: ",receipt)
|
1641
|
-
// })
|
1642
|
-
// .on('confirmation', function(confirmationNumber:any, receipt:any){
|
1643
|
-
// console.log(confirmationNumber,receipt)
|
1644
|
-
// })
|
1645
|
-
// .on('error', console.error);
|
1646
|
-
//console.log("resp: ",resp)
|
1647
|
-
if (!resp.error)
|
1648
|
-
output.success = true;
|
1649
|
-
if (resp.error)
|
1650
|
-
output.error = resp;
|
1651
|
-
if (resp.result)
|
1652
|
-
output.txid = resp.result;
|
1653
|
-
return [2 /*return*/, output];
|
1654
|
-
case 3:
|
1655
|
-
e_27 = _a.sent();
|
1656
|
-
log.error(tag, e_27);
|
1657
|
-
throw e_27;
|
1658
|
-
case 4: return [2 /*return*/];
|
1659
|
-
}
|
1297
|
+
const gasLimit = await get_gas_limit({
|
1298
|
+
asset: params.asset,
|
1299
|
+
amount: params.amount,
|
1300
|
+
recipient: params.recipient,
|
1301
|
+
memo: params.memo,
|
1660
1302
|
});
|
1661
|
-
|
1303
|
+
let output = {
|
1304
|
+
gasPrices,
|
1305
|
+
fees: {
|
1306
|
+
type: 'byte',
|
1307
|
+
average: (0, utils_1.getFee)({ gasPrice: averageGP, gasLimit }).amount().toString(),
|
1308
|
+
fast: (0, utils_1.getFee)({ gasPrice: fastGP, gasLimit }).amount().toString(),
|
1309
|
+
fastest: (0, utils_1.getFee)({ gasPrice: fastestGP, gasLimit }).amount().toString(),
|
1310
|
+
},
|
1311
|
+
gasLimit,
|
1312
|
+
};
|
1313
|
+
return output;
|
1314
|
+
}
|
1315
|
+
catch (e) {
|
1316
|
+
log.error(tag, e);
|
1317
|
+
throw e;
|
1318
|
+
}
|
1662
1319
|
};
|
1663
|
-
|
1664
|
-
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1320
|
+
let broadcast_transaction = async function (tx) {
|
1321
|
+
let tag = TAG + " | broadcast_transaction | ";
|
1322
|
+
try {
|
1323
|
+
let output = {};
|
1324
|
+
output.success = false;
|
1325
|
+
log.debug(tag, "tx: ", tx);
|
1326
|
+
if (!tx)
|
1327
|
+
throw Error("101: missing tx!");
|
1328
|
+
//push node
|
1329
|
+
// web3.eth.sendSignedTransaction(tx)
|
1330
|
+
//push etherscan
|
1331
|
+
//https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=0xf904808000831cfde080&apikey=YourApiKeyToken
|
1332
|
+
let resp = await axios({
|
1333
|
+
method: 'GET',
|
1334
|
+
url: 'https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=' + tx + '&apikey=' + process.env['ETHERSCAN_API_KEY']
|
1677
1335
|
});
|
1678
|
-
|
1336
|
+
resp = resp.data;
|
1337
|
+
console.log(resp);
|
1338
|
+
//push blockbook
|
1339
|
+
//TODO lifecycle hook?
|
1340
|
+
// let resp2 = await web3.eth.sendSignedTransaction(tx)
|
1341
|
+
// .on('transactionHash', function(hash:any){
|
1342
|
+
// console.log("hash: ",hash)
|
1343
|
+
// })
|
1344
|
+
// .on('receipt', function(receipt:any){
|
1345
|
+
// console.log("receipt: ",receipt)
|
1346
|
+
// })
|
1347
|
+
// .on('confirmation', function(confirmationNumber:any, receipt:any){
|
1348
|
+
// console.log(confirmationNumber,receipt)
|
1349
|
+
// })
|
1350
|
+
// .on('error', console.error);
|
1351
|
+
//console.log("resp: ",resp)
|
1352
|
+
if (!resp.error)
|
1353
|
+
output.success = true;
|
1354
|
+
if (resp.error)
|
1355
|
+
output.error = resp;
|
1356
|
+
if (resp.result)
|
1357
|
+
output.txid = resp.result;
|
1358
|
+
return output;
|
1359
|
+
}
|
1360
|
+
catch (e) {
|
1361
|
+
log.error(tag, e);
|
1362
|
+
throw e;
|
1363
|
+
}
|
1364
|
+
};
|
1365
|
+
const get_balance_tokens_by_network = async function (networkId, address) {
|
1366
|
+
let tag = TAG + " | get_balance_tokens_by_network | ";
|
1367
|
+
try {
|
1368
|
+
let output = {};
|
1369
|
+
//@TODO zapper? covalent?
|
1370
|
+
return "";
|
1371
|
+
}
|
1372
|
+
catch (e) {
|
1373
|
+
console.error(tag, e);
|
1374
|
+
}
|
1679
1375
|
};
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
log.debug(tag, "
|
1704
|
-
//
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
rate = 0;
|
1713
|
-
if (info.tokenInfo.price && info.tokenInfo.price.rate) {
|
1714
|
-
log.debug(tag, "rate: ", info.tokenInfo.price.rate);
|
1715
|
-
rate = info.tokenInfo.price.rate;
|
1716
|
-
}
|
1717
|
-
balance = info.balance / parseInt(Math.pow(10, info.tokenInfo.decimals));
|
1718
|
-
log.debug({ rate: rate, symbol: symbol, balance: balance });
|
1719
|
-
balances[symbol] = balance;
|
1720
|
-
valueUsds[symbol] = balance * rate;
|
1721
|
-
coinInfo[symbol] = info.tokenInfo;
|
1722
|
-
}
|
1723
|
-
}
|
1376
|
+
const get_balance_tokens = async function (address) {
|
1377
|
+
let tag = TAG + " | get_balance_tokens | ";
|
1378
|
+
try {
|
1379
|
+
let balances = {};
|
1380
|
+
let valueUsds = {};
|
1381
|
+
let coinInfo = {};
|
1382
|
+
//TODO other? backup?
|
1383
|
+
//ethpolorer.io
|
1384
|
+
let resp = await axios({
|
1385
|
+
method: 'GET',
|
1386
|
+
url: 'http://api.ethplorer.io/getAddressInfo/' + address + '?apiKey=' + ETHPLORER_API_KEY
|
1387
|
+
});
|
1388
|
+
log.debug(tag, "resp: ", resp.data);
|
1389
|
+
balances['ETH'] = resp.data.ETH.balance;
|
1390
|
+
valueUsds['ETH'] = parseFloat(resp.data.ETH.balance) * parseFloat(resp.data.ETH.price.rate);
|
1391
|
+
//infura
|
1392
|
+
let tokenInfo = resp.data.tokens;
|
1393
|
+
log.debug(tag, "tokenInfo: ", tokenInfo);
|
1394
|
+
//
|
1395
|
+
if (tokenInfo && Object.keys(tokenInfo).length > 0) {
|
1396
|
+
for (let i = 0; i < tokenInfo.length; i++) {
|
1397
|
+
let info = tokenInfo[i];
|
1398
|
+
if (info) {
|
1399
|
+
log.debug(tag, "info: ", info);
|
1400
|
+
//let symbol
|
1401
|
+
let symbol = info.tokenInfo.symbol;
|
1402
|
+
log.debug(tag, "symbol: ", symbol);
|
1403
|
+
//rate
|
1404
|
+
let rate = 0;
|
1405
|
+
if (info.tokenInfo.price && info.tokenInfo.price.rate) {
|
1406
|
+
log.debug(tag, "rate: ", info.tokenInfo.price.rate);
|
1407
|
+
rate = info.tokenInfo.price.rate;
|
1724
1408
|
}
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
1730
|
-
|
1409
|
+
// @ts-ignore
|
1410
|
+
let balance = info.balance / parseInt(Math.pow(10, info.tokenInfo.decimals));
|
1411
|
+
log.debug({ rate, symbol, balance });
|
1412
|
+
balances[symbol] = balance;
|
1413
|
+
valueUsds[symbol] = balance * rate;
|
1414
|
+
coinInfo[symbol] = info.tokenInfo;
|
1415
|
+
}
|
1731
1416
|
}
|
1732
|
-
}
|
1733
|
-
|
1417
|
+
}
|
1418
|
+
return { balances, valueUsds, coinInfo };
|
1419
|
+
}
|
1420
|
+
catch (e) {
|
1421
|
+
console.error(tag, e);
|
1422
|
+
}
|
1734
1423
|
};
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
|
1743
|
-
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
return [4 /*yield*/, contract.methods.balanceOf(address).call()
|
1757
|
-
//log.debug(tag,"balance: ",balance)
|
1758
|
-
];
|
1759
|
-
case 3:
|
1760
|
-
balance = _a.sent();
|
1761
|
-
//log.debug(tag,"balance: ",balance)
|
1762
|
-
return [2 /*return*/, balance / Math.pow(10, decimals)];
|
1763
|
-
case 4:
|
1764
|
-
e_29 = _a.sent();
|
1765
|
-
console.error(tag, e_29);
|
1766
|
-
return [3 /*break*/, 5];
|
1767
|
-
case 5: return [2 /*return*/];
|
1768
|
-
}
|
1769
|
-
});
|
1770
|
-
});
|
1424
|
+
const get_balance_token_by_network = async function (networkId, address, token) {
|
1425
|
+
let tag = TAG + " | get_balance_token_by_network | ";
|
1426
|
+
try {
|
1427
|
+
let output = {};
|
1428
|
+
//find in node array node by networkId
|
1429
|
+
let node = NODES.find((n) => { return n.networkId == networkId; });
|
1430
|
+
if (!node)
|
1431
|
+
throw Error("101: missing node! for network " + networkId);
|
1432
|
+
//init new web3
|
1433
|
+
let web3 = new Web3(node.service);
|
1434
|
+
//decimals
|
1435
|
+
let contract = new web3.eth.Contract(constant_1.ERC20ABI, token);
|
1436
|
+
let decimals = await contract.methods.decimals().call();
|
1437
|
+
//log.debug(tag,"decimals: ",decimals)
|
1438
|
+
let balance = await contract.methods.balanceOf(address).call();
|
1439
|
+
//log.debug(tag,"balance: ",balance)
|
1440
|
+
return balance / Math.pow(10, decimals);
|
1441
|
+
}
|
1442
|
+
catch (e) {
|
1443
|
+
console.error(tag, e);
|
1444
|
+
}
|
1771
1445
|
};
|
1772
|
-
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
case 2:
|
1787
|
-
decimals = _a.sent();
|
1788
|
-
return [4 /*yield*/, contract.methods.balanceOf(address).call()
|
1789
|
-
//log.debug(tag,"balance: ",balance)
|
1790
|
-
];
|
1791
|
-
case 3:
|
1792
|
-
balance = _a.sent();
|
1793
|
-
//log.debug(tag,"balance: ",balance)
|
1794
|
-
return [2 /*return*/, balance / Math.pow(10, decimals)];
|
1795
|
-
case 4:
|
1796
|
-
e_30 = _a.sent();
|
1797
|
-
console.error(tag, e_30);
|
1798
|
-
return [3 /*break*/, 5];
|
1799
|
-
case 5: return [2 /*return*/];
|
1800
|
-
}
|
1801
|
-
});
|
1802
|
-
});
|
1446
|
+
const get_balance_token = async function (address, token) {
|
1447
|
+
let tag = TAG + " | get_balance | ";
|
1448
|
+
try {
|
1449
|
+
//decimals
|
1450
|
+
let contract = new web3.eth.Contract(constant_1.ERC20ABI, token);
|
1451
|
+
let decimals = await contract.methods.decimals().call();
|
1452
|
+
//log.debug(tag,"decimals: ",decimals)
|
1453
|
+
let balance = await contract.methods.balanceOf(address).call();
|
1454
|
+
//log.debug(tag,"balance: ",balance)
|
1455
|
+
return balance / Math.pow(10, decimals);
|
1456
|
+
}
|
1457
|
+
catch (e) {
|
1458
|
+
console.error(tag, e);
|
1459
|
+
}
|
1803
1460
|
};
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
//normal tx info
|
1822
|
-
output = (_a.sent()) / BASE;
|
1823
|
-
return [2 /*return*/, output];
|
1824
|
-
case 3:
|
1825
|
-
e_31 = _a.sent();
|
1826
|
-
console.error(tag, e_31);
|
1827
|
-
return [3 /*break*/, 4];
|
1828
|
-
case 4: return [2 /*return*/];
|
1829
|
-
}
|
1830
|
-
});
|
1831
|
-
});
|
1461
|
+
const get_balance_by_network = async function (networkId, address) {
|
1462
|
+
let tag = TAG + " | get_balance_by_network | ";
|
1463
|
+
try {
|
1464
|
+
let output = {};
|
1465
|
+
//find in node array node by networkId
|
1466
|
+
let node = NODES.find((n) => { return n.networkId == networkId; });
|
1467
|
+
if (!node)
|
1468
|
+
throw Error("101: missing node! for network " + networkId);
|
1469
|
+
//init new web3
|
1470
|
+
let web3 = new Web3(node.service);
|
1471
|
+
//normal tx info
|
1472
|
+
output = (await web3.eth.getBalance(address)) / BASE;
|
1473
|
+
return output;
|
1474
|
+
}
|
1475
|
+
catch (e) {
|
1476
|
+
console.error(tag, e);
|
1477
|
+
}
|
1832
1478
|
};
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
return [4 /*yield*/, web3.eth.getBalance(address)];
|
1845
|
-
case 2:
|
1846
|
-
//normal tx info
|
1847
|
-
output = (_a.sent()) / BASE;
|
1848
|
-
return [2 /*return*/, output];
|
1849
|
-
case 3:
|
1850
|
-
e_32 = _a.sent();
|
1851
|
-
console.error(tag, e_32);
|
1852
|
-
return [3 /*break*/, 4];
|
1853
|
-
case 4: return [2 /*return*/];
|
1854
|
-
}
|
1855
|
-
});
|
1856
|
-
});
|
1479
|
+
const get_balance = async function (address) {
|
1480
|
+
let tag = TAG + " | get_balance | ";
|
1481
|
+
try {
|
1482
|
+
let output = {};
|
1483
|
+
//normal tx info
|
1484
|
+
output = (await web3.eth.getBalance(address)) / BASE;
|
1485
|
+
return output;
|
1486
|
+
}
|
1487
|
+
catch (e) {
|
1488
|
+
console.error(tag, e);
|
1489
|
+
}
|
1857
1490
|
};
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
output = {};
|
1869
|
-
return [4 /*yield*/, blockbook.getAddressInfo('ETH', address)];
|
1870
|
-
case 2:
|
1871
|
-
ethInfo = _a.sent();
|
1872
|
-
return [2 /*return*/, ethInfo];
|
1873
|
-
case 3:
|
1874
|
-
e_33 = _a.sent();
|
1875
|
-
console.error(tag, e_33);
|
1876
|
-
return [3 /*break*/, 4];
|
1877
|
-
case 4: return [2 /*return*/];
|
1878
|
-
}
|
1879
|
-
});
|
1880
|
-
});
|
1491
|
+
const get_transactions = async function (address, options) {
|
1492
|
+
let tag = TAG + " | get_transactions | ";
|
1493
|
+
try {
|
1494
|
+
let output = {};
|
1495
|
+
let ethInfo = await blockbook.getAddressInfo('ETH', address);
|
1496
|
+
return ethInfo;
|
1497
|
+
}
|
1498
|
+
catch (e) {
|
1499
|
+
console.error(tag, e);
|
1500
|
+
}
|
1881
1501
|
};
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
return [4 /*yield*/, web3.eth.getTransaction(txid)
|
1896
|
-
//if contract
|
1897
|
-
];
|
1898
|
-
case 2:
|
1899
|
-
//normal tx info
|
1900
|
-
_a.txInfo = _c.sent();
|
1901
|
-
//if contract
|
1902
|
-
_b = output;
|
1903
|
-
return [4 /*yield*/, web3.eth.getTransactionReceipt(txid)];
|
1904
|
-
case 3:
|
1905
|
-
//if contract
|
1906
|
-
_b.receipt = _c.sent();
|
1907
|
-
return [2 /*return*/, output];
|
1908
|
-
case 4:
|
1909
|
-
e_34 = _c.sent();
|
1910
|
-
console.error(tag, e_34);
|
1911
|
-
return [3 /*break*/, 5];
|
1912
|
-
case 5: return [2 /*return*/];
|
1913
|
-
}
|
1914
|
-
});
|
1915
|
-
});
|
1502
|
+
const get_transaction = async function (txid) {
|
1503
|
+
let tag = TAG + " | get_transaction | ";
|
1504
|
+
try {
|
1505
|
+
let output = {};
|
1506
|
+
//normal tx info
|
1507
|
+
output.txInfo = await web3.eth.getTransaction(txid);
|
1508
|
+
//if contract
|
1509
|
+
output.receipt = await web3.eth.getTransactionReceipt(txid);
|
1510
|
+
return output;
|
1511
|
+
}
|
1512
|
+
catch (e) {
|
1513
|
+
console.error(tag, e);
|
1514
|
+
}
|
1916
1515
|
};
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
break;
|
1958
|
-
case "3":
|
1959
|
-
networkName = "Ropsten";
|
1960
|
-
break;
|
1961
|
-
case "4":
|
1962
|
-
networkName = "Rinkeby";
|
1963
|
-
break;
|
1964
|
-
case "42":
|
1965
|
-
networkName = "Kovan";
|
1966
|
-
break;
|
1967
|
-
default:
|
1968
|
-
networkName = "Unknown";
|
1969
|
-
}
|
1970
|
-
output.networkName = networkName;
|
1971
|
-
//
|
1972
|
-
_e = output;
|
1973
|
-
return [4 /*yield*/, web3.eth.getGasPrice()
|
1974
|
-
//
|
1975
|
-
];
|
1976
|
-
case 6:
|
1977
|
-
//
|
1978
|
-
_e.gasPrice = _g.sent();
|
1979
|
-
//
|
1980
|
-
_f = output;
|
1981
|
-
return [4 /*yield*/, web3.eth.isSyncing()];
|
1982
|
-
case 7:
|
1983
|
-
//
|
1984
|
-
_f.syncing = _g.sent();
|
1985
|
-
return [2 /*return*/, output];
|
1986
|
-
case 8:
|
1987
|
-
e_35 = _g.sent();
|
1988
|
-
console.error(tag, e_35);
|
1989
|
-
return [3 /*break*/, 9];
|
1990
|
-
case 9: return [2 /*return*/];
|
1991
|
-
}
|
1992
|
-
});
|
1993
|
-
});
|
1516
|
+
let check_online_status = async function () {
|
1517
|
+
let tag = TAG + " | check_online_status | ";
|
1518
|
+
try {
|
1519
|
+
let output = {};
|
1520
|
+
//isTestnet
|
1521
|
+
output.version = await web3.eth.getNodeInfo();
|
1522
|
+
output.chainId = await web3.eth.getChainId();
|
1523
|
+
output.height = await web3.eth.getBlockNumber();
|
1524
|
+
//TODO get peer count
|
1525
|
+
output.peers = await web3.eth.net.getPeerCount();
|
1526
|
+
let networkName;
|
1527
|
+
switch (output.chainId.toString()) {
|
1528
|
+
case "1":
|
1529
|
+
networkName = "Main";
|
1530
|
+
break;
|
1531
|
+
case "2":
|
1532
|
+
networkName = "Morden";
|
1533
|
+
break;
|
1534
|
+
case "3":
|
1535
|
+
networkName = "Ropsten";
|
1536
|
+
break;
|
1537
|
+
case "4":
|
1538
|
+
networkName = "Rinkeby";
|
1539
|
+
break;
|
1540
|
+
case "42":
|
1541
|
+
networkName = "Kovan";
|
1542
|
+
break;
|
1543
|
+
default:
|
1544
|
+
networkName = "Unknown";
|
1545
|
+
}
|
1546
|
+
output.networkName = networkName;
|
1547
|
+
//
|
1548
|
+
output.gasPrice = await web3.eth.getGasPrice();
|
1549
|
+
//
|
1550
|
+
output.syncing = await web3.eth.isSyncing();
|
1551
|
+
return output;
|
1552
|
+
}
|
1553
|
+
catch (e) {
|
1554
|
+
console.error(tag, e);
|
1555
|
+
}
|
1994
1556
|
};
|
1557
|
+
// Helper functions for ethers v5 compatibility
|
1558
|
+
const parseUnits = (value, unit) => ethers.utils.parseUnits(value, unit);
|
1559
|
+
const toUtf8Bytes = (text) => ethers.utils.toUtf8Bytes(text);
|
1560
|
+
// Define our own FeeOption enum
|
1561
|
+
var FeeOption;
|
1562
|
+
(function (FeeOption) {
|
1563
|
+
FeeOption["Average"] = "average";
|
1564
|
+
FeeOption["Fast"] = "fast";
|
1565
|
+
FeeOption["Fastest"] = "fastest";
|
1566
|
+
})(FeeOption || (FeeOption = {}));
|
1567
|
+
//# sourceMappingURL=index.js.map
|