diff --git a/packages/xchain-cosmos-sdk/CHANGELOG.md b/packages/xchain-cosmos-sdk/CHANGELOG.md index 2d5646b2f..51bf82a8e 100644 --- a/packages/xchain-cosmos-sdk/CHANGELOG.md +++ b/packages/xchain-cosmos-sdk/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.2 + +### Patch Changes + +- ae35c36: GetTransactionData for non native asset transactions + ## 0.2.1 ### Patch Changes diff --git a/packages/xchain-cosmos-sdk/__e2e__/cosmos-sdk-client.e2e.ts b/packages/xchain-cosmos-sdk/__e2e__/cosmos-sdk-client.e2e.ts index 37c224622..3b61c1de5 100644 --- a/packages/xchain-cosmos-sdk/__e2e__/cosmos-sdk-client.e2e.ts +++ b/packages/xchain-cosmos-sdk/__e2e__/cosmos-sdk-client.e2e.ts @@ -1,6 +1,9 @@ -import { AssetInfo, Network, TxParams } from '@xchainjs/xchain-client' +import { StdFee } from '@cosmjs/stargate' +import { AssetInfo, Network, PreparedTx, TxParams } from '@xchainjs/xchain-client' import { Asset, assetFromString, assetToString, baseAmount, eqAsset } from '@xchainjs/xchain-util' +import Client from '../src/client' + const AssetKUJI = assetFromString('KUJI.KUJI') as Asset const AssetTokenKuji = { chain: 'KUJI', @@ -9,11 +12,18 @@ const AssetTokenKuji = { synth: false, } -import Client from '../src/client' - let xchainClient: Client class CustomSdkClient extends Client { + public prepareTx(): Promise { + throw new Error('Method not implemented.') + } + protected getMsgTypeUrlByType(): string { + throw new Error('Method not implemented.') + } + protected getStandardFee(): StdFee { + throw new Error('Method not implemented.') + } getAssetInfo(): AssetInfo { throw new Error('Method not implemented.') } @@ -61,6 +71,7 @@ describe('Cosmos SDK client Integration Tests', () => { [Network.Stagenet]: 'wip', [Network.Mainnet]: 'wip', }, + registryTypes: [], } xchainClient = new CustomSdkClient(settings) }) diff --git a/packages/xchain-cosmos-sdk/package.json b/packages/xchain-cosmos-sdk/package.json index 8b936f611..2cbf399f9 100644 --- a/packages/xchain-cosmos-sdk/package.json +++ b/packages/xchain-cosmos-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@xchainjs/xchain-cosmos-sdk", - "version": "0.2.1", + "version": "0.2.2", "description": "Genereic Cosmos SDK client for XChainJS", "keywords": [ "XChain", diff --git a/packages/xchain-cosmos-sdk/src/client.ts b/packages/xchain-cosmos-sdk/src/client.ts index ab895aff1..8b970988e 100644 --- a/packages/xchain-cosmos-sdk/src/client.ts +++ b/packages/xchain-cosmos-sdk/src/client.ts @@ -28,7 +28,7 @@ import { singleFee, } from '@xchainjs/xchain-client' import * as xchainCrypto from '@xchainjs/xchain-crypto' -import { Address, Asset, BaseAmount, CachedValue, Chain, baseAmount } from '@xchainjs/xchain-util' +import { Address, Asset, BaseAmount, CachedValue, Chain, assetToString, baseAmount } from '@xchainjs/xchain-util' import * as bech32 from 'bech32' import * as BIP32 from 'bip32' import * as crypto from 'crypto' @@ -104,7 +104,7 @@ export default abstract class Client extends BaseXChainClient implements XChainC private splitAmountAndDenom(amountsAndDenoms: string[]) { const amounAndDenomParsed: { amount: string; denom: string }[] = [] amountsAndDenoms.forEach((amountAndDenom) => { - const regex = /^(\d+)(\D+)$/ + const regex = /^(\d+)(.*)$/ const match = amountAndDenom.match(regex) if (match) { @@ -123,10 +123,15 @@ export default abstract class Client extends BaseXChainClient implements XChainC * @returns {Tx} transaction with xchainjs format */ private async mapIndexedTxToTx(indexedTx: IndexedTx): Promise { - const mapTo: Map = new Map() - const mapFrom: Map = new Map() + const mapTo: Map = new Map() + const mapFrom: Map = new Map() - indexedTx.events.forEach((event) => { + /** + * Approach to be compatible with other clients. Due to Cosmos transaction sorted events, the first 7 events + * belongs to the transaction fee, so they can be skipped + */ + + indexedTx.events.slice(7).forEach((event) => { if (event.type === 'transfer') { const keyAmount = event.attributes.find((atribute) => atribute.key === 'amount') as { key: string @@ -143,40 +148,55 @@ export default abstract class Client extends BaseXChainClient implements XChainC try { const allTokensInEvent = keyAmount.value.split(',') // More than one asset per event (kuji faucet example) const amounts = this.splitAmountAndDenom(allTokensInEvent) - const nativeAssetAmounts = amounts.filter((amount) => amount.denom === this.baseDenom) // TODO: Temporally discard non native assets - const totalNativeAmount = nativeAssetAmounts.reduce( - // TODO: Diferenciate fee from amount - (acum, amount) => acum.plus(amount.amount), - baseAmount(0, this.defaultDecimals), - ) - // Fill to - if (mapTo.has(keyRecipient.value)) { - const currentTo = mapTo.get(keyRecipient.value) as { amount: BaseAmount; asset: Asset | undefined } - currentTo.amount = currentTo?.amount.plus(totalNativeAmount) - mapTo.set(keyRecipient.value, currentTo) - } else { - const asset = this.assetFromDenom(this.baseDenom) - if (asset) { - mapTo.set(keyRecipient.value, { - amount: totalNativeAmount, - asset, - }) + const denomAmountMap: Record = {} + amounts.forEach((amount) => { + if (amount.denom in denomAmountMap) { + denomAmountMap[amount.denom] = denomAmountMap[amount.denom].plus( + baseAmount(amount.amount, this.defaultDecimals), + ) + } else { + denomAmountMap[amount.denom] = baseAmount(amount.amount, this.defaultDecimals) } - } - // Fill from - if (mapFrom.has(keySender.value)) { - const currentTo = mapFrom.get(keySender.value) as { amount: BaseAmount; asset: Asset | undefined } - currentTo.amount = currentTo?.amount.plus(totalNativeAmount) - mapFrom.set(keySender.value, currentTo) - } else { - const asset = this.assetFromDenom(this.baseDenom) + }) + Object.entries(denomAmountMap).forEach(([denom, amount]) => { + // Fill to + const asset = this.assetFromDenom(denom) if (asset) { - mapFrom.set(keySender.value, { - amount: totalNativeAmount, - asset, - }) + const recipientAssetKey = `${keyRecipient.value}${assetToString(asset)}` + if (mapTo.has(recipientAssetKey)) { + const currentTo = mapTo.get(keyRecipient.value) as { + amount: BaseAmount + asset: Asset + address: Address + } + currentTo.amount = currentTo.amount.plus(amount) + mapTo.set(recipientAssetKey, currentTo) + } else { + mapTo.set(recipientAssetKey, { + amount, + asset, + address: keyRecipient.value, + }) + } + // Fill from + const senderAssetKey = `${keySender.value}${assetToString(asset)}` + if (mapFrom.has(senderAssetKey)) { + const currentTo = mapFrom.get(senderAssetKey) as { + amount: BaseAmount + asset: Asset + address: Address + } + currentTo.amount = currentTo.amount.plus(amount) + mapFrom.set(senderAssetKey, currentTo) + } else { + mapFrom.set(senderAssetKey, { + amount, + asset, + address: keySender.value, + }) + } } - } + }) } catch (e) { console.error('Error:', e) } @@ -184,9 +204,9 @@ export default abstract class Client extends BaseXChainClient implements XChainC }) const txTo: TxTo[] = [] - for (const [key, value] of mapTo.entries()) { + for (const value of mapTo.values()) { const txToObj: TxTo = { - to: key, + to: value.address, amount: value.amount, asset: value.asset, } @@ -194,9 +214,9 @@ export default abstract class Client extends BaseXChainClient implements XChainC } const txFrom: TxFrom[] = [] - for (const [key, value] of mapFrom.entries()) { + for (const value of mapFrom.values()) { const txFromObj: TxFrom = { - from: key, + from: value.address, amount: value.amount, asset: value.asset, } diff --git a/packages/xchain-kujira/CHANGELOG.md b/packages/xchain-kujira/CHANGELOG.md index e1930b9ea..7115b44ff 100644 --- a/packages/xchain-kujira/CHANGELOG.md +++ b/packages/xchain-kujira/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.1.10 + +### Patch Changes + +- Updated dependencies [ae35c36] + - @xchainjs/xchain-cosmos-sdk@0.2.2 + ## 0.1.9 ### Patch Changes diff --git a/packages/xchain-kujira/package.json b/packages/xchain-kujira/package.json index b20ddb597..9ed9b4bea 100644 --- a/packages/xchain-kujira/package.json +++ b/packages/xchain-kujira/package.json @@ -1,6 +1,6 @@ { "name": "@xchainjs/xchain-kujira", - "version": "0.1.9", + "version": "0.1.10", "description": "Custom Kujira client", "keywords": [ "XChain", @@ -34,7 +34,7 @@ "dependencies": { "@cosmjs/encoding": "0.31.1", "@cosmjs/stargate": "0.31.1", - "@xchainjs/xchain-cosmos-sdk": "0.2.1" + "@xchainjs/xchain-cosmos-sdk": "0.2.2" }, "devDependencies": { "@cosmjs/amino": "0.31.1", diff --git a/packages/xchain-mayachain-amm/CHANGELOG.md b/packages/xchain-mayachain-amm/CHANGELOG.md index 37216f452..92202d7ac 100644 --- a/packages/xchain-mayachain-amm/CHANGELOG.md +++ b/packages/xchain-mayachain-amm/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.0.8 + +### Patch Changes + +- Updated dependencies [e1ec010] + - @xchainjs/xchain-thorchain@1.0.2 + - @xchainjs/xchain-kujira@0.1.10 + - @xchainjs/xchain-wallet@0.1.4 + ## 1.0.7 ### Patch Changes diff --git a/packages/xchain-mayachain-amm/package.json b/packages/xchain-mayachain-amm/package.json index 354d43326..3d45a9ea3 100644 --- a/packages/xchain-mayachain-amm/package.json +++ b/packages/xchain-mayachain-amm/package.json @@ -1,6 +1,6 @@ { "name": "@xchainjs/xchain-mayachain-amm", - "version": "1.0.7", + "version": "1.0.8", "description": "module that exposes estimating & swapping cryptocurrency assets on mayachain", "keywords": [ "MAYAChain", @@ -37,11 +37,11 @@ }, "dependencies": { "@xchainjs/xchain-ethereum": "0.31.5", - "@xchainjs/xchain-kujira": "0.1.9", + "@xchainjs/xchain-kujira": "0.1.10", "@xchainjs/xchain-mayachain-query": "0.1.7", "@xchainjs/xchain-mayachain": "0.2.16", - "@xchainjs/xchain-thorchain": "1.0.1", - "@xchainjs/xchain-wallet": "0.1.3" + "@xchainjs/xchain-thorchain": "1.0.2", + "@xchainjs/xchain-wallet": "0.1.4" }, "devDependencies": { "@cosmos-client/core": "0.46.1", diff --git a/packages/xchain-thorchain-amm/CHANGELOG.md b/packages/xchain-thorchain-amm/CHANGELOG.md index f215f2ba5..bc50b8875 100644 --- a/packages/xchain-thorchain-amm/CHANGELOG.md +++ b/packages/xchain-thorchain-amm/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.8.21 + +### Patch Changes + +- Updated dependencies [e1ec010] + - @xchainjs/xchain-thorchain@1.0.2 + ## 0.8.20 ### Patch Changes diff --git a/packages/xchain-thorchain-amm/package.json b/packages/xchain-thorchain-amm/package.json index e69a383cb..53fdb8810 100644 --- a/packages/xchain-thorchain-amm/package.json +++ b/packages/xchain-thorchain-amm/package.json @@ -1,6 +1,6 @@ { "name": "@xchainjs/xchain-thorchain-amm", - "version": "0.8.20", + "version": "0.8.21", "description": "module that exposes estimating & swappping cryptocurrency assets on thorchain", "keywords": [ "THORChain", @@ -40,7 +40,7 @@ "@xchainjs/xchain-avax": "0.4.5", "@xchainjs/xchain-bsc": "0.4.6", "@xchainjs/xchain-ethereum": "0.31.5", - "@xchainjs/xchain-thorchain": "1.0.1", + "@xchainjs/xchain-thorchain": "1.0.2", "@xchainjs/xchain-mayachain": "0.2.16" }, "devDependencies": { diff --git a/packages/xchain-thorchain/CHANGELOG.md b/packages/xchain-thorchain/CHANGELOG.md index a7e21f62a..6675ef5fe 100644 --- a/packages/xchain-thorchain/CHANGELOG.md +++ b/packages/xchain-thorchain/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.0.2 + +### Patch Changes + +- e1ec010: getDenom, getChainId and getPrefix util functions +- Updated dependencies [ae35c36] + - @xchainjs/xchain-cosmos-sdk@0.2.2 + ## 1.0.1 ### Patch Changes diff --git a/packages/xchain-thorchain/package.json b/packages/xchain-thorchain/package.json index 02d456266..68c85962b 100644 --- a/packages/xchain-thorchain/package.json +++ b/packages/xchain-thorchain/package.json @@ -1,6 +1,6 @@ { "name": "@xchainjs/xchain-thorchain", - "version": "1.0.1", + "version": "1.0.2", "description": "Custom Thorchain client and utilities used by XChainJS clients", "keywords": [ "THORChain", @@ -37,8 +37,9 @@ "@cosmjs/encoding": "0.31.1", "@cosmjs/crypto": "0.31.1", "@xchainjs/xchain-client": "0.16.1", - "@xchainjs/xchain-cosmos-sdk": "0.2.1", + "@xchainjs/xchain-cosmos-sdk": "0.2.2", "@xchainjs/xchain-util": "0.13.2", + "axios": "1.3.6", "bignumber.js": "9.0.0", "protobufjs": "6.11.4" }, diff --git a/packages/xchain-thorchain/src/client.ts b/packages/xchain-thorchain/src/client.ts index 064a2be61..cebca08e9 100644 --- a/packages/xchain-thorchain/src/client.ts +++ b/packages/xchain-thorchain/src/client.ts @@ -17,7 +17,7 @@ import { bech32ToBase64, makeClientPath, } from '@xchainjs/xchain-cosmos-sdk' -import { Address, Asset, assetFromString, assetToString, eqAsset, isSynthAsset } from '@xchainjs/xchain-util' +import { Address, Asset, assetFromString, eqAsset } from '@xchainjs/xchain-util' import { BigNumber } from 'bignumber.js' import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx' @@ -32,7 +32,7 @@ import { defaultClientConfig, } from './const' import { DepositParam, DepositTx, TxOfflineParams } from './types' -import { getDefaultExplorers, getExplorerAddressUrl, getExplorerTxUrl, isAssetRuneNative as isAssetRune } from './utils' +import { getDefaultExplorers, getDenom, getExplorerAddressUrl, getExplorerTxUrl, getPrefix } from './utils' /** * Interface for custom Thorchain client @@ -70,14 +70,7 @@ export class Client extends CosmosSDKClient implements ThorchainClient { * @returns the address prefix */ protected getPrefix(network: Network): string { - switch (network) { - case Network.Mainnet: - return 'thor' - case Network.Stagenet: - return 'sthor' - case Network.Testnet: - return 'tthor' - } + return getPrefix(network) } /** @@ -150,9 +143,7 @@ export class Client extends CosmosSDKClient implements ThorchainClient { * @returns {string} The denomination of the given asset. */ public getDenom(asset: Asset): string | null { - if (isAssetRune(asset)) return RUNE_DENOM - if (isSynthAsset(asset)) return assetToString(asset).toLowerCase() - return asset.symbol.toLowerCase() + return getDenom(asset) } /** diff --git a/packages/xchain-thorchain/src/utils.ts b/packages/xchain-thorchain/src/utils.ts index 2d5f8d4b9..d3acd93e7 100644 --- a/packages/xchain-thorchain/src/utils.ts +++ b/packages/xchain-thorchain/src/utils.ts @@ -1,7 +1,8 @@ import { Network, RootDerivationPaths, TxHash } from '@xchainjs/xchain-client' -import { Address, Asset, assetToString } from '@xchainjs/xchain-util' +import { Address, Asset, assetToString, isSynthAsset } from '@xchainjs/xchain-util' +import axios from 'axios' -import { AssetRuneNative as AssetRUNE, DEFAULT_EXPLORER_URL } from './const' +import { AssetRuneNative as AssetRUNE, DEFAULT_EXPLORER_URL, RUNE_DENOM } from './const' export const getDefaultClientUrls = (): Record => { return { @@ -41,3 +42,48 @@ export const getExplorerTxUrl = (tx: TxHash): Record => ({ * @returns {boolean} `true` or `false` */ export const isAssetRuneNative = (asset: Asset): boolean => assetToString(asset) === assetToString(AssetRUNE) + +/** + * Get denomination from Asset + * + * @param {Asset} asset + * @returns {string} The denomination of the given asset. + */ +export const getDenom = (asset: Asset) => { + if (isAssetRuneNative(asset)) return RUNE_DENOM + if (isSynthAsset(asset)) return assetToString(asset).toLowerCase() + return asset.symbol.toLowerCase() +} + +/** + * Get chain id from node url + * + * @param {string} nodeUrl + * @returns the chainId + */ +export const getChainId = async (nodeUrl: string): Promise => { + /** + * TODO: To avoid axios dependency. ChainId can be retrieved from the Stargate client, to achieve this, + * getChainId has to work with JSON-RPC endpoint instead of REST endpoints + */ + const { data } = await axios.get<{ default_node_info?: { network?: string } }>( + `${nodeUrl}/cosmos/base/tendermint/v1beta1/node_info`, + ) + return data?.default_node_info?.network || Promise.reject('Could not parse chain id') +} + +/** + * Get address prefix by network + * @param {Network} network The network of which return the prefix + * @returns the address prefix + */ +export const getPrefix = (network: Network): string => { + switch (network) { + case Network.Mainnet: + return 'thor' + case Network.Stagenet: + return 'sthor' + case Network.Testnet: + return 'tthor' + } +} diff --git a/packages/xchain-wallet/CHANGELOG.md b/packages/xchain-wallet/CHANGELOG.md index 1d9387f87..e3a7856ea 100644 --- a/packages/xchain-wallet/CHANGELOG.md +++ b/packages/xchain-wallet/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.1.4 + +### Patch Changes + +- Updated dependencies [e1ec010] + - @xchainjs/xchain-thorchain@1.0.2 + ## 0.1.3 ### Patch Changes diff --git a/packages/xchain-wallet/package.json b/packages/xchain-wallet/package.json index 6bb5529b7..8c242919b 100644 --- a/packages/xchain-wallet/package.json +++ b/packages/xchain-wallet/package.json @@ -1,7 +1,7 @@ { "name": "@xchainjs/xchain-wallet", "description": "XChainjs clients wrapper to work with several chains at the same time", - "version": "0.1.3", + "version": "0.1.4", "license": "MIT", "main": "lib/index.js", "module": "lib/index.esm.js", @@ -31,7 +31,7 @@ "@xchainjs/xchain-evm": "0.4.4", "@xchainjs/xchain-util": "0.13.2", "@xchainjs/xchain-client": "0.16.1", - "@xchainjs/xchain-thorchain": "1.0.1", + "@xchainjs/xchain-thorchain": "1.0.2", "@xchainjs/xchain-mayachain": "0.2.16", "ethers": "5.6.6" }, diff --git a/yarn.lock b/yarn.lock index ab38b47f6..610c98cf4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3239,6 +3239,20 @@ "@typescript-eslint/types" "5.59.1" eslint-visitor-keys "^3.3.0" +"@xchainjs/xchain-cosmos-sdk@0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@xchainjs/xchain-cosmos-sdk/-/xchain-cosmos-sdk-0.2.1.tgz#564e7d014eefcaf8646df93a7c85aaab1e1e5935" + integrity sha512-aIMV7cM55rO9zGYiSo+4ut1O0BoNTWqQcof+6pidtoKe+rvAcrPFqf2MB3nBEAhcKJNEySvVUA3nXyvkV9YFAA== + dependencies: + "@cosmjs/crypto" "0.31.1" + "@cosmjs/encoding" "0.31.1" + "@cosmjs/proto-signing" "0.31.1" + "@cosmjs/stargate" "^0.31.1" + "@scure/base" "1.1.5" + bech32 "^1.1.3" + bip32 "^2.0.6" + secp256k1 "^5.0.0" + "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"