@xchainjs/xchain-thorchain 0.27.7 → 0.27.9
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/client.d.ts +6 -0
- package/lib/const.d.ts +5 -3
- package/lib/index.esm.js +161 -37
- package/lib/index.js +162 -36
- package/lib/types/client-types.d.ts +21 -0
- package/lib/utils.d.ts +1 -1
- package/package.json +5 -5
package/lib/client.d.ts
CHANGED
|
@@ -167,6 +167,12 @@ declare class Client extends BaseXChainClient implements ThorchainClient, XChain
|
|
|
167
167
|
* @returns {Tx} The transaction details of the given transaction id.
|
|
168
168
|
*/
|
|
169
169
|
getTransactionData(txId: string, address: Address): Promise<Tx>;
|
|
170
|
+
/** This function is used when in bound or outbound tx is not of thorchain
|
|
171
|
+
*
|
|
172
|
+
* @param txId - transaction hash
|
|
173
|
+
* @returns - Tx object
|
|
174
|
+
*/
|
|
175
|
+
private getTransactionDataThornode;
|
|
170
176
|
/**
|
|
171
177
|
* Get the transaction details of a given transaction id. (from /thorchain/txs/hash)
|
|
172
178
|
*
|
package/lib/const.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { Asset
|
|
1
|
+
import { Asset } from '@xchainjs/xchain-util/lib';
|
|
2
2
|
import { ExplorerUrls } from './types';
|
|
3
3
|
export declare const DECIMAL = 8;
|
|
4
4
|
export declare const DEFAULT_GAS_ADJUSTMENT = 2;
|
|
5
5
|
export declare const DEFAULT_GAS_LIMIT_VALUE = "4000000";
|
|
6
6
|
export declare const DEPOSIT_GAS_LIMIT_VALUE = "600000000";
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const MAX_TX_COUNT_PER_PAGE = 100;
|
|
8
|
+
export declare const MAX_TX_COUNT_PER_FUNCTION_CALL = 500;
|
|
9
|
+
export declare const MAX_PAGES_PER_FUNCTION_CALL = 15;
|
|
8
10
|
export declare const RUNE_SYMBOL = "\u16B1";
|
|
9
11
|
export declare const defaultExplorerUrls: ExplorerUrls;
|
|
10
12
|
/**
|
|
11
13
|
* Chain identifier for Thorchain
|
|
12
14
|
*
|
|
13
15
|
*/
|
|
14
|
-
export declare const THORChain:
|
|
16
|
+
export declare const THORChain: "THOR";
|
|
15
17
|
/**
|
|
16
18
|
* Base "chain" asset for RUNE-67C on Binance test net.
|
|
17
19
|
*
|
package/lib/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import cosmosclient from '@cosmos-client/core';
|
|
2
2
|
import { Network as Network$1, TxType, singleFee, FeeType, BaseXChainClient } from '@xchainjs/xchain-client';
|
|
3
3
|
import { GAIAChain, CosmosSDKClient } from '@xchainjs/xchain-cosmos';
|
|
4
|
-
import { assetToString, isSynthAsset, assetFromString, baseAmount, assetToBase, assetAmount } from '@xchainjs/xchain-util';
|
|
4
|
+
import { assetToString, isSynthAsset, assetFromString, baseAmount, assetToBase, assetAmount, delay, assetFromStringEx } from '@xchainjs/xchain-util';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { Network } from '@xchainjs/xchain-client/lib';
|
|
7
7
|
import { decode } from 'bech32-buffer';
|
|
@@ -4269,7 +4269,9 @@ const DECIMAL = 8;
|
|
|
4269
4269
|
const DEFAULT_GAS_ADJUSTMENT = 2;
|
|
4270
4270
|
const DEFAULT_GAS_LIMIT_VALUE = '4000000';
|
|
4271
4271
|
const DEPOSIT_GAS_LIMIT_VALUE = '600000000';
|
|
4272
|
-
const
|
|
4272
|
+
const MAX_TX_COUNT_PER_PAGE = 100;
|
|
4273
|
+
const MAX_TX_COUNT_PER_FUNCTION_CALL = 500;
|
|
4274
|
+
const MAX_PAGES_PER_FUNCTION_CALL = 15;
|
|
4273
4275
|
const RUNE_SYMBOL = 'ᚱ';
|
|
4274
4276
|
const defaultExplorerUrls = {
|
|
4275
4277
|
root: {
|
|
@@ -9757,7 +9759,7 @@ const registerSendCodecs = () => {
|
|
|
9757
9759
|
* @param {Address} address - Address to get transaction data for
|
|
9758
9760
|
* @returns {TxData} Parsed transaction data
|
|
9759
9761
|
*/
|
|
9760
|
-
const getDepositTxDataFromLogs = (logs, address) => {
|
|
9762
|
+
const getDepositTxDataFromLogs = (logs, address, senderAsset, receiverAsset) => {
|
|
9761
9763
|
var _a;
|
|
9762
9764
|
const events = (_a = logs[0]) === null || _a === void 0 ? void 0 : _a.events;
|
|
9763
9765
|
if (!events) {
|
|
@@ -9784,7 +9786,7 @@ const getDepositTxDataFromLogs = (logs, address) => {
|
|
|
9784
9786
|
// filter out txs which are not based on given address
|
|
9785
9787
|
.filter(({ sender, recipient }) => sender === address || recipient === address)
|
|
9786
9788
|
// transform `TransferData` -> `TxData`
|
|
9787
|
-
.reduce((acc, { sender, recipient, amount }) => (Object.assign(Object.assign({}, acc), { from: [...acc.from, { amount, from: sender }], to: [...acc.to, { amount, to: recipient }] })), { from: [], to: [], type: TxType.Transfer });
|
|
9789
|
+
.reduce((acc, { sender, recipient, amount }) => (Object.assign(Object.assign({}, acc), { from: [...acc.from, { amount, from: sender, asset: senderAsset }], to: [...acc.to, { amount, to: recipient, asset: receiverAsset }] })), { from: [], to: [], type: TxType.Transfer });
|
|
9788
9790
|
return txData;
|
|
9789
9791
|
};
|
|
9790
9792
|
/**
|
|
@@ -10058,24 +10060,45 @@ class Client extends BaseXChainClient {
|
|
|
10058
10060
|
const address = (params === null || params === void 0 ? void 0 : params.address) || this.getAddress();
|
|
10059
10061
|
const txMinHeight = undefined;
|
|
10060
10062
|
const txMaxHeight = undefined;
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
10064
|
-
|
|
10065
|
-
|
|
10066
|
-
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
const
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10063
|
+
if (limit + offset > MAX_PAGES_PER_FUNCTION_CALL * MAX_TX_COUNT_PER_PAGE) {
|
|
10064
|
+
throw Error(`limit plus offset can not be grater than ${MAX_PAGES_PER_FUNCTION_CALL * MAX_TX_COUNT_PER_PAGE}`);
|
|
10065
|
+
}
|
|
10066
|
+
if (limit > MAX_TX_COUNT_PER_FUNCTION_CALL) {
|
|
10067
|
+
throw Error(`Maximum number of transaction per call is ${MAX_TX_COUNT_PER_FUNCTION_CALL}`);
|
|
10068
|
+
}
|
|
10069
|
+
const pagesNumber = Math.ceil((limit + offset) / MAX_TX_COUNT_PER_PAGE);
|
|
10070
|
+
const promiseTotalTxIncomingHistory = [];
|
|
10071
|
+
const promiseTotalTxOutgoingHistory = [];
|
|
10072
|
+
for (let index = 1; index <= pagesNumber; index++) {
|
|
10073
|
+
promiseTotalTxIncomingHistory.push(this.cosmosClient.searchTxFromRPC({
|
|
10074
|
+
rpcEndpoint: this.getClientUrl().rpc,
|
|
10075
|
+
messageAction,
|
|
10076
|
+
transferRecipient: address,
|
|
10077
|
+
page: index,
|
|
10078
|
+
limit: MAX_TX_COUNT_PER_PAGE,
|
|
10079
|
+
txMinHeight,
|
|
10080
|
+
txMaxHeight,
|
|
10081
|
+
}));
|
|
10082
|
+
promiseTotalTxOutgoingHistory.push(this.cosmosClient.searchTxFromRPC({
|
|
10083
|
+
rpcEndpoint: this.getClientUrl().rpc,
|
|
10084
|
+
messageAction,
|
|
10085
|
+
transferSender: address,
|
|
10086
|
+
page: index,
|
|
10087
|
+
limit: MAX_TX_COUNT_PER_PAGE,
|
|
10088
|
+
txMinHeight,
|
|
10089
|
+
txMaxHeight,
|
|
10090
|
+
}));
|
|
10091
|
+
}
|
|
10092
|
+
const incomingSearchResult = yield Promise.all(promiseTotalTxIncomingHistory);
|
|
10093
|
+
const outgoingSearchResult = yield Promise.all(promiseTotalTxOutgoingHistory);
|
|
10094
|
+
const totalTxIncomingHistory = incomingSearchResult.reduce((allTxs, searchResult) => {
|
|
10095
|
+
return [...allTxs, ...searchResult.txs];
|
|
10096
|
+
}, []);
|
|
10097
|
+
const totalTxOutgoingHistory = outgoingSearchResult.reduce((allTxs, searchResult) => {
|
|
10098
|
+
return [...allTxs, ...searchResult.txs];
|
|
10099
|
+
}, []);
|
|
10100
|
+
let history = totalTxIncomingHistory
|
|
10101
|
+
.concat(totalTxOutgoingHistory)
|
|
10079
10102
|
.sort((a, b) => {
|
|
10080
10103
|
if (a.height !== b.height)
|
|
10081
10104
|
return parseInt(b.height) > parseInt(a.height) ? 1 : -1;
|
|
@@ -10084,12 +10107,16 @@ class Client extends BaseXChainClient {
|
|
|
10084
10107
|
return 0;
|
|
10085
10108
|
})
|
|
10086
10109
|
.reduce((acc, tx) => [...acc, ...(acc.length === 0 || acc[acc.length - 1].hash !== tx.hash ? [tx] : [])], [])
|
|
10087
|
-
.filter((params === null || params === void 0 ? void 0 : params.filterFn) ? params.filterFn : (tx) => tx)
|
|
10088
|
-
.filter((_, index) => index < MAX_TX_COUNT);
|
|
10089
|
-
// get `total` before filtering txs out for pagination
|
|
10090
|
-
const total = history.length;
|
|
10110
|
+
.filter((params === null || params === void 0 ? void 0 : params.filterFn) ? params.filterFn : (tx) => tx);
|
|
10091
10111
|
history = history.filter((_, index) => index >= offset && index < offset + limit);
|
|
10092
|
-
const
|
|
10112
|
+
const total = history.length;
|
|
10113
|
+
const txs = [];
|
|
10114
|
+
for (let i = 0; i < history.length; i += 10) {
|
|
10115
|
+
const batch = history.slice(i, i + 10);
|
|
10116
|
+
const result = yield Promise.all(batch.map(({ hash }) => this.getTransactionData(hash, address)));
|
|
10117
|
+
txs.push(...result);
|
|
10118
|
+
delay(2000); // Delay to avoid 503 from ninerealms server
|
|
10119
|
+
}
|
|
10093
10120
|
return {
|
|
10094
10121
|
total,
|
|
10095
10122
|
txs,
|
|
@@ -10274,20 +10301,117 @@ class Client extends BaseXChainClient {
|
|
|
10274
10301
|
* @returns {Tx} The transaction details of the given transaction id.
|
|
10275
10302
|
*/
|
|
10276
10303
|
getTransactionData(txId, address) {
|
|
10304
|
+
var _a, _b, _c;
|
|
10277
10305
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10306
|
+
try {
|
|
10307
|
+
const txResult = yield this.cosmosClient.txsHashGet(txId);
|
|
10308
|
+
const bond = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'bond');
|
|
10309
|
+
const transfer = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'transfer');
|
|
10310
|
+
if (!transfer)
|
|
10311
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10312
|
+
const sender = (_a = transfer[0].attributes.find((attr) => attr.key === 'sender')) === null || _a === void 0 ? void 0 : _a.value;
|
|
10313
|
+
const senderAmount = transfer[0].attributes.filter((attr) => attr.key === 'amount')[1].value;
|
|
10314
|
+
const assetString = senderAmount.split(/(?<=\d)(?=[a-zA-Z])/);
|
|
10315
|
+
const senderAsset = assetString[1] === 'rune' ? AssetRuneNative : assetFromStringEx(assetString[1]);
|
|
10316
|
+
const senderAddress = sender ? sender : address;
|
|
10317
|
+
const message = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'message');
|
|
10318
|
+
const coinSpent = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'coin_spent');
|
|
10319
|
+
if (!message || !coinSpent)
|
|
10320
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10321
|
+
const action = (_b = message[0].attributes.find((attr) => attr.key === 'action')) === null || _b === void 0 ? void 0 : _b.value;
|
|
10322
|
+
if (!bond)
|
|
10323
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10324
|
+
// Rune only transactions
|
|
10325
|
+
if (bond[0].type === 'bond' || action === 'send') {
|
|
10326
|
+
const assetTo = AssetRuneNative;
|
|
10327
|
+
const txData = txResult && txResult.logs
|
|
10328
|
+
? getDepositTxDataFromLogs(txResult.logs, senderAddress, senderAsset, assetTo)
|
|
10329
|
+
: null;
|
|
10330
|
+
//console.log(JSON.stringify(txData, null, 2))
|
|
10331
|
+
if (!txData)
|
|
10332
|
+
throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
|
|
10333
|
+
const { from, to, type } = txData;
|
|
10334
|
+
return {
|
|
10335
|
+
hash: txId,
|
|
10336
|
+
asset: senderAsset,
|
|
10337
|
+
from,
|
|
10338
|
+
to,
|
|
10339
|
+
date: new Date(txResult.timestamp),
|
|
10340
|
+
type,
|
|
10341
|
+
};
|
|
10342
|
+
}
|
|
10343
|
+
// synths and other tx types
|
|
10344
|
+
const messageBody = JSON.stringify((_c = txResult.tx) === null || _c === void 0 ? void 0 : _c.body.messages).split(':');
|
|
10345
|
+
const assetTo = assetFromStringEx(messageBody[7]);
|
|
10346
|
+
const txData = txResult && txResult.logs ? getDepositTxDataFromLogs(txResult.logs, senderAddress, senderAsset, assetTo) : null;
|
|
10347
|
+
if (!txData)
|
|
10348
|
+
throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
|
|
10349
|
+
const { from, to, type } = txData;
|
|
10350
|
+
return {
|
|
10351
|
+
hash: txId,
|
|
10352
|
+
asset: senderAsset,
|
|
10353
|
+
from,
|
|
10354
|
+
to,
|
|
10355
|
+
date: new Date(txResult.timestamp),
|
|
10356
|
+
type,
|
|
10357
|
+
};
|
|
10358
|
+
}
|
|
10359
|
+
catch (error) { }
|
|
10360
|
+
return yield this.getTransactionDataThornode(txId);
|
|
10361
|
+
});
|
|
10362
|
+
}
|
|
10363
|
+
/** This function is used when in bound or outbound tx is not of thorchain
|
|
10364
|
+
*
|
|
10365
|
+
* @param txId - transaction hash
|
|
10366
|
+
* @returns - Tx object
|
|
10367
|
+
*/
|
|
10368
|
+
getTransactionDataThornode(txId) {
|
|
10369
|
+
var _a, _b, _c;
|
|
10370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10371
|
+
const txResult = JSON.stringify(yield this.thornodeAPIGet(`/tx/${txId}`));
|
|
10372
|
+
const getTx = JSON.parse(txResult);
|
|
10373
|
+
if (!getTx)
|
|
10374
|
+
throw Error(`Could not return tx data`);
|
|
10375
|
+
const senderAsset = assetFromStringEx(`${(_a = getTx.observed_tx) === null || _a === void 0 ? void 0 : _a.tx.coins[0].asset}`);
|
|
10376
|
+
const fromAddress = `${getTx.observed_tx.tx.from_address}`;
|
|
10377
|
+
const from = [
|
|
10378
|
+
{ from: fromAddress, amount: baseAmount((_b = getTx.observed_tx) === null || _b === void 0 ? void 0 : _b.tx.coins[0].amount), asset: senderAsset },
|
|
10379
|
+
];
|
|
10380
|
+
const splitMemo = (_c = getTx.observed_tx.tx.memo) === null || _c === void 0 ? void 0 : _c.split(':');
|
|
10381
|
+
if (!splitMemo)
|
|
10382
|
+
throw Error(`Could not parse memo`);
|
|
10383
|
+
let asset;
|
|
10384
|
+
let amount;
|
|
10385
|
+
if (splitMemo[0] === 'OUT') {
|
|
10386
|
+
asset = assetFromStringEx(getTx.observed_tx.tx.coins[0].asset);
|
|
10387
|
+
amount = getTx.observed_tx.tx.coins[0].amount;
|
|
10388
|
+
const addressTo = getTx.observed_tx.tx.to_address ? getTx.observed_tx.tx.to_address : 'undefined';
|
|
10389
|
+
const to = [{ to: addressTo, amount: baseAmount(amount, DECIMAL), asset: asset }];
|
|
10390
|
+
const txData = {
|
|
10391
|
+
hash: txId,
|
|
10392
|
+
asset: senderAsset,
|
|
10393
|
+
from,
|
|
10394
|
+
to,
|
|
10395
|
+
date: new Date(),
|
|
10396
|
+
type: TxType.Transfer,
|
|
10397
|
+
};
|
|
10398
|
+
return txData;
|
|
10399
|
+
}
|
|
10400
|
+
asset = assetFromStringEx(splitMemo[1]);
|
|
10401
|
+
const address = splitMemo[2];
|
|
10402
|
+
amount = splitMemo[3];
|
|
10403
|
+
const receiverAsset = asset;
|
|
10404
|
+
const recieverAmount = amount;
|
|
10405
|
+
const to = [{ to: address, amount: baseAmount(recieverAmount, DECIMAL), asset: receiverAsset }];
|
|
10406
|
+
const txData = {
|
|
10284
10407
|
hash: txId,
|
|
10285
|
-
asset:
|
|
10408
|
+
asset: senderAsset,
|
|
10286
10409
|
from,
|
|
10287
10410
|
to,
|
|
10288
|
-
date: new Date(
|
|
10289
|
-
type,
|
|
10411
|
+
date: new Date(),
|
|
10412
|
+
type: TxType.Transfer,
|
|
10290
10413
|
};
|
|
10414
|
+
return txData;
|
|
10291
10415
|
});
|
|
10292
10416
|
}
|
|
10293
10417
|
/**
|
|
@@ -10529,4 +10653,4 @@ const msgNativeTxFromJson = (value) => {
|
|
|
10529
10653
|
return new MsgNativeTx(value.coins, value.memo, cosmosclient.AccAddress.fromString(value.signer));
|
|
10530
10654
|
};
|
|
10531
10655
|
|
|
10532
|
-
export { AssetRune67C, AssetRuneB1A, AssetRuneERC20, AssetRuneERC20Testnet, AssetRuneNative, Client, DECIMAL, DEFAULT_GAS_ADJUSTMENT, DEFAULT_GAS_LIMIT_VALUE, DEPOSIT_GAS_LIMIT_VALUE,
|
|
10656
|
+
export { AssetRune67C, AssetRuneB1A, AssetRuneERC20, AssetRuneERC20Testnet, AssetRuneNative, Client, DECIMAL, DEFAULT_GAS_ADJUSTMENT, DEFAULT_GAS_LIMIT_VALUE, DEPOSIT_GAS_LIMIT_VALUE, MAX_PAGES_PER_FUNCTION_CALL, MAX_TX_COUNT_PER_FUNCTION_CALL, MAX_TX_COUNT_PER_PAGE, MsgNativeTx, RUNE_SYMBOL, THORChain, assetFromDenom, buildDepositTx, buildTransferTx, buildUnsignedTx, defaultExplorerUrls, getAccount, getBalance, getChainId, getDefaultFees, getDenom, getDepositTxDataFromLogs, getEstimatedGas, getExplorerAddressUrl, getExplorerTxUrl, getExplorerUrl, getPrefix, getSequence, getTxType, isAssetRuneNative, isBroadcastSuccess, msgNativeTxFromJson, registerDepositCodecs, registerSendCodecs };
|
package/lib/index.js
CHANGED
|
@@ -4278,7 +4278,9 @@ const DECIMAL = 8;
|
|
|
4278
4278
|
const DEFAULT_GAS_ADJUSTMENT = 2;
|
|
4279
4279
|
const DEFAULT_GAS_LIMIT_VALUE = '4000000';
|
|
4280
4280
|
const DEPOSIT_GAS_LIMIT_VALUE = '600000000';
|
|
4281
|
-
const
|
|
4281
|
+
const MAX_TX_COUNT_PER_PAGE = 100;
|
|
4282
|
+
const MAX_TX_COUNT_PER_FUNCTION_CALL = 500;
|
|
4283
|
+
const MAX_PAGES_PER_FUNCTION_CALL = 15;
|
|
4282
4284
|
const RUNE_SYMBOL = 'ᚱ';
|
|
4283
4285
|
const defaultExplorerUrls = {
|
|
4284
4286
|
root: {
|
|
@@ -9766,7 +9768,7 @@ const registerSendCodecs = () => {
|
|
|
9766
9768
|
* @param {Address} address - Address to get transaction data for
|
|
9767
9769
|
* @returns {TxData} Parsed transaction data
|
|
9768
9770
|
*/
|
|
9769
|
-
const getDepositTxDataFromLogs = (logs, address) => {
|
|
9771
|
+
const getDepositTxDataFromLogs = (logs, address, senderAsset, receiverAsset) => {
|
|
9770
9772
|
var _a;
|
|
9771
9773
|
const events = (_a = logs[0]) === null || _a === void 0 ? void 0 : _a.events;
|
|
9772
9774
|
if (!events) {
|
|
@@ -9793,7 +9795,7 @@ const getDepositTxDataFromLogs = (logs, address) => {
|
|
|
9793
9795
|
// filter out txs which are not based on given address
|
|
9794
9796
|
.filter(({ sender, recipient }) => sender === address || recipient === address)
|
|
9795
9797
|
// transform `TransferData` -> `TxData`
|
|
9796
|
-
.reduce((acc, { sender, recipient, amount }) => (Object.assign(Object.assign({}, acc), { from: [...acc.from, { amount, from: sender }], to: [...acc.to, { amount, to: recipient }] })), { from: [], to: [], type: xchainClient.TxType.Transfer });
|
|
9798
|
+
.reduce((acc, { sender, recipient, amount }) => (Object.assign(Object.assign({}, acc), { from: [...acc.from, { amount, from: sender, asset: senderAsset }], to: [...acc.to, { amount, to: recipient, asset: receiverAsset }] })), { from: [], to: [], type: xchainClient.TxType.Transfer });
|
|
9797
9799
|
return txData;
|
|
9798
9800
|
};
|
|
9799
9801
|
/**
|
|
@@ -10067,24 +10069,45 @@ class Client extends xchainClient.BaseXChainClient {
|
|
|
10067
10069
|
const address = (params === null || params === void 0 ? void 0 : params.address) || this.getAddress();
|
|
10068
10070
|
const txMinHeight = undefined;
|
|
10069
10071
|
const txMaxHeight = undefined;
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
const
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10072
|
+
if (limit + offset > MAX_PAGES_PER_FUNCTION_CALL * MAX_TX_COUNT_PER_PAGE) {
|
|
10073
|
+
throw Error(`limit plus offset can not be grater than ${MAX_PAGES_PER_FUNCTION_CALL * MAX_TX_COUNT_PER_PAGE}`);
|
|
10074
|
+
}
|
|
10075
|
+
if (limit > MAX_TX_COUNT_PER_FUNCTION_CALL) {
|
|
10076
|
+
throw Error(`Maximum number of transaction per call is ${MAX_TX_COUNT_PER_FUNCTION_CALL}`);
|
|
10077
|
+
}
|
|
10078
|
+
const pagesNumber = Math.ceil((limit + offset) / MAX_TX_COUNT_PER_PAGE);
|
|
10079
|
+
const promiseTotalTxIncomingHistory = [];
|
|
10080
|
+
const promiseTotalTxOutgoingHistory = [];
|
|
10081
|
+
for (let index = 1; index <= pagesNumber; index++) {
|
|
10082
|
+
promiseTotalTxIncomingHistory.push(this.cosmosClient.searchTxFromRPC({
|
|
10083
|
+
rpcEndpoint: this.getClientUrl().rpc,
|
|
10084
|
+
messageAction,
|
|
10085
|
+
transferRecipient: address,
|
|
10086
|
+
page: index,
|
|
10087
|
+
limit: MAX_TX_COUNT_PER_PAGE,
|
|
10088
|
+
txMinHeight,
|
|
10089
|
+
txMaxHeight,
|
|
10090
|
+
}));
|
|
10091
|
+
promiseTotalTxOutgoingHistory.push(this.cosmosClient.searchTxFromRPC({
|
|
10092
|
+
rpcEndpoint: this.getClientUrl().rpc,
|
|
10093
|
+
messageAction,
|
|
10094
|
+
transferSender: address,
|
|
10095
|
+
page: index,
|
|
10096
|
+
limit: MAX_TX_COUNT_PER_PAGE,
|
|
10097
|
+
txMinHeight,
|
|
10098
|
+
txMaxHeight,
|
|
10099
|
+
}));
|
|
10100
|
+
}
|
|
10101
|
+
const incomingSearchResult = yield Promise.all(promiseTotalTxIncomingHistory);
|
|
10102
|
+
const outgoingSearchResult = yield Promise.all(promiseTotalTxOutgoingHistory);
|
|
10103
|
+
const totalTxIncomingHistory = incomingSearchResult.reduce((allTxs, searchResult) => {
|
|
10104
|
+
return [...allTxs, ...searchResult.txs];
|
|
10105
|
+
}, []);
|
|
10106
|
+
const totalTxOutgoingHistory = outgoingSearchResult.reduce((allTxs, searchResult) => {
|
|
10107
|
+
return [...allTxs, ...searchResult.txs];
|
|
10108
|
+
}, []);
|
|
10109
|
+
let history = totalTxIncomingHistory
|
|
10110
|
+
.concat(totalTxOutgoingHistory)
|
|
10088
10111
|
.sort((a, b) => {
|
|
10089
10112
|
if (a.height !== b.height)
|
|
10090
10113
|
return parseInt(b.height) > parseInt(a.height) ? 1 : -1;
|
|
@@ -10093,12 +10116,16 @@ class Client extends xchainClient.BaseXChainClient {
|
|
|
10093
10116
|
return 0;
|
|
10094
10117
|
})
|
|
10095
10118
|
.reduce((acc, tx) => [...acc, ...(acc.length === 0 || acc[acc.length - 1].hash !== tx.hash ? [tx] : [])], [])
|
|
10096
|
-
.filter((params === null || params === void 0 ? void 0 : params.filterFn) ? params.filterFn : (tx) => tx)
|
|
10097
|
-
.filter((_, index) => index < MAX_TX_COUNT);
|
|
10098
|
-
// get `total` before filtering txs out for pagination
|
|
10099
|
-
const total = history.length;
|
|
10119
|
+
.filter((params === null || params === void 0 ? void 0 : params.filterFn) ? params.filterFn : (tx) => tx);
|
|
10100
10120
|
history = history.filter((_, index) => index >= offset && index < offset + limit);
|
|
10101
|
-
const
|
|
10121
|
+
const total = history.length;
|
|
10122
|
+
const txs = [];
|
|
10123
|
+
for (let i = 0; i < history.length; i += 10) {
|
|
10124
|
+
const batch = history.slice(i, i + 10);
|
|
10125
|
+
const result = yield Promise.all(batch.map(({ hash }) => this.getTransactionData(hash, address)));
|
|
10126
|
+
txs.push(...result);
|
|
10127
|
+
xchainUtil.delay(2000); // Delay to avoid 503 from ninerealms server
|
|
10128
|
+
}
|
|
10102
10129
|
return {
|
|
10103
10130
|
total,
|
|
10104
10131
|
txs,
|
|
@@ -10283,20 +10310,117 @@ class Client extends xchainClient.BaseXChainClient {
|
|
|
10283
10310
|
* @returns {Tx} The transaction details of the given transaction id.
|
|
10284
10311
|
*/
|
|
10285
10312
|
getTransactionData(txId, address) {
|
|
10313
|
+
var _a, _b, _c;
|
|
10286
10314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10315
|
+
try {
|
|
10316
|
+
const txResult = yield this.cosmosClient.txsHashGet(txId);
|
|
10317
|
+
const bond = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'bond');
|
|
10318
|
+
const transfer = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'transfer');
|
|
10319
|
+
if (!transfer)
|
|
10320
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10321
|
+
const sender = (_a = transfer[0].attributes.find((attr) => attr.key === 'sender')) === null || _a === void 0 ? void 0 : _a.value;
|
|
10322
|
+
const senderAmount = transfer[0].attributes.filter((attr) => attr.key === 'amount')[1].value;
|
|
10323
|
+
const assetString = senderAmount.split(/(?<=\d)(?=[a-zA-Z])/);
|
|
10324
|
+
const senderAsset = assetString[1] === 'rune' ? AssetRuneNative : xchainUtil.assetFromStringEx(assetString[1]);
|
|
10325
|
+
const senderAddress = sender ? sender : address;
|
|
10326
|
+
const message = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'message');
|
|
10327
|
+
const coinSpent = txResult.logs && txResult.logs[0].events.filter((i) => i.type === 'coin_spent');
|
|
10328
|
+
if (!message || !coinSpent)
|
|
10329
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10330
|
+
const action = (_b = message[0].attributes.find((attr) => attr.key === 'action')) === null || _b === void 0 ? void 0 : _b.value;
|
|
10331
|
+
if (!bond)
|
|
10332
|
+
throw new Error(`Failed to get transaction logs (tx-hash: ${txId})`);
|
|
10333
|
+
// Rune only transactions
|
|
10334
|
+
if (bond[0].type === 'bond' || action === 'send') {
|
|
10335
|
+
const assetTo = AssetRuneNative;
|
|
10336
|
+
const txData = txResult && txResult.logs
|
|
10337
|
+
? getDepositTxDataFromLogs(txResult.logs, senderAddress, senderAsset, assetTo)
|
|
10338
|
+
: null;
|
|
10339
|
+
//console.log(JSON.stringify(txData, null, 2))
|
|
10340
|
+
if (!txData)
|
|
10341
|
+
throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
|
|
10342
|
+
const { from, to, type } = txData;
|
|
10343
|
+
return {
|
|
10344
|
+
hash: txId,
|
|
10345
|
+
asset: senderAsset,
|
|
10346
|
+
from,
|
|
10347
|
+
to,
|
|
10348
|
+
date: new Date(txResult.timestamp),
|
|
10349
|
+
type,
|
|
10350
|
+
};
|
|
10351
|
+
}
|
|
10352
|
+
// synths and other tx types
|
|
10353
|
+
const messageBody = JSON.stringify((_c = txResult.tx) === null || _c === void 0 ? void 0 : _c.body.messages).split(':');
|
|
10354
|
+
const assetTo = xchainUtil.assetFromStringEx(messageBody[7]);
|
|
10355
|
+
const txData = txResult && txResult.logs ? getDepositTxDataFromLogs(txResult.logs, senderAddress, senderAsset, assetTo) : null;
|
|
10356
|
+
if (!txData)
|
|
10357
|
+
throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
|
|
10358
|
+
const { from, to, type } = txData;
|
|
10359
|
+
return {
|
|
10360
|
+
hash: txId,
|
|
10361
|
+
asset: senderAsset,
|
|
10362
|
+
from,
|
|
10363
|
+
to,
|
|
10364
|
+
date: new Date(txResult.timestamp),
|
|
10365
|
+
type,
|
|
10366
|
+
};
|
|
10367
|
+
}
|
|
10368
|
+
catch (error) { }
|
|
10369
|
+
return yield this.getTransactionDataThornode(txId);
|
|
10370
|
+
});
|
|
10371
|
+
}
|
|
10372
|
+
/** This function is used when in bound or outbound tx is not of thorchain
|
|
10373
|
+
*
|
|
10374
|
+
* @param txId - transaction hash
|
|
10375
|
+
* @returns - Tx object
|
|
10376
|
+
*/
|
|
10377
|
+
getTransactionDataThornode(txId) {
|
|
10378
|
+
var _a, _b, _c;
|
|
10379
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10380
|
+
const txResult = JSON.stringify(yield this.thornodeAPIGet(`/tx/${txId}`));
|
|
10381
|
+
const getTx = JSON.parse(txResult);
|
|
10382
|
+
if (!getTx)
|
|
10383
|
+
throw Error(`Could not return tx data`);
|
|
10384
|
+
const senderAsset = xchainUtil.assetFromStringEx(`${(_a = getTx.observed_tx) === null || _a === void 0 ? void 0 : _a.tx.coins[0].asset}`);
|
|
10385
|
+
const fromAddress = `${getTx.observed_tx.tx.from_address}`;
|
|
10386
|
+
const from = [
|
|
10387
|
+
{ from: fromAddress, amount: xchainUtil.baseAmount((_b = getTx.observed_tx) === null || _b === void 0 ? void 0 : _b.tx.coins[0].amount), asset: senderAsset },
|
|
10388
|
+
];
|
|
10389
|
+
const splitMemo = (_c = getTx.observed_tx.tx.memo) === null || _c === void 0 ? void 0 : _c.split(':');
|
|
10390
|
+
if (!splitMemo)
|
|
10391
|
+
throw Error(`Could not parse memo`);
|
|
10392
|
+
let asset;
|
|
10393
|
+
let amount;
|
|
10394
|
+
if (splitMemo[0] === 'OUT') {
|
|
10395
|
+
asset = xchainUtil.assetFromStringEx(getTx.observed_tx.tx.coins[0].asset);
|
|
10396
|
+
amount = getTx.observed_tx.tx.coins[0].amount;
|
|
10397
|
+
const addressTo = getTx.observed_tx.tx.to_address ? getTx.observed_tx.tx.to_address : 'undefined';
|
|
10398
|
+
const to = [{ to: addressTo, amount: xchainUtil.baseAmount(amount, DECIMAL), asset: asset }];
|
|
10399
|
+
const txData = {
|
|
10400
|
+
hash: txId,
|
|
10401
|
+
asset: senderAsset,
|
|
10402
|
+
from,
|
|
10403
|
+
to,
|
|
10404
|
+
date: new Date(),
|
|
10405
|
+
type: xchainClient.TxType.Transfer,
|
|
10406
|
+
};
|
|
10407
|
+
return txData;
|
|
10408
|
+
}
|
|
10409
|
+
asset = xchainUtil.assetFromStringEx(splitMemo[1]);
|
|
10410
|
+
const address = splitMemo[2];
|
|
10411
|
+
amount = splitMemo[3];
|
|
10412
|
+
const receiverAsset = asset;
|
|
10413
|
+
const recieverAmount = amount;
|
|
10414
|
+
const to = [{ to: address, amount: xchainUtil.baseAmount(recieverAmount, DECIMAL), asset: receiverAsset }];
|
|
10415
|
+
const txData = {
|
|
10293
10416
|
hash: txId,
|
|
10294
|
-
asset:
|
|
10417
|
+
asset: senderAsset,
|
|
10295
10418
|
from,
|
|
10296
10419
|
to,
|
|
10297
|
-
date: new Date(
|
|
10298
|
-
type,
|
|
10420
|
+
date: new Date(),
|
|
10421
|
+
type: xchainClient.TxType.Transfer,
|
|
10299
10422
|
};
|
|
10423
|
+
return txData;
|
|
10300
10424
|
});
|
|
10301
10425
|
}
|
|
10302
10426
|
/**
|
|
@@ -10548,7 +10672,9 @@ exports.DECIMAL = DECIMAL;
|
|
|
10548
10672
|
exports.DEFAULT_GAS_ADJUSTMENT = DEFAULT_GAS_ADJUSTMENT;
|
|
10549
10673
|
exports.DEFAULT_GAS_LIMIT_VALUE = DEFAULT_GAS_LIMIT_VALUE;
|
|
10550
10674
|
exports.DEPOSIT_GAS_LIMIT_VALUE = DEPOSIT_GAS_LIMIT_VALUE;
|
|
10551
|
-
exports.
|
|
10675
|
+
exports.MAX_PAGES_PER_FUNCTION_CALL = MAX_PAGES_PER_FUNCTION_CALL;
|
|
10676
|
+
exports.MAX_TX_COUNT_PER_FUNCTION_CALL = MAX_TX_COUNT_PER_FUNCTION_CALL;
|
|
10677
|
+
exports.MAX_TX_COUNT_PER_PAGE = MAX_TX_COUNT_PER_PAGE;
|
|
10552
10678
|
exports.MsgNativeTx = MsgNativeTx;
|
|
10553
10679
|
exports.RUNE_SYMBOL = RUNE_SYMBOL;
|
|
10554
10680
|
exports.THORChain = THORChain;
|
|
@@ -69,3 +69,24 @@ export declare type SimulateResponse = {
|
|
|
69
69
|
gas_used: string;
|
|
70
70
|
};
|
|
71
71
|
};
|
|
72
|
+
export declare type MessageSend = {
|
|
73
|
+
'@type': string;
|
|
74
|
+
from_address: string;
|
|
75
|
+
to_address: string;
|
|
76
|
+
amount: Amount;
|
|
77
|
+
};
|
|
78
|
+
export declare type Amount = {
|
|
79
|
+
denom: string;
|
|
80
|
+
amount: string;
|
|
81
|
+
};
|
|
82
|
+
export declare type MessageDeposit = {
|
|
83
|
+
'@type': string;
|
|
84
|
+
coins: Coins[];
|
|
85
|
+
memo: string;
|
|
86
|
+
signer: string;
|
|
87
|
+
};
|
|
88
|
+
export declare type Coins = {
|
|
89
|
+
asset: string;
|
|
90
|
+
amount: number;
|
|
91
|
+
decimals: number;
|
|
92
|
+
};
|
package/lib/utils.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export declare const registerSendCodecs: () => void;
|
|
|
57
57
|
* @param {Address} address - Address to get transaction data for
|
|
58
58
|
* @returns {TxData} Parsed transaction data
|
|
59
59
|
*/
|
|
60
|
-
export declare const getDepositTxDataFromLogs: (logs: TxLog[], address: Address) => TxData;
|
|
60
|
+
export declare const getDepositTxDataFromLogs: (logs: TxLog[], address: Address, senderAsset?: Asset | undefined, receiverAsset?: Asset | undefined) => TxData;
|
|
61
61
|
/**
|
|
62
62
|
* Get the default fee.
|
|
63
63
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xchainjs/xchain-thorchain",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.9",
|
|
4
4
|
"description": "Custom Thorchain client and utilities used by XChainJS clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"THORChain",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@cosmos-client/core": "0.46.1",
|
|
38
38
|
"@types/big.js": "^6.0.0",
|
|
39
|
-
"@xchainjs/xchain-binance": "^5.6.
|
|
39
|
+
"@xchainjs/xchain-binance": "^5.6.7",
|
|
40
40
|
"@xchainjs/xchain-client": "^0.13.5",
|
|
41
|
-
"@xchainjs/xchain-cosmos": "^0.20.
|
|
41
|
+
"@xchainjs/xchain-cosmos": "^0.20.8",
|
|
42
42
|
"@xchainjs/xchain-crypto": "^0.2.6",
|
|
43
|
-
"@xchainjs/xchain-ethereum": "^0.27.
|
|
43
|
+
"@xchainjs/xchain-ethereum": "^0.27.7",
|
|
44
44
|
"@xchainjs/xchain-util": "^0.12.0",
|
|
45
45
|
"axios": "^0.25.0",
|
|
46
46
|
"bech32-buffer": "^0.2.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@cosmos-client/core": "0.46.1",
|
|
54
54
|
"@xchainjs/xchain-client": "^0.13.5",
|
|
55
|
-
"@xchainjs/xchain-cosmos": "^0.20.
|
|
55
|
+
"@xchainjs/xchain-cosmos": "^0.20.8",
|
|
56
56
|
"@xchainjs/xchain-crypto": "^0.2.6",
|
|
57
57
|
"@xchainjs/xchain-util": "^0.12.0",
|
|
58
58
|
"axios": "^0.25.0",
|