@pioneer-platform/eth-network 8.4.7 → 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 -1469
- 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);
|
@@ -297,478 +321,371 @@ module.exports = {
|
|
297
321
|
return broadcast_transaction(tx);
|
298
322
|
}
|
299
323
|
};
|
300
|
-
|
301
|
-
|
302
|
-
|
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
|
-
if
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
receipt = _c.sent();
|
348
|
-
transactions.push({
|
349
|
-
txHash: tx.hash,
|
350
|
-
from: tx.from,
|
351
|
-
to: tx.to,
|
352
|
-
value: tx.value,
|
353
|
-
gas: tx.gas,
|
354
|
-
gasPrice: tx.gasPrice,
|
355
|
-
blockNumber: tx.blockNumber,
|
356
|
-
receipt: receipt,
|
357
|
-
});
|
358
|
-
_c.label = 7;
|
359
|
-
case 7:
|
360
|
-
_i++;
|
361
|
-
return [3 /*break*/, 5];
|
362
|
-
case 8:
|
363
|
-
blockNumber++;
|
364
|
-
return [3 /*break*/, 3];
|
365
|
-
case 9: return [4 /*yield*/, web3_1.eth.getTransactionCount(checksumAddress, "pending")];
|
366
|
-
case 10:
|
367
|
-
currentNonce = _c.sent();
|
368
|
-
return [4 /*yield*/, web3_1.eth.getTransactionCount(checksumAddress, "latest")];
|
369
|
-
case 11:
|
370
|
-
confirmedNonce = _c.sent();
|
371
|
-
log.info(tag, "Current Nonce: ".concat(currentNonce, ", Confirmed Nonce: ").concat(confirmedNonce));
|
372
|
-
hasPendingTransactions = currentNonce > confirmedNonce;
|
373
|
-
if (hasPendingTransactions) {
|
374
|
-
log.info(tag, "Pending transactions detected");
|
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
|
+
});
|
375
371
|
}
|
376
|
-
|
377
|
-
|
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
|
+
});
|
378
401
|
}
|
379
|
-
|
380
|
-
address: address,
|
381
|
-
networkId: networkId,
|
382
|
-
fromBlock: fromBlock,
|
383
|
-
toBlock: toBlock,
|
384
|
-
currentBlockHeight: currentBlockHeight,
|
385
|
-
currentNonce: currentNonce,
|
386
|
-
hasPendingTransactions: hasPendingTransactions,
|
387
|
-
transactions: transactions,
|
388
|
-
}];
|
389
|
-
case 12:
|
390
|
-
e_1 = _c.sent();
|
391
|
-
console.error(tag, e_1);
|
392
|
-
throw e_1; // Rethrow the error to handle it upstream
|
393
|
-
case 13: return [2 /*return*/];
|
402
|
+
}
|
394
403
|
}
|
395
|
-
}
|
396
|
-
|
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
|
+
}
|
397
423
|
};
|
398
424
|
// Broadcast transaction by network
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
})
|
425
|
-
.on('error', function (error) {
|
426
|
-
console.error("Broadcast Error:", error);
|
427
|
-
throw error;
|
428
|
-
})];
|
429
|
-
case 2:
|
430
|
-
result = _a.sent();
|
431
|
-
return [2 /*return*/, result];
|
432
|
-
case 3:
|
433
|
-
e_2 = _a.sent();
|
434
|
-
console.error(tag, e_2);
|
435
|
-
throw e_2;
|
436
|
-
case 4: return [2 /*return*/];
|
437
|
-
}
|
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;
|
438
450
|
});
|
439
|
-
|
451
|
+
return result;
|
452
|
+
}
|
453
|
+
catch (e) {
|
454
|
+
console.error(tag, e);
|
455
|
+
throw e;
|
456
|
+
}
|
440
457
|
};
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
];
|
461
|
-
case 2:
|
462
|
-
//normal tx info
|
463
|
-
_a.txInfo = _c.sent();
|
464
|
-
//if contract
|
465
|
-
_b = output;
|
466
|
-
return [4 /*yield*/, web3_3.eth.getTransactionReceipt(txid)];
|
467
|
-
case 3:
|
468
|
-
//if contract
|
469
|
-
_b.receipt = _c.sent();
|
470
|
-
return [2 /*return*/, output];
|
471
|
-
case 4:
|
472
|
-
e_3 = _c.sent();
|
473
|
-
console.error(tag, e_3);
|
474
|
-
return [3 /*break*/, 5];
|
475
|
-
case 5: return [2 /*return*/];
|
476
|
-
}
|
477
|
-
});
|
478
|
-
});
|
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
|
+
}
|
479
477
|
};
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
return [2 /*return*/, gasPrice];
|
498
|
-
case 3:
|
499
|
-
e_4 = _a.sent();
|
500
|
-
console.error(tag, e_4);
|
501
|
-
throw e_4;
|
502
|
-
case 4: return [2 /*return*/];
|
503
|
-
}
|
504
|
-
});
|
505
|
-
});
|
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
|
+
}
|
506
495
|
};
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
return [2 /*return*/, nonce];
|
527
|
-
case 3:
|
528
|
-
e_5 = _a.sent();
|
529
|
-
console.error(tag, e_5);
|
530
|
-
throw e_5;
|
531
|
-
case 4: return [2 /*return*/];
|
532
|
-
}
|
533
|
-
});
|
534
|
-
});
|
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
|
+
}
|
535
515
|
};
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
return [2 /*return*/, gas];
|
556
|
-
case 3:
|
557
|
-
e_6 = _a.sent();
|
558
|
-
console.error(tag, e_6);
|
559
|
-
throw e_6;
|
560
|
-
case 4: return [2 /*return*/];
|
561
|
-
}
|
562
|
-
});
|
563
|
-
});
|
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
|
+
}
|
564
535
|
};
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
owner = _a.sent();
|
595
|
-
log.debug(tag, "owner: ", owner);
|
596
|
-
output['owners'].push(owner.toLowerCase());
|
597
|
-
return [4 /*yield*/, metadataContract.methods.getAttributes(i).call()];
|
598
|
-
case 6:
|
599
|
-
imageInfo = _a.sent();
|
600
|
-
imageName = JSON.parse(imageInfo['0'])["0-backgrounds"];
|
601
|
-
baseImageUrl = "https://ipfs.io/ipfs/bafybeiezdzjofkcpiwy5hlvxwzkgcztxc6xtodh3q7eddfjmqsguqs47aa/0-backgrounds/";
|
602
|
-
fullImageUrl = baseImageUrl + imageName + ".png";
|
603
|
-
// Add this image URL to the images array in output
|
604
|
-
output['images'].push({ address: owner.toLowerCase(), image: fullImageUrl });
|
605
|
-
return [3 /*break*/, 8];
|
606
|
-
case 7:
|
607
|
-
e_7 = _a.sent();
|
608
|
-
log.debug("no image for: ", i);
|
609
|
-
return [3 /*break*/, 8];
|
610
|
-
case 8:
|
611
|
-
i++;
|
612
|
-
return [3 /*break*/, 3];
|
613
|
-
case 9: return [2 /*return*/, output];
|
614
|
-
case 10:
|
615
|
-
e_8 = _a.sent();
|
616
|
-
console.error(tag, e_8);
|
617
|
-
return [3 /*break*/, 11];
|
618
|
-
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 });
|
619
565
|
}
|
620
|
-
|
621
|
-
|
622
|
-
};
|
623
|
-
var get_all_pioneers_base = function () {
|
624
|
-
return __awaiter(this, void 0, void 0, function () {
|
625
|
-
var tag, output, nftContract, metadataContract, totalSupply, i, owner, imageInfo, imageName, baseImageUrl, fullImageUrl, e_9, e_10;
|
626
|
-
return __generator(this, function (_a) {
|
627
|
-
switch (_a.label) {
|
628
|
-
case 0:
|
629
|
-
tag = TAG + " | get_all_pioneers_base | ";
|
630
|
-
_a.label = 1;
|
631
|
-
case 1:
|
632
|
-
_a.trys.push([1, 10, , 11]);
|
633
|
-
output = {};
|
634
|
-
log.info(tag, "PIONEER_CONTRACT_ADDRESS_BASE: ", constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
635
|
-
nftContract = new web3Base.eth.Contract(constant_1.ERC721_ABI, constant_1.PIONEER_CONTRACT_ADDRESS_BASE);
|
636
|
-
metadataContract = new web3Base.eth.Contract(constant_1.METADATA_ABI, constant_1.PIONEER_METADATA_CONTRACT_ADDRESS_BASE);
|
637
|
-
return [4 /*yield*/, nftContract.methods.totalSupply().call()];
|
638
|
-
case 2:
|
639
|
-
totalSupply = _a.sent();
|
640
|
-
log.info("totalSupply: ", totalSupply);
|
641
|
-
output['totalSupply'] = totalSupply;
|
642
|
-
output['owners'] = [];
|
643
|
-
output['images'] = []; // add an images array to output
|
644
|
-
i = 0;
|
645
|
-
_a.label = 3;
|
646
|
-
case 3:
|
647
|
-
if (!(i < totalSupply)) return [3 /*break*/, 9];
|
648
|
-
_a.label = 4;
|
649
|
-
case 4:
|
650
|
-
_a.trys.push([4, 7, , 8]);
|
651
|
-
return [4 /*yield*/, nftContract.methods.ownerOf(i).call()];
|
652
|
-
case 5:
|
653
|
-
owner = _a.sent();
|
654
|
-
log.info(tag, "owner: ", owner);
|
655
|
-
output['owners'].push(owner.toLowerCase());
|
656
|
-
return [4 /*yield*/, metadataContract.methods.getAttributes(i).call()];
|
657
|
-
case 6:
|
658
|
-
imageInfo = _a.sent();
|
659
|
-
log.info(tag, "imageInfo: ", imageInfo);
|
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_9 = _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_10 = _a.sent();
|
676
|
-
console.error(tag, e_10);
|
677
|
-
return [3 /*break*/, 11];
|
678
|
-
case 11: return [2 /*return*/];
|
566
|
+
catch (e) {
|
567
|
+
log.debug("no image for: ", i);
|
679
568
|
}
|
680
|
-
}
|
681
|
-
|
569
|
+
}
|
570
|
+
return output;
|
571
|
+
}
|
572
|
+
catch (e) {
|
573
|
+
console.error(tag, e);
|
574
|
+
}
|
682
575
|
};
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
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);
|
688
592
|
try {
|
689
|
-
|
690
|
-
|
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 });
|
691
606
|
}
|
692
607
|
catch (e) {
|
693
|
-
|
608
|
+
log.debug("no image for: ", i);
|
694
609
|
}
|
695
|
-
|
696
|
-
|
697
|
-
}
|
610
|
+
}
|
611
|
+
return output;
|
612
|
+
}
|
613
|
+
catch (e) {
|
614
|
+
console.error(tag, e);
|
615
|
+
}
|
698
616
|
};
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
_a.trys.push([1, 3, , 4]);
|
709
|
-
airdropContract = new web3.eth.Contract(constant_1.AIRDROP_ABI, constant_1.AIRDROP_CONTRACT);
|
710
|
-
return [4 /*yield*/, axios({ method: 'GET', url: constant_1.CLAIM_URL + '/' + address })
|
711
|
-
//console.log("accountInfo: ",accountInfo)
|
712
|
-
];
|
713
|
-
case 2:
|
714
|
-
accountInfo = _a.sent();
|
715
|
-
//console.log("accountInfo: ",accountInfo)
|
716
|
-
if (!accountInfo.data.index)
|
717
|
-
throw Error("Not found in db! ");
|
718
|
-
AirDropInterface = new abi_1.Interface(constant_1.AIRDROP_ABI);
|
719
|
-
data = AirDropInterface.encodeFunctionData('claim', [
|
720
|
-
accountInfo.data.index,
|
721
|
-
address,
|
722
|
-
'0x0821ab0d4414980000',
|
723
|
-
accountInfo.data.proof
|
724
|
-
]);
|
725
|
-
return [2 /*return*/, data];
|
726
|
-
case 3:
|
727
|
-
e_11 = _a.sent();
|
728
|
-
console.error(tag, e_11);
|
729
|
-
return [3 /*break*/, 4];
|
730
|
-
case 4: return [2 /*return*/];
|
731
|
-
}
|
732
|
-
});
|
733
|
-
});
|
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
|
+
}
|
734
626
|
};
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
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
|
+
}
|
772
689
|
};
|
773
690
|
// const get_token_transfer_data = async function(toAddress: string, amount: string, contract: string) {
|
774
691
|
// const tag = TAG + " | get_token_transfer_data | ";
|
@@ -880,64 +797,56 @@ var check_airdrop_claim = function (address) {
|
|
880
797
|
// console.error(tag, e);
|
881
798
|
// }
|
882
799
|
// }
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
// decimals
|
903
|
-
{
|
904
|
-
"constant": true,
|
905
|
-
"inputs": [],
|
906
|
-
"name": "decimals",
|
907
|
-
"outputs": [{ "name": "", "type": "uint8" }],
|
908
|
-
"type": "function"
|
909
|
-
}
|
910
|
-
];
|
911
|
-
newContract = new web3.eth.Contract(minABI, contract);
|
912
|
-
return [4 /*yield*/, newContract.methods.decimals().call()];
|
913
|
-
case 2:
|
914
|
-
decimalPlaces = _a.sent();
|
915
|
-
amountInSmallestUnit = web3.utils.toBN(parseFloat(amount) * Math.pow(10, decimalPlaces));
|
916
|
-
amountHex = amountInSmallestUnit.toString(16);
|
917
|
-
amountHexPadded = amountHex.padStart(64, '0');
|
918
|
-
tokenData = web3.eth.abi.encodeFunctionCall({
|
919
|
-
name: 'transfer',
|
920
|
-
type: 'function',
|
921
|
-
inputs: [
|
922
|
-
{
|
923
|
-
type: 'address',
|
924
|
-
name: '_to'
|
925
|
-
},
|
926
|
-
{
|
927
|
-
type: 'uint256',
|
928
|
-
name: '_value'
|
929
|
-
}
|
930
|
-
]
|
931
|
-
}, [toAddress, amountInSmallestUnit.toString()]);
|
932
|
-
return [2 /*return*/, tokenData];
|
933
|
-
case 3:
|
934
|
-
e_13 = _a.sent();
|
935
|
-
console.error(tag, e_13);
|
936
|
-
return [3 /*break*/, 4];
|
937
|
-
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"
|
938
819
|
}
|
939
|
-
|
940
|
-
|
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
|
+
}
|
941
850
|
};
|
942
851
|
// //get_token_transfer_data
|
943
852
|
// const get_token_transfer_data = async function(toAddress:string, amount:string, contract:string){
|
@@ -1003,330 +912,207 @@ var get_token_transfer_data = function (toAddress, amount, contract) {
|
|
1003
912
|
// console.error(tag,e)
|
1004
913
|
// }
|
1005
914
|
// }
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
case 2:
|
1021
|
-
tokenName = _a.sent();
|
1022
|
-
//log.debug(tag,"tokenName: ",tokenName)
|
1023
|
-
return [2 /*return*/, tokenName];
|
1024
|
-
case 3:
|
1025
|
-
e_14 = _a.sent();
|
1026
|
-
console.error(tag, e_14);
|
1027
|
-
return [3 /*break*/, 4];
|
1028
|
-
case 4: return [2 /*return*/];
|
1029
|
-
}
|
1030
|
-
});
|
1031
|
-
});
|
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
|
+
}
|
1032
929
|
};
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
];
|
1050
|
-
case 2:
|
1051
|
-
totalFox = _a.sent();
|
1052
|
-
//log.debug(tag,"totalFox: ",totalFox)
|
1053
|
-
return [2 /*return*/, totalFox];
|
1054
|
-
case 3:
|
1055
|
-
e_15 = _a.sent();
|
1056
|
-
console.error(tag, e_15);
|
1057
|
-
return [3 /*break*/, 4];
|
1058
|
-
case 4: return [2 /*return*/];
|
1059
|
-
}
|
1060
|
-
});
|
1061
|
-
});
|
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
|
+
}
|
1062
946
|
};
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
case 3:
|
1085
|
-
txsWithPending = _a.sent();
|
1086
|
-
pending = txsConfirmed - txsWithPending;
|
1087
|
-
return [2 /*return*/, {
|
1088
|
-
confirmed: txsConfirmed,
|
1089
|
-
total: txsWithPending,
|
1090
|
-
pending: pending
|
1091
|
-
}];
|
1092
|
-
case 4:
|
1093
|
-
e_16 = _a.sent();
|
1094
|
-
console.error(tag, e_16);
|
1095
|
-
return [3 /*break*/, 5];
|
1096
|
-
case 5: return [2 /*return*/];
|
1097
|
-
}
|
1098
|
-
});
|
1099
|
-
});
|
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
|
+
}
|
1100
968
|
};
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
case 5:
|
1137
|
-
e_17 = _a.sent();
|
1138
|
-
console.error(tag, e_17);
|
1139
|
-
return [3 /*break*/, 6];
|
1140
|
-
case 6: return [2 /*return*/];
|
1141
|
-
}
|
1142
|
-
});
|
1143
|
-
});
|
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
|
+
}
|
1144
1004
|
};
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
balance = entry.result;
|
1173
|
-
balance = Web3Utils.hexToNumberString(balance);
|
1174
|
-
balance = balance / BASE;
|
1175
|
-
output.push(balance);
|
1176
|
-
}
|
1177
|
-
return [2 /*return*/, output];
|
1178
|
-
case 3:
|
1179
|
-
e_18 = _a.sent();
|
1180
|
-
console.error(tag, e_18);
|
1181
|
-
return [3 /*break*/, 4];
|
1182
|
-
case 4: return [2 /*return*/];
|
1183
|
-
}
|
1184
|
-
});
|
1185
|
-
});
|
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
|
+
}
|
1186
1032
|
};
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
"jsonrpc": "2.0",
|
1201
|
-
"method": action.method,
|
1202
|
-
"params": action.params,
|
1203
|
-
"id": 1
|
1204
|
-
};
|
1205
|
-
body.push(req);
|
1206
|
-
}
|
1207
|
-
options = {
|
1208
|
-
method: "POST",
|
1209
|
-
url: NODE_URL,
|
1210
|
-
headers: { 'content-type': 'application/json' },
|
1211
|
-
body: JSON.stringify(body)
|
1212
|
-
};
|
1213
|
-
return [4 /*yield*/, request(options)];
|
1214
|
-
case 2:
|
1215
|
-
result = _a.sent();
|
1216
|
-
//console.log("result: ",result)
|
1217
|
-
result = JSON.parse(result);
|
1218
|
-
if (result.error)
|
1219
|
-
throw JSON.stringify(result.error);
|
1220
|
-
return [2 /*return*/, result];
|
1221
|
-
case 3:
|
1222
|
-
err_1 = _a.sent();
|
1223
|
-
throw new Error(err_1);
|
1224
|
-
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);
|
1225
1046
|
}
|
1226
|
-
|
1227
|
-
|
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
|
+
};
|
1228
1065
|
//get_approval_status
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
contract = new web3.eth.Contract(constant_1.ERC20ABI, tokenAddress);
|
1240
|
-
return [4 /*yield*/, contract.methods.allowance(spender, sender).call()];
|
1241
|
-
case 2:
|
1242
|
-
allowance = _a.sent();
|
1243
|
-
return [2 /*return*/, allowance];
|
1244
|
-
case 3:
|
1245
|
-
e_19 = _a.sent();
|
1246
|
-
console.error(tag, e_19);
|
1247
|
-
return [3 /*break*/, 4];
|
1248
|
-
case 4: return [2 /*return*/];
|
1249
|
-
}
|
1250
|
-
});
|
1251
|
-
});
|
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
|
+
}
|
1252
1076
|
};
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
case 2:
|
1265
|
-
ethInto = _a.sent();
|
1266
|
-
log.debug(tag, "ethInto: ", ethInto);
|
1267
|
-
return [2 /*return*/, true];
|
1268
|
-
case 3:
|
1269
|
-
e_20 = _a.sent();
|
1270
|
-
console.error(tag, e_20);
|
1271
|
-
return [3 /*break*/, 4];
|
1272
|
-
case 4: return [2 /*return*/];
|
1273
|
-
}
|
1274
|
-
});
|
1275
|
-
});
|
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
|
+
}
|
1276
1088
|
};
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
case 2:
|
1291
|
-
ethInfo = _a.sent();
|
1292
|
-
//TODO filter by LP contracts
|
1293
|
-
log.debug(tag, "ethInfo: ", ethInfo);
|
1294
|
-
return [2 /*return*/, ethInfo];
|
1295
|
-
case 3:
|
1296
|
-
e_21 = _a.sent();
|
1297
|
-
console.error(tag, e_21);
|
1298
|
-
return [3 /*break*/, 4];
|
1299
|
-
case 4: return [2 /*return*/];
|
1300
|
-
}
|
1301
|
-
});
|
1302
|
-
});
|
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
|
+
}
|
1303
1102
|
};
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
case 2:
|
1318
|
-
ethInfo = _a.sent();
|
1319
|
-
//TODO filter by LP contracts
|
1320
|
-
log.debug(tag, "ethInfo: ", ethInfo);
|
1321
|
-
return [2 /*return*/, ethInfo];
|
1322
|
-
case 3:
|
1323
|
-
e_22 = _a.sent();
|
1324
|
-
console.error(tag, e_22);
|
1325
|
-
return [3 /*break*/, 4];
|
1326
|
-
case 4: return [2 /*return*/];
|
1327
|
-
}
|
1328
|
-
});
|
1329
|
-
});
|
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
|
+
}
|
1330
1116
|
};
|
1331
1117
|
/*
|
1332
1118
|
let swap = {
|
@@ -1347,588 +1133,435 @@ let swap = {
|
|
1347
1133
|
amount: "0.1"
|
1348
1134
|
}
|
1349
1135
|
*/
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
throw e;
|
1370
|
-
}
|
1371
|
-
return [2 /*return*/];
|
1372
|
-
});
|
1373
|
-
});
|
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
|
+
}
|
1374
1155
|
};
|
1375
1156
|
/*
|
1376
1157
|
X-chain compatible call
|
1377
1158
|
*/
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
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 })
|
1433
1224
|
}
|
1434
|
-
}
|
1435
|
-
}
|
1225
|
+
};
|
1226
|
+
}
|
1227
|
+
catch (e) {
|
1228
|
+
console.error(tag, "Error: ", e);
|
1229
|
+
throw e;
|
1230
|
+
}
|
1436
1231
|
};
|
1437
|
-
|
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
|
-
case 5: return [2 /*return*/, estimate];
|
1475
|
-
case 6:
|
1476
|
-
e_24 = _b.sent();
|
1477
|
-
log.error(tag, e_24);
|
1478
|
-
throw e_24;
|
1479
|
-
case 7: return [2 /*return*/];
|
1480
|
-
}
|
1481
|
-
});
|
1482
|
-
});
|
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
|
+
}
|
1483
1269
|
};
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
// @ts-ignore
|
1511
|
-
params.amount = {
|
1512
|
-
// @ts-ignore
|
1513
|
-
amount: function () { return .98; }
|
1514
|
-
};
|
1515
|
-
}
|
1516
|
-
log.debug(tag, "get_gas_limit: ", {
|
1517
|
-
asset: params.asset,
|
1518
|
-
amount: params.amount,
|
1519
|
-
recipient: params.recipient,
|
1520
|
-
memo: params.memo,
|
1521
|
-
});
|
1522
|
-
return [4 /*yield*/, get_gas_limit({
|
1523
|
-
asset: params.asset,
|
1524
|
-
amount: params.amount,
|
1525
|
-
recipient: params.recipient,
|
1526
|
-
memo: params.memo,
|
1527
|
-
})];
|
1528
|
-
case 3:
|
1529
|
-
gasLimit = _b.sent();
|
1530
|
-
output = {
|
1531
|
-
gasPrices: gasPrices,
|
1532
|
-
fees: {
|
1533
|
-
type: 'byte',
|
1534
|
-
average: (0, utils_1.getFee)({ gasPrice: averageGP, gasLimit: gasLimit }).amount().toString(),
|
1535
|
-
fast: (0, utils_1.getFee)({ gasPrice: fastGP, gasLimit: gasLimit }).amount().toString(),
|
1536
|
-
fastest: (0, utils_1.getFee)({ gasPrice: fastestGP, gasLimit: gasLimit }).amount().toString(),
|
1537
|
-
},
|
1538
|
-
gasLimit: gasLimit,
|
1539
|
-
};
|
1540
|
-
return [2 /*return*/, output];
|
1541
|
-
case 4:
|
1542
|
-
e_25 = _b.sent();
|
1543
|
-
log.error(tag, e_25);
|
1544
|
-
throw e_25;
|
1545
|
-
case 5: return [2 /*return*/];
|
1546
|
-
}
|
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,
|
1547
1296
|
});
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
return __generator(this, function (_a) {
|
1554
|
-
switch (_a.label) {
|
1555
|
-
case 0:
|
1556
|
-
tag = TAG + " | broadcast_transaction | ";
|
1557
|
-
_a.label = 1;
|
1558
|
-
case 1:
|
1559
|
-
_a.trys.push([1, 3, , 4]);
|
1560
|
-
output = {};
|
1561
|
-
output.success = false;
|
1562
|
-
log.debug(tag, "tx: ", tx);
|
1563
|
-
if (!tx)
|
1564
|
-
throw Error("101: missing tx!");
|
1565
|
-
return [4 /*yield*/, axios({
|
1566
|
-
method: 'GET',
|
1567
|
-
url: 'https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=' + tx + '&apikey=' + process.env['ETHERSCAN_API_KEY']
|
1568
|
-
})];
|
1569
|
-
case 2:
|
1570
|
-
resp = _a.sent();
|
1571
|
-
resp = resp.data;
|
1572
|
-
console.log(resp);
|
1573
|
-
//push blockbook
|
1574
|
-
//TODO lifecycle hook?
|
1575
|
-
// let resp2 = await web3.eth.sendSignedTransaction(tx)
|
1576
|
-
// .on('transactionHash', function(hash:any){
|
1577
|
-
// console.log("hash: ",hash)
|
1578
|
-
// })
|
1579
|
-
// .on('receipt', function(receipt:any){
|
1580
|
-
// console.log("receipt: ",receipt)
|
1581
|
-
// })
|
1582
|
-
// .on('confirmation', function(confirmationNumber:any, receipt:any){
|
1583
|
-
// console.log(confirmationNumber,receipt)
|
1584
|
-
// })
|
1585
|
-
// .on('error', console.error);
|
1586
|
-
//console.log("resp: ",resp)
|
1587
|
-
if (!resp.error)
|
1588
|
-
output.success = true;
|
1589
|
-
if (resp.error)
|
1590
|
-
output.error = resp;
|
1591
|
-
if (resp.result)
|
1592
|
-
output.txid = resp.result;
|
1593
|
-
return [2 /*return*/, output];
|
1594
|
-
case 3:
|
1595
|
-
e_26 = _a.sent();
|
1596
|
-
log.error(tag, e_26);
|
1597
|
-
throw e_26;
|
1598
|
-
case 4: return [2 /*return*/];
|
1599
|
-
}
|
1297
|
+
const gasLimit = await get_gas_limit({
|
1298
|
+
asset: params.asset,
|
1299
|
+
amount: params.amount,
|
1300
|
+
recipient: params.recipient,
|
1301
|
+
memo: params.memo,
|
1600
1302
|
});
|
1601
|
-
|
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
|
+
}
|
1602
1319
|
};
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
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']
|
1617
1335
|
});
|
1618
|
-
|
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
|
+
}
|
1619
1364
|
};
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
}
|
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
|
+
}
|
1375
|
+
};
|
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;
|
1664
1408
|
}
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
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
|
+
}
|
1671
1416
|
}
|
1672
|
-
}
|
1673
|
-
|
1417
|
+
}
|
1418
|
+
return { balances, valueUsds, coinInfo };
|
1419
|
+
}
|
1420
|
+
catch (e) {
|
1421
|
+
console.error(tag, e);
|
1422
|
+
}
|
1674
1423
|
};
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
return [4 /*yield*/, contract.methods.balanceOf(address).call()
|
1697
|
-
//log.debug(tag,"balance: ",balance)
|
1698
|
-
];
|
1699
|
-
case 3:
|
1700
|
-
balance = _a.sent();
|
1701
|
-
//log.debug(tag,"balance: ",balance)
|
1702
|
-
return [2 /*return*/, balance / Math.pow(10, decimals)];
|
1703
|
-
case 4:
|
1704
|
-
e_28 = _a.sent();
|
1705
|
-
console.error(tag, e_28);
|
1706
|
-
return [3 /*break*/, 5];
|
1707
|
-
case 5: return [2 /*return*/];
|
1708
|
-
}
|
1709
|
-
});
|
1710
|
-
});
|
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
|
+
}
|
1711
1445
|
};
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
case 2:
|
1727
|
-
decimals = _a.sent();
|
1728
|
-
return [4 /*yield*/, contract.methods.balanceOf(address).call()
|
1729
|
-
//log.debug(tag,"balance: ",balance)
|
1730
|
-
];
|
1731
|
-
case 3:
|
1732
|
-
balance = _a.sent();
|
1733
|
-
//log.debug(tag,"balance: ",balance)
|
1734
|
-
return [2 /*return*/, balance / Math.pow(10, decimals)];
|
1735
|
-
case 4:
|
1736
|
-
e_29 = _a.sent();
|
1737
|
-
console.error(tag, e_29);
|
1738
|
-
return [3 /*break*/, 5];
|
1739
|
-
case 5: return [2 /*return*/];
|
1740
|
-
}
|
1741
|
-
});
|
1742
|
-
});
|
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
|
+
}
|
1743
1460
|
};
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
//normal tx info
|
1762
|
-
output = (_a.sent()) / BASE;
|
1763
|
-
return [2 /*return*/, output];
|
1764
|
-
case 3:
|
1765
|
-
e_30 = _a.sent();
|
1766
|
-
console.error(tag, e_30);
|
1767
|
-
return [3 /*break*/, 4];
|
1768
|
-
case 4: return [2 /*return*/];
|
1769
|
-
}
|
1770
|
-
});
|
1771
|
-
});
|
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
|
+
}
|
1772
1478
|
};
|
1773
|
-
|
1774
|
-
|
1775
|
-
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
return [4 /*yield*/, web3.eth.getBalance(address)];
|
1785
|
-
case 2:
|
1786
|
-
//normal tx info
|
1787
|
-
output = (_a.sent()) / BASE;
|
1788
|
-
return [2 /*return*/, output];
|
1789
|
-
case 3:
|
1790
|
-
e_31 = _a.sent();
|
1791
|
-
console.error(tag, e_31);
|
1792
|
-
return [3 /*break*/, 4];
|
1793
|
-
case 4: return [2 /*return*/];
|
1794
|
-
}
|
1795
|
-
});
|
1796
|
-
});
|
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
|
+
}
|
1797
1490
|
};
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
output = {};
|
1809
|
-
return [4 /*yield*/, blockbook.getAddressInfo('ETH', address)];
|
1810
|
-
case 2:
|
1811
|
-
ethInfo = _a.sent();
|
1812
|
-
return [2 /*return*/, ethInfo];
|
1813
|
-
case 3:
|
1814
|
-
e_32 = _a.sent();
|
1815
|
-
console.error(tag, e_32);
|
1816
|
-
return [3 /*break*/, 4];
|
1817
|
-
case 4: return [2 /*return*/];
|
1818
|
-
}
|
1819
|
-
});
|
1820
|
-
});
|
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
|
+
}
|
1821
1501
|
};
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
return [4 /*yield*/, web3.eth.getTransaction(txid)
|
1836
|
-
//if contract
|
1837
|
-
];
|
1838
|
-
case 2:
|
1839
|
-
//normal tx info
|
1840
|
-
_a.txInfo = _c.sent();
|
1841
|
-
//if contract
|
1842
|
-
_b = output;
|
1843
|
-
return [4 /*yield*/, web3.eth.getTransactionReceipt(txid)];
|
1844
|
-
case 3:
|
1845
|
-
//if contract
|
1846
|
-
_b.receipt = _c.sent();
|
1847
|
-
return [2 /*return*/, output];
|
1848
|
-
case 4:
|
1849
|
-
e_33 = _c.sent();
|
1850
|
-
console.error(tag, e_33);
|
1851
|
-
return [3 /*break*/, 5];
|
1852
|
-
case 5: return [2 /*return*/];
|
1853
|
-
}
|
1854
|
-
});
|
1855
|
-
});
|
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
|
+
}
|
1856
1515
|
};
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
break;
|
1898
|
-
case "3":
|
1899
|
-
networkName = "Ropsten";
|
1900
|
-
break;
|
1901
|
-
case "4":
|
1902
|
-
networkName = "Rinkeby";
|
1903
|
-
break;
|
1904
|
-
case "42":
|
1905
|
-
networkName = "Kovan";
|
1906
|
-
break;
|
1907
|
-
default:
|
1908
|
-
networkName = "Unknown";
|
1909
|
-
}
|
1910
|
-
output.networkName = networkName;
|
1911
|
-
//
|
1912
|
-
_e = output;
|
1913
|
-
return [4 /*yield*/, web3.eth.getGasPrice()
|
1914
|
-
//
|
1915
|
-
];
|
1916
|
-
case 6:
|
1917
|
-
//
|
1918
|
-
_e.gasPrice = _g.sent();
|
1919
|
-
//
|
1920
|
-
_f = output;
|
1921
|
-
return [4 /*yield*/, web3.eth.isSyncing()];
|
1922
|
-
case 7:
|
1923
|
-
//
|
1924
|
-
_f.syncing = _g.sent();
|
1925
|
-
return [2 /*return*/, output];
|
1926
|
-
case 8:
|
1927
|
-
e_34 = _g.sent();
|
1928
|
-
console.error(tag, e_34);
|
1929
|
-
return [3 /*break*/, 9];
|
1930
|
-
case 9: return [2 /*return*/];
|
1931
|
-
}
|
1932
|
-
});
|
1933
|
-
});
|
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
|
+
}
|
1934
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
|