@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 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, Chain } from '@xchainjs/xchain-util/lib';
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 MAX_TX_COUNT = 100;
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: Chain;
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 MAX_TX_COUNT = 100;
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
- const txIncomingHistory = (yield this.cosmosClient.searchTxFromRPC({
10062
- rpcEndpoint: this.getClientUrl().rpc,
10063
- messageAction,
10064
- transferRecipient: address,
10065
- limit: MAX_TX_COUNT,
10066
- txMinHeight,
10067
- txMaxHeight,
10068
- })).txs;
10069
- const txOutgoingHistory = (yield this.cosmosClient.searchTxFromRPC({
10070
- rpcEndpoint: this.getClientUrl().rpc,
10071
- messageAction,
10072
- transferSender: address,
10073
- limit: MAX_TX_COUNT,
10074
- txMinHeight,
10075
- txMaxHeight,
10076
- })).txs;
10077
- let history = txIncomingHistory
10078
- .concat(txOutgoingHistory)
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 txs = yield Promise.all(history.map(({ hash }) => this.getTransactionData(hash, address)));
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
- const txResult = yield this.cosmosClient.txsHashGet(txId);
10279
- const txData = txResult && txResult.logs ? getDepositTxDataFromLogs(txResult.logs, address) : null;
10280
- if (!txResult || !txData)
10281
- throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
10282
- const { from, to, type } = txData;
10283
- return {
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: AssetRuneNative,
10408
+ asset: senderAsset,
10286
10409
  from,
10287
10410
  to,
10288
- date: new Date(txResult.timestamp),
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, MAX_TX_COUNT, 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 };
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 MAX_TX_COUNT = 100;
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
- const txIncomingHistory = (yield this.cosmosClient.searchTxFromRPC({
10071
- rpcEndpoint: this.getClientUrl().rpc,
10072
- messageAction,
10073
- transferRecipient: address,
10074
- limit: MAX_TX_COUNT,
10075
- txMinHeight,
10076
- txMaxHeight,
10077
- })).txs;
10078
- const txOutgoingHistory = (yield this.cosmosClient.searchTxFromRPC({
10079
- rpcEndpoint: this.getClientUrl().rpc,
10080
- messageAction,
10081
- transferSender: address,
10082
- limit: MAX_TX_COUNT,
10083
- txMinHeight,
10084
- txMaxHeight,
10085
- })).txs;
10086
- let history = txIncomingHistory
10087
- .concat(txOutgoingHistory)
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 txs = yield Promise.all(history.map(({ hash }) => this.getTransactionData(hash, address)));
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
- const txResult = yield this.cosmosClient.txsHashGet(txId);
10288
- const txData = txResult && txResult.logs ? getDepositTxDataFromLogs(txResult.logs, address) : null;
10289
- if (!txResult || !txData)
10290
- throw new Error(`Failed to get transaction data (tx-hash: ${txId})`);
10291
- const { from, to, type } = txData;
10292
- return {
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: AssetRuneNative,
10417
+ asset: senderAsset,
10295
10418
  from,
10296
10419
  to,
10297
- date: new Date(txResult.timestamp),
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.MAX_TX_COUNT = MAX_TX_COUNT;
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.7",
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.6",
39
+ "@xchainjs/xchain-binance": "^5.6.7",
40
40
  "@xchainjs/xchain-client": "^0.13.5",
41
- "@xchainjs/xchain-cosmos": "^0.20.6",
41
+ "@xchainjs/xchain-cosmos": "^0.20.8",
42
42
  "@xchainjs/xchain-crypto": "^0.2.6",
43
- "@xchainjs/xchain-ethereum": "^0.27.6",
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.6",
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",