diff --git a/.github/workflows/publish_package_common_v3.yml b/.github/workflows/publish_package_common_v3.yml new file mode 100644 index 00000000..eb69ecfb --- /dev/null +++ b/.github/workflows/publish_package_common_v3.yml @@ -0,0 +1,69 @@ +name: publish_package_universal_common + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [feat/intergrate_common] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build: + runs-on: ubuntu-20.04 + strategy: + matrix: + node-version: ["18"] + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.8.0 + with: + access_token: ${{ github.token }} + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + # - name: Get yarn cache directory path + # id: yarn-cache-dir-path + # run: echo "::set-output name=dir::$(yarn cache dir)" + # - uses: actions/cache@v4 + # id: yarn-cache + # with: + # path: | + # ${{ steps.yarn-cache-dir-path.outputs.dir }} + # ./node_modules/ + # key: ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} + # restore-keys: | + # ${{ runner.os }}-yarn- + - name: Install Dependencies + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn + - name: Build + run: yarn build + - name: Authenticate with private NPM package + run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc + - name: Publish Oraidex Common + id: publish-common + continue-on-error: true + run: yarn deploy packages/oraidex-common + env: + CI: false + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish Oraiswap v3 + id: publish-oraiswap-v3 + continue-on-error: true + run: yarn deploy:beta packages/oraiswap-v3 + env: + CI: false + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish Universal-swap + id: publish-universal-swap + continue-on-error: true + run: yarn deploy:beta packages/universal-swap + env: + CI: false + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/package.json b/package.json index 5a967510..406d31f7 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "devDependencies": { "@babel/traverse": "7.24.1", "@cosmjs/encoding": "^0.32.4", - "@oraichain/cw-simulate": "^2.8.68", + "@oraichain/cw-simulate": "^2.8.108", "@swc/core": "^1.4.11", "@swc/jest": "^0.2.36", "@types/jest": "^29.5.12", diff --git a/packages/ibc-routing/package.json b/packages/ibc-routing/package.json index a5a8b576..8026b6cd 100644 --- a/packages/ibc-routing/package.json +++ b/packages/ibc-routing/package.json @@ -8,9 +8,9 @@ "license": "MIT", "dependencies": { "@duckdb/duckdb-wasm": "^1.27.1-dev125.0", - "@oraichain/oraidex-common": "^1.0.10", - "@oraichain/oraidex-contracts-sdk": "^1.0.24", - "@oraichain/oraidex-universal-swap": "1.0.14", + "@oraichain/oraidex-common": "^1.1.34", + "@oraichain/oraidex-contracts-sdk": "^1.0.56", + "@oraichain/oraidex-universal-swap": "^1.1.23", "@xstate/inspect": "^0.8.0", "bech32": "1.1.4", "ethers": "^5.5.1", diff --git a/packages/oraidex-common/package.json b/packages/oraidex-common/package.json index 1e90ce1b..81ffe75d 100644 --- a/packages/oraidex-common/package.json +++ b/packages/oraidex-common/package.json @@ -1,9 +1,11 @@ { "name": "@oraichain/oraidex-common", - "version": "1.1.44", - "main": "build/index.js", + "version": "2.0.6", + "main": "./build/index.js", + "module": "./build/index.js", + "types": "./build/index.d.ts", "files": [ - "build/" + "./build/" ], "scripts": { "build": "tsc -p tsconfig.json", @@ -27,11 +29,10 @@ "@oraichain/oraidex-contracts-sdk": "latest", "@injectivelabs/sdk-ts": "1.12.1", "tronweb": "6.0.0-beta.4", + "@oraichain/common": "1.2.7", "@ton/core": "0.56.3", - "@ton/crypto": "3.3.0", - "@ton/ton": "14.0.0" + "@ton/crypto": "3.3.0" }, - "devDependencies": {}, "resolutions": { "bech32": "1.1.4" } diff --git a/packages/oraidex-common/src/alpha-network.ts b/packages/oraidex-common/src/alpha-network.ts deleted file mode 100644 index 92011158..00000000 --- a/packages/oraidex-common/src/alpha-network.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - ATOM_OSMOSIS_CONTRACT, - INJ_OSMOSIS_CONTRACT, - ORAI_OSMOSIS_CONTRACT, - TIA_OSMOSIS_CONTRACT, - TON_ALL_OSMOSIS_CONTRACT, - TON_OSMOSIS_CONTRACT, - USDC_OSMOSIS_CONTRACT -} from "./constant"; -import { BridgeAppCurrency } from "./network"; - -export const AtomOsmosisToken: BridgeAppCurrency = { - coinDenom: "ATOM", - coinMinimalDenom: ATOM_OSMOSIS_CONTRACT, - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/atom.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const UsdcOsmosisToken: BridgeAppCurrency = { - coinDenom: "USDC", - coinMinimalDenom: USDC_OSMOSIS_CONTRACT, - coinDecimals: 6, - coinGeckoId: "usd-coin", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const OraiOsmosisToken: BridgeAppCurrency = { - coinDenom: "ORAI", - coinMinimalDenom: ORAI_OSMOSIS_CONTRACT, - coinDecimals: 6, - coinGeckoId: "oraichain-token", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const TiaOsmosisToken: BridgeAppCurrency = { - coinDenom: "TIA", - coinMinimalDenom: TIA_OSMOSIS_CONTRACT, - coinDecimals: 6, - coinGeckoId: "celestia", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/celestia/images/celestia.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const InjOsmosisToken: BridgeAppCurrency = { - coinDenom: "INJ", - coinMinimalDenom: INJ_OSMOSIS_CONTRACT, - coinDecimals: 18, - coinGeckoId: "injective-protocol", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/injective/images/inj.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const TonOsmosisToken: BridgeAppCurrency = { - coinDenom: "TON", - coinMinimalDenom: TON_ALL_OSMOSIS_CONTRACT, - coinDecimals: 9, - bridgeTo: ["ton", "Oraichain"], - coinGeckoId: "the-open-network", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ton/images/ton.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const TonOraiOsmosisToken: BridgeAppCurrency = { - coinDenom: "TON.orai", - coinMinimalDenom: TON_OSMOSIS_CONTRACT, - coinDecimals: 9, - bridgeTo: ["ton", "Oraichain"], - coinGeckoId: "the-open-network", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/_non-cosmos/ton/images/ton.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const listOsmosisToken = [ - AtomOsmosisToken, - OraiOsmosisToken, - TiaOsmosisToken, - TonOsmosisToken, - TonOraiOsmosisToken, - InjOsmosisToken -]; diff --git a/packages/oraidex-common/src/celestia-network.ts b/packages/oraidex-common/src/celestia-network.ts deleted file mode 100644 index ea2629d3..00000000 --- a/packages/oraidex-common/src/celestia-network.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { CustomChainInfo, defaultBech32Config } from "./network"; - -export const celestiaNetwork: CustomChainInfo = { - bech32Config: { - bech32PrefixAccAddr: "celestia", - bech32PrefixAccPub: "celestiapub", - bech32PrefixConsAddr: "celestiavalcons", - bech32PrefixConsPub: "celestiavalconspub", - bech32PrefixValAddr: "celestiavaloper", - bech32PrefixValPub: "celestiavaloperpub" - }, - bip44: { - coinType: 118 - }, - networkType: "cosmos", - chainId: "celestia", - chainName: "Celestia", - chainSymbolImageUrl: - "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/celestia/chain.png", - currencies: [ - { - coinDecimals: 6, - coinDenom: "TIA", - coinGeckoId: "celestia", - coinMinimalDenom: "utia", - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/celestia/chain.png" - } - ], - features: [], - feeCurrencies: [ - { - coinDecimals: 6, - coinDenom: "TIA", - coinGeckoId: "celestia", - coinMinimalDenom: "utia", - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/celestia/chain.png", - gasPriceStep: { - low: 0.01, - average: 0.02, - high: 0.1 - } - } - ], - rpc: "https://celestia.rpc.orai.io", - rest: "https://celestia.lcd.orai.io", - stakeCurrency: { - coinDecimals: 6, - coinDenom: "TIA", - coinGeckoId: "celestia", - coinMinimalDenom: "utia", - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/celestia/utia.png" - }, - walletUrlForStaking: "https://wallet.keplr.app/chains/celestia" -}; diff --git a/packages/oraidex-common/src/common.ts b/packages/oraidex-common/src/common.ts new file mode 100644 index 00000000..05c64036 --- /dev/null +++ b/packages/oraidex-common/src/common.ts @@ -0,0 +1,170 @@ +import { BridgeAppCurrency, ChainInfos, CoinType, MULTICALL_CONTRACT, OraiCommon, TokenItems } from "@oraichain/common"; +import { flatten } from "lodash"; +import { chainIcons, mapListWithIcon, tokensIcon } from "./config"; +import { + AMM_V3_CONTRACT, + CONVERTER_CONTRACT, + CW20_STAKING_CONTRACT, + FACTORY_CONTRACT, + FACTORY_V2_CONTRACT, + MIXED_ROUTER, + ORACLE_CONTRACT, + ORAIDEX_BID_POOL_CONTRACT, + ORAIDEX_LISTING_CONTRACT, + REWARDER_CONTRACT, + ROUTER_V2_CONTRACT, + solChainId, + STAKING_CONTRACT +} from "./constant"; +import { NetworkConfig } from "./network"; +import { CustomChainInfo } from "./format-types"; +import { ChainIdEnum } from "./interface"; +import { FeeCurrency } from "@keplr-wallet/types"; + +export class OraidexCommon { + static instance: OraidexCommon; + + constructor(public readonly tokenConfig: TokenItems, public readonly chainConfig: ChainInfos) {} + + static async load(): Promise { + if (!OraidexCommon.instance) { + const oraiCommon = await OraiCommon.initializeFromBackend("https://oraicommon.oraidex.io", "oraidex"); + OraidexCommon.instance = new OraidexCommon(oraiCommon.tokenItems, oraiCommon.chainInfos); + } + return OraidexCommon.instance; + } + + get oraichainTokens() { + return this.tokenConfig.oraichainTokens; + } + + get otherChainTokens() { + return this.tokenConfig.otherChainTokens; + } + + get chainInfosCommon() { + return this.chainConfig; + } + + get tokens() { + return this.tokenConfig.tokens; + } + + get flattenTokens() { + return this.tokenConfig.flattenTokens; + } + + get tokenMap() { + return this.tokenConfig.tokenMap; + } + + get assetInfoMap() { + return this.tokenConfig.assetInfoMap; + } + + get cosmosTokens() { + return this.tokenConfig.cosmosTokens; + } + + get cw20Tokens() { + return this.tokenConfig.cw20Tokens; + } + + get cw20TokenMap() { + return this.tokenConfig.cw20TokenMap; + } + + get evmTokens() { + return this.tokenConfig.evmTokens; + } + + get kawaiiTokens() { + return this.tokenConfig.kawaiiTokens; + } + + get btcTokens() { + return this.flattenTokens.filter((token) => token.chainId === ChainIdEnum.Bitcoin); + } + + get solTokens() { + return this.flattenTokens.filter((token) => token.chainId === solChainId); + } + + get tonTokens() { + return this.flattenTokens.filter((token) => token.chainId === "ton"); + } + + get oraichainTokensWithIcon() { + return mapListWithIcon(this.oraichainTokens, tokensIcon, "coinGeckoId"); + } + + get otherTokensWithIcon() { + return mapListWithIcon(this.otherChainTokens, tokensIcon, "coinGeckoId"); + } + + get tokensWithIcon() { + return [this.otherTokensWithIcon, this.oraichainTokensWithIcon]; + } + + get flattenTokensWithIcon() { + return flatten(this.tokensWithIcon); + } + + get oraichainNetwork() { + return this.chainConfig.getSpecificChainInfo("Oraichain"); + } + + get chainInfos() { + return this.chainConfig.chainInfos; + } + + get network(): CustomChainInfo & NetworkConfig { + return { + ...this.oraichainNetwork, + + coinType: this.oraichainNetwork.coinType, + explorer: "https://scan.orai.io", + fee: { gasPrice: "0.00506", amount: "1518", gas: "2000000" }, // 0.000500 ORAI + factory: FACTORY_CONTRACT, + factory_v2: FACTORY_V2_CONTRACT, + oracle: ORACLE_CONTRACT, + staking: STAKING_CONTRACT, + router: ROUTER_V2_CONTRACT, + mixer_router: MIXED_ROUTER, + denom: "orai", + prefix: this.oraichainNetwork.bech32Config.bech32PrefixAccAddr, + rewarder: REWARDER_CONTRACT, + converter: CONVERTER_CONTRACT, + oraidex_listing: ORAIDEX_LISTING_CONTRACT, + bid_pool: ORAIDEX_BID_POOL_CONTRACT, + multicall: MULTICALL_CONTRACT, + pool_v3: AMM_V3_CONTRACT, + staking_oraix: CW20_STAKING_CONTRACT, + indexer_v3: "https://ammv3-indexer.oraidex.io/" + }; + } + + get evmChains() { + return this.chainConfig.evmChains; + } + + get cosmosChains() { + return this.chainConfig.cosmosChains; + } + + get btcChains() { + return this.chainInfos.filter((c) => c.networkType === "bitcoin"); + } + + get chainInfosWithIcon() { + return mapListWithIcon(this.chainInfos, chainIcons, "chainId"); + } + + get celestiaNetwork() { + return this.chainConfig.getSpecificChainInfo("celestia"); + } + + get tonNetworkMainnet() { + return this.chainConfig.getSpecificChainInfo("ton"); + } +} diff --git a/packages/oraidex-common/src/config/chainInfosWithIcon.ts b/packages/oraidex-common/src/config/chainInfosWithIcon.ts index 33744158..ce0dd7e7 100644 --- a/packages/oraidex-common/src/config/chainInfosWithIcon.ts +++ b/packages/oraidex-common/src/config/chainInfosWithIcon.ts @@ -1,35 +1,38 @@ -const OraiIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png"; -const OraiLightIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png"; -const AtomIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3794.png"; -const AiriIcon = "https://i.ibb.co/m8mCyMr/airi.png"; -const UsdtIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png"; -const KwtIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png"; -const OsmoLightIcon = "https://assets.coingecko.com/coins/images/16724/large/osmo.png?1632763885"; -const OsmoIcon = "https://assets.coingecko.com/coins/images/16724/large/osmo.png?1632763885"; -const UsdcIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png"; -const ScOraiIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png"; -const OraixIcon = "https://assets.coingecko.com/coins/images/28104/standard/oraix.png?1696527113"; -const MilkyIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png"; -const TronIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1958.png"; -const ScAtomIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3794.png"; -const EthIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png"; -const BnbIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png"; -const InjIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7226.png"; -const OraixLightIcon = "https://assets.coingecko.com/coins/images/28104/standard/oraix.png?1696527113"; -const NobleIcon = "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/stake.png"; -const BtcIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png"; -const OCHIcon = - "https://assets.coingecko.com/coins/images/34236/standard/orchai_logo_white_copy_4x-8_%281%29.png?1704307670"; -const PepeIcon = "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776"; -const HamsterIcon = "https://assets.coingecko.com/coins/images/39102/standard/hamster-removebg-preview.png?1720514486"; +import { TokenItemType } from "src/format-types"; +import { + AiriIcon, + AtomIcon, + BnbIcon, + BtcIcon, + CelestiaIcon, + EthIcon, + HamsterIcon, + InjIcon, + KwtIcon, + MilkyIcon, + NeutaroIcon, + NobleIcon, + OCHIcon, + OraiIcon, + OraiLightIcon, + OraixIcon, + OraixLightIcon, + OsmoIcon, + OsmoLightIcon, + PepeIcon, + ScAtomIcon, + ScOraiIcon, + TronIcon, + UsdcIcon, + UsdtIcon +} from "./icon"; -import { flatten } from "lodash"; -import { chainInfos as customChainInfos, CustomChainInfo } from "../network"; -import { TokenItemType, tokens } from "../token"; - -const [otherChainTokens, oraichainTokens] = tokens; -type TokenIcon = Pick; -type ChainIcon = Pick; +export type TokenIcon = Pick; +export type ChainIcon = { + Icon: any; + IconLight?: any; + chainId: string; +}; export const tokensIcon: TokenIcon[] = [ { @@ -145,6 +148,11 @@ export const chainIcons: ChainIcon[] = [ Icon: OraiIcon, IconLight: OraiLightIcon }, + { + chainId: "celestia", + Icon: CelestiaIcon, + IconLight: CelestiaIcon + }, { chainId: "kawaii_6886-1", Icon: KwtIcon, @@ -189,8 +197,39 @@ export const chainIcons: ChainIcon[] = [ chainId: "noble-1", Icon: NobleIcon, IconLight: NobleIcon + }, + { + chainId: "oraibridge-subnet-2", + Icon: OraiIcon, + IconLight: OraiLightIcon + }, + { + chainId: "Neutaro-1", + Icon: NeutaroIcon, + IconLight: NeutaroIcon + }, + { + chainId: "oraibtc-mainnet-1", + Icon: BtcIcon, + IconLight: BtcIcon + }, + { + chainId: "bitcoin", + Icon: BtcIcon, + IconLight: BtcIcon } ]; + +export const tokenIconByCoingeckoId: Record = tokensIcon.reduce((acc, cur) => { + acc[cur.coinGeckoId] = cur; + return acc; +}, {}); + +export const chainIconByChainId: Record = chainIcons.reduce((acc, cur) => { + acc[cur.chainId] = cur; + return acc; +}, {}); + export const mapListWithIcon = (list: any[], listIcon: ChainIcon[] | TokenIcon[], key: "chainId" | "coinGeckoId") => { return list.map((item) => { let Icon = OraiIcon; @@ -210,13 +249,3 @@ export const mapListWithIcon = (list: any[], listIcon: ChainIcon[] | TokenIcon[] }; }); }; - -// mapped chain info with icon -export const chainInfosWithIcon = mapListWithIcon(customChainInfos, chainIcons, "chainId"); - -// mapped token with icon -export const oraichainTokensWithIcon = mapListWithIcon(oraichainTokens, tokensIcon, "coinGeckoId"); -export const otherTokensWithIcon = mapListWithIcon(otherChainTokens, tokensIcon, "coinGeckoId"); - -export const tokensWithIcon = [otherTokensWithIcon, oraichainTokensWithIcon]; -export const flattenTokensWithIcon = flatten(tokensWithIcon); diff --git a/packages/oraidex-common/src/config/icon.ts b/packages/oraidex-common/src/config/icon.ts new file mode 100644 index 00000000..8815436c --- /dev/null +++ b/packages/oraidex-common/src/config/icon.ts @@ -0,0 +1,54 @@ +const OraiIcon = "https://raw.githubusercontent.com/cosmos/chain-registry/master/oraichain/images/orai-token.png"; +const OraiLightIcon = "https://raw.githubusercontent.com/cosmos/chain-registry/master/oraichain/images/orai-token.png"; +const AtomIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3794.png"; +const AiriIcon = "https://i.ibb.co/m8mCyMr/airi.png"; +const UsdtIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png"; +const KwtIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png"; +const OsmoLightIcon = "https://assets.coingecko.com/coins/images/16724/large/osmo.png?1632763885"; +const OsmoIcon = "https://assets.coingecko.com/coins/images/16724/large/osmo.png?1632763885"; +const UsdcIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png"; +const ScOraiIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png"; +const OraixIcon = "https://assets.coingecko.com/coins/images/28104/standard/oraix.png?1696527113"; +const MilkyIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png"; +const TronIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1958.png"; +const ScAtomIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/3794.png"; +const EthIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png"; +const BnbIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png"; +const InjIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/7226.png"; +const OraixLightIcon = "https://assets.coingecko.com/coins/images/28104/standard/oraix.png?1696527113"; +const NobleIcon = "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/stake.png"; +const BtcIcon = "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png"; +const OCHIcon = + "https://assets.coingecko.com/coins/images/34236/standard/orchai_logo_white_copy_4x-8_%281%29.png?1704307670"; +const PepeIcon = "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776"; +const HamsterIcon = "https://assets.coingecko.com/coins/images/39102/standard/hamster-removebg-preview.png?1720514486"; +const CelestiaIcon = "https://assets.coingecko.com/coins/images/31967/standard/tia.jpg?1696530772"; +const NeutaroIcon = "https://assets.coingecko.com/coins/images/36277/standard/Neutaro_logo.jpg?1711371142"; + +export { + NeutaroIcon, + CelestiaIcon, + OraiIcon, + OraiLightIcon, + AtomIcon, + AiriIcon, + UsdtIcon, + KwtIcon, + OsmoLightIcon, + OsmoIcon, + UsdcIcon, + ScOraiIcon, + OraixIcon, + MilkyIcon, + TronIcon, + ScAtomIcon, + EthIcon, + BnbIcon, + InjIcon, + OraixLightIcon, + NobleIcon, + BtcIcon, + OCHIcon, + PepeIcon, + HamsterIcon +}; diff --git a/packages/oraidex-common/src/config/index.ts b/packages/oraidex-common/src/config/index.ts new file mode 100644 index 00000000..aea63b97 --- /dev/null +++ b/packages/oraidex-common/src/config/index.ts @@ -0,0 +1,2 @@ +export * from "./chainInfosWithIcon"; +export * from "./icon"; diff --git a/packages/oraidex-common/src/constant.ts b/packages/oraidex-common/src/constant.ts index c2eebebf..bdddbf2b 100644 --- a/packages/oraidex-common/src/constant.ts +++ b/packages/oraidex-common/src/constant.ts @@ -1,4 +1,4 @@ -import { CosmosChainId, EvmChainId, chainInfos, cosmosChains, evmChains } from "./network"; +import { EvmChainId } from "@oraichain/common"; export const truncDecimals = 6; export const atomic = 10 ** truncDecimals; @@ -153,6 +153,7 @@ export const TON_CONTRACT = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c"; export const TON_BRIDGE_ADAPTER = "EQC-aFP0rJXwTgKZQJPbPfTSpBFc8wxOgKHWD9cPvOl_DnaY"; export const TON_LIGHT_CLIENT = "EQDzy_POlimFDyzrHd3OQsb9sZCngyG3O7Za4GRFzM-rrO93"; export const TON_WHITE_LIST = "EQATDM6mfPZjPDMD9TVa6D9dlbmAKY5w6xOJiTXJ9Nqj_dsu"; + /** * TODO: This is the object containing the hardcoded addresses of cw20 TON Network. They are obtained from the formula below. We need to add more when we support new TON20. * const client = await getTonClient(); @@ -297,4 +298,18 @@ export const gravityContracts: Omit, "0x1ae6"> = { "0x2b6653dc": GRAVITY_TRON_CONTRACT }; +// mapping evm denom to a token from network not from evm +export const evmDenomsMap = { + kwt: [KWTBSC_ORAICHAIN_DENOM], + milky: [MILKYBSC_ORAICHAIN_DENOM], + injective: [INJECTIVE_ORAICHAIN_DENOM] +}; + +// minimum amount user can swap for specific token +export const minAmountSwapMap = { + trx: 10 +}; + +export type EvmDenom = "bep20_orai" | "bep20_airi" | "erc20_orai" | "kawaii_orai"; + export const solChainId = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"; diff --git a/packages/oraidex-common/src/format-types.ts b/packages/oraidex-common/src/format-types.ts new file mode 100644 index 00000000..78d4f6f4 --- /dev/null +++ b/packages/oraidex-common/src/format-types.ts @@ -0,0 +1,38 @@ +import { TokenItemType as TokenItemTypeCommon, CustomChainInfo as CustomChainInfoCommon } from "@oraichain/common"; +import { PairInfo } from "@oraichain/oraidex-contracts-sdk"; + +export type CoinGeckoPrices = { + [C in T]: number | null; +}; + +export type TokenItemType = TokenItemTypeCommon & { + Icon?: any; + IconLight?: any; +}; + +export type TokenInfo = TokenItemType & { + symbol?: string; + total_supply?: string; + icon?: string; + verified?: boolean; +}; + +export type CustomChainInfo = CustomChainInfoCommon & { + icon?: any; + iconLight?: any; +} + +export type PairInfoExtend = PairInfo & { + asset_infos_raw: [string, string]; +}; + +export interface FormatNumberDecimal { + price: number; + maxDecimal?: number; + unit?: string; + minDecimal?: number; + minPrice?: number; + unitPosition?: "prefix" | "suffix"; +} + +export type AmountDetails = { [denom: string]: string }; diff --git a/packages/oraidex-common/src/helper.ts b/packages/oraidex-common/src/helper.ts index e9f55b18..b3a9af9c 100644 --- a/packages/oraidex-common/src/helper.ts +++ b/packages/oraidex-common/src/helper.ts @@ -1,39 +1,29 @@ import { ExecuteInstruction, JsonObject, fromBinary, toBinary, wasmTypes } from "@cosmjs/cosmwasm-stargate"; import { fromAscii, toUtf8 } from "@cosmjs/encoding"; import { Coin, EncodeObject, Registry, decodeTxRaw } from "@cosmjs/proto-signing"; -import { Event, Attribute } from "@cosmjs/tendermint-rpc/build/tendermint37"; +import { Attribute, Event } from "@cosmjs/tendermint-rpc/build/tendermint37"; import { AssetInfo, Uint128 } from "@oraichain/oraidex-contracts-sdk"; import { TokenInfoResponse } from "@oraichain/oraidex-contracts-sdk/build/OraiswapToken.types"; import bech32 from "bech32"; +import { TextProposal } from "cosmjs-types/cosmos/gov/v1beta1/gov"; import { Tx as CosmosTx } from "cosmjs-types/cosmos/tx/v1beta1/tx"; import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { ethers } from "ethers"; import Long from "long"; +import { BigDecimal } from "./bigdecimal"; import { AVERAGE_COSMOS_GAS_PRICE, + GAS_ESTIMATION_BRIDGE_DEFAULT, + MULTIPLIER, WRAP_BNB_CONTRACT, WRAP_ETH_CONTRACT, atomic, - truncDecimals, - GAS_ESTIMATION_BRIDGE_DEFAULT, - MULTIPLIER, - CW20_DECIMALS + truncDecimals } from "./constant"; -import { CoinGeckoId, NetworkChainId, cosmosChainIds, cosmosChains, evmChainIds, tonChainId } from "./network"; -import { - AmountDetails, - TokenInfo, - TokenItemType, - cosmosTokens, - flattenTokens, - oraichainTokens, - CoinGeckoPrices, - tokenMap -} from "./token"; import { StargateMsg, Tx } from "./tx"; -import { BigDecimal } from "./bigdecimal"; -import { TextProposal } from "cosmjs-types/cosmos/gov/v1beta1/gov"; -import { defaultRegistryTypes as defaultStargateTypes, IndexedTx, logs, StargateClient } from "@cosmjs/stargate"; +import { CustomChainInfo, AmountDetails, TokenInfo, TokenItemType, CoinGeckoPrices } from "./format-types"; +import { defaultRegistryTypes as defaultStargateTypes, logs } from "@cosmjs/stargate"; +import { CoinGeckoId } from "./network"; import { Address } from "@ton/core"; export const getEvmAddress = (bech32Address: string) => { @@ -71,7 +61,12 @@ export const validateNumber = (amount: number | string): number => { // decimals always >= 6 export const toAmount = (amount: number | string, decimals = 6): bigint => { const validatedAmount = validateNumber(amount); - return BigInt(Math.trunc(validatedAmount * atomic)) * BigInt(10 ** (decimals - truncDecimals)); + return BigInt( + new BigDecimal(validatedAmount) + .mul(10 ** decimals) + .toString() + .split(".")[0] + ); }; /** @@ -99,7 +94,12 @@ export const toDisplay = (amount: string | bigint, sourceDecimals: number = 6, d // guarding conditions to prevent crashing const validatedAmount = typeof amount === "string" ? BigInt(amount || "0") : amount; const displayDecimals = Math.min(truncDecimals, desDecimals); - const returnAmount = validatedAmount / BigInt(10 ** (sourceDecimals - displayDecimals)); + const returnAmount = BigInt( + new BigDecimal(validatedAmount) + .div(10 ** (sourceDecimals - displayDecimals)) + .toString() + .split(".")[0] + ); // save calculation by using cached atomic return Number(returnAmount) / (displayDecimals === truncDecimals ? atomic : 10 ** displayDecimals); }; @@ -188,14 +188,16 @@ export const calculateMinReceive = ( ).toString(); }; -export const parseAssetInfoFromContractAddrOrDenom = (addressOrDenomToken: string) => { +export const parseAssetInfoFromContractAddrOrDenom = (addressOrDenomToken: string, cosmosTokens: TokenItemType[]) => { if (!addressOrDenomToken) return null; const addressOrDenomLowerCase = addressOrDenomToken.toLowerCase(); + const tokenItem = cosmosTokens.find((cosmosToken) => { return !cosmosToken.contractAddress ? cosmosToken.denom.toLowerCase() === addressOrDenomLowerCase : cosmosToken.contractAddress.toLowerCase() === addressOrDenomLowerCase; }); + // @ts-ignore return tokenItem ? parseTokenInfo(tokenItem).info : null; }; @@ -231,7 +233,11 @@ export const proxyContractInfo: { [x: string]: { wrapNativeAddr: string; routerA } }; -export const findToTokenOnOraiBridge = (fromCoingeckoId: CoinGeckoId, toNetwork: NetworkChainId) => { +export const findToTokenOnOraiBridge = ( + fromCoingeckoId: CoinGeckoId, + toNetwork: string, + cosmosTokens: TokenItemType[] +) => { return cosmosTokens.find( (t) => t.chainId === "oraibridge-subnet-2" && @@ -248,8 +254,10 @@ export const parseAssetInfo = (assetInfo: AssetInfo): string => { export const getTokenOnSpecificChainId = ( coingeckoId: CoinGeckoId, - chainId: NetworkChainId + chainId: string, + flattenTokens: TokenItemType[] ): TokenItemType | undefined => { + // const flattenTokens = getOraidexCommonAttribute("flattenTokens"); return flattenTokens.find((t) => t.coinGeckoId === coingeckoId && t.chainId === chainId); }; @@ -260,7 +268,8 @@ export const getTokenOnSpecificChainId = ( * @returns token on oraichain */ -export const getTokenOnOraichain = (coingeckoId: CoinGeckoId, isNative?: boolean) => { +export const getTokenOnOraichain = (coingeckoId: CoinGeckoId, oraichainTokens: TokenItemType[], isNative?: boolean) => { + // const oraichainTokens = getOraidexCommonAttribute("oraichainTokens"); const filterOraichainToken = oraichainTokens.filter((orai) => orai.coinGeckoId === coingeckoId); if (!filterOraichainToken.length) return undefined; if (filterOraichainToken.length === 1) return filterOraichainToken[0]; @@ -338,8 +347,8 @@ export const getSwapType = ({ fromCoingeckoId, toCoingeckoId }: { - fromChainId: NetworkChainId; - toChainId: NetworkChainId; + fromChainId: string; + toChainId: string; fromCoingeckoId: CoinGeckoId; toCoingeckoId: CoinGeckoId; }): SwapType => { @@ -393,8 +402,13 @@ export const calcMaxAmount = ({ return finalAmount; }; -export const getTotalUsd = (amounts: AmountDetails, prices: CoinGeckoPrices): number => { +export const getTotalUsd = ( + amounts: AmountDetails, + prices: CoinGeckoPrices, + tokenMap: Record +): number => { let usd = 0; + for (const denom in amounts) { const tokenInfo = tokenMap[denom]; if (!tokenInfo) continue; @@ -404,17 +418,25 @@ export const getTotalUsd = (amounts: AmountDetails, prices: CoinGeckoPrices { +export const toSubDisplay = ( + amounts: AmountDetails, + tokenInfo: TokenItemType, + tokenMap: Record +): number => { const subAmounts = getSubAmountDetails(amounts, tokenInfo); - return toSumDisplay(subAmounts); + return toSumDisplay(subAmounts, tokenMap); }; -export const toSubAmount = (amounts: AmountDetails, tokenInfo: TokenItemType): bigint => { - const displayAmount = toSubDisplay(amounts, tokenInfo); +export const toSubAmount = ( + amounts: AmountDetails, + tokenInfo: TokenItemType, + tokenMap: Record +): bigint => { + const displayAmount = toSubDisplay(amounts, tokenInfo, tokenMap); return toAmount(displayAmount, tokenInfo.decimals); }; -export const toSumDisplay = (amounts: AmountDetails): number => { +export const toSumDisplay = (amounts: AmountDetails, tokenMap: Record): number => { // get all native balances that are from oraibridge (ibc/...) let amount = 0; @@ -512,7 +534,7 @@ export const parseTxToMsgsAndEvents = (indexedTx: Tx, eventsParser?: (events: re }); }; -export const validateAndIdentifyCosmosAddress = (address: string, network: string) => { +export const validateAndIdentifyCosmosAddress = (address: string, network: string, cosmosChains: CustomChainInfo[]) => { try { const cosmosAddressRegex = /^[a-z]{1,6}[0-9a-z]{0,64}$/; if (!cosmosAddressRegex.test(address)) { @@ -523,6 +545,7 @@ export const validateAndIdentifyCosmosAddress = (address: string, network: strin const prefix = decodedAddress.prefix; let chainInfo; + const networkMap = cosmosChains.reduce((acc, cur) => { if (cur.chainId === network) chainInfo = cur; return { @@ -544,7 +567,6 @@ export const validateAndIdentifyCosmosAddress = (address: string, network: strin throw new Error("Unsupported address network"); } } catch (error) { - console.log("error:", error); return { isValid: false, error: error.message @@ -601,7 +623,7 @@ export const validateAddressTonTron = (address: string, network: string) => { } }; -export const checkValidateAddressWithNetwork = (address: string, network: NetworkChainId) => { +export const checkValidateAddressWithNetwork = (address: string, network: string, cosmosChains: CustomChainInfo[]) => { switch (network) { case "0x01": case "0x38": @@ -613,21 +635,20 @@ export const checkValidateAddressWithNetwork = (address: string, network: Networ return validateAddressTonTron(address, network); default: - return validateAndIdentifyCosmosAddress(address, network); + return validateAndIdentifyCosmosAddress(address, network, cosmosChains); } }; -export const isCosmosChain = (chainId: string): boolean => { - const hasValue = cosmosChainIds.find((id) => id === chainId); +export const isCosmosChain = (chainId: string, cosmosChains = []): boolean => { + const hasValue = cosmosChains.find((chain) => chain.chainId === chainId); return Boolean(hasValue); }; -export const isEvmChain = (chainId: string): boolean => { - const hasValue = evmChainIds.find((id) => id === chainId); +export const isEvmChain = (chainId: string, evmChains = []): boolean => { + const hasValue = evmChains.find((chain) => chain.chainId === chainId); return Boolean(hasValue); }; export const isTonChain = (chainId: string): boolean => { - const hasValue = tonChainId.find((id) => id === chainId); - return Boolean(hasValue); + return chainId === "ton"; }; diff --git a/packages/oraidex-common/src/ibc-info.ts b/packages/oraidex-common/src/ibc-info.ts index 5c063496..d6e891ab 100644 --- a/packages/oraidex-common/src/ibc-info.ts +++ b/packages/oraidex-common/src/ibc-info.ts @@ -1,5 +1,6 @@ // exclude evm chain +import { CosmosChainId } from "@oraichain/common"; import { ATOM_ORAICHAIN_CHANNELS, IBC_TRANSFER_TIMEOUT, @@ -15,7 +16,6 @@ import { OSMOSIS_ORAICHAIN_CHANNELS, NEUTARO_ORAICHAIN_CHANNELS } from "./constant"; -import { CosmosChainId, NetworkChainId } from "./network"; export interface IBCInfo { source: string; @@ -24,7 +24,7 @@ export interface IBCInfo { timeout: number; } -export type IBCInfoMap = { [key in CosmosChainId]: { [key in NetworkChainId]?: IBCInfo } }; +export type IBCInfoMap = { [key in CosmosChainId]: { [key in string]?: IBCInfo } }; // ibc constants @@ -40,8 +40,8 @@ const [oraib2oraichain_old, oraichain2oraib_old] = ORAIB_ORAICHAIN_CHANNELS_OLD. const [kwt2oraichain, oraichain2kwt] = KWT_ORAICHAIN_CHANNELS.split(/\s+/); // exclude evm chain - -export const ibcInfos: Omit = { +// FIXME: Callback info when Osor met problems +export const ibcInfos: Omit | any = { "cosmoshub-4": { Oraichain: { source: "transfer", @@ -164,7 +164,7 @@ export const ibcInfos: Omit = { timeout: IBC_TRANSFER_TIMEOUT }, timeout: IBC_TRANSFER_TIMEOUT - } + }, }, "oraibridge-subnet-2": { Oraichain: { @@ -183,7 +183,7 @@ export const ibcInfos: Omit = { export const ibcInfosOld: Omit< IBCInfoMap, "osmosis-1" | "cosmoshub-4" | "injective-1" | "noble-1" | "Neutaro-1" | "celestia" -> = { +> | any= { Oraichain: { "oraibridge-subnet-2": { source: "transfer", diff --git a/packages/oraidex-common/src/index.ts b/packages/oraidex-common/src/index.ts index 2816b6b5..6a6ea262 100644 --- a/packages/oraidex-common/src/index.ts +++ b/packages/oraidex-common/src/index.ts @@ -1,14 +1,18 @@ -export * from "./token"; -export * from "./network"; -export * from "./ibc-info"; -export * from "./helper"; +export * from "./axios-request"; +export * from "./bigdecimal"; +export * from "./config/chainInfosWithIcon"; export * from "./constant"; +export * from "./helper"; +export * from "./ibc-info"; +export * from "./interface"; +export * from "./network"; export * from "./pairs"; -export * from "./wallet"; -export * from "./typechain-types"; +export * from "./format-types"; +// export * from "./token"; export * from "./tx"; -export * from "./bigdecimal"; -export * from "./interface"; -export * from "./config/chainInfosWithIcon"; -export * from "./axios-request"; -export * from "./celestia-network"; +export * from "./typechain-types"; +export * from "./wallet"; +// export * from "./celestia-network"; +export * from "./common"; +export * from "./config"; +export * from "./supported"; diff --git a/packages/oraidex-common/src/interface/wallet.ts b/packages/oraidex-common/src/interface/wallet.ts index 5bb03eeb..c3d81629 100644 --- a/packages/oraidex-common/src/interface/wallet.ts +++ b/packages/oraidex-common/src/interface/wallet.ts @@ -1,3 +1,5 @@ +// FIXME: Still use? + export enum NetworkEnum { Cosmos = "cosmos", Evm = "evm", diff --git a/packages/oraidex-common/src/network.ts b/packages/oraidex-common/src/network.ts index 0768c70b..ebcc9b74 100644 --- a/packages/oraidex-common/src/network.ts +++ b/packages/oraidex-common/src/network.ts @@ -1,124 +1,6 @@ -import { Bech32Config, ChainInfo, Currency, FeeCurrency } from "@keplr-wallet/types"; -import { - AIRI_BSC_CONTRACT, - AIRI_CONTRACT, - ATOM_ORAICHAIN_DENOM, - CONVERTER_CONTRACT, - FACTORY_CONTRACT, - FACTORY_V2_CONTRACT, - INJECTIVE_CONTRACT, - INJECTIVE_ORAICHAIN_DENOM, - KWTBSC_ORAICHAIN_DENOM, - KWT_BSC_CONTRACT, - KWT_CONTRACT, - KWT_DENOM, - KWT_SUB_NETWORK_DENOM, - MILKYBSC_ORAICHAIN_DENOM, - MILKY_BSC_CONTRACT, - MILKY_CONTRACT, - MILKY_DENOM, - MILKY_ERC_CONTRACT, - MILKY_SUB_NETWORK_DENOM, - MULTICALL_CONTRACT, - ORACLE_CONTRACT, - ORAIDEX_LISTING_CONTRACT, - ORAIIBC_INJECTIVE_DENOM, - ORAIX_CONTRACT, - ORAI_BRIDGE_EVM_DENOM_PREFIX, - ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, - ORAI_BSC_CONTRACT, - ORAI_ETH_CONTRACT, - OSMOSIS_ORAICHAIN_DENOM, - REWARDER_CONTRACT, - ROUTER_V2_CONTRACT, - SCATOM_CONTRACT, - SCORAI_CONTRACT, - STAKING_CONTRACT, - TRX_CONTRACT, - USDC_CONTRACT, - USDC_ETH_CONTRACT, - USDT_BSC_CONTRACT, - USDT_CONTRACT, - USDT_TRON_CONTRACT, - WETH_CONTRACT, - WRAP_BNB_CONTRACT, - WRAP_ETH_CONTRACT, - WRAP_TRON_TRX_CONTRACT, - USDT_ETH_CONTRACT, - BTC_CONTRACT, - NEUTARO_ORAICHAIN_DENOM, - OCH_ETH_CONTRACT, - OCH_CONTRACT, - TON_ORAICHAIN_DENOM, - ORAIDEX_BID_POOL_CONTRACT, - ORAIX_ETH_CONTRACT, - MIXED_ROUTER, - AMM_V3_CONTRACT, - PEPE_ORAICHAIN_EXT_DENOM as PEPE_ORAICHAIN_DENOM, - CAT_ORAICHAIN_EXT_DENOM as CAT_ORAICHAIN_DENOM, - PEPE_ETH_CONTRACT, - PEPE_BSC_CONTRACT, - CAT_BSC_CONTRACT, - HMSTR_ORAICHAIN_DENOM, - TON20_USDT_CONTRACT, - TON_CONTRACT, - OBTC_ORAICHAIN_EXT_DENOM, - DOGE_BNB_ORAICHAIN_DENOM, - DOGE_BSC_CONTRACT, - jUSDC_TON_CONTRACT, - HMSTR_TON_CONTRACT, - WSOL_WORMHOLE_BNB_ORAICHAIN_DENOM, - WSOL_WORMHOLE_BSC_CONTRACT, - solChainId, - MAX_SOL_CONTRACT_ADDRESS, - MAX_ORAICHAIN_DENOM, - ORAI_SOL_CONTRACT_ADDRESS, - RACKS_ORAICHAIN_DENOM, - RACKS_SOL_CONTRACT_ADDRESS -} from "./constant"; -import { listOsmosisToken } from "./alpha-network"; -import { celestiaNetwork } from "./celestia-network"; - -export type NetworkName = - | "Oraichain" - | "Cosmos Hub" - | "Osmosis" - | "OraiBridge" - | "BNB Chain" - | "Ethereum" - | "Kawaiiverse" - | "Kawaiiverse EVM" - | "Tron Network" - | "Injective" - | "Noble" - | "Neutaro" - | "Celestia" - | "TON" - | "Solana"; - -export const cosmosChainIds = [ - "Oraichain", // oraichain - "oraibridge-subnet-2", // oraibridge - "osmosis-1", // osmosis - "cosmoshub-4", // cosmos hub - "injective-1", // injective network - "kawaii_6886-1", // kawaii subnetwork - "noble-1", // noble network - "Neutaro-1", // neutaro network; - "celestia" // Celestia -] as const; -export type CosmosChainId = (typeof cosmosChainIds)[number]; - -export const evmChainIds = ["0x38", "0x01", "0x1ae6", "0x2b6653dc"] as const; -export type EvmChainId = (typeof evmChainIds)[number]; - -export const tonChainId = ["ton"] as const; // FIXME: don;t know ton chainID -export type TonChainId = (typeof tonChainId)[number]; - -export type SolChainId = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"; -export type NetworkChainId = CosmosChainId | EvmChainId | TonChainId | SolChainId; +import { CoinType } from "@oraichain/common"; +// Incase when a new supported token is added, the coingecko id should be added here export type CoinGeckoId = | "oraichain-token" | "osmosis" @@ -147,6 +29,7 @@ export type CoinGeckoId = | "simon-s-cat" | "hamster-kombat" | "dogecoin" + | string | "solana" | "max-2" // | "black-rack" @@ -154,7 +37,7 @@ export type CoinGeckoId = export type NetworkType = "cosmos" | "evm" | "ton" | "svm"; export interface NetworkConfig { - coinType?: number; + coinType?: CoinType; explorer: string; /** Fixed fee */ fee: { gasPrice: string; amount: string; gas: string }; @@ -172,47 +55,8 @@ export interface NetworkConfig { bid_pool: string; multicall: string; pool_v3: string; -} - -export type CoinIcon = any; -export type BridgeAppCurrency = FeeCurrency & { - readonly bridgeTo?: NetworkChainId[]; - readonly coinGeckoId?: CoinGeckoId; - readonly Icon?: CoinIcon; - readonly IconLight?: CoinIcon; - readonly bridgeNetworkIdentifier?: EvmChainId; - readonly coinDecimals: 6 | 9 | 14 | 18 | 8; - readonly contractAddress?: string; - readonly prefixToken?: string; -}; - -export type CoinType = 118 | 60 | 195 | 501 | 607; - -/** - * A list of Cosmos chain infos. If we need to add / remove any chains, just directly update this variable. - * some chain is already in wallet so we override some attributes as optional - */ -export interface CustomChainInfo - extends Omit { - readonly chainId: NetworkChainId; - readonly chainName: NetworkName; - readonly Icon?: CoinIcon; - readonly IconLight?: CoinIcon; - readonly networkType: NetworkType; - readonly bip44: { - coinType: CoinType; - }; - readonly bech32Config?: Bech32Config; - readonly rest?: string; // optional, rest api tron and lcd for cosmos - readonly stakeCurrency?: Currency; - readonly feeCurrencies?: FeeCurrency[]; - readonly currencies: BridgeAppCurrency[]; - readonly hideInUI?: boolean; - readonly txExplorer?: { - readonly name: string; - readonly txUrl: string; - readonly accountUrl?: string; - }; + staking_oraix: string; + indexer_v3: string; } export const defaultBech32Config = ( @@ -231,1203 +75,3 @@ export const defaultBech32Config = ( bech32PrefixConsPub: mainPrefix + validatorPrefix + consensusPrefix + publicPrefix }; }; - -export const OraiToken: BridgeAppCurrency = { - coinDenom: "ORAI", - coinMinimalDenom: "orai", - coinDecimals: 6, - coinGeckoId: "oraichain-token", - bridgeTo: ["0x38", "0x01", "injective-1", solChainId], - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png", - gasPriceStep: { - low: 0.003, - average: 0.005, - high: 0.007 - } -}; - -export const OraiBToken: BridgeAppCurrency = { - coinDenom: "ORAIB", - coinMinimalDenom: "uoraib", - coinDecimals: 6, - gasPriceStep: { - low: 0, - average: 0, - high: 0 - } -}; - -export const KawaiiToken: BridgeAppCurrency = { - coinDenom: "ORAIE", - coinMinimalDenom: "oraie", - coinDecimals: 18, - coinGeckoId: "kawaii-islands", - gasPriceStep: { - low: 0, - average: 0.000025, - high: 0.00004 - } -}; - -export const InjectiveToken: BridgeAppCurrency = { - coinDenom: "INJ", - coinMinimalDenom: "inj", - coinDecimals: 18, - coinGeckoId: "injective-protocol", - gasPriceStep: { - low: 5000000000, - average: 25000000000, - high: 50000000000 - } -}; - -export const AtomToken: BridgeAppCurrency = { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/atom.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const NeutaroToken: BridgeAppCurrency = { - coinDenom: "NTMPI", - coinMinimalDenom: "uneutaro", - coinDecimals: 6, - coinGeckoId: "neutaro", - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/Neutaro/chain.png", - gasPriceStep: { - low: 0.01, - average: 0.025, - high: 0.03 - } -}; - -export const NativeUsdcNobleToken: BridgeAppCurrency = { - coinDenom: "USDC", - coinMinimalDenom: "uusdc", - coinDecimals: 6, - coinGeckoId: "usd-coin", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.03 - } -}; - -export const OsmoToken: BridgeAppCurrency = { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "osmosis", - coinImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/osmo.png", - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04 - } -}; - -export const tonNetworkMainnet: CustomChainInfo = { - rest: "https://toncenter.com/api/v2/jsonRPC", - rpc: "https://toncenter.com/api/v2/jsonRPC", - chainId: "ton", - chainName: "TON", - bip44: { - coinType: 607 - }, - coinType: 607, - stakeCurrency: { - coinDenom: "TON", - coinMinimalDenom: "ton", - coinDecimals: 9, - coinGeckoId: "the-open-network", - coinImageUrl: "https://assets.coingecko.com/coins/images/17980/standard/ton_symbol.png" - }, - bech32Config: defaultBech32Config("ton"), - networkType: "ton", - currencies: [ - { - coinDenom: "TON", - coinMinimalDenom: "ton", - coinDecimals: 9, - bridgeTo: ["Oraichain"], - prefixToken: "ton20_", - contractAddress: TON_CONTRACT, - coinGeckoId: "the-open-network", - coinImageUrl: "https://assets.coingecko.com/coins/images/17980/standard/ton_symbol.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: "ton20_usdt", - coinDecimals: 6, - bridgeTo: ["Oraichain"], - contractAddress: TON20_USDT_CONTRACT, - prefixToken: "ton20_", - coinGeckoId: "tether", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "HMSTR", - coinMinimalDenom: "ton20_hamster_kombat", - coinDecimals: 9, - bridgeTo: ["Oraichain"], - contractAddress: HMSTR_TON_CONTRACT, - prefixToken: "ton20_", - coinGeckoId: "hamster-kombat", - coinImageUrl: "https://assets.coingecko.com/coins/images/39102/standard/hamster-removebg-preview.png?1720514486" - }, - { - coinDenom: "jUSDC", - coinMinimalDenom: "ton20_usdc", - coinDecimals: 6, - bridgeTo: ["Oraichain"], - contractAddress: jUSDC_TON_CONTRACT, - prefixToken: "ton20_", - coinGeckoId: "usd-coin", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png" - } - ], - get feeCurrencies() { - return this.currencies; - }, - features: ["isTon"], - txExplorer: { - name: "BlockStream", - txUrl: "https://tonviewer.com/transaction/{txHash}", - accountUrl: `https://tonviewer.com/transaction/{address}` - } -}; - -export const oraichainNetwork: CustomChainInfo = { - rpc: "https://rpc.orai.io", - rest: "https://lcd.orai.io", - chainId: "Oraichain", - chainName: "Oraichain", - networkType: "cosmos", - stakeCurrency: OraiToken, - feeCurrencies: [OraiToken], - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("orai"), - - features: ["stargate", "ibc-transfer", "cosmwasm", "wasmd_0.24+", "no-legacy-stdTx"], - txExplorer: { - name: "Oraiscan", - txUrl: "https://scan.orai.io/txs/{txHash}", - accountUrl: "https://scan.orai.io/account/{address}" - }, - currencies: [ - OraiToken, - { - coinDenom: "PEPE", - coinGeckoId: "pepe", - coinMinimalDenom: PEPE_ORAICHAIN_DENOM, - bridgeTo: ["0x38", "0x01"], - coinDecimals: 6, - coinImageUrl: "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776" - }, - { - coinDenom: "DOGE", - coinMinimalDenom: DOGE_BNB_ORAICHAIN_DENOM, - coinDecimals: 8, - bridgeTo: ["0x38"], - coinGeckoId: "dogecoin", - coinImageUrl: "https://assets.coingecko.com/coins/images/5/standard/dogecoin.png?1696501409" - }, - { - coinDenom: "WSOL", - coinMinimalDenom: WSOL_WORMHOLE_BNB_ORAICHAIN_DENOM, - coinDecimals: 9, - bridgeTo: ["0x38"], - coinGeckoId: "solana", - coinImageUrl: "https://assets.coingecko.com/coins/images/4128/standard/solana.png?1718769756" - }, - // { - // coinDenom: "CAT", - // coinMinimalDenom: CAT_ORAICHAIN_DENOM, - // coinDecimals: 6, - // bridgeTo: ["0x38"], - // coinGeckoId: "simon-s-cat", - // coinImageUrl: "https://assets.coingecko.com/coins/images/39765/standard/Simon's_Cat_Logo.png?1724017505" - // }, - { - coinDenom: "ATOM", - coinGeckoId: "cosmos", - coinMinimalDenom: ATOM_ORAICHAIN_DENOM, - bridgeTo: ["cosmoshub-4"], - coinDecimals: 6, - coinImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/atom.png" - }, - { - coinDenom: "NTMPI", - coinGeckoId: "neutaro", - coinMinimalDenom: NEUTARO_ORAICHAIN_DENOM, - bridgeTo: ["Neutaro-1"], - coinDecimals: 6, - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/Neutaro/chain.png" - }, - // { - // coinDenom: 'BEP20 AIRI', - // coinGeckoId: 'airight', - // coinMinimalDenom: AIRIBSC_ORAICHAIN_DENOM, - // coinDecimals: 18, - // Icon: AiriIcon - // }, - { - coinDenom: "AIRI", - coinGeckoId: "airight", - coinMinimalDenom: "airi", - type: "cw20", - contractAddress: AIRI_CONTRACT, - bridgeTo: ["0x38"], - coinDecimals: 6, - coinImageUrl: "https://i.ibb.co/m8mCyMr/airi.png" - }, - { - coinDenom: "USDT", - coinGeckoId: "tether", - coinMinimalDenom: "usdt", - type: "cw20", - contractAddress: USDT_CONTRACT, - bridgeTo: ["0x38", "0x2b6653dc", "0x01", "ton"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "USDC", - coinGeckoId: "usd-coin", - coinMinimalDenom: "usdc", - type: "cw20", - contractAddress: USDC_CONTRACT, - bridgeTo: ["0x01", "noble-1", "ton"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png" - }, - { - coinDenom: "OSMO", - coinMinimalDenom: OSMOSIS_ORAICHAIN_DENOM, - coinDecimals: 6, - coinGeckoId: "osmosis", - bridgeTo: ["osmosis-1"], - coinImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/osmo.png" - }, - { - coinDenom: "BEP20 KWT", - coinGeckoId: "kawaii-islands", - coinMinimalDenom: KWTBSC_ORAICHAIN_DENOM, - coinDecimals: 18, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png" - }, - { - coinDenom: "KWT", - coinGeckoId: "kawaii-islands", - coinMinimalDenom: "kwt", - type: "cw20", - contractAddress: KWT_CONTRACT, - bridgeTo: ["0x38"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png" - }, - { - coinDenom: "BEP20 MILKY", - coinGeckoId: "milky-token", - coinMinimalDenom: MILKYBSC_ORAICHAIN_DENOM, - coinDecimals: 18, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png" - }, - { - coinDenom: "MILKY", - coinGeckoId: "milky-token", - coinMinimalDenom: "milky", - type: "cw20", - contractAddress: MILKY_CONTRACT, - bridgeTo: ["0x38"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png" - }, - { - coinDenom: "ORAIX", - coinMinimalDenom: "oraix", - type: "cw20", - contractAddress: ORAIX_CONTRACT, - bridgeTo: ["0x01"], - coinGeckoId: "oraidex", - coinDecimals: 6, - coinImageUrl: "https://i.ibb.co/VmMJtf7/oraix.png" - }, - { - coinDenom: "scORAI", - coinMinimalDenom: "scorai", - type: "cw20", - contractAddress: SCORAI_CONTRACT, - coinGeckoId: "scorai", - coinDecimals: 6 - }, - { - coinDenom: "wTRX", - coinGeckoId: "tron", - coinMinimalDenom: "trx", - type: "cw20", - contractAddress: TRX_CONTRACT, - bridgeTo: ["0x2b6653dc"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1958.png" - }, - { - coinDenom: "scATOM", - coinMinimalDenom: "scatom", - type: "cw20", - contractAddress: SCATOM_CONTRACT, - coinGeckoId: "scatom", - coinDecimals: 6 - }, - { - coinDenom: "IBC INJ", - coinGeckoId: "injective-protocol", - coinMinimalDenom: INJECTIVE_ORAICHAIN_DENOM, - coinDecimals: 18, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7226.png" - }, - { - coinDenom: "INJ", - coinGeckoId: "injective-protocol", - coinMinimalDenom: "injective", - contractAddress: INJECTIVE_CONTRACT, - bridgeTo: ["injective-1"], - type: "cw20", - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7226.png" - }, - { - coinDenom: "WETH", - coinGeckoId: "weth", - coinMinimalDenom: "weth", - type: "cw20", - contractAddress: WETH_CONTRACT, - bridgeTo: ["0x01"], - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" - }, - { - coinDenom: "BTC (Legacy)", - coinGeckoId: "bitcoin", - coinMinimalDenom: "usat", - type: "cw20", - contractAddress: BTC_CONTRACT, - bridgeTo: ["bitcoin"] as any, - coinDecimals: 6, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png" - }, - { - coinDenom: "BTC", - coinGeckoId: "bitcoin", - coinMinimalDenom: OBTC_ORAICHAIN_EXT_DENOM, - bridgeTo: ["bitcoin"] as any, - coinDecimals: 14, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png" - }, - { - coinDenom: "OCH", - coinGeckoId: "och", - coinMinimalDenom: "och", - type: "cw20", - contractAddress: OCH_CONTRACT, - bridgeTo: ["0x01"], - coinDecimals: 6, - coinImageUrl: - "https://assets.coingecko.com/coins/images/34236/standard/orchai_logo_white_copy_4x-8_%281%29.png?1704307670" - }, - { - coinDenom: "TON", - coinMinimalDenom: TON_ORAICHAIN_DENOM, - coinDecimals: 9, - bridgeTo: ["ton", "osmosis-1"], - coinGeckoId: "the-open-network", - coinImageUrl: "https://assets.coingecko.com/coins/images/17980/standard/ton_symbol.png?1696517498" - }, - { - coinDenom: "HMSTR", - coinMinimalDenom: HMSTR_ORAICHAIN_DENOM, - bridgeTo: ["ton"], - coinDecimals: 9, - coinGeckoId: "hamster-kombat", - coinImageUrl: "https://assets.coingecko.com/coins/images/39102/standard/hamster-removebg-preview.png?1720514486" - }, - { - coinDenom: "MAX", - coinGeckoId: "max-2", - coinMinimalDenom: MAX_ORAICHAIN_DENOM, - bridgeTo: [solChainId], - coinDecimals: 6, - coinImageUrl: - "https://pump.mypinata.cloud/ipfs/QmcGwYebsQfYbNSM9QDAMS2wKZ8fZNEiMbezJah1zgEWWS?img-width=256&img-dpr=2" - } - // { - // coinDenom: "RACKS", - // coinGeckoId: "black-rack", - // coinMinimalDenom: RACKS_ORAICHAIN_DENOM, - // bridgeTo: [solChainId], - // coinDecimals: 6, - // coinImageUrl: - // "https://pump.mypinata.cloud/ipfs/QmcGwYebsQfYbNSM9QDAMS2wKZ8fZNEiMbezJah1zgEWWS?img-width=256&img-dpr=2" - // } - ] -}; - -export const solanaMainnet: CustomChainInfo = { - rpc: "https://swr.xnftdata.com/rpc-proxy/", - rest: "https://swr.xnftdata.com/rpc-proxy/", - chainId: solChainId, - chainName: "Solana", - bip44: { - coinType: 501 - }, - bech32Config: defaultBech32Config("sol"), - stakeCurrency: { - coinDenom: "SOL", - coinMinimalDenom: "sol", - coinDecimals: 9, - coinGeckoId: "solana", - coinImageUrl: "https://assets.coingecko.com/coins/images/4128/standard/solana.png?1718769756" - }, - chainSymbolImageUrl: "https://upload.wikimedia.org/wikipedia/en/b/b9/Solana_logo.png", - networkType: "svm", - currencies: [ - { - coinDenom: "MAX", - coinMinimalDenom: "max", - coinDecimals: 6, - bridgeTo: ["Oraichain"], - contractAddress: MAX_SOL_CONTRACT_ADDRESS, - coinGeckoId: "max-2", - coinImageUrl: - "https://pump.mypinata.cloud/ipfs/QmcGwYebsQfYbNSM9QDAMS2wKZ8fZNEiMbezJah1zgEWWS?img-width=256&img-dpr=2" - }, - // { - // coinDenom: "RACKS", - // coinMinimalDenom: "racks", - // coinDecimals: 6, - // bridgeTo: ["Oraichain"], - // contractAddress: RACKS_SOL_CONTRACT_ADDRESS, - // coinGeckoId: "black-rack", - // coinImageUrl: "https://ipfs.io/ipfs/QmVRPsBSHpamDzcDzVL9wsbB9gr4frtNrrFF7g44Xa9FuS" - // }, - { - coinDenom: "ORAI", - coinMinimalDenom: "s20_orai", - coinDecimals: 6, - bridgeTo: ["Oraichain"], - contractAddress: ORAI_SOL_CONTRACT_ADDRESS, - coinGeckoId: "oraichain-token", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png" - } - ], - get feeCurrencies() { - return [ - { - coinDenom: "SOL", - coinMinimalDenom: "sol", - coinDecimals: 9, - coinGeckoId: "solana", - coinImageUrl: "https://assets.coingecko.com/coins/images/4128/standard/solana.png?1718769756", - gasPriceStep: { - low: 1, - average: 1.25, - high: 1.5 - } - } - ]; - }, - - features: [], - txExplorer: { - name: "Sol Scan", - txUrl: "https://solscan.io/tx/{txHash}", - accountUrl: "https://solscan.io/address/{address}" - } -}; - -export const chainInfos: CustomChainInfo[] = [ - // networks to add on keplr - oraichainNetwork, - tonNetworkMainnet, - celestiaNetwork, - solanaMainnet, - { - rpc: "https://bridge-v2.rpc.orai.io", - rest: "https://bridge-v2.lcd.orai.io", - chainId: "oraibridge-subnet-2", - chainName: "OraiBridge", - networkType: "cosmos", - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("oraib"), - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - stakeCurrency: OraiBToken, - feeCurrencies: [OraiBToken], - // not use oraib as currency - currencies: [ - OraiBToken, - { - coinDenom: "ORAI", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + ORAI_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 18, - coinGeckoId: "oraichain-token", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png" - }, - { - coinDenom: "ORAI", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + ORAI_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 18, - coinGeckoId: "oraichain-token", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png" - }, - { - coinDenom: "USDC", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + USDC_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 6, - coinGeckoId: "usd-coin", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png" - }, - { - coinDenom: "AIRI", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + AIRI_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 18, - coinGeckoId: "airight", - coinImageUrl: "https://i.ibb.co/m8mCyMr/airi.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + USDT_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 18, - coinGeckoId: "tether", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX + USDT_TRON_CONTRACT, - bridgeNetworkIdentifier: "0x2b6653dc", - prefixToken: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, - coinDecimals: 6, - coinGeckoId: "tether", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "wTRX", - coinMinimalDenom: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX + WRAP_TRON_TRX_CONTRACT, - bridgeNetworkIdentifier: "0x2b6653dc", - coinDecimals: 6, - coinGeckoId: "tron", - prefixToken: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1958.png" - }, - { - coinDenom: "KWT", - bridgeNetworkIdentifier: "0x38", - coinMinimalDenom: KWT_DENOM, - coinDecimals: 18, - coinGeckoId: "kawaii-islands", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png" - }, - { - coinDenom: "MILKY", - bridgeNetworkIdentifier: "0x38", - coinMinimalDenom: MILKY_DENOM, - coinDecimals: 18, - coinGeckoId: "milky-token", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png" - }, - { - coinDenom: "WETH", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + WRAP_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 18, - coinGeckoId: "weth", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + USDT_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 6, - coinGeckoId: "tether", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "OCH", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + OCH_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 18, - coinGeckoId: "och", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: - "https://assets.coingecko.com/coins/images/34236/standard/orchai_logo_white_copy_4x-8_%281%29.png?1704307670" - }, - { - coinDenom: "ORAIX", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + ORAIX_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 18, - coinGeckoId: "oraidex", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://i.ibb.co/VmMJtf7/oraix.png" - }, - { - coinDenom: "PEPE", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + PEPE_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 18, - coinGeckoId: "pepe", - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776" - }, - { - coinDenom: "PEPE", - coinMinimalDenom: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX + PEPE_ETH_CONTRACT, - bridgeNetworkIdentifier: "0x01", - coinDecimals: 18, - coinGeckoId: "pepe", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776" - }, - { - coinDenom: "DOGE", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + DOGE_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 8, - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinGeckoId: "dogecoin", - coinImageUrl: "https://assets.coingecko.com/coins/images/5/standard/dogecoin.png?1696501409" - }, - { - coinDenom: "WSOL", - coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + WSOL_WORMHOLE_BSC_CONTRACT, - bridgeNetworkIdentifier: "0x38", - coinDecimals: 9, - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinGeckoId: "solana", - coinImageUrl: "https://assets.coingecko.com/coins/images/4128/standard/solana.png?1718769756" - } - // { - // coinDenom: "CAT", - // coinMinimalDenom: ORAI_BRIDGE_EVM_DENOM_PREFIX + CAT_BSC_CONTRACT, - // bridgeNetworkIdentifier: "0x38", - // coinDecimals: 18, - // prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - // coinGeckoId: "simon-s-cat", - // coinImageUrl: "https://assets.coingecko.com/coins/images/39765/standard/Simon's_Cat_Logo.png?1724017505" - // } - ], - txExplorer: { - name: "OraiBridge Scan", - txUrl: "https://scan.bridge.orai.io/tx/${txHash}", - accountUrl: "https://scan.bridge.orai.io/account/{address}" - } - }, - - /// popular networks already included - { - rpc: "https://osmosis.rpc.orai.io/", - rest: "https://osmosis.lcd.orai.io/", - chainId: "osmosis-1", - chainName: "Osmosis", - networkType: "cosmos", - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("osmo"), - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go", "cosmwasm"], - stakeCurrency: OsmoToken, - feeCurrencies: [OsmoToken], - currencies: [ - { - ...OsmoToken, - bridgeTo: ["Oraichain"] - }, - ...listOsmosisToken - ] - }, - /// popular networks already included - { - rpc: "https://injective.rpc.orai.io/", - rest: "https://injective.lcd.orai.io/", - chainId: "injective-1", - chainName: "Injective", - networkType: "cosmos", - bip44: { - coinType: 60 - }, - bech32Config: defaultBech32Config("inj"), - features: ["stargate", "no-legacy-stdTx", "ibc-transfer", "ibc-go"], - stakeCurrency: InjectiveToken, - feeCurrencies: [InjectiveToken], - currencies: [ - { - ...InjectiveToken, - bridgeTo: ["Oraichain"] - }, - { - coinDenom: "ORAI", - coinMinimalDenom: ORAIIBC_INJECTIVE_DENOM, - coinDecimals: 6, - coinGeckoId: "oraichain-token", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png", - bridgeTo: ["Oraichain"] - } - ], - txExplorer: { - name: "Injective Scan", - txUrl: "https://explorer.injective.network/transaction/{txHash}" - }, - beta: true - }, - { - rpc: "https://cosmos-rpc.publicnode.com:443", - rest: "https://cosmos-rest.publicnode.com", - chainId: "cosmoshub-4", - chainName: "Cosmos Hub", - networkType: "cosmos", - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("cosmos"), - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - currencies: [ - { - ...AtomToken, - bridgeTo: ["Oraichain"] - } - ], - feeCurrencies: [AtomToken], - stakeCurrency: AtomToken, - chainSymbolImageUrl: "https://dhj8dql1kzq2v.cloudfront.net/white/atom.png", - txExplorer: { - name: "Mintscan", - txUrl: "https://www.mintscan.io/cosmos/txs/{txHash}" - } - }, - { - // rpc: 'http://rpc.neutaro.tech:26657/', - rpc: "https://neutaro.rpc.orai.io", - rest: "https://neutaro.lcd.orai.io", - // rest: "http://api.neutaro.tech:1317/", - chainId: "Neutaro-1", - chainName: "Neutaro", - networkType: "cosmos", - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("neutaro"), - stakeCurrency: { - coinDenom: "ntmpi", - coinMinimalDenom: "uneutaro", - coinDecimals: 6, - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/Neutaro/chain.png" - }, - feeCurrencies: [ - { - coinDenom: "ntmpi", - coinMinimalDenom: "uneutaro", - coinDecimals: 6, - coinImageUrl: "https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/Neutaro/chain.png", - gasPriceStep: { - low: 0.01, - average: 0.025, - high: 0.03 - } - } - ], - currencies: [ - { - ...NeutaroToken, - bridgeTo: ["Oraichain"] - } - ] - }, - { - rpc: "https://rpc.cosmos.directory/noble", - rest: "https://rest.cosmos.directory/noble", - chainId: "noble-1", - chainName: "Noble", - networkType: "cosmos", - bip44: { - coinType: 118 - }, - bech32Config: defaultBech32Config("noble"), - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - currencies: [ - { - ...NativeUsdcNobleToken, - bridgeTo: ["Oraichain"] - } - ], - feeCurrencies: [NativeUsdcNobleToken], - stakeCurrency: { - coinDecimals: 6, - coinDenom: "STAKE", - coinMinimalDenom: "ustake", - coinImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/stake.png" - }, - chainSymbolImageUrl: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/stake.png", - txExplorer: { - name: "Mintscan", - txUrl: "https://www.mintscan.io/noble/txs/{txHash}" - } - }, - - /// evm chain info - { - rpc: "https://rpc.ankr.com/eth", - chainId: "0x01", - chainName: "Ethereum", - bip44: { - coinType: 60 - }, - networkType: "evm", - features: ["isEvm"], - currencies: [ - { - coinDenom: "ORAI", - coinMinimalDenom: "erc20_orai", - contractAddress: ORAI_ETH_CONTRACT, - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "oraichain-token", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png" - }, - { - coinDenom: "USDC", - coinMinimalDenom: "erc20_usdc", - contractAddress: USDC_ETH_CONTRACT, - coinDecimals: 6, - bridgeTo: ["Oraichain"], - coinGeckoId: "usd-coin", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/3408.png" - }, - { - coinDenom: "WETH", - coinMinimalDenom: "erc20_eth", - contractAddress: WRAP_ETH_CONTRACT, - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "weth", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" - }, - { - coinDenom: "ETH", - coinMinimalDenom: "eth", - contractAddress: "", - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "ethereum", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1027.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: "erc20_usdt", - contractAddress: USDT_ETH_CONTRACT, - coinDecimals: 6, - bridgeTo: ["Oraichain"], - coinGeckoId: "tether", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "OCH", - coinMinimalDenom: "erc20_och", - contractAddress: OCH_ETH_CONTRACT, - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "och", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: - "https://assets.coingecko.com/coins/images/34236/standard/orchai_logo_white_copy_4x-8_%281%29.png?1704307670" - }, - { - coinDenom: "ORAIX", - coinMinimalDenom: "erc20_oraix", - contractAddress: ORAIX_ETH_CONTRACT, - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "oraidex", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://i.ibb.co/VmMJtf7/oraix.png" - }, - { - coinDenom: "PEPE", - coinMinimalDenom: "erc20_pepe", - contractAddress: PEPE_ETH_CONTRACT, - coinDecimals: 18, - bridgeTo: ["Oraichain"], - coinGeckoId: "pepe", - prefixToken: ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776" - } - ], - txExplorer: { - name: "Etherscan", - txUrl: "https://etherscan.io/tx/{txHash}", - accountUrl: "https://etherscan.io/address/{address}" - } - }, - { - rpc: "https://api.trongrid.io/jsonrpc", - rest: "https://api.trongrid.io", - chainId: "0x2b6653dc", - networkType: "evm", - chainName: "Tron Network", - features: ["isEvm"], - currencies: [ - { - coinDenom: "USDT", - coinMinimalDenom: "trx20_usdt", - contractAddress: USDT_TRON_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 6, - coinGeckoId: "tether", - prefixToken: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "wTRX", - coinMinimalDenom: "trx20_trx", - contractAddress: WRAP_TRON_TRX_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 6, - coinGeckoId: "tron", - prefixToken: ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1958.png" - } - ], - bip44: { - coinType: 195 - }, - txExplorer: { - name: "Tronscan", - txUrl: "https://tronscan.org/#/transaction/{txHash}", - accountUrl: "https://tronscan.org/#/address/{address}" - } - }, - { - rpc: "https://bsc-dataseed1.binance.org", - networkType: "evm", - chainId: "0x38", - chainName: "BNB Chain", - bip44: { - coinType: 60 - }, - features: ["isEvm"], - currencies: [ - { - coinDenom: "ORAI", - coinMinimalDenom: "bep20_orai", - contractAddress: ORAI_BSC_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 18, - coinGeckoId: "oraichain-token", - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/7533.png" - }, - { - coinDenom: "AIRI", - coinMinimalDenom: "bep20_airi", - contractAddress: AIRI_BSC_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 18, - coinGeckoId: "airight", - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://i.ibb.co/m8mCyMr/airi.png" - }, - { - coinDenom: "USDT", - coinMinimalDenom: "bep20_usdt", - contractAddress: USDT_BSC_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 18, - coinGeckoId: "tether", - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/825.png" - }, - { - coinDenom: "KWT", - coinMinimalDenom: "bep20_kwt", - contractAddress: KWT_BSC_CONTRACT, - bridgeTo: ["Oraichain"], - coinDecimals: 18, - coinGeckoId: "kawaii-islands", - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/12313.png" - }, - { - coinDenom: "MILKY", - coinMinimalDenom: "bep20_milky", - contractAddress: MILKY_BSC_CONTRACT, - coinDecimals: 18, - coinGeckoId: "milky-token", - bridgeTo: ["Oraichain"], - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/14418.png" - }, - { - coinDenom: "WBNB", - coinMinimalDenom: "bep20_wbnb", - contractAddress: WRAP_BNB_CONTRACT, - coinDecimals: 18, - coinGeckoId: "wbnb", - bridgeTo: ["Oraichain"], - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png" - }, - { - coinDenom: "BNB", - coinMinimalDenom: "bnb", - contractAddress: "", - coinDecimals: 18, - coinGeckoId: "binancecoin", - bridgeTo: ["Oraichain"], - coinImageUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/1839.png" - }, - { - coinDenom: "PEPE", - coinMinimalDenom: "bep20_pepe", - contractAddress: PEPE_BSC_CONTRACT, - coinDecimals: 18, - coinGeckoId: "pepe", - bridgeTo: ["Oraichain"], - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/29850/standard/pepe-token.jpeg?1696528776" - }, - { - coinDenom: "DOGE", - coinMinimalDenom: "bep20_doge", - contractAddress: DOGE_BSC_CONTRACT, - coinDecimals: 8, - coinGeckoId: "dogecoin", - bridgeTo: ["Oraichain"], - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/5/standard/dogecoin.png?1696501409" - }, - { - coinDenom: "WSOL", - coinMinimalDenom: "bep20_wsol", - contractAddress: WSOL_WORMHOLE_BSC_CONTRACT, - coinDecimals: 9, - coinGeckoId: "solana", - bridgeTo: ["Oraichain"], - prefixToken: ORAI_BRIDGE_EVM_DENOM_PREFIX, - coinImageUrl: "https://assets.coingecko.com/coins/images/4128/standard/solana.png?1718769756" - } - // { - // coinDenom: "CAT", - // coinMinimalDenom: "bep20_cat", - // contractAddress: CAT_BSC_CONTRACT, - // coinDecimals: 18, - // coinGeckoId: "simon-s-cat", - // bridgeTo: ["Oraichain"], - // coinImageUrl: "https://assets.coingecko.com/coins/images/39765/standard/Simon's_Cat_Logo.png?1724017505" - // } - ], - txExplorer: { - name: "Bsc Scan", - txUrl: "https://bscscan.com/tx/${txHash}", - accountUrl: "https://bscscan.com/address/{address}" - } - } -]; - -export const network: CustomChainInfo & NetworkConfig = { - ...oraichainNetwork, - prefix: oraichainNetwork.bech32Config.bech32PrefixAccAddr, - denom: "orai", - coinType: oraichainNetwork.bip44.coinType, - fee: { gasPrice: "0.00506", amount: "1518", gas: "2000000" }, // 0.000500 ORAI - factory: FACTORY_CONTRACT, - factory_v2: FACTORY_V2_CONTRACT, - router: ROUTER_V2_CONTRACT, - mixer_router: MIXED_ROUTER, - oracle: ORACLE_CONTRACT, - staking: STAKING_CONTRACT, - rewarder: REWARDER_CONTRACT, - converter: CONVERTER_CONTRACT, - oraidex_listing: ORAIDEX_LISTING_CONTRACT, - multicall: MULTICALL_CONTRACT, - bid_pool: ORAIDEX_BID_POOL_CONTRACT, - explorer: "https://scan.orai.io", - pool_v3: AMM_V3_CONTRACT -}; - -// exclude kawaiverse subnet and other special evm that has different cointype -export const evmChains = chainInfos.filter((c) => c.networkType === "evm"); -export const cosmosChains = chainInfos.filter((c) => c.networkType === "cosmos"); - -// evm network -export enum Networks { - mainnet = 1, - ropsten = 3, - rinkeby = 4, - goerli = 5, - optimism = 10, - kovan = 42, - matic = 137, - kovanOptimism = 69, - xdai = 100, - goerliOptimism = 420, - arbitrum = 42161, - rinkebyArbitrum = 421611, - goerliArbitrum = 421613, - mumbai = 80001, - sepolia = 11155111, - avalancheMainnet = 43114, - avalancheFuji = 43113, - fantomTestnet = 4002, - fantom = 250, - bsc = 56, - bsc_testnet = 97, - moonbeam = 1284, - moonriver = 1285, - moonbaseAlphaTestnet = 1287, - harmony = 1666600000, - cronos = 25, - fuse = 122, - songbirdCanaryNetwork = 19, - costonTestnet = 16, - boba = 288, - aurora = 1313161554, - astar = 592, - okc = 66, - heco = 128, - metis = 1088, - rsk = 30, - rskTestnet = 31, - evmos = 9001, - evmosTestnet = 9000, - thundercore = 108, - thundercoreTestnet = 18, - oasis = 26863, - celo = 42220, - godwoken = 71402, - godwokentestnet = 71401, - klatyn = 8217, - milkomeda = 2001, - kcc = 321, - kawaiiverse = 6886, - etherlite = 111, - tron = 728126428 -} diff --git a/packages/oraidex-common/src/pairs.ts b/packages/oraidex-common/src/pairs.ts index 2bc5999c..e1adee9d 100644 --- a/packages/oraidex-common/src/pairs.ts +++ b/packages/oraidex-common/src/pairs.ts @@ -20,9 +20,9 @@ import { MAX_ORAICHAIN_DENOM } from "./constant"; import { parseAssetInfo } from "./helper"; -import { TokenItemType, assetInfoMap } from "./token"; import uniq from "lodash/uniq"; import flatten from "lodash/flatten"; +import { TokenItemType } from "./format-types"; export type PairMapping = { asset_infos: [AssetInfo, AssetInfo]; @@ -112,87 +112,3 @@ export const PAIRS: PairMapping[] = [ symbols: ["MAX", "ORAIX"] } ]; - -// FIXME: makes this dynamic in the future so that permissionless listing is simpler -export enum pairLpTokens { - AIRI_ORAI = "orai1hxm433hnwthrxneyjysvhny539s9kh6s2g2n8y", - ORAIX_ORAI = "orai1qmy3uuxktflvreanaqph6yua7stjn6j65rur62", - SCORAI_ORAI = "orai1ay689ltr57jt2snujarvakxrmtuq8fhuat5rnvq6rct89vjer9gqm2vde6", - ATOM_ORAI = "orai1g2prqry343kx566cp7uws9w7v78n5tejylvaz6", - USDT_ORAI = "orai1mav52eqhd07c3lwevcnqdykdzhh4733zf32jcn", - KWT_ORAI = "orai17rcfcrwltujfvx7w4l2ggyku8qrncy0hdvrzvc", - OSMO_ORAI = "orai19ltj97jmdqnz5mrd2amethetvcwsp0220kww3e", - MILKY_USDT = "orai18ywllw03hvy720l06rme0apwyyq9plk64h9ccf", - USDC_ORAI = "orai1e0x87w9ezwq2sdmvv5dq5ngzy98lt47tqfaf2m7zpkg49g5dj6fqred5d7", - TRX_ORAI = "orai1wgywgvumt5dxhm7vjpwx5es9ecrtl85qaqdspjqwx2lugy7vmw5qlwrn88", - SCATOM_ATOM = "orai1hcjne0hmdj6pjrc3xuksucr0yplsa9ny7v047c34y8k8hfflq6yqyjapnn", - INJ_ORAI = "orai1slqw6gfvs6l2jgvh5ryjayf4g77d7sgfv6fumtyzcr06a6g9gnrq6c4rgg", - USDC_ORAIX = "orai1nwpfd09mr4rf8d5c9mh43axzezkwyr7dq2lus23jsw4xw2jqkaxqxwmkd3", - ORAI_WETH = "orai1rvr9wk6mdlfysvgp72ltthqvkkd5677mp892efq86yyr9alt0tms2a6lcs", - ORAI_BTC = "orai1jd9lc2qt0ltjsatgnu38xsz8ngp89clp0dpeh8geyjj70yvkn4kqmrmh3m", - NTMPI_USDC = "orai1rmvjmwd940ztafxue7630g75px8tqma4jskjuu57fkj0eqahqfgqqwjm00", - OCH_ORAI = "orai1xs5aj90d5m8kwfp9t6ghkcpk8d7sy5jsxdsyejjdxudhhfm7wegsdg929d", - MAX_ORAIX = "orai1gswmxchtlkav289eq86z4ehaezntctdrptcww4yvpp20d93xza0qsqjxvv" -} - -// token identifier can be denom or contract addr -export const isInPairList = (tokenIdentifier: string) => { - return PAIRS.some((pair) => - pair.asset_infos.some((info) => { - if ("native_token" in info) { - return info.native_token.denom === tokenIdentifier; - } - return info.token.contract_addr === tokenIdentifier; - }) - ); -}; - -export const isFactoryV1 = (assetInfos: [AssetInfo, AssetInfo]): boolean => { - const pair = PAIRS.find( - (pair) => - pair.asset_infos.find((info) => parseAssetInfo(info) === parseAssetInfo(assetInfos[0])) && - pair.asset_infos.find((info) => parseAssetInfo(info) === parseAssetInfo(assetInfos[1])) - ); - if (!pair) { - return true; - } - return pair.factoryV1 ?? false; -}; - -export const getPoolTokens = (): TokenItemType[] => { - return uniq(flatten(PAIRS.map((pair) => pair.asset_infos)).map((info) => assetInfoMap[parseAssetInfo(info)])); -}; - -export const PAIRS_CHART = PAIRS.map((pair) => { - const assets = pair.asset_infos.map((info) => { - if ("native_token" in info) return info.native_token.denom; - return info.token.contract_addr; - }); - - return { - ...pair, - symbol: `${pair.symbols[0]}/${pair.symbols[1]}`, - info: `${assets[0]}-${assets[1]}` - }; -}); - -export enum PairAddress { - AIRI_ORAI = "orai1wkhkazf88upf2dxqedggy3ldja342rzmfs2mep", - ORAIX_ORAI = "orai1m6q5k5nr2eh8q0rdrf57wr7phk7uvlpg7mwfv5", - ATOM_ORAI = "orai1jf74ry4m0jcy9emsaudkhe7vte9l8qy8enakvs", - USDT_ORAI = "orai1c5s03c3l336dgesne7dylnmhszw8554tsyy9yt", - KWT_ORAI = "orai1ynmd2cemryhcwtjq3adhcwayrm89l2cr4tws4v", - OSMO_ORAI = "orai1d37artrk4tkhz2qyjmaulc2jzjkx7206tmpfug", - MILKY_USDT = "orai1hr2l03ep6p9lwdkuqu5253fgpzc40xcpwymjfc", - SCORAI_ORAI = "orai15aunrryk5yqsrgy0tvzpj7pupu62s0t2n09t0dscjgzaa27e44esefzgf8", - USDC_ORAI = "orai19ttg0j7w5kr83js32tmwnwxxdq9rkmw4m3d7mn2j2hkpugwwa4tszwsnkg", - TRX_ORAI = "orai103ya8qkcf3vg4nksqquy0v5pvnugjtlt0uxpfh0fkuqge2a6k4aqwurg22", - SCATOM_ATOM = "orai16ltg2c8u9styus3dgql64mpupvtclxt9xdzvz0slx3pnrycxpm3qw75c5x", - INJ_ORAI = "orai1le7w5dmd23ky8f6zgtgfnpdv269qs6ezgr839sm8kj24rwaqqnrs58wf4u", - USDC_ORAIX = "orai1n4edv5h86rawzrvhy8lmrmnnmmherxnhuwqnk3yuvt0wgclh75usyn3md6", - ORAI_WETH = "orai10jgd0l4l0p2h7ugpk2lz64wpefjxc0h7evnlxf76a3fspdplarnsl9ma4j", - ORAI_BTC = "orai1fv5kwdv4z0gvp75ht378x8cg2j7prlywa0g35qmctez9q8u4xryspn6lrd", - NTMPI_USDC = "orai1yemx80gvcw05trjehy94rl4jz5dqjf2qxhks6258uvxd5s0m7h2quavx0g", - OCH_ORAI = "orai1d3f3e3j400hxse5z8vxxnxdwmvljs7mh8xa3wp3spe8g4ngnc3cqx8scs3", - MAX_ORAIX = "orai1s3746evfgwm7dtl3x4s7fmd37c4s8t566z0xvflr4shdculkxw5qa3pusc" -} diff --git a/packages/oraidex-common/src/supported/config/oraidex.json b/packages/oraidex-common/src/supported/config/oraidex.json new file mode 100644 index 00000000..a66aa5b2 --- /dev/null +++ b/packages/oraidex-common/src/supported/config/oraidex.json @@ -0,0 +1,323 @@ +{ + "Oraichain": { + "ORAI": { + "denom": "orai", + "coingecko_id": "oraichain-token" + }, + "PEPE": { + "denom": "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/extPEPE", + "coingecko_id": "pepe" + }, + "ATOM": { + "denom": "ibc/A2E2EEC9057A4A1C2C0A6A4C78B0239118DF5F278830F50B4A6BDD7A66506B78", + "coingecko_id": "cosmos" + }, + "NTMPI": { + "denom": "ibc/576B1D63E401B6A9A071C78A1D1316D016EC9333D2FEB14AD503FAC4B8731CD1", + "coingecko_id": "neutaro" + }, + "AIRI": { + "denom": "orai10ldgzued6zjp0mkqwsv2mux3ml50l97c74x8sg", + "coingecko_id": "airight" + }, + "USDT": { + "denom": "orai12hzjxfh77wl572gdzct2fxv2arxcwh6gykc7qh", + "coingecko_id": "tether" + }, + "USDC": { + "denom": "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd", + "coingecko_id": "usd-coin" + }, + "OSMO": { + "denom": "ibc/9C4DCD21B48231D0BC2AC3D1B74A864746B37E4292694C93C617324250D002FC", + "coingecko_id": "osmosis" + }, + "BEP20 KWT": { + "denom": "ibc/4F7464EEE736CCFB6B444EB72DE60B3B43C0DD509FFA2B87E05D584467AAE8C8", + "coingecko_id": "kawaii-islands" + }, + "KWT": { + "denom": "orai1nd4r053e3kgedgld2ymen8l9yrw8xpjyaal7j5", + "coingecko_id": "kawaii-islands" + }, + "BEP20 MILKY": { + "denom": "ibc/E12A2298AC40011C79F02F26C324BD54DF20F4B2904CB9028BFDEDCFAA89B906", + "coingecko_id": "milky-token" + }, + "MILKY": { + "denom": "orai1gzvndtzceqwfymu2kqhta2jn6gmzxvzqwdgvjw", + "coingecko_id": "milky-token" + }, + "ORAIX": { + "denom": "orai1lus0f0rhx8s03gdllx2n6vhkmf0536dv57wfge", + "coingecko_id": "oraidex" + }, + "scORAI": { + "denom": "orai1065qe48g7aemju045aeyprflytemx7kecxkf5m7u5h5mphd0qlcs47pclp", + "coingecko_id": "scorai" + }, + "wTRX": { + "denom": "orai1c7tpjenafvgjtgm9aqwm7afnke6c56hpdms8jc6md40xs3ugd0es5encn0", + "coingecko_id": "tron" + }, + "scATOM": { + "denom": "orai19q4qak2g3cj2xc2y3060t0quzn3gfhzx08rjlrdd3vqxhjtat0cq668phq", + "coingecko_id": "scatom" + }, + "IBC INJ": { + "denom": "ibc/49D820DFDE9F885D7081725A58202ABA2F465CAEE4AFBC683DFB79A8E013E83E", + "coingecko_id": "injective-protocol" + }, + "INJ": { + "denom": "orai19rtmkk6sn4tppvjmp5d5zj6gfsdykrl5rw2euu5gwur3luheuuusesqn49", + "coingecko_id": "injective-protocol" + }, + "WETH": { + "denom": "orai1dqa52a7hxxuv8ghe7q5v0s36ra0cthea960q2cukznleqhk0wpnshfegez", + "coingecko_id": "weth" + }, + "BTC": { + "denom": "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/obtc", + "coingecko_id": "bitcoin" + }, + "BTC (Legacy)": { + "denom": "orai10g6frpysmdgw5tdqke47als6f97aqmr8s3cljsvjce4n5enjftcqtamzsd", + "coingecko_id": "bitcoin" + }, + "OCH": { + "denom": "orai1hn8w33cqvysun2aujk5sv33tku4pgcxhhnsxmvnkfvdxagcx0p8qa4l98q", + "coingecko_id": "och" + }, + "TON": { + "denom": "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton", + "coingecko_id": "the-open-network" + }, + "HMSTR": { + "denom": "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/HMSTR", + "coingecko_id": "hamster-kombat" + }, + "DOGE": { + "denom": "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/DogeBNB", + "coingecko_id": "dogecoin" + }, + "THT": { + "denom": "cw20:orai1fkz48mkvw9cs848kjmr69gn7znj9flyc3vd2xvzud7h2x36xaj7q6p48re:THT", + "coingecko_id": "polkadot" + } + }, + "celestia": { + "TIA": { + "denom": "utia", + "coingecko_id": "celestia" + } + }, + "oraibridge-subnet-2": { + "ORAIB": { + "denom": "uoraib", + "coingecko_id": "" + }, + "ORAI": { + "denom": "eth-mainnet0x4c11249814f11b9346808179Cf06e71ac328c1b5", + "coingecko_id": "oraichain-token" + }, + "USDC": { + "denom": "eth-mainnet0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "coingecko_id": "usd-coin" + }, + "AIRI": { + "denom": "oraib0x7e2A35C746F2f7C240B664F1Da4DD100141AE71F", + "coingecko_id": "airight" + }, + "USDT": { + "denom": "eth-mainnet0xdAC17F958D2ee523a2206206994597C13D831ec7", + "coingecko_id": "tether" + }, + "wTRX": { + "denom": "trontrx-mainnet0x891cdb91d149f23B1a45D9c5Ca78a88d0cB44C18", + "coingecko_id": "tron" + }, + "KWT": { + "denom": "oraib0x257a8d1E03D17B8535a182301f15290F11674b53", + "coingecko_id": "kawaii-islands" + }, + "MILKY": { + "denom": "oraib0x6fE3d0F096FC932A905accd1EB1783F6e4cEc717", + "coingecko_id": "milky-token" + }, + "WETH": { + "denom": "eth-mainnet0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "coingecko_id": "weth" + }, + "OCH": { + "denom": "eth-mainnet0x19373EcBB4B8cC2253D70F2a246fa299303227Ba", + "coingecko_id": "och" + }, + "ORAIX": { + "denom": "eth-mainnet0x2d869aE129e308F94Cc47E66eaefb448CEe0d03e", + "coingecko_id": "oraidex" + }, + "PEPE": { + "denom": "eth-mainnet0x6982508145454Ce325dDbE47a25d4ec3d2311933", + "coingecko_id": "pepe" + } + }, + "osmosis-1": { + "OSMO": { + "denom": "uosmo", + "coingecko_id": "osmosis" + }, + "ATOM": { + "denom": "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", + "coingecko_id": "cosmos" + }, + "ORAI": { + "denom": "ibc/161D7D62BAB3B9C39003334F1671208F43C06B643CC9EDBBE82B64793C857F1D", + "coingecko_id": "oraichain-token" + }, + "TIA": { + "denom": "ibc/D79E7D83AB399BFFF93433E54FAA480C191248FC556924A2A8351AE2638B3877", + "coingecko_id": "celestia" + }, + "INJ": { + "denom": "ibc/64BA6E31FE887D66C6F8F31C7B1A80C7CA179239677B4088BB55F5EA07DBE273", + "coingecko_id": "injective-protocol" + } + }, + "injective-1": { + "INJ": { + "denom": "inj", + "coingecko_id": "injective-protocol" + }, + "ORAI": { + "denom": "ibc/C20C0A822BD22B2CEF0D067400FCCFB6FAEEE9E91D360B4E0725BD522302D565", + "coingecko_id": "oraichain-token" + } + }, + "cosmoshub-4": { + "ATOM": { + "denom": "uatom", + "coingecko_id": "cosmos" + } + }, + "Neutaro-1": { + "NTMPI": { + "denom": "uneutaro", + "coingecko_id": "neutaro" + } + }, + "noble-1": { + "USDC": { + "denom": "uusdc", + "coingecko_id": "usd-coin" + } + }, + "0x01": { + "ORAI": { + "denom": "0x4c11249814f11b9346808179Cf06e71ac328c1b5", + "coingecko_id": "oraichain-token" + }, + "USDC": { + "denom": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "coingecko_id": "usd-coin" + }, + "WETH": { + "denom": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "coingecko_id": "weth" + }, + "ETH": { + "denom": "eth", + "coingecko_id": "ethereum" + }, + "USDT": { + "denom": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "coingecko_id": "tether" + }, + "OCH": { + "denom": "0x19373EcBB4B8cC2253D70F2a246fa299303227Ba", + "coingecko_id": "och" + }, + "ORAIX": { + "denom": "0x2d869aE129e308F94Cc47E66eaefb448CEe0d03e", + "coingecko_id": "oraidex" + }, + "PEPE": { + "denom": "0x6982508145454Ce325dDbE47a25d4ec3d2311933", + "coingecko_id": "pepe" + } + }, + "0x2b6653dc": { + "USDT": { + "denom": "0xa614f803B6FD780986A42c78Ec9c7f77e6DeD13C", + "coingecko_id": "tether" + }, + "wTRX": { + "denom": "0x891cdb91d149f23B1a45D9c5Ca78a88d0cB44C18", + "coingecko_id": "tron" + } + }, + "0x38": { + "ORAI": { + "denom": "0xA325Ad6D9c92B55A3Fc5aD7e412B1518F96441C0", + "coingecko_id": "oraichain-token" + }, + "AIRI": { + "denom": "0x7e2A35C746F2f7C240B664F1Da4DD100141AE71F", + "coingecko_id": "airight" + }, + "USDT": { + "denom": "0x55d398326f99059fF775485246999027B3197955", + "coingecko_id": "tether" + }, + "KWT": { + "denom": "0x257a8d1E03D17B8535a182301f15290F11674b53", + "coingecko_id": "kawaii-islands" + }, + "MILKY": { + "denom": "0x6fE3d0F096FC932A905accd1EB1783F6e4cEc717", + "coingecko_id": "milky-token" + }, + "WBNB": { + "denom": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "coingecko_id": "wbnb" + }, + "BNB": { + "denom": "bnb", + "coingecko_id": "binancecoin" + }, + "PEPE": { + "denom": "0x25d887Ce7a35172C62FeBFD67a1856F20FaEbB00", + "coingecko_id": "pepe" + }, + "DOGE": { + "denom": "0xbA2aE424d960c26247Dd6c32edC70B295c744C43", + "coingecko_id": "dogecoin" + } + }, + "oraibtc-mainnet-1": { + "ORAIBTC": { + "denom": "uoraibtc", + "coingecko_id": "bitcoin" + }, + "oBTC": { + "denom": "usat", + "coingecko_id": "bitcoin" + } + }, + "bitcoin": { + "BTC": { + "denom": "btc", + "coingecko_id": "bitcoin" + } + }, + "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp": { + "MAX": { + "denom": "max", + "coingecko_id": "max-2" + }, + "ORAI": { + "denom": "s20_orai", + "coingecko_id": "oraichain-token" + } + }, + "ton": {} +} diff --git a/packages/oraidex-common/src/supported/index.ts b/packages/oraidex-common/src/supported/index.ts new file mode 100644 index 00000000..214b52a0 --- /dev/null +++ b/packages/oraidex-common/src/supported/index.ts @@ -0,0 +1,3 @@ +export * from "./supported"; +export * from "./supported-reader"; +export * from "./types"; \ No newline at end of file diff --git a/packages/oraidex-common/src/supported/supported-reader.ts b/packages/oraidex-common/src/supported/supported-reader.ts new file mode 100644 index 00000000..297f4f14 --- /dev/null +++ b/packages/oraidex-common/src/supported/supported-reader.ts @@ -0,0 +1,27 @@ +import { fetchRetry } from "../helper"; +import oraidexJson from "./config/oraidex.json"; + +// BASE_URL: "https://raw.githubusercontent.com/oraidex/oraidex-sdk", +// SUPPORTED_INFO: "/packages/oraidex-common/src/supported/config/" +const ORAIDEX_API_ENDPOINTS = { + BASE_URL: "https://oraicommon-staging.oraidex.io", + SUPPORTED_INFO: "/api/v1/supported-tokens/oraidex" +}; + +export const readSupportedChainInfoStatic = async () => { + const options = { + method: "GET", + headers: { + Accept: "application/json" + } + }; + const supportedChainInfo = await ( + await fetchRetry(`${ORAIDEX_API_ENDPOINTS.BASE_URL}${ORAIDEX_API_ENDPOINTS.SUPPORTED_INFO}`, options) + ).json(); + + if (!supportedChainInfo) { + return oraidexJson; + } + + return supportedChainInfo; +}; diff --git a/packages/oraidex-common/src/supported/supported.ts b/packages/oraidex-common/src/supported/supported.ts new file mode 100644 index 00000000..1e047efe --- /dev/null +++ b/packages/oraidex-common/src/supported/supported.ts @@ -0,0 +1,85 @@ +export const supportedBridge = { + Oraichain: { + "oraichain-token": ["0x38", "0x01", "injective-1"], + pepe: ["0x38", "0x01"], + cosmos: ["cosmoshub-4"], + neutaro: ["Neutaro-1"], + airight: ["0x38"], + tether: ["0x38", "0x2b6653dc", "0x01"], + "usd-coin": ["0x01", "noble-1"], + osmosis: ["osmosis-1"], + "kawaii-islands": ["0x38"], + "milky-token": ["0x38"], + oraidex: ["0x01"], + scorai: [], + tron: ["0x2b6653dc"], + scatom: [], + "injective-protocol": ["injective-1"], + weth: ["0x01"], + bitcoin: ["bitcoin"], + och: ["0x01"], + "the-open-network": [], + "hamster-kombat": [] + }, + celestia: { + celestia: [] + }, + "oraibridge-subnet-2": { + undefined: [], + "oraichain-token": [], + "usd-coin": [], + airight: [], + tether: [], + tron: [], + "kawaii-islands": [], + "milky-token": [], + weth: [], + och: [], + oraidex: [], + pepe: [] + }, + "osmosis-1": { + osmosis: ["Oraichain"], + cosmos: [], + "oraichain-token": [], + celestia: [], + "injective-protocol": [] + }, + "injective-1": { + "injective-protocol": ["Oraichain"], + "oraichain-token": ["Oraichain"] + }, + "cosmoshub-4": { + cosmos: ["Oraichain"] + }, + "Neutaro-1": { + neutaro: ["Oraichain"] + }, + "noble-1": { + "usd-coin": ["Oraichain"] + }, + "0x01": { + "oraichain-token": ["Oraichain"], + "usd-coin": ["Oraichain"], + weth: ["Oraichain"], + ethereum: ["Oraichain"], + tether: ["Oraichain"], + och: ["Oraichain"], + oraidex: ["Oraichain"], + pepe: ["Oraichain"] + }, + "0x2b6653dc": { + tether: ["Oraichain"], + tron: ["Oraichain"] + }, + "0x38": { + "oraichain-token": ["Oraichain"], + airight: ["Oraichain"], + tether: ["Oraichain"], + "kawaii-islands": ["Oraichain"], + "milky-token": ["Oraichain"], + wbnb: ["Oraichain"], + binancecoin: ["Oraichain"], + pepe: ["Oraichain"] + } +}; diff --git a/packages/oraidex-common/src/supported/types.ts b/packages/oraidex-common/src/supported/types.ts new file mode 100644 index 00000000..3ad8785c --- /dev/null +++ b/packages/oraidex-common/src/supported/types.ts @@ -0,0 +1,16 @@ +export type SupportedChainInfo = { + [chainId: string]: Record; +}; + +export type SupportedTokenInfo = { + denom: string; + coingecko_id: string; +}; + +export interface SupportedChainInfoReader { + readSupportedChainInfo(): Promise; +} + +export interface SupportedTokens { + getSupportedTokensByChain: (chainId: string) => Record; +} diff --git a/packages/oraidex-common/src/token.ts b/packages/oraidex-common/src/token.ts deleted file mode 100644 index b12a664b..00000000 --- a/packages/oraidex-common/src/token.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { FeeCurrency } from "@keplr-wallet/types"; -import { PairInfo } from "@oraichain/oraidex-contracts-sdk"; -import { flatten, uniqBy } from "lodash"; -import { INJECTIVE_ORAICHAIN_DENOM, KWTBSC_ORAICHAIN_DENOM, MILKYBSC_ORAICHAIN_DENOM } from "./constant"; -import { - CoinGeckoId, - CoinIcon, - CustomChainInfo, - NetworkChainId, - NetworkName, - chainInfos, - oraichainNetwork -} from "./network"; - -export type EvmDenom = "bep20_orai" | "bep20_airi" | "erc20_orai" | "kawaii_orai"; -export type AmountDetails = { [denom: string]: string }; - -/** - * Prices of each token. - */ -export type CoinGeckoPrices = { - [C in T]: number | null; -}; - -export type TokenItemType = { - name: string; - org: NetworkName; - denom: string; - prefix?: string; - contractAddress?: string; - evmDenoms?: string[]; - bridgeNetworkIdentifier?: NetworkChainId; - bridgeTo?: NetworkChainId[]; - Icon: CoinIcon; - IconLight?: CoinIcon; - chainId: NetworkChainId; - coinType?: number; - rpc: string; - decimals: number; - maxGas?: number; - coinGeckoId: CoinGeckoId; - cosmosBased: Boolean; - minAmountSwap?: number; - gasPriceStep?: { - readonly low: number; - readonly average: number; - readonly high: number; - }; - feeCurrencies?: FeeCurrency[]; -}; - -export type TokenInfo = TokenItemType & { - symbol?: string; - total_supply?: string; - icon?: string; - verified?: boolean; -}; - -export type PairInfoExtend = PairInfo & { - asset_infos_raw: [string, string]; -}; - -export interface FormatNumberDecimal { - price: number; - maxDecimal?: number; - unit?: string; - minDecimal?: number; - minPrice?: number; - unitPosition?: "prefix" | "suffix"; -} - -const evmDenomsMap = { - kwt: [KWTBSC_ORAICHAIN_DENOM], - milky: [MILKYBSC_ORAICHAIN_DENOM], - injective: [INJECTIVE_ORAICHAIN_DENOM] -}; -const minAmountSwapMap = { - trx: 10 -}; - -export const getTokensFromNetwork = (network: CustomChainInfo): TokenItemType[] => { - return network.currencies.map((currency) => ({ - name: currency.coinDenom, - org: network.chainName, - coinType: network.bip44.coinType, - contractAddress: currency.contractAddress, - prefix: currency?.prefixToken ?? network.bech32Config?.bech32PrefixAccAddr, - coinGeckoId: currency.coinGeckoId, - denom: currency.coinMinimalDenom, - bridgeNetworkIdentifier: currency.bridgeNetworkIdentifier, - decimals: currency.coinDecimals, - bridgeTo: currency.bridgeTo, - chainId: network.chainId, - rpc: network.rpc, - lcd: network.rest, - cosmosBased: network.networkType === "cosmos", - maxGas: (network.feeCurrencies?.[0].gasPriceStep?.high ?? 0) * 20000, - gasPriceStep: currency.gasPriceStep, - feeCurrencies: network.feeCurrencies, - minAmountSwap: minAmountSwapMap[currency.coinMinimalDenom], - evmDenoms: evmDenomsMap[currency.coinMinimalDenom], - Icon: currency.Icon, - IconLight: currency?.IconLight - })); -}; - -// other chains, oraichain -const otherChainTokens = flatten( - chainInfos.filter((chainInfo) => chainInfo.chainId !== "Oraichain").map(getTokensFromNetwork) -); -export const oraichainTokens: TokenItemType[] = getTokensFromNetwork(oraichainNetwork); - -export const tokens = [otherChainTokens, oraichainTokens]; -export const flattenTokens = flatten(tokens); -export const tokenMap = Object.fromEntries(flattenTokens.map((c) => [c.denom, c])); -export const assetInfoMap = Object.fromEntries(flattenTokens.map((c) => [c.contractAddress || c.denom, c])); -export const cosmosTokens = uniqBy( - flattenTokens.filter( - (token) => - // !token.contractAddress && - token.denom && token.cosmosBased && token.coinGeckoId - ), - (c) => c.denom -); - -export const cw20Tokens = uniqBy( - cosmosTokens.filter( - // filter cosmos based tokens to collect tokens that have contract addresses - (token) => - // !token.contractAddress && - token.contractAddress - ), - (c) => c.denom -); - -export const cw20TokenMap = Object.fromEntries(cw20Tokens.map((c) => [c.contractAddress, c])); - -export const evmTokens = uniqBy( - flattenTokens.filter( - (token) => - // !token.contractAddress && - token.denom && !token.cosmosBased && token.coinGeckoId && token.chainId !== "kawaii_6886-1" - ), - (c) => c.denom -); - -export const kawaiiTokens = uniqBy( - cosmosTokens.filter((token) => token.chainId === "kawaii_6886-1"), - (c) => c.denom -); diff --git a/packages/oraidex-common/src/wallet.ts b/packages/oraidex-common/src/wallet.ts index 596c045b..6f1e1cb0 100644 --- a/packages/oraidex-common/src/wallet.ts +++ b/packages/oraidex-common/src/wallet.ts @@ -1,9 +1,8 @@ import { OfflineSigner } from "@cosmjs/proto-signing"; -import { CosmosChainId, EvmChainId, NetworkChainId, Networks } from "./network"; import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate"; import { SigningStargateClient, SigningStargateClientOptions } from "@cosmjs/stargate"; import { ethToTronAddress, tronToEthAddress } from "./helper"; -import { TokenItemType } from "./token"; +import { TokenItemType } from "./format-types"; import { ethers } from "ethers"; import { IERC20Upgradeable__factory } from "./typechain-types"; import { JsonRpcSigner } from "@ethersproject/providers"; @@ -12,6 +11,7 @@ import { EncodeObject } from "@cosmjs/proto-signing"; import { Tendermint37Client } from "@cosmjs/tendermint-rpc"; import { Stargate } from "@injectivelabs/sdk-ts"; import { BROADCAST_POLL_INTERVAL } from "./constant"; +import { CosmosChainId, EVM_CHAIN_IDS_DECIMAL, EvmChainId } from "@oraichain/common"; export interface EvmResponse { transactionHash: string; @@ -108,10 +108,10 @@ export abstract class EvmWallet { public abstract getSigner(): JsonRpcSigner; public isTron(chainId: string | number) { - return Number(chainId) == Networks.tron; + return Number(chainId) == EVM_CHAIN_IDS_DECIMAL.tron; } public getFinalEvmAddress( - chainId: NetworkChainId, + chainId: string, address: { metamaskAddress?: string; tronAddress?: string } ): string | undefined { if (this.isTron(chainId)) return address.tronAddress; diff --git a/packages/oraidex-common/tests/helper.spec.ts b/packages/oraidex-common/tests/helper.spec.ts index 90934a03..2d938e70 100644 --- a/packages/oraidex-common/tests/helper.spec.ts +++ b/packages/oraidex-common/tests/helper.spec.ts @@ -1,8 +1,12 @@ import { Coin } from "@cosmjs/amino"; import { toBinary } from "@cosmjs/cosmwasm-stargate"; -import { StargateClient } from "@cosmjs/stargate"; import { Event } from "@cosmjs/tendermint-rpc/build/tendermint37"; import { AssetInfo } from "@oraichain/oraidex-contracts-sdk"; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import { beforeAll, describe, expect, it } from "vitest"; +import { OraidexCommon } from "../src/common"; import { AIRI_CONTRACT, AVERAGE_COSMOS_GAS_PRICE, BTC_CONTRACT, MILKYBSC_ORAICHAIN_DENOM, ORAI } from "../src/constant"; import { calculateMinReceive, @@ -36,13 +40,8 @@ import { validateAddressTonTron, parseAssetInfoFromContractAddrOrDenom } from "../src/helper"; -import { CoinGeckoId, NetworkChainId } from "../src/network"; -import { isFactoryV1 } from "../src/pairs"; -import { AmountDetails, TokenItemType, cosmosTokens, flattenTokens, oraichainTokens } from "../src/token"; -import fs from "fs"; -import path from "path"; -import { expect, afterAll, beforeAll, describe, it } from "vitest"; -import { fileURLToPath } from "url"; +import { AmountDetails } from "../src/format-types"; +import { CoinGeckoId } from "../src/network"; const __filename = fileURLToPath(import.meta.url); console.log("__filename: ", __filename); const __dirname = path.dirname(__filename); @@ -55,6 +54,12 @@ describe("should helper functions in helper run exactly", () => { [MILKYBSC_ORAICHAIN_DENOM]: "1000000000000000000" // 1 }; + let oraidexCommon: OraidexCommon; + + beforeAll(async () => { + oraidexCommon = await OraidexCommon.load(); + }); + it.each<[string, boolean]>([ ["0x", false], ["orai1g4h64yjt0fvzv5v2j8tyfnpe5kmnetejvfgs7g", false], @@ -66,33 +71,55 @@ describe("should helper functions in helper run exactly", () => { it("should get sub amount of evm token correctly and to sum display, to total display correctly", () => { // test for milky token that have evm denom => have sub amount. - const tokenInfo = flattenTokens.find((t) => t.evmDenoms && t.coinGeckoId === "milky-token")!; + console.log( + "oraidexCommon.flattenTokens: ", + oraidexCommon.flattenTokens.filter((t) => t.evmDenoms) + ); + const tokenInfo = oraidexCommon.flattenTokens.find((t) => t.evmDenoms && t.coinGeckoId === "milky-token")!; const subAmounts = getSubAmountDetails(amounts, tokenInfo); expect(subAmounts).toEqual({ [MILKYBSC_ORAICHAIN_DENOM]: "1000000000000000000" }); }); - it.each<[TokenItemType, string]>([ + it.each<[{ coinGeckoID: string; chain: string; type: "token" | "native" }]>([ [ - flattenTokens.find((item) => item.coinGeckoId === "airight" && item.chainId === "Oraichain")!, - flattenTokens.find((item) => item.coinGeckoId === "airight" && item.chainId === "Oraichain")!.contractAddress! + { + coinGeckoID: "airight", + chain: "Oraichain", + type: "token" + } ], [ - flattenTokens.find((item) => item.coinGeckoId === "cosmos" && item.chainId === "Oraichain")!, - flattenTokens.find((item) => item.coinGeckoId === "cosmos" && item.chainId === "Oraichain")!.denom + { + coinGeckoID: "cosmos", + chain: "Oraichain", + type: "native" + } ] - ])("test-parseTokenInfoRawDenom-given-%j-should-receive-%s", (token, expectedDenom) => { + ])("test-parseTokenInfoRawDenom-given-%j-should-receive-%s", ({ coinGeckoID, chain, type }) => { + const token = oraidexCommon.flattenTokens.find( + (item) => item.coinGeckoId === coinGeckoID && item.chainId === chain + )!; + let expectedDenom = ""; + if (type === "token") { + expectedDenom = token.contractAddress!; + } else { + expectedDenom = token.denom!; + } expect(parseTokenInfoRawDenom(token)).toEqual(expectedDenom); }); - it.each<[CoinGeckoId, TokenItemType, string]>([ - ["airight", cosmosTokens.find((token) => token.coinGeckoId === "airight" && token.chainId === "Oraichain")!, ""], - ["tether", cosmosTokens.find((token) => token.coinGeckoId === "tether" && token.chainId === "Oraichain")!, ""], - ["tron", cosmosTokens.find((token) => token.coinGeckoId === "tron" && token.chainId === "Oraichain")!, ""] + it.each<[CoinGeckoId, string, string]>([ + ["airight", "airight"!, ""], + ["tether", "tether"!, ""], + ["tron", "tron"!, ""] ])("test-getTokenOnOraichain-given-%s-should-receive-%j", (coingeckoId, expectedToken, err) => { try { - expect(getTokenOnOraichain(coingeckoId)).toEqual(expectedToken); + const token = oraidexCommon.cosmosTokens.find( + (token) => token.coinGeckoId === expectedToken && token.chainId === "Oraichain" + )!; + expect(getTokenOnOraichain(coingeckoId, oraidexCommon.oraichainTokens)).toEqual(token); } catch (error) { expect(error).toEqual(new Error(err)); } @@ -105,22 +132,6 @@ describe("should helper functions in helper run exactly", () => { expect(parseAssetInfo(assetInfo)).toEqual(expectedResult); }); - it("test-isFactoryV1-true", () => { - const data = isFactoryV1([ - { native_token: { denom: ORAI } }, - { token: { contract_addr: "orai10ldgzued6zjp0mkqwsv2mux3ml50l97c74x8sg" } } - ]); - expect(data).toEqual(true); - }); - - it("test-isFactoryV1-false", () => { - const data = isFactoryV1([ - { native_token: { denom: ORAI } }, - { token: { contract_addr: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd" } } - ]); - expect(data).toEqual(false); - }); - it.each([ ["1000000", "1000000", 1, 6, "990000"], ["1800000", "100000", 1, 6, "178200"], @@ -209,7 +220,11 @@ describe("should helper functions in helper run exactly", () => { [2000000, 18, "2000000000000000000000000"], [6000.5043177, 6, "6000504317"], [6000.504317725654, 6, "6000504317"], - [0.0006863532, 6, "686"] + [0.0006863532, 6, "686"], + [1, 1, "10"], + [1.5555, 1, "15"], + [1.5555, 0, "1"], + [null, 0, "0"] ])( "toAmount number %.7f with decimal %d should return %s", (amount: number, decimal: number, expectedAmount: string) => { @@ -224,7 +239,8 @@ describe("should helper functions in helper run exactly", () => { ["1000", 6, "0.001", 6], ["454136345353413531", 15, "454.136345", 6], ["454136345353413531", 15, "454.13", 2], - ["100000000000000", 18, "0.0001", 6] + ["100000000000000", 18, "0.0001", 6], + ["100", 0, "100", 6] ])( "toDisplay number %d with decimal %d should return %s", (amount: string, decimal: number, expectedAmount: string, desDecimal: number) => { @@ -278,7 +294,7 @@ describe("should helper functions in helper run exactly", () => { ["airi", { token: { contract_addr: AIRI_CONTRACT } }] ])("test-toAssetInfo", (denom, expectedAssetInfo) => { // fixture - const token = oraichainTokens.find((t) => t.denom === denom); + const token = oraidexCommon.oraichainTokens.find((t) => t.denom === denom); const tokenInfo = toTokenInfo(token!); expect(toAssetInfo(tokenInfo)).toEqual(expectedAssetInfo); }); @@ -288,7 +304,7 @@ describe("should helper functions in helper run exactly", () => { expect(calculateTimeoutTimestamp(10, now)).toEqual((11000000000).toString()); }); - it.each<[CoinGeckoId, NetworkChainId, CoinGeckoId, NetworkChainId | undefined]>([ + it.each<[CoinGeckoId, string, CoinGeckoId, string | undefined]>([ // ["cosmos", "cosmoshub-4", "cosmos", undefined], // ["osmosis", "osmosis-1", "osmosis", undefined], ["airight", "0x38", "airight", "oraibridge-subnet-2"], @@ -297,17 +313,17 @@ describe("should helper functions in helper run exactly", () => { ])( "test-findToTokenOnOraiBridge-when-universalSwap-from-Oraichain-to%s", (fromCoingeckoId, toChainId, expectedToCoinGeckoId, expectedToChainId) => { - const toTokenTransfer = findToTokenOnOraiBridge(fromCoingeckoId, toChainId); + const toTokenTransfer = findToTokenOnOraiBridge(fromCoingeckoId, toChainId, oraidexCommon.cosmosTokens); expect(toTokenTransfer!.coinGeckoId).toEqual(expectedToCoinGeckoId); expect(toTokenTransfer!.chainId).toEqual(expectedToChainId); } ); - it.each<[CoinGeckoId, NetworkChainId, undefined]>([ + it.each<[CoinGeckoId, string, undefined]>([ ["cosmos", "cosmoshub-4", undefined], ["osmosis", "osmosis-1", undefined] ])("test-findToTokenOnOraiBridge-expect-undefined", (fromCoingeckoId, toChainId) => { - const toTokenTransfer = findToTokenOnOraiBridge(fromCoingeckoId, toChainId); + const toTokenTransfer = findToTokenOnOraiBridge(fromCoingeckoId, toChainId, oraidexCommon.cosmosTokens); expect(toTokenTransfer).toEqual(undefined); }); @@ -318,36 +334,47 @@ describe("should helper functions in helper run exactly", () => { expect(parseAssetInfo(assetInfo)).toEqual(expectedResult); }); - it.each<[CoinGeckoId, NetworkChainId, boolean]>([ + it.each<[CoinGeckoId, string, boolean]>([ ["wbnb", "0x38", false], ["wbnb", "Oraichain", true] ])("test-getTokenOnSpecificChainId", (coingeckoId, chainId, expectedResult) => { - const result = getTokenOnSpecificChainId(coingeckoId, chainId); + const result = getTokenOnSpecificChainId(coingeckoId, chainId, oraidexCommon.flattenTokens); expect(result === undefined).toEqual(expectedResult); }); - it.each<[CoinGeckoId, TokenItemType, string]>([ - ["airight", cosmosTokens.find((token) => token.coinGeckoId === "airight" && token.chainId === "Oraichain")!, ""], - ["tether", cosmosTokens.find((token) => token.coinGeckoId === "tether" && token.chainId === "Oraichain")!, ""], - ["tron", cosmosTokens.find((token) => token.coinGeckoId === "tron" && token.chainId === "Oraichain")!, ""] + it.each<[CoinGeckoId, string, string]>([ + ["airight", "airight", ""], + ["tether", "tether", ""], + ["tron", "tron", ""] ])("test-getTokenOnOraichain-given-%s-should-receive-%j", (coingeckoId, expectedToken, err) => { try { - expect(getTokenOnOraichain(coingeckoId)).toEqual(expectedToken); + const token = oraidexCommon.cosmosTokens.find( + (token) => token.coinGeckoId === expectedToken && token.chainId === "Oraichain" + )!; + expect(getTokenOnOraichain(coingeckoId, oraidexCommon.oraichainTokens)).toEqual(token); } catch (error) { expect(error).toEqual(new Error(err)); } }); - it.each<[TokenItemType, string]>([ + it.each<[{ coinGeckoId: CoinGeckoId; type: "token" | "native" }]>([ [ - flattenTokens.find((item) => item.coinGeckoId === "airight" && item.chainId === "Oraichain")!, - flattenTokens.find((item) => item.coinGeckoId === "airight" && item.chainId === "Oraichain")!.contractAddress! + { + coinGeckoId: "airight", + type: "token" + } ], [ - flattenTokens.find((item) => item.coinGeckoId === "cosmos" && item.chainId === "Oraichain")!, - flattenTokens.find((item) => item.coinGeckoId === "cosmos" && item.chainId === "Oraichain")!.denom + { + coinGeckoId: "cosmos", + type: "native" + } ] - ])("test-parseTokenInfoRawDenom-given-%j-should-receive-%s", (token, expectedDenom) => { + ])("test-parseTokenInfoRawDenom-given-%j-should-receive-%s", ({ coinGeckoId, type }) => { + const token = oraidexCommon.flattenTokens.find( + (item) => item.coinGeckoId === coinGeckoId && item.chainId === "Oraichain" + )!; + const expectedDenom = type === "token" ? token.contractAddress! : token.denom; expect(parseTokenInfoRawDenom(token)).toEqual(expectedDenom); }); @@ -358,11 +385,13 @@ describe("should helper functions in helper run exactly", () => { ["airi", undefined, { token: { contract_addr: AIRI_CONTRACT } }, undefined] ])("test-parseTokenInfo", (denom, amount, expectedInfo, expectedFund) => { // fixture - const token = oraichainTokens.find((t) => t.denom === denom)!; + // console.log("oraichainTokens1: ", oraidexCommon.oraichainTokens); + const token = oraidexCommon.oraichainTokens.find((t) => t.denom === denom)!; const expectedResult: { info: AssetInfo; fund: any } = { info: expectedInfo, fund: expectedFund }; + // console.log("token: ", token); expect(parseTokenInfo(token, amount)).toEqual(expectedResult); }); @@ -552,7 +581,7 @@ describe("should helper functions in helper run exactly", () => { expect(parseWasmEvents(input).filter((event) => event)).toEqual(expectedOutput); }); - it.each<[string, NetworkChainId, { isValid: boolean; network?: string; error?: string }]>([ + it.each<[string, string, { isValid: boolean; network?: string; error?: string }]>([ [ "0x1CE09E54A5d7432ecabf3b085BAda7920aeb7dab", "0x01", @@ -608,8 +637,10 @@ describe("should helper functions in helper run exactly", () => { error: "Invalid address" } ] - ])("test-check-validate-address-wallet-with-network", (address, network, expected) => { - const check = checkValidateAddressWithNetwork(address, network); + ])("test-check-validate-address-wallet-with-network", async (address, network, expected) => { + const oraidexCommon = await OraidexCommon.load(); + const cosmosChains = oraidexCommon.cosmosChains; + const check = checkValidateAddressWithNetwork(address, network, cosmosChains); expect(check).toEqual(expected); }); @@ -654,7 +685,7 @@ describe("should helper functions in helper run exactly", () => { ["", "cosmoshub-4", false] ])("test-validateTronAddress", (value, network, expectation) => { try { - const { isValid } = validateAndIdentifyCosmosAddress(value, network); + const { isValid } = validateAndIdentifyCosmosAddress(value, network, oraidexCommon.cosmosChains); expect(isValid).toEqual(expectation); } catch (error) { expect(expectation).toEqual(false); @@ -667,7 +698,7 @@ describe("should helper functions in helper run exactly", () => { ["orai", { native_token: { denom: "orai" } }], [BTC_CONTRACT, { token: { contract_addr: BTC_CONTRACT } }] ])("test-generateConvertErc20Cw20Message-should-return-correct-message", (addressOrDenom, expectedMessage) => { - const result = parseAssetInfoFromContractAddrOrDenom(addressOrDenom); + const result = parseAssetInfoFromContractAddrOrDenom(addressOrDenom, oraidexCommon.cosmosTokens); expect(result).toEqual(expectedMessage); }); }); diff --git a/packages/oraidex-common/tests/pairs.spec.ts b/packages/oraidex-common/tests/pairs.spec.ts deleted file mode 100644 index a67ca2b3..00000000 --- a/packages/oraidex-common/tests/pairs.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { MILKY_CONTRACT, OSMOSIS_ORAICHAIN_DENOM, USDC_CONTRACT, USDT_CONTRACT } from "../src/constant"; -import { isFactoryV1, isInPairList } from "../src/pairs"; -import { expect, afterAll, beforeAll, describe, it } from "vitest"; - -describe("test pairs functions should behave correctly", () => { - it("test-isFactoryV1", () => { - const oraiToken = { native_token: { denom: "orai" } }; - expect( - isFactoryV1([oraiToken, { token: { contract_addr: "orai10ldgzued6zjp0mkqwsv2mux3ml50l97c74x8sg" } }]) - ).toEqual(true); - - expect( - isFactoryV1([ - oraiToken, - { token: { contract_addr: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd" } } - ]) - ).toEqual(false); - }); - - it.each<[string, boolean]>([ - [USDT_CONTRACT, true], - [OSMOSIS_ORAICHAIN_DENOM, true], - ["foobar", false] - ])("test-isInPairList", (identifier, expectedResult) => { - expect(isInPairList(identifier)).toEqual(expectedResult); - }); -}); diff --git a/packages/oraidex-common/tsconfig.json b/packages/oraidex-common/tsconfig.json index 03124b1e..10f6b605 100644 --- a/packages/oraidex-common/tsconfig.json +++ b/packages/oraidex-common/tsconfig.json @@ -4,7 +4,8 @@ "baseUrl": ".", "outDir": "build", "declaration": true, - "rootDir": "src" + "rootDir": "src", + "resolveJsonModule": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules/"] diff --git a/packages/oraidex-common/tsconfig.test.json b/packages/oraidex-common/tsconfig.test.json index 33df60bb..aaa39e30 100644 --- a/packages/oraidex-common/tsconfig.test.json +++ b/packages/oraidex-common/tsconfig.test.json @@ -5,7 +5,8 @@ "outDir": "build", "declaration": true, "rootDir": "src", - "module": "es2020" + "module": "esnext", + "resolveJsonModule": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules/"] diff --git a/packages/oraiswap-v3/package.json b/packages/oraiswap-v3/package.json index ef5c4c6a..16324c51 100644 --- a/packages/oraiswap-v3/package.json +++ b/packages/oraiswap-v3/package.json @@ -1,9 +1,9 @@ { "name": "@oraichain/oraiswap-v3", - "version": "1.1.2", + "version": "1.3.0", "main": "build/index.js", "files": [ - "build/" + "./build/" ], "scripts": { "build": "tsc -p tsconfig.json", @@ -13,6 +13,6 @@ "dependencies": { "@cosmjs/cosmwasm-stargate": "^0.32.4", "@oraichain/oraidex-contracts-sdk": "^1.0.54", - "@oraichain/oraidex-common": "^1.1.32" + "@oraichain/oraidex-common": "2.0.5" } } diff --git a/packages/oraiswap-v3/src/helpers.ts b/packages/oraiswap-v3/src/helpers.ts index 6a38980e..9b597a04 100644 --- a/packages/oraiswap-v3/src/helpers.ts +++ b/packages/oraiswap-v3/src/helpers.ts @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { - calculateAmountDelta, - calculateSqrtPrice, - getLiquidityByX, - getLiquidityByY, - getMaxSqrtPrice, - getMinSqrtPrice, - simulateSwap -} from "./wasm/oraiswap_v3_wasm"; + BigDecimal, + OraidexCommon, + parseAssetInfoFromContractAddrOrDenom, + TokenItemType +} from "@oraichain/oraidex-common"; +import { Pool, PoolWithPoolKey, Position } from "@oraichain/oraidex-contracts-sdk/build/OraiswapV3.types"; +import { Asset, Route, SwapOperation } from "@oraichain/oraidex-contracts-sdk/build/Zapper.types"; +import { DENOMINATOR, LIQUIDITY_DENOMINATOR, PRICE_DENOMINATOR } from "./const"; import { ActionRoute, AmountDeltaResult, @@ -19,17 +19,20 @@ import { RouteResponse, SmartRouteResponse, Tickmap, - TokenData, VirtualRange, ZapInLiquidityResponse, - ZapInResult, ZapOutLiquidityResponse, ZapOutResult } from "./types"; -import { DENOMINATOR, LIQUIDITY_DENOMINATOR, PRICE_DENOMINATOR } from "./const"; -import { Pool, PoolWithPoolKey, Position } from "@oraichain/oraidex-contracts-sdk/build/OraiswapV3.types"; -import { BigDecimal, parseAssetInfoFromContractAddrOrDenom, TokenItemType } from "@oraichain/oraidex-common"; -import { Asset, Route, SwapOperation } from "@oraichain/oraidex-contracts-sdk/build/Zapper.types"; +import { + calculateAmountDelta, + calculateSqrtPrice, + getLiquidityByX, + getLiquidityByY, + getMaxSqrtPrice, + getMinSqrtPrice, + simulateSwap +} from "./wasm/oraiswap_v3_wasm"; export const getVolume = (pool: PoolWithPoolKey, protocolFee: number): { volumeX: bigint; volumeY: bigint } => { const feeDenominator = (BigInt(protocolFee) * BigInt(pool.pool_key.fee_tier.fee)) / DENOMINATOR; @@ -296,27 +299,31 @@ export const parseAsset = (token: TokenItemType, amount: string): Asset => { }; }; -export const generateMessageSwapOperation = (responses: SmartRouteResponse[], slippage: number): Route[] => { +export const generateMessageSwapOperation = ( + responses: SmartRouteResponse[], + slippage: number, + oraidexCommon: OraidexCommon +): Route[] => { const flattenRoutes: Route[] = []; for (const response of responses) { if (!response.routes) continue; if (response.routes.length === 0) continue; - const { routes, returnAmount, swapAmount } = response; + const { routes } = response; for (const route of routes) { const { swapAmount, returnAmount, paths } = route; const operations: SwapOperation[] = []; for (const path of paths) { - const { actions, chainId, tokenIn, tokenInAmount, tokenOut, tokenOutAmount, tokenOutChainId } = path; + const { actions } = path; for (const action of actions) { - const { protocol, swapInfo, tokenIn, tokenInAmount, tokenOut, tokenOutAmount, type } = action; - let currTokenIn = parseAssetInfoFromContractAddrOrDenom(tokenIn); + const { swapInfo, tokenIn } = action; + let currTokenIn = parseAssetInfoFromContractAddrOrDenom(tokenIn, oraidexCommon.cosmosTokens); for (const swap of swapInfo) { const { poolId } = swap; const [tokenX, tokenY, fee, tickSpacing] = poolId.split("-"); - const tokenOut = parseAssetInfoFromContractAddrOrDenom(swap.tokenOut); + const tokenOut = parseAssetInfoFromContractAddrOrDenom(swap.tokenOut, oraidexCommon.cosmosTokens); if (tokenX && tokenY && fee && tickSpacing) { operations.push({ swap_v3: { @@ -451,7 +458,8 @@ export const buildZapOutMessage = ( positionIndex: number, xRouteInfo: SmartRouteResponse, yRouteInfo: SmartRouteResponse, - slippage: number + slippage: number, + oraidexCommon: OraidexCommon ): ZapOutLiquidityResponse => { const minimumReceiveX = xRouteInfo.routes ? Math.trunc(new BigDecimal(xRouteInfo.returnAmount).mul((100 - slippage) / 100).toNumber()).toString() @@ -460,7 +468,7 @@ export const buildZapOutMessage = ( ? Math.trunc(new BigDecimal(yRouteInfo.returnAmount).mul((100 - slippage) / 100).toNumber()).toString() : yRouteInfo.returnAmount; - const routes = generateMessageSwapOperation([xRouteInfo, yRouteInfo], slippage); + const routes = generateMessageSwapOperation([xRouteInfo, yRouteInfo], slippage, oraidexCommon); let swapFee = 0; routes.forEach((route) => { route.operations.forEach((operation) => { @@ -510,6 +518,7 @@ export const populateMessageZapIn = ( lowerTick: number, upperTick: number, slippage: number, + oraidexCommon: OraidexCommon, buildZapInMessageOptions?: buildZapInMessageOptions ) => { message.amountX = actualAmountXReceived.returnAmount; @@ -525,9 +534,13 @@ export const populateMessageZapIn = ( } else { message.amountX = "0"; } - message.routes = generateMessageSwapOperation([actualAmountXReceived], slippage); + message.routes = generateMessageSwapOperation([actualAmountXReceived], slippage, oraidexCommon); } else { - message.routes = generateMessageSwapOperation([actualAmountXReceived, actualAmountYReceived], slippage); + message.routes = generateMessageSwapOperation( + [actualAmountXReceived, actualAmountYReceived], + slippage, + oraidexCommon + ); } calculateSwapFee(message); diff --git a/packages/oraiswap-v3/src/main.ts b/packages/oraiswap-v3/src/main.ts index 501342e4..45d1d328 100644 --- a/packages/oraiswap-v3/src/main.ts +++ b/packages/oraiswap-v3/src/main.ts @@ -2,7 +2,8 @@ import { AMM_V3_CONTRACT, KWT_CONTRACT, MULTICALL_CONTRACT, - oraichainTokens, + OraidexCommon, + // oraichainTokens, ORAIX_CONTRACT, OSMO, OSMOSIS_ORAICHAIN_DENOM, @@ -15,6 +16,7 @@ import { extractAddress, parsePoolKey } from "./helpers"; import { getTickAtSqrtPrice } from "./wasm/oraiswap_v3_wasm"; async function main() { + const oraidexCommon = await OraidexCommon.load(); const zapper = new ZapConsumer({ routerApi: "https://osor.oraidex.io/smart-router/alpha-router", client: await CosmWasmClient.connect("https://rpc.orai.io"), @@ -25,20 +27,21 @@ async function main() { swapOptions: { protocols: ["OraidexV3"] } - } + }, + oraidexCommon }); - const tokenIn = oraichainTokens.find((t) => t.name === "USDT") as TokenItemType; + const tokenIn = oraidexCommon.oraichainTokens.find((t) => t.name === "USDT") as TokenItemType; const pool = `${OSMOSIS_ORAICHAIN_DENOM}-orai-${(0.3 / 100) * 10 ** 12}-100`; - const poolKey = parsePoolKey(pool); + // const poolKey = parsePoolKey(pool); // for (let i = 0; i < 10; i++) { - // const poolInfo = await zapper.handler.getPool(poolKey); - // console.log("poolInfo", poolInfo); + // const poolInfo = await zapper.handler.getPool(poolKey); + // console.log("poolInfo", poolInfo); // } - const tickSpacing = poolKey.fee_tier.tick_spacing; - const currentTick = (await zapper.handler.getPool(poolKey)).pool.current_tick_index; + // const tickSpacing = poolKey.fee_tier.tick_spacing; + // const currentTick = (await zapper.handler.getPool(poolKey)).pool.current_tick_index; // console.log(getTickAtSqrtPrice(314557996917228655710133n, 10)); @@ -55,10 +58,10 @@ async function main() { // console.timeEnd("processZapInPositionLiquidity"); const res = await zapper.processZapOutPositionLiquidity({ - owner: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", - tokenId: 4275, + owner: "orai1zyvk3n9r8sax4xvqph97pxuhduqqsqwq6dwzj2", + tokenId: 12046, tokenOut: tokenIn, - zapFee: 0, + zapFee: 0 }); console.dir(res, { depth: null }); // console.dir(res, { depth: null }); diff --git a/packages/oraiswap-v3/src/types.ts b/packages/oraiswap-v3/src/types.ts index 81063b2f..722a59c3 100644 --- a/packages/oraiswap-v3/src/types.ts +++ b/packages/oraiswap-v3/src/types.ts @@ -1,5 +1,5 @@ import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate"; -import { TokenItemType } from "@oraichain/oraidex-common"; +import { OraidexCommon, TokenItemType } from "@oraichain/oraidex-common"; import { Asset, Route, SwapOperation, Uint128 } from "@oraichain/oraidex-contracts-sdk/build/Zapper.types"; export interface SnapshotValueData { @@ -193,6 +193,7 @@ export type ZapConfig = { multiCallAddress: string; deviation: number; smartRouteConfig: SmartRouteConfig; + oraidexCommon: OraidexCommon; }; export type ActionRoute = { diff --git a/packages/oraiswap-v3/src/zap-consumer.ts b/packages/oraiswap-v3/src/zap-consumer.ts index 8a9a8edc..0e403cf6 100644 --- a/packages/oraiswap-v3/src/zap-consumer.ts +++ b/packages/oraiswap-v3/src/zap-consumer.ts @@ -1,4 +1,4 @@ -import { BigDecimal, oraichainTokens, TokenItemType } from "@oraichain/oraidex-common"; +import { BigDecimal, OraidexCommon, TokenItemType } from "@oraichain/oraidex-common"; import { OraiswapV3Handler } from "./handler"; import { ActionRoute, @@ -56,12 +56,14 @@ export class ZapConsumer { private _handler: OraiswapV3Handler; private _smartRouteConfig: SmartRouteConfig; private _deviation: number; + private _oraidexCommon: OraidexCommon; constructor(config: ZapConfig) { this._router = config.routerApi; this._handler = new OraiswapV3Handler(config.client, config.dexV3Address, config.multiCallAddress); this._smartRouteConfig = config.smartRouteConfig; this._deviation = config.deviation; + this._oraidexCommon = config.oraidexCommon; } public get handler(): OraiswapV3Handler { @@ -191,7 +193,7 @@ export class ZapConsumer { pool.current_tick_index = tick; // NOTE: now simulate one time only - break; + break; } } } @@ -259,6 +261,7 @@ export class ZapConsumer { lowerTick, upperTick, slippage, + this._oraidexCommon, { isTokenX, isSingleSide: true @@ -370,8 +373,14 @@ export class ZapConsumer { true ); - const extendDecimalX = getXPriceByTokenIn.swapAmount.length - 1 > tokenIn.decimals ? getXPriceByTokenIn.swapAmount.length - 1 - tokenIn.decimals : 0; - const extendDecimalY = getYPriceByTokenIn.swapAmount.length - 1 > tokenIn.decimals ? getYPriceByTokenIn.swapAmount.length - 1 - tokenIn.decimals : 0; + const extendDecimalX = + getXPriceByTokenIn.swapAmount.length - 1 > tokenIn.decimals + ? getXPriceByTokenIn.swapAmount.length - 1 - tokenIn.decimals + : 0; + const extendDecimalY = + getYPriceByTokenIn.swapAmount.length - 1 > tokenIn.decimals + ? getYPriceByTokenIn.swapAmount.length - 1 - tokenIn.decimals + : 0; if (![pool.pool_key.token_x, pool.pool_key.token_y].includes(extractAddress(tokenIn))) { xPriceByTokenIn = shiftDecimal(BigInt(getXPriceByTokenIn.returnAmount), tokenIn.decimals + extendDecimalX); @@ -437,7 +446,8 @@ export class ZapConsumer { pool.pool_key, lowerTick, upperTick, - slippage + slippage, + this._oraidexCommon ); return zapInResult; } @@ -478,7 +488,10 @@ export class ZapConsumer { true ); console.log(`[CAL3] xPriceByYAmount: ${xPriceByYAmount.returnAmount}`); - const extendDecimal = xPriceByYAmount.swapAmount.length - 1 > tokenY.decimals ? xPriceByYAmount.swapAmount.length - 1 - tokenY.decimals : 0; + const extendDecimal = + xPriceByYAmount.swapAmount.length - 1 > tokenY.decimals + ? xPriceByYAmount.swapAmount.length - 1 - tokenY.decimals + : 0; const xPriceByY = shiftDecimal(BigInt(xPriceByYAmount.returnAmount), tokenY.decimals + extendDecimal); console.log(`[CAL3] xPriceByY: ${xPriceByY}`); const deltaX = yAmount.sub(yPerX.mul(xAmount)).div(yPerX.add(xPriceByY)); @@ -511,7 +524,8 @@ export class ZapConsumer { pool.pool_key, lowerTick, upperTick, - slippage + slippage, + this._oraidexCommon ); return zapInResult; @@ -553,8 +567,13 @@ export class ZapConsumer { const pool = await this._handler.getPool(position.pool_key); const { amountX, amountY } = calculateRewardAmounts(pool, position, zapFee); - const tokenX = oraichainTokens.find((t) => extractAddress(t) === pool.pool_key.token_x) as TokenItemType; - const tokenY = oraichainTokens.find((t) => extractAddress(t) === pool.pool_key.token_y) as TokenItemType; + //TODO: fix type + const tokenX = this._oraidexCommon.oraichainTokens.find( + (t) => extractAddress(t as any) === pool.pool_key.token_x + ) as TokenItemType; + const tokenY = this._oraidexCommon.oraichainTokens.find( + (t) => extractAddress(t as any) === pool.pool_key.token_y + ) as TokenItemType; if (!tokenX || !tokenY) { throw new Error("Token X or Token Y not found in oraichainTokens."); @@ -573,7 +592,7 @@ export class ZapConsumer { } ]); - return buildZapOutMessage(ZapOutResult.Success, index, xRouteInfo, yRouteInfo, slippage); + return buildZapOutMessage(ZapOutResult.Success, index, xRouteInfo, yRouteInfo, slippage, this._oraidexCommon); } catch (e) { console.log(`[ZapConsumer] ZapOut error: ${e}`); throw e; diff --git a/packages/oraiswap-v3/tests/helpers.spec.ts b/packages/oraiswap-v3/tests/helpers.spec.ts index a577188b..a7eb6fc5 100644 --- a/packages/oraiswap-v3/tests/helpers.spec.ts +++ b/packages/oraiswap-v3/tests/helpers.spec.ts @@ -518,7 +518,7 @@ describe("test oraiswap-v3 helper functions", () => { // TODO: add more expect }); - it.each<[TokenItemType]>([ + it.each<[any]>([ [ { name: "ORAI", diff --git a/packages/oraiswap-v3/tests/zap-consumer.spec.ts b/packages/oraiswap-v3/tests/zap-consumer.spec.ts index 10dd0a4d..a2c3cc25 100644 --- a/packages/oraiswap-v3/tests/zap-consumer.spec.ts +++ b/packages/oraiswap-v3/tests/zap-consumer.spec.ts @@ -34,6 +34,7 @@ import { OraiswapV3Handler } from "../src"; import { MulticallQueryClient } from "@oraichain/common-contracts-sdk"; +import { OraidexCommon } from "@oraichain/oraidex-common"; // move signer to dynamic signing of an object declare module "@oraichain/oraidex-contracts-sdk" { @@ -104,8 +105,10 @@ describe("ZapConsumer", () => { let handler: OraiswapV3Handler; let feeTier1: OraiswapV3Types.FeeTier; let feeTier2: OraiswapV3Types.FeeTier; + let oraidexCommon: OraidexCommon; beforeEach(async () => { + oraidexCommon = await OraidexCommon.load(); oraix = await createTokenWithDecimal("ORAIX", 6); usdt = await createTokenWithDecimal("USDT", 6); usdc = await createTokenWithDecimal("USDC", 6); @@ -198,6 +201,7 @@ describe("ZapConsumer", () => { }); zapConsumer = new ZapConsumer({ + oraidexCommon, client: client, dexV3Address: oraiswapV3.contractAddress, deviation: 0, diff --git a/packages/oraiswap-v3/tsconfig.json b/packages/oraiswap-v3/tsconfig.json index 1c026311..856cb0ad 100644 --- a/packages/oraiswap-v3/tsconfig.json +++ b/packages/oraiswap-v3/tsconfig.json @@ -8,4 +8,4 @@ }, "include": ["src/**/*.ts", "src/**/*.js"], "exclude": ["node_modules/", "src/main.ts"] -} +} \ No newline at end of file diff --git a/packages/universal-swap/package.json b/packages/universal-swap/package.json index 2d3f52e1..18e78f78 100644 --- a/packages/universal-swap/package.json +++ b/packages/universal-swap/package.json @@ -1,6 +1,6 @@ { "name": "@oraichain/oraidex-universal-swap", - "version": "1.1.26", + "version": "1.3.0", "main": "build/index.js", "files": [ "build/" @@ -11,12 +11,12 @@ }, "license": "MIT", "dependencies": { - "@oraichain/oraidex-common": "^1.1.27", + "@oraichain/oraidex-common": "2.0.5", "@oraichain/oraidex-contracts-sdk": "^1.0.49", "bech32": "1.1.4", "ethers": "^5.0.15", "tronweb": "5.3.2", - "@oraichain/common": "^1.2.4", + "@oraichain/common": "1.2.6", "ts-protoc-gen": "^0.15.0", "@oraichain/osor-api-contracts-sdk": "^1.0.2", "cosmjs-types": "^0.9.0" diff --git a/packages/universal-swap/src/handler.ts b/packages/universal-swap/src/handler.ts index 426f2e68..0225d50f 100644 --- a/packages/universal-swap/src/handler.ts +++ b/packages/universal-swap/src/handler.ts @@ -6,43 +6,41 @@ import { ExecuteInstruction, ExecuteResult, toBinary } from "@cosmjs/cosmwasm-st import { TransferBackMsg } from "@oraichain/common-contracts-sdk/build/CwIcs20Latest.types"; import { TokenItemType, - NetworkChainId, IBCInfo, calculateTimeoutTimestamp, generateError, getEncodedExecuteContractMsgs, toAmount, - // buildMultipleExecuteMessages, parseTokenInfo, calculateMinReceive, handleSentFunds, tronToEthAddress, ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, oraichain2oraib, - CosmosChainId, - findToTokenOnOraiBridge, + // findToTokenOnOraiBridge, getTokenOnSpecificChainId, UNISWAP_ROUTER_DEADLINE, gravityContracts, Bridge__factory, IUniswapV2Router02__factory, ethToTronAddress, - network, + // network, EvmResponse, - getTokenOnOraichain, + // getTokenOnOraichain, getCosmosGasPrice, CoinGeckoId, IBC_WASM_CONTRACT, IBC_WASM_CONTRACT_TEST, - tokenMap, + // tokenMap, buildMultipleExecuteMessages, ibcInfosOld, - checkValidateAddressWithNetwork, BigDecimal, - OSMOSIS_ROUTER_CONTRACT, - cosmosChains, toDisplay, ChainIdEnum, + OraidexCommon, + checkValidateAddressWithNetwork, + getTokenOnOraichain, + findToTokenOnOraiBridge, isCosmosChain, TON_BRIDGE_ADAPTER_ORAICHAIN, TON_BRIDGE_ADAPTER @@ -64,8 +62,16 @@ import { import { GasPrice } from "@cosmjs/stargate"; import { OraiswapRouterQueryClient } from "@oraichain/oraidex-contracts-sdk"; import { Affiliate } from "@oraichain/oraidex-contracts-sdk/build/OraiswapMixedRouter.types"; -import { COSMOS_CHAIN_IDS, EVM_CHAIN_IDS } from "@oraichain/common"; import { generateMsgSwap } from "./msg/msgs"; +import { + notAllowBEP20Token, + notAllowDenom, + notAllowSwapCoingeckoIds, + notAllowSwapFromChainIds, + notAllowSwapToChainIds +} from "./swap-filter"; +import { COSMOS_CHAIN_IDS, CosmosChainId, EVM_CHAIN_IDS, NetworkChainId } from "@oraichain/common/build/constants"; +// import { calculateTimeoutTimestampTon, createTonBridgeHandler } from "@oraichain/tonbridge-sdk"; import { toNano } from "@ton/core"; import { getHttpEndpoint } from "@orbs-network/ton-access"; @@ -74,11 +80,12 @@ export class UniversalSwapHandler { constructor( public swapData: UniversalSwapData, public config: UniversalSwapConfig, + private readonly oraidexCommon: OraidexCommon, private readonly currentTimestamp = Date.now() ) {} private getTokenOnOraichain(coinGeckoId: CoinGeckoId, isNative?: boolean): TokenItemType { - const fromTokenOnOrai = getTokenOnOraichain(coinGeckoId, isNative); + const fromTokenOnOrai = getTokenOnOraichain(coinGeckoId, this.oraidexCommon.oraichainTokens, isNative); if (!fromTokenOnOrai) throw generateError(`Could not find token ${coinGeckoId} on Oraichain. Could not swap`); return fromTokenOnOrai; } @@ -87,12 +94,34 @@ export class UniversalSwapHandler { return this.config.swapOptions?.ibcInfoTestMode ? IBC_WASM_CONTRACT_TEST : IBC_WASM_CONTRACT; } - public getIbcInfo(fromChainId: CosmosChainId, toChainId: NetworkChainId) { + public getIbcInfo(fromChainId: CosmosChainId, toChainId: string) { const ibcInfo = UniversalSwapHelper.getIbcInfo(fromChainId, toChainId); if (!this.config.swapOptions?.ibcInfoTestMode || !ibcInfo.testInfo) return ibcInfo; return ibcInfo.testInfo; } + get swapFromTokens(): TokenItemType[] { + return this.oraidexCommon.flattenTokens.filter((token) => { + return ( + !notAllowDenom.includes(token?.denom) && + !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && + !notAllowSwapFromChainIds.includes(token.chainId) && + !notAllowBEP20Token.includes(token?.contractAddress) + ); + }); + } + + get swapToTokens(): TokenItemType[] { + return this.oraidexCommon.flattenTokens.filter((token) => { + return ( + !notAllowDenom.includes(token?.denom) && + !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && + !notAllowSwapToChainIds.includes(token.chainId) && + !notAllowBEP20Token.includes(token?.contractAddress) + ); + }); + } + async getUniversalSwapToAddress( toChainId: NetworkChainId, address: { metamaskAddress?: string; tronAddress?: string; tonAddress?: string } @@ -115,7 +144,8 @@ export class UniversalSwapHandler { throw generateError("Cannot find tron web to nor tron address to send to Tron network"); } - if (isCosmosChain(toChainId.toString())) return this.config.cosmosWallet.getKeplrAddr(toChainId as CosmosChainId); + if (isCosmosChain(toChainId.toString(), this.oraidexCommon.cosmosChains)) + return this.config.cosmosWallet.getKeplrAddr(toChainId as CosmosChainId); throw generateError(`Cannot not get address for chain: ${toChainId}`); } @@ -138,7 +168,11 @@ export class UniversalSwapHandler { let ibcReceiveAddr = ""; if (this.swapData.recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(this.swapData.recipientAddress, toChainId); + const isValidRecipient = checkValidateAddressWithNetwork( + this.swapData.recipientAddress, + toChainId, + this.oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid) throw generateError("Recipient address invalid!"); ibcReceiveAddr = this.swapData.recipientAddress; @@ -190,13 +224,15 @@ export class UniversalSwapHandler { if (isSpecialChain) { // convert token if (isSpecialCoingecko) { - const evmToken = tokenMap[toTokenInOrai.denom]; + const evmToken = this.oraidexCommon.tokenMap[toTokenInOrai.denom]; const evmAmount = coin(toAmount(this.swapData.fromAmount, evmToken.decimals).toString(), evmToken.denom); const msgConvertReverses = UniversalSwapHelper.generateConvertCw20Erc20Message( this.swapData.amounts, this.getTokenOnOraichain(toCoinGeckoId), sender, - evmAmount + evmAmount, + this.oraidexCommon.tokenMap, + this.oraidexCommon.network ); const executeContractMsgs = buildMultipleExecuteMessages(undefined, ...msgConvertReverses); getEncodedExecuteMsgs = getEncodedExecuteContractMsgs(sender, executeContractMsgs); @@ -240,12 +276,16 @@ export class UniversalSwapHandler { metamaskAddress: string, tronAddress: string, channel: string, - toToken: { chainId: string; prefix: string; originalChainId: NetworkChainId }, + toToken: { chainId: string; prefix: string; originalChainId: string }, recipientAddress?: string ) { let transferAddress; if (recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(this.swapData.recipientAddress, toToken.originalChainId); + const isValidRecipient = checkValidateAddressWithNetwork( + this.swapData.recipientAddress, + toToken.originalChainId, + this.oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid) throw generateError("Recipient address invalid!"); transferAddress = toToken.originalChainId === ChainIdEnum.TRON ? tronToEthAddress(recipientAddress) : recipientAddress; @@ -270,7 +310,11 @@ export class UniversalSwapHandler { } // then find new _toToken in Oraibridge that have same coingeckoId with originalToToken. - const newToToken = findToTokenOnOraiBridge(originalToToken.coinGeckoId, originalToToken.chainId); + const newToToken = findToTokenOnOraiBridge( + originalToToken.coinGeckoId, + originalToToken.chainId, + this.oraidexCommon.cosmosTokens + ); const toAddress = await this.config.cosmosWallet.getKeplrAddr(newToToken.chainId as CosmosChainId); if (!toAddress) throw generateError("Please login cosmos wallet!"); @@ -292,13 +336,15 @@ export class UniversalSwapHandler { let getEncodedExecuteMsgs = []; if (["kawaii-islands", "milky-token"].includes(originalToToken.coinGeckoId)) { const toTokenInOrai = this.getTokenOnOraichain(originalToToken.coinGeckoId, true); - const evmToken = tokenMap[toTokenInOrai.denom]; + const evmToken = this.oraidexCommon.tokenMap[toTokenInOrai.denom]; const evmAmount = coin(toAmount(this.swapData.fromAmount, evmToken.decimals).toString(), evmToken.denom); const msgConvertReverses = UniversalSwapHelper.generateConvertCw20Erc20Message( this.swapData.amounts, this.getTokenOnOraichain(originalToToken.coinGeckoId), this.swapData.sender.cosmos, - evmAmount + evmAmount, + this.oraidexCommon.tokenMap, + this.oraidexCommon.network ); // for KWT & MILKY tokens, we use the old ibc info channel const { chainId: fromChainId } = originalFromToken; @@ -332,8 +378,8 @@ export class UniversalSwapHandler { async swap(): Promise { const messages = this.generateMsgsSwap(); const { client } = await this.config.cosmosWallet.getCosmWasmClient( - { chainId: "Oraichain", rpc: network.rpc }, - { gasPrice: GasPrice.fromString(`${network.fee.gasPrice}${network.denom}`) } + { chainId: "Oraichain", rpc: this.oraidexCommon.network.rpc }, + { gasPrice: GasPrice.fromString(`${this.oraidexCommon.network.fee.gasPrice}${this.oraidexCommon.network.denom}`) } ); const result = await client.executeMultiple(this.swapData.sender.cosmos, messages, "auto"); return result; @@ -516,7 +562,7 @@ export class UniversalSwapHandler { throw generateError("Cannot transfer and swap if the cosmos wallet is not initialized"); // we get cosmwasm client on Oraichain because this is checking channel balance on Oraichain const { client } = await this.config.cosmosWallet.getCosmWasmClient( - { rpc: network.rpc, chainId: network.chainId as CosmosChainId }, + { rpc: this.oraidexCommon.network.rpc, chainId: this.oraidexCommon.network.chainId as CosmosChainId }, { gasPrice: this.getGasPriceFromToken() } @@ -534,12 +580,13 @@ export class UniversalSwapHandler { case "oraichain-to-evm": const { evm: metamaskAddress, tron: tronAddress } = this.swapData.sender; if (!this.config?.swapOptions?.isCheckBalanceIbc) { - const routerClient = new OraiswapRouterQueryClient(client, network.mixer_router); + const routerClient = new OraiswapRouterQueryClient(client, this.oraidexCommon.network.mixer_router); const isSufficient = await UniversalSwapHelper.checkFeeRelayer({ originalFromToken: this.swapData.originalFromToken, fromAmount: this.swapData.fromAmount, relayerFee: this.swapData.relayerFee, - routerClient + routerClient, + oraichainTokens: this.oraidexCommon.oraichainTokens }); if (!isSufficient) throw generateError( @@ -561,7 +608,9 @@ export class UniversalSwapHandler { originalToToken, simulateAmount, client, - this.getCwIcs20ContractAddr() + this.getCwIcs20ContractAddr(), + this.oraidexCommon.network, + this.oraidexCommon.oraichainTokens ); } @@ -587,7 +636,7 @@ export class UniversalSwapHandler { if (!this.config.cosmosWallet) throw generateError("Cannot transfer and swap if cosmos wallet is not initialized"); // we get cosmwasm client on Oraichain because this is checking channel balance on Oraichain const { client } = await this.config.cosmosWallet.getCosmWasmClient( - { rpc: network.rpc, chainId: network.chainId as CosmosChainId }, + { rpc: this.oraidexCommon.network.rpc, chainId: this.oraidexCommon.network.chainId as CosmosChainId }, {} ); @@ -615,7 +664,11 @@ export class UniversalSwapHandler { await this.config.evmWallet.switchNetwork(originalFromToken.chainId); if (UniversalSwapHelper.isEvmSwappable(swappableData)) return this.evmSwap(evmSwapData); - const toTokenSameFromChainId = getTokenOnSpecificChainId(originalToToken.coinGeckoId, originalFromToken.chainId); + const toTokenSameFromChainId = getTokenOnSpecificChainId( + originalToToken.coinGeckoId, + originalFromToken.chainId, + this.oraidexCommon.flattenTokens + ); if (toTokenSameFromChainId) { swappableData.toChainId = toTokenSameFromChainId.chainId; swappableData.toContractAddr = toTokenSameFromChainId.contractAddress; @@ -639,11 +692,14 @@ export class UniversalSwapHandler { fromAmount, simulateAmount, client, - this.getCwIcs20ContractAddr() + this.getCwIcs20ContractAddr(), + this.oraidexCommon.network, + this.oraidexCommon.oraichainTokens ); - const routerClient = new OraiswapRouterQueryClient(client, network.mixer_router); + const routerClient = new OraiswapRouterQueryClient(client, this.oraidexCommon.network.mixer_router); const isSufficient = await UniversalSwapHelper.checkFeeRelayer({ + oraichainTokens: this.oraidexCommon.oraichainTokens, originalFromToken, fromAmount, relayerFee, @@ -703,6 +759,7 @@ export class UniversalSwapHandler { originalToToken, minimumReceive, userSlippage, + this.oraidexCommon, this.config.swapOptions, alphaSmartRoutes ); @@ -741,7 +798,11 @@ export class UniversalSwapHandler { // check if from chain is noble, use ibc-wasm instead of ibc-hooks if (originalFromToken.chainId === "noble-1") { if (this.swapData.recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(this.swapData.recipientAddress, "Oraichain"); + const isValidRecipient = checkValidateAddressWithNetwork( + this.swapData.recipientAddress, + "Oraichain", + this.oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid || isValidRecipient.network !== "Oraichain") { throw generateError("Recipient address invalid! Only support bridge to Oraichain"); @@ -802,12 +863,15 @@ export class UniversalSwapHandler { originalToToken, simulateAmount, client, - this.getCwIcs20ContractAddr() + this.getCwIcs20ContractAddr(), + this.oraidexCommon.network, + this.oraidexCommon.oraichainTokens ); } const msgs = alphaSmartRoutes.routes.map((route) => { - return generateMsgSwap(route, userSlippage / 100, receiverAddresses, recipientAddress); + return generateMsgSwap(route, userSlippage / 100, receiverAddresses, this.oraidexCommon, recipientAddress); + // return generateMsgSwap(route, userSlippage / 100, receiverAddresses, recipientAddress); }); const { client } = await this.config.cosmosWallet.getCosmWasmClient( @@ -841,7 +905,7 @@ export class UniversalSwapHandler { if (!this.config.cosmosWallet) throw generateError("Cannot transfer and swap if cosmos wallet is not initialized"); // we get cosmwasm client on Oraichain because this is checking channel balance on Oraichain const { client } = await this.config.cosmosWallet.getCosmWasmClient( - { rpc: network.rpc, chainId: network.chainId as CosmosChainId }, + { rpc: this.oraidexCommon.network.rpc, chainId: this.oraidexCommon.network.chainId as CosmosChainId }, {} ); @@ -852,11 +916,14 @@ export class UniversalSwapHandler { fromAmount, simulateAmount, client, - this.getCwIcs20ContractAddr() + this.getCwIcs20ContractAddr(), + this.oraidexCommon.network, + this.oraidexCommon.oraichainTokens ); - const routerClient = new OraiswapRouterQueryClient(client, network.mixer_router); + const routerClient = new OraiswapRouterQueryClient(client, this.oraidexCommon.network.mixer_router); const isSufficient = await UniversalSwapHelper.checkFeeRelayer({ + oraichainTokens: this.oraidexCommon.oraichainTokens, originalFromToken, fromAmount, relayerFee, @@ -915,7 +982,11 @@ export class UniversalSwapHandler { async getToAddressUniversalSwap({ evm, tron, ton }, recipientAddress, originalToToken) { if (this.swapData.recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(recipientAddress, originalToToken.chainId); + const isValidRecipient = checkValidateAddressWithNetwork( + recipientAddress, + originalToToken.chainId, + this.oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid) throw generateError("Recipient address invalid!"); @@ -944,7 +1015,11 @@ export class UniversalSwapHandler { ); const oraiAddress = await this.config.cosmosWallet.getKeplrAddr(COSMOS_CHAIN_IDS.ORAICHAIN); if (!oraiAddress) throw generateError("orai address and obridge address invalid!"); - const isValidRecipientOraichain = checkValidateAddressWithNetwork(oraiAddress, COSMOS_CHAIN_IDS.ORAICHAIN); + const isValidRecipientOraichain = checkValidateAddressWithNetwork( + oraiAddress, + COSMOS_CHAIN_IDS.ORAICHAIN, + this.oraidexCommon.cosmosChains + ); if (!isValidRecipientOraichain.isValid) throw generateError("orai get address invalid!"); let injAddress = undefined; @@ -956,7 +1031,8 @@ export class UniversalSwapHandler { ton: ton, [EVM_CHAIN_IDS.ETH]: evm, [EVM_CHAIN_IDS.BSC]: evm - } as any + } as any, + cosmosChains: this.oraidexCommon.cosmosChains }; const isAlphaIbcWasmHasRoute = swapOptions?.isAlphaIbcWasm && alphaSmartRoutes?.routes?.length; @@ -998,6 +1074,7 @@ export class UniversalSwapHandler { originalToToken, minimumReceive, userSlippage, + this.oraidexCommon, this.config.swapOptions, alphaSmartRoutes ); @@ -1023,12 +1100,16 @@ export class UniversalSwapHandler { if (originalToToken.coinGeckoId !== "oraichain-token") { const { client } = await cosmosWallet.getCosmWasmClient( - { rpc: network.rpc, chainId: network.chainId as CosmosChainId }, - { gasPrice: GasPrice.fromString(`${network.fee.gasPrice}${network.denom}`) } + { rpc: this.oraidexCommon.network.rpc, chainId: this.oraidexCommon.network.chainId as CosmosChainId }, + { + gasPrice: GasPrice.fromString(`${this.oraidexCommon.network.fee.gasPrice}${this.oraidexCommon.network.denom}`) + } ); if (!!subRelayerFee) { - const routerClient = new OraiswapRouterQueryClient(client, network.mixer_router); + const routerClient = new OraiswapRouterQueryClient(client, this.oraidexCommon.network.mixer_router); const { amount } = await UniversalSwapHelper.handleSimulateSwap({ + flattenTokens: this.oraidexCommon.flattenTokens, + oraichainTokens: this.oraidexCommon.oraichainTokens, originalFromInfo: this.getTokenOnOraichain("oraichain-token"), originalToInfo: this.getTokenOnOraichain(originalToToken.coinGeckoId), originalAmount: toDisplay(subRelayerFee), @@ -1069,7 +1150,7 @@ export class UniversalSwapHandler { * @returns */ generateMsgsSmartRouterSwap(route: Routes, isLastRoute: boolean) { - let contractAddr: string = network.mixer_router; + let contractAddr: string = this.oraidexCommon.network.mixer_router; const { originalFromToken, fromAmount, affiliates, userSlippage } = this.swapData; const fromTokenOnOrai = this.getTokenOnOraichain(originalFromToken.coinGeckoId); const _fromAmount = toAmount(fromAmount, fromTokenOnOrai.decimals).toString(); @@ -1081,9 +1162,18 @@ export class UniversalSwapHandler { } const to = isLastRoute ? this.swapData.recipientAddress : undefined; const { info: offerInfo } = parseTokenInfo(fromTokenOnOrai, _fromAmount); - const msgConvertsFrom = UniversalSwapHelper.generateConvertErc20Cw20Message(this.swapData.amounts, fromTokenOnOrai); + const msgConvertsFrom = UniversalSwapHelper.generateConvertErc20Cw20Message( + this.swapData.amounts, + fromTokenOnOrai, + this.oraidexCommon.tokenMap, + this.oraidexCommon.network + ); - const routes = UniversalSwapHelper.generateMsgsSmartRouterV2withV3([route], offerInfo); + const routes = UniversalSwapHelper.generateMsgsSmartRouterV2withV3( + [route], + offerInfo, + this.oraidexCommon.cosmosTokens + ); const msgs: ExecuteInstruction[] = UniversalSwapHelper.buildSwapMsgsFromSmartRoute( routes, fromTokenOnOrai, @@ -1097,7 +1187,7 @@ export class UniversalSwapHandler { generateMsgsSwap() { let input: any; - let contractAddr: string = network.mixer_router; + let contractAddr: string = this.oraidexCommon.network.mixer_router; const { originalFromToken, originalToToken, fromAmount, affiliates, userSlippage } = this.swapData; // since we're swapping on Oraichain, we need to get from token on Oraichain const fromTokenOnOrai = this.getTokenOnOraichain(originalFromToken.coinGeckoId); @@ -1106,9 +1196,16 @@ export class UniversalSwapHandler { const _fromAmount = toAmount(fromAmount, fromTokenOnOrai.decimals).toString(); const msgConvertsFrom = UniversalSwapHelper.generateConvertErc20Cw20Message( this.swapData.amounts, - fromTokenOnOrai + fromTokenOnOrai, + this.oraidexCommon.tokenMap, + this.oraidexCommon.network + ); + const msgConvertTo = UniversalSwapHelper.generateConvertErc20Cw20Message( + this.swapData.amounts, + toTokenInOrai, + this.oraidexCommon.tokenMap, + this.oraidexCommon.network ); - const msgConvertTo = UniversalSwapHelper.generateConvertErc20Cw20Message(this.swapData.amounts, toTokenInOrai); const isValidSlippage = userSlippage || userSlippage === 0; if (!this.swapData.simulatePrice || !isValidSlippage) { throw generateError( @@ -1123,7 +1220,8 @@ export class UniversalSwapHandler { if (this.swapData.recipientAddress && originalToToken.chainId === "Oraichain") { const isValidRecipient = checkValidateAddressWithNetwork( this.swapData.recipientAddress, - this.swapData.originalToToken.chainId + this.swapData.originalToToken.chainId, + this.oraidexCommon.cosmosChains ); if (!isValidRecipient.isValid) { @@ -1147,7 +1245,11 @@ export class UniversalSwapHandler { if (hasRouteNotIsOraichain) throw "Only support routes in Oraichain!"; const routesFlatten = UniversalSwapHelper.flattenSmartRouters(routes); - const generatedRoutes = UniversalSwapHelper.generateMsgsSmartRouterV2withV3(routesFlatten, offerInfo); + const generatedRoutes = UniversalSwapHelper.generateMsgsSmartRouterV2withV3( + routesFlatten, + offerInfo, + this.oraidexCommon.cosmosTokens + ); msgs = UniversalSwapHelper.buildSwapMsgsFromSmartRoute( generatedRoutes, diff --git a/packages/universal-swap/src/helper.ts b/packages/universal-swap/src/helper.ts index bce6058b..77be0389 100644 --- a/packages/universal-swap/src/helper.ts +++ b/packages/universal-swap/src/helper.ts @@ -9,10 +9,7 @@ import { WRAP_ETH_CONTRACT, USDC_ETH_CONTRACT, USDT_ETH_CONTRACT, - EvmChainId, proxyContractInfo, - CosmosChainId, - NetworkChainId, IBCInfo, generateError, ibcInfos, @@ -21,7 +18,8 @@ import { MILKY_BSC_CONTRACT, TokenItemType, parseTokenInfoRawDenom, - getTokenOnOraichain, + // TODO: INIT ORAI COMMON HERE + // getTokenOnOraichain, isEthAddress, PAIRS, ORAI_INFO, @@ -30,27 +28,32 @@ import { toDisplay, getTokenOnSpecificChainId, IUniswapV2Router02__factory, - cosmosTokens, + // cosmosTokens, StargateMsg, - isInPairList, BigDecimal, NEUTARO_INFO, USDC_INFO, - network, + // network, ORAIX_ETH_CONTRACT, AmountDetails, handleSentFunds, - tokenMap, + // tokenMap, oraib2oraichainTest, getSubAmountDetails, - evmChains, + // evmChains, getAxios, - parseAssetInfoFromContractAddrOrDenom, + // parseAssetInfoFromContractAddrOrDenom, parseAssetInfo, calculateTimeoutTimestamp, COSMOS_CHAIN_ID_COMMON, + OraidexCommon, + NetworkConfig, checkValidateAddressWithNetwork, - cosmosChains + getTokenOnOraichain, + parseAssetInfoFromContractAddrOrDenom, + IBC_TRANSFER_TIMEOUT, + CustomChainInfo + // cosmosChains } from "@oraichain/oraidex-common"; import { ConvertReverse, @@ -75,18 +78,18 @@ import { OraiswapTokenQueryClient, SwapOperation } from "@oraichain/oraidex-contracts-sdk"; -import { isEqual } from "lodash"; +import isEqual from "lodash/isEqual"; import { ethers } from "ethers"; import { Amount, CwIcs20LatestQueryClient, Uint128 } from "@oraichain/common-contracts-sdk"; import { CosmWasmClient, ExecuteInstruction, toBinary } from "@cosmjs/cosmwasm-stargate"; -import { swapFromTokens, swapToTokens } from "./swap-filter"; +// import { swapFromTokens, swapToTokens } from "./swap-filter"; import { Coin } from "@cosmjs/proto-signing"; -import { AXIOS_TIMEOUT, COSMOS_CHAIN_IDS, EVM_CHAIN_IDS, IBC_TRANSFER_TIMEOUT } from "@oraichain/common"; import { TransferBackMsg } from "@oraichain/common-contracts-sdk/build/CwIcs20Latest.types"; import { buildUniversalSwapMemo } from "./proto/universal-swap-memo-proto-handler"; import { Affiliate } from "@oraichain/oraidex-contracts-sdk/build/OraiswapMixedRouter.types"; import { generateMemoSwap, generateMsgSwap } from "./msg/msgs"; import { fromBech32, toBech32 } from "@cosmjs/encoding"; +import { COSMOS_CHAIN_IDS, CosmosChainId, EVM_CHAIN_IDS, EvmChainId } from "@oraichain/common/build/constants"; const caseSwapNativeAndWrapNative = (fromCoingecko, toCoingecko) => { const arr = ["ethereum", "weth"]; @@ -113,7 +116,7 @@ export class UniversalSwapHelper { } }; - static isEvmNetworkNativeSwapSupported = (chainId: NetworkChainId) => { + static isEvmNetworkNativeSwapSupported = (chainId: string) => { switch (chainId) { case "0x01": case "0x38": @@ -202,7 +205,7 @@ export class UniversalSwapHelper { }; // ibc helpers - static getIbcInfo = (fromChainId: CosmosChainId, toChainId: NetworkChainId): IBCInfo => { + static getIbcInfo = (fromChainId: CosmosChainId, toChainId: string): IBCInfo => { if (!ibcInfos[fromChainId]) throw generateError("Cannot find ibc info"); const ibcInfo = ibcInfos[fromChainId][toChainId]; if (!ibcInfo) throw generateError(`Cannot find ibc info from ${fromChainId} to ${toChainId}`); @@ -222,9 +225,10 @@ export class UniversalSwapHelper { static getSourceReceiver = ( oraiAddress: string, contractAddress?: string, - isSourceReceiverTest?: boolean + isSourceReceiverTest?: boolean, + cosmosChains?: CustomChainInfo[] ): string => { - const isValidRecipient = checkValidateAddressWithNetwork(oraiAddress, COSMOS_CHAIN_IDS.ORAICHAIN); + const isValidRecipient = checkValidateAddressWithNetwork(oraiAddress, COSMOS_CHAIN_IDS.ORAICHAIN, cosmosChains); if (!isValidRecipient.isValid) throw generateError("orai Address get source receiver invalid!"); let sourceReceiver = `${oraib2oraichain}/${oraiAddress}`; @@ -247,7 +251,12 @@ export class UniversalSwapHelper { * @param destReceiver - destination destReceiver * @returns destination in the format /: */ - static getRoute = (fromToken?: TokenItemType, toToken?: TokenItemType, destReceiver?: string): SwapRoute => { + static getRoute = ( + cosmosTokens: TokenItemType[], + fromToken?: TokenItemType, + toToken?: TokenItemType, + destReceiver?: string + ): SwapRoute => { if (!fromToken || !toToken || !destReceiver) return { swapRoute: "", universalSwapType: "other-networks-to-oraichain", isSmartRouter: false }; // this is the simplest case. Both tokens on the same Oraichain network => simple swap with to token denom @@ -341,10 +350,12 @@ export class UniversalSwapHelper { static generateAddress = ({ oraiAddress, injAddress, + cosmosChains, evmInfo }: { oraiAddress: string; injAddress?: string; + cosmosChains: CustomChainInfo[]; evmInfo?: { [key: string]: string; }; @@ -379,6 +390,8 @@ export class UniversalSwapHelper { }; } + console.log("cosmosChains--", cosmosChains, cosmosAddress, addressFollowCoinType); + return cosmosAddress; }; @@ -396,6 +409,7 @@ export class UniversalSwapHelper { toToken: TokenItemType, minimumReceive: string, userSlippage: number, + oraidexCommon: OraidexCommon, swapOption?: { isSourceReceiverTest?: boolean; isIbcWasm?: boolean; @@ -409,10 +423,12 @@ export class UniversalSwapHelper { const source = UniversalSwapHelper.getSourceReceiver( addresses.sourceReceiver, fromToken.contractAddress, - swapOption?.isSourceReceiverTest + swapOption?.isSourceReceiverTest, + oraidexCommon.cosmosChains ); let { swapRoute, universalSwapType, isSmartRouter } = UniversalSwapHelper.getRoute( + oraidexCommon.cosmosTokens, fromToken, toToken, addresses.destReceiver @@ -438,6 +454,7 @@ export class UniversalSwapHelper { destChainId: toToken.chainId, destTokenPrefix: toToken.prefix }, + oraidexCommon.evmChains, swapOption.ibcInfoTestMode ); } @@ -479,7 +496,8 @@ export class UniversalSwapHelper { let receiverAddresses = UniversalSwapHelper.generateAddress({ injAddress: addresses.injAddress, oraiAddress: addresses.sourceReceiver, - evmInfo + evmInfo, + cosmosChains: oraidexCommon.cosmosChains }); const { memo } = generateMemoSwap( @@ -489,6 +507,7 @@ export class UniversalSwapHelper { }, userSlippage / 100, receiverAddresses, + oraidexCommon, addresses.recipientAddress, alphaRoutes.paths[0].chainId ); @@ -515,6 +534,7 @@ export class UniversalSwapHelper { remoteAddressObridge?: string; // add with oraibridge }, userSwap: RouterResponse & { destTokenPrefix: string; destAsset: string; destChainId: string }, + evmChains: CustomChainInfo[], ibcInfoTestMode?: boolean ) => { const { destReceiver, remoteAddressObridge } = basic; @@ -734,41 +754,6 @@ export class UniversalSwapHelper { }; }; - /** - * @deprecated. Use UniversalSwapHelper.handleSimulateSwap - */ - static simulateSwap = async (query: { - fromInfo: TokenItemType; - toInfo: TokenItemType; - amount: string; - routerClient: OraiswapRouterReadOnlyInterface; - }): Promise<{ amount: Uint128 }> => { - const { amount, fromInfo, toInfo, routerClient } = query; - - // check for universal-swap 2 tokens that have same coingeckoId, should return simulate data with average ratio 1-1. - if (fromInfo.coinGeckoId === toInfo.coinGeckoId) { - return { - amount - }; - } - - // check if they have pairs. If not then we go through ORAI - const { info: offerInfo } = parseTokenInfo(fromInfo, amount); - const { info: askInfo } = parseTokenInfo(toInfo); - const operations = UniversalSwapHelper.generateSwapOperationMsgs(offerInfo, askInfo); - console.log("operations: ", operations); - try { - let finalAmount = amount; - const data = await routerClient.simulateSwapOperations({ - offerAmount: finalAmount, - operations - }); - return data; - } catch (error) { - throw new Error(`Error when trying to simulate swap using router v2: ${JSON.stringify(error)}`); - } - }; - // simulate swap functions static simulateSwapUsingSmartRoute = async (query: { fromInfo: TokenItemType; @@ -778,7 +763,7 @@ export class UniversalSwapHelper { }): Promise => { const { amount, fromInfo, toInfo, routerConfig } = query; // check for universal-swap 2 tokens that have same coingeckoId, should return simulate data with average ratio 1-1. - if (fromInfo.chainId === toInfo.chainId && fromInfo.coinGeckoId === toInfo.coinGeckoId) { + if (fromInfo.chainId === toInfo.chainId && fromInfo.coinGeckoId && fromInfo.coinGeckoId === toInfo.coinGeckoId) { return { swapAmount: amount, returnAmount: amount, @@ -814,6 +799,7 @@ export class UniversalSwapHelper { fromInfo: TokenItemType; toInfo: TokenItemType; amount: string; + flattenTokens: TokenItemType[]; }): Promise => { const { amount, fromInfo, toInfo } = query; // check swap native and wrap native @@ -833,7 +819,11 @@ export class UniversalSwapHelper { try { // get proxy contract object so that we can query the corresponding router address const provider = new ethers.providers.JsonRpcProvider(fromInfo.rpc); - const toTokenInfoOnSameChainId = getTokenOnSpecificChainId(toInfo.coinGeckoId, fromInfo.chainId); + const toTokenInfoOnSameChainId = getTokenOnSpecificChainId( + toInfo.coinGeckoId, + fromInfo.chainId, + query.flattenTokens + ); const swapRouterV2 = IUniswapV2Router02__factory.connect( proxyContractInfo[fromInfo.chainId].routerAddr, provider @@ -857,7 +847,26 @@ export class UniversalSwapHelper { } }; + static getRouterConfig = (options: { + path?: string; + protocols?: string[]; + dontAllowSwapAfter?: string[]; + maxSplits?: number; + ignoreFee?: boolean; + }) => { + return { + url: "https://osor.oraidex.io", + path: options?.path ?? "/smart-router/alpha-router", + protocols: options?.protocols ?? ["Oraidex", "OraidexV3"], + dontAllowSwapAfter: options?.dontAllowSwapAfter ?? ["Oraidex", "OraidexV3"], + maxSplits: options?.maxSplits ?? 1, + ignoreFee: options?.ignoreFee ?? false + }; + }; + static handleSimulateSwap = async (query: { + flattenTokens: TokenItemType[]; + oraichainTokens: TokenItemType[]; originalFromInfo: TokenItemType; originalToInfo: TokenItemType; originalAmount: number; @@ -883,23 +892,16 @@ export class UniversalSwapHelper { const { amount, displayAmount } = await UniversalSwapHelper.simulateSwapEvm({ fromInfo: query.originalFromInfo, toInfo: query.originalToInfo, - amount: toAmount(query.originalAmount, query.originalFromInfo.decimals).toString() + amount: toAmount(query.originalAmount, query.originalFromInfo.decimals).toString(), + flattenTokens: query.flattenTokens }); console.log("amount, display amount: ", { amount, displayAmount }); return { amount, displayAmount }; } - const routerConfigDefault = { - url: query?.routerConfig?.url ?? "https://osor.oraidex.io", - path: query?.routerConfig?.path ?? "/smart-router/alpha-router", - protocols: query?.routerConfig?.protocols ?? ["Oraidex", "OraidexV3"], - dontAllowSwapAfter: query?.routerConfig?.dontAllowSwapAfter ?? ["Oraidex", "OraidexV3"], - maxSplits: query?.routerConfig?.maxSplits ?? 10, - ignoreFee: query?.routerConfig?.ignoreFee ?? false - }; - - let fromInfo = getTokenOnOraichain(query.originalFromInfo.coinGeckoId); - let toInfo = getTokenOnOraichain(query.originalToInfo.coinGeckoId); + const routerConfigDefault = UniversalSwapHelper.getRouterConfig(query.routerConfig); + let fromInfo = getTokenOnOraichain(query.originalFromInfo.coinGeckoId, query.oraichainTokens); + let toInfo = getTokenOnOraichain(query.originalToInfo.coinGeckoId, query.oraichainTokens); /** * useAlphaIbcWasm case: (evm -> oraichain -> osmosis -> inj not using wasm) @@ -930,6 +932,7 @@ export class UniversalSwapHelper { }; static checkFeeRelayer = async (query: { + oraichainTokens: TokenItemType[]; originalFromToken: TokenItemType; relayerFee: { relayerAmount: string; @@ -949,7 +952,8 @@ export class UniversalSwapHelper { } return UniversalSwapHelper.checkFeeRelayerNotOrai({ - fromTokenInOrai: getTokenOnOraichain(originalFromToken.coinGeckoId), + oraichainTokens: query.oraichainTokens, + fromTokenInOrai: getTokenOnOraichain(originalFromToken.coinGeckoId, query.oraichainTokens), fromAmount, relayerAmount: relayerFee.relayerAmount, routerClient @@ -957,31 +961,31 @@ export class UniversalSwapHelper { }; static checkFeeRelayerNotOrai = async (query: { + oraichainTokens: TokenItemType[]; fromTokenInOrai: TokenItemType; fromAmount: number; relayerAmount: string; routerClient: OraiswapRouterReadOnlyInterface; }): Promise => { - const { fromTokenInOrai, fromAmount, routerClient, relayerAmount } = query; + const { fromTokenInOrai, fromAmount, routerClient, relayerAmount, oraichainTokens } = query; if (!fromTokenInOrai) return true; if (fromTokenInOrai.chainId !== "Oraichain") throw generateError( "From token on Oraichain is not on Oraichain. The developers have made a mistake. Please notify them!" ); // estimate exchange token when From Token not orai. Only need to swap & check if it is swappable with ORAI. Otherwise, we ignore the fees - if (isInPairList(fromTokenInOrai.denom) || isInPairList(fromTokenInOrai.contractAddress)) { - const oraiToken = getTokenOnOraichain("oraichain-token"); - const { amount } = await UniversalSwapHelper.simulateSwap({ - fromInfo: fromTokenInOrai, - toInfo: oraiToken, - amount: toAmount(fromAmount, fromTokenInOrai.decimals).toString(), - routerClient: routerClient - }); - const amountDisplay = toDisplay(amount, fromTokenInOrai.decimals); - const relayerAmountDisplay = toDisplay(relayerAmount); - if (relayerAmountDisplay > amountDisplay) return false; - return true; - } + const oraiToken = getTokenOnOraichain("oraichain-token", oraichainTokens); + const { amount } = await UniversalSwapHelper.handleSimulateSwap({ + flattenTokens: [], + oraichainTokens, + originalFromInfo: fromTokenInOrai, + originalToInfo: oraiToken, + originalAmount: fromAmount, + routerClient: routerClient + }); + const amountDisplay = toDisplay(amount, fromTokenInOrai.decimals); + const relayerAmountDisplay = toDisplay(relayerAmount); + if (relayerAmountDisplay > amountDisplay) return false; return true; }; @@ -992,7 +996,9 @@ export class UniversalSwapHelper { toToken: TokenItemType, toSimulateAmount: string, client: CosmWasmClient, - ibcWasmContract: string + ibcWasmContract: string, + network: CustomChainInfo & NetworkConfig, + oraichainTokens: TokenItemType[] ) => { try { let pairKey = UniversalSwapHelper.buildIbcWasmPairKey(ibcInfo.source, ibcInfo.channel, toToken.denom); @@ -1024,17 +1030,19 @@ export class UniversalSwapHelper { const trueBalance = toDisplay(balance.native.amount, pairMapping.pair_mapping.remote_decimals); let _toAmount = toDisplay(toSimulateAmount, toToken.decimals); if (fromToken.coinGeckoId !== toToken.coinGeckoId) { - const fromTokenInfo = getTokenOnOraichain(fromToken.coinGeckoId); - const toTokenInfo = getTokenOnOraichain(toToken.coinGeckoId); + const fromTokenInfo = getTokenOnOraichain(fromToken.coinGeckoId, oraichainTokens); + const toTokenInfo = getTokenOnOraichain(toToken.coinGeckoId, oraichainTokens); const routerClient = new OraiswapRouterQueryClient(client, network.mixer_router); if (!fromTokenInfo || !toTokenInfo) throw generateError( `Error in checking balance channel ibc: cannot simulate from: ${fromToken.coinGeckoId} to: ${toToken.coinGeckoId}` ); - const { amount } = await UniversalSwapHelper.simulateSwap({ - fromInfo: fromTokenInfo, - toInfo: toTokenInfo, - amount: toAmount(_toAmount, fromTokenInfo.decimals).toString(), + const { amount } = await UniversalSwapHelper.handleSimulateSwap({ + flattenTokens: [], + oraichainTokens, + originalFromInfo: fromTokenInfo, + originalToInfo: toTokenInfo, + originalAmount: _toAmount, routerClient }); _toAmount = toDisplay(amount, fromTokenInfo.decimals); @@ -1065,13 +1073,15 @@ export class UniversalSwapHelper { fromAmount: number, toSimulateAmount: string, client: CosmWasmClient, - ibcWasmContract: string + ibcWasmContract: string, + network: CustomChainInfo & NetworkConfig, + oraichainTokens: TokenItemType[] ) => { // ORAI ( ETH ) -> check ORAI (ORAICHAIN) -> ORAI (BSC) // no need to check this case because users will swap directly. This case should be impossible because it is only called when transferring from evm to other networks if (from.chainId === "Oraichain" && to.chainId === from.chainId) return; // always check from token in ibc wasm should have enough tokens to swap / send to destination - const token = getTokenOnOraichain(from.coinGeckoId); + const token = getTokenOnOraichain(from.coinGeckoId, oraichainTokens); if (!token) return; // hardcode if is token factory ( mint) then return @@ -1098,7 +1108,16 @@ export class UniversalSwapHelper { if (to.chainId === "0x01" || to.chainId === "0x38" || to.chainId === "0x2b6653dc") { const ibcInfo: IBCInfo | undefined = UniversalSwapHelper.getIbcInfo("Oraichain", to.chainId); if (!ibcInfo) throw generateError("IBC Info error when checking ibc balance"); - await UniversalSwapHelper.checkBalanceChannelIbc(ibcInfo, from, to, toSimulateAmount, client, ibcWasmContract); + await UniversalSwapHelper.checkBalanceChannelIbc( + ibcInfo, + from, + to, + toSimulateAmount, + client, + ibcWasmContract, + network, + oraichainTokens + ); } }; @@ -1107,7 +1126,11 @@ export class UniversalSwapHelper { coingeckoId: CoinGeckoId, denom: string, searchTokenName: string, - direction: SwapDirection // direction = to means we are filtering to tokens + direction: SwapDirection, // direction = to means we are filtering to tokens + swapFromTokens: TokenItemType[], + swapToTokens: TokenItemType[], + oraichainTokens: TokenItemType[], + flattenTokens: TokenItemType[] ) => { // basic filter. Dont include itself & only collect tokens with searched letters const listTokens = direction === SwapDirection.From ? swapFromTokens : swapToTokens; @@ -1122,19 +1145,23 @@ export class UniversalSwapHelper { // tokens that dont have a pool on Oraichain like WETH or WBNB cannot be swapped from a token on Oraichain if (direction === SwapDirection.To) return [ - ...new Set(filteredTokens.concat(filteredTokens.map((token) => getTokenOnOraichain(token.coinGeckoId)))) + ...new Set( + filteredTokens.concat( + filteredTokens.map((token) => getTokenOnOraichain(token.coinGeckoId, oraichainTokens)) + ) + ) ]; filteredToTokens = filteredTokens; } // special case filter. Tokens on networks other than supported evm cannot swap to tokens, so we need to remove them - if (!UniversalSwapHelper.isEvmNetworkNativeSwapSupported(chainId as NetworkChainId)) + if (!UniversalSwapHelper.isEvmNetworkNativeSwapSupported(chainId as string)) return filteredToTokens.filter((t) => { // one-directional swap. non-pool tokens of evm network can swap be swapped with tokens on Oraichain, but not vice versa const isSupported = UniversalSwapHelper.isSupportedNoPoolSwapEvm(t.coinGeckoId); if (direction === SwapDirection.To) return !isSupported; if (isSupported) { // if we cannot find any matched token then we dont include it in the list since it cannot be swapped - const sameChainId = getTokenOnSpecificChainId(coingeckoId, t.chainId as NetworkChainId); + const sameChainId = getTokenOnSpecificChainId(coingeckoId, t.chainId as string, flattenTokens); if (!sameChainId) return false; return true; } @@ -1150,6 +1177,8 @@ export class UniversalSwapHelper { static generateConvertErc20Cw20Message = ( amounts: AmountDetails, tokenInfo: TokenItemType, + tokenMap: Record, + network: CustomChainInfo & NetworkConfig, sender?: string ): ExecuteInstruction[] => { if (!tokenInfo.evmDenoms) return []; @@ -1160,12 +1189,15 @@ export class UniversalSwapHelper { // reset so we convert using native first const erc20TokenInfo = tokenMap[denom]; if (balance > 0) { - const msgConvert: ExecuteInstruction = UniversalSwapHelper.generateConvertMsgs({ - type: Type.CONVERT_TOKEN, - sender, - inputAmount: balance.toString(), - inputToken: erc20TokenInfo - }); + const msgConvert: ExecuteInstruction = UniversalSwapHelper.generateConvertMsgs( + { + type: Type.CONVERT_TOKEN, + sender, + inputAmount: balance.toString(), + inputToken: erc20TokenInfo + }, + network + ); return [msgConvert]; } } @@ -1176,7 +1208,9 @@ export class UniversalSwapHelper { amounts: AmountDetails, tokenInfo: TokenItemType, sender: string, - sendCoin: Coin + sendCoin: Coin, + tokenMap: Record, + network: CustomChainInfo & NetworkConfig ): ExecuteInstruction[] => { if (!tokenInfo.evmDenoms) return []; // we convert all mapped tokens to cw20 to unify the token @@ -1197,20 +1231,23 @@ export class UniversalSwapHelper { contractAddress: undefined, decimals: evmToken.decimals }; - const msgConvert = UniversalSwapHelper.generateConvertMsgs({ - type: Type.CONVERT_TOKEN_REVERSE, - sender, - inputAmount: balance, - inputToken: tokenInfo, - outputToken - }); + const msgConvert = UniversalSwapHelper.generateConvertMsgs( + { + type: Type.CONVERT_TOKEN_REVERSE, + sender, + inputAmount: balance, + inputToken: tokenInfo, + outputToken + }, + network + ); return [msgConvert]; } } return []; }; - static generateConvertMsgs = (data: ConvertType): ExecuteInstruction => { + static generateConvertMsgs = (data: ConvertType, network: CustomChainInfo & NetworkConfig): ExecuteInstruction => { const { type, sender, inputToken, inputAmount } = data; let funds: Coin[] | null; // for withdraw & provide liquidity methods, we need to interact with the oraiswap pair contract @@ -1291,13 +1328,13 @@ export class UniversalSwapHelper { * @param offerInfo * @returns */ - static generateMsgsSmartRouterV2withV3(routes, offerInfo) { + static generateMsgsSmartRouterV2withV3(routes, offerInfo, cosmosTokens: TokenItemType[]) { return routes.map((route) => { let ops = []; let currTokenIn = offerInfo; for (let swap of route.swapInfo) { const [tokenX, tokenY, fee, tickSpacing] = swap.poolId.split("-"); - let tokenOut = parseAssetInfoFromContractAddrOrDenom(swap.tokenOut); + let tokenOut = parseAssetInfoFromContractAddrOrDenom(swap.tokenOut, cosmosTokens); if (tokenX && tokenY && fee && tickSpacing) { ops.push({ swap_v3: { @@ -1541,12 +1578,6 @@ export const generateSwapRoute = UniversalSwapHelper.generateSwapRoute; */ export const generateSwapOperationMsgs = UniversalSwapHelper.generateSwapOperationMsgs; -// simulate swap functions -/** - * @deprecated - */ -export const simulateSwap = UniversalSwapHelper.simulateSwap; - /** * @deprecated */ diff --git a/packages/universal-swap/src/msg/chains/chain.ts b/packages/universal-swap/src/msg/chains/chain.ts index 1e92800f..34b266a2 100644 --- a/packages/universal-swap/src/msg/chains/chain.ts +++ b/packages/universal-swap/src/msg/chains/chain.ts @@ -1,3 +1,4 @@ +import { OraidexCommon } from "@oraichain/oraidex-common"; import { Path } from "../../types"; import { validatePath, validateReceiver } from "../common"; @@ -7,7 +8,8 @@ export class ChainMsg { protected minimumReceive: string, protected receiver: string, protected currentChainAddress: string, - protected memo: string = "" + protected memo: string = "", + protected oraidexCommon: OraidexCommon ) { // validate path validatePath(path); diff --git a/packages/universal-swap/src/msg/chains/cosmos.ts b/packages/universal-swap/src/msg/chains/cosmos.ts index 85c3b7a3..8c95d4e1 100644 --- a/packages/universal-swap/src/msg/chains/cosmos.ts +++ b/packages/universal-swap/src/msg/chains/cosmos.ts @@ -6,15 +6,22 @@ import { calculateTimeoutTimestamp, generateError, IBC_TRANSFER_TIMEOUT, - NetworkChainId + OraidexCommon } from "@oraichain/oraidex-common"; import { EncodeObject } from "@cosmjs/proto-signing"; import { ChainMsg } from "./chain"; export class CosmosMsg extends ChainMsg { - constructor(path: Path, minimumReceive: string, receiver: string, currentChainAddress: string, memo: string = "") { - super(path, minimumReceive, receiver, currentChainAddress, memo); + constructor( + path: Path, + minimumReceive: string, + receiver: string, + currentChainAddress: string, + memo: string = "", + oraidexCommon: OraidexCommon + ) { + super(path, minimumReceive, receiver, currentChainAddress, memo, oraidexCommon); } setMinimumReceiveForSwap(slippage: number = 0.01) { @@ -46,8 +53,8 @@ export class CosmosMsg extends ChainMsg { timeout: +calculateTimeoutTimestamp(IBC_TRANSFER_TIMEOUT), fromToken: action.tokenIn, toToken: action.tokenOut, - fromChain: this.path.chainId as NetworkChainId, - toChain: this.path.tokenOutChainId as NetworkChainId + fromChain: this.path.chainId as string, + toChain: this.path.tokenOutChainId as string }; break; } else { diff --git a/packages/universal-swap/src/msg/chains/oraichain.ts b/packages/universal-swap/src/msg/chains/oraichain.ts index 1a4fc0a8..cb38f14d 100644 --- a/packages/universal-swap/src/msg/chains/oraichain.ts +++ b/packages/universal-swap/src/msg/chains/oraichain.ts @@ -14,7 +14,7 @@ import { isEthAddress, isTonChain, JETTONS_ADDRESS, - NetworkChainId + OraidexCommon } from "@oraichain/oraidex-common"; import { toBinary } from "@cosmjs/cosmwasm-stargate"; import { Memo, Memo_PostAction, Memo_UserSwap } from "../../proto/universal_swap_memo"; @@ -35,10 +35,12 @@ export class OraichainMsg extends ChainMsg { receiver: string, currentChainAddress: string, memo: string = "", + oraidexCommon: OraidexCommon, + protected destPrefix: string = undefined, protected obridgeAddress: string = undefined ) { - super(path, minimumReceive, receiver, currentChainAddress, memo); + super(path, minimumReceive, receiver, currentChainAddress, memo, oraidexCommon); // check chainId = "Oraichain" if (path.chainId !== "Oraichain") { throw generateError("This path must be on Oraichain"); @@ -143,8 +145,8 @@ export class OraichainMsg extends ChainMsg { timeout: +calculateTimeoutTimestamp(IBC_TRANSFER_TIMEOUT), fromToken: action.tokenIn, toToken: action.tokenOut, - fromChain: this.path.chainId as NetworkChainId, - toChain: this.path.tokenOutChainId as NetworkChainId + fromChain: this.path.chainId as string, + toChain: this.path.tokenOutChainId as string }; break; } @@ -463,9 +465,8 @@ export class OraichainMsg extends ChainMsg { // ibc transfer // ibc wasm transfer // ton bridge - // ibc transfer - if (bridgeInfo.sourcePort == "transfer" && isCosmosChain(bridgeInfo.toChain)) { + if (bridgeInfo.sourcePort == "transfer" && isCosmosChain(bridgeInfo.toChain, this.oraidexCommon.cosmosChains)) { return { typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", value: { @@ -537,6 +538,8 @@ export class OraichainMsg extends ChainMsg { } } + console.log({ msg, contractAddr }); + if (!msg || !contractAddr) { throw generateError("Error on generate executeMsg on Oraichain: Only support ibc, ibc wasm bridge, ton bridge"); } @@ -595,7 +598,6 @@ export class OraichainMsg extends ChainMsg { } let tokenOutOfSwap = swapOps[swapOps.length - 1].denom_out; - console.log({ tokenOutOfSwap }); let min_asset = isCw20Token(tokenOutOfSwap) ? { cw20: { diff --git a/packages/universal-swap/src/msg/chains/osmosis.ts b/packages/universal-swap/src/msg/chains/osmosis.ts index afd55762..a0ffefd3 100644 --- a/packages/universal-swap/src/msg/chains/osmosis.ts +++ b/packages/universal-swap/src/msg/chains/osmosis.ts @@ -8,7 +8,7 @@ import { calculateTimeoutTimestamp, generateError, IBC_TRANSFER_TIMEOUT, - NetworkChainId + OraidexCommon } from "@oraichain/oraidex-common"; import { toBinary } from "@cosmjs/cosmwasm-stargate"; import { EncodeObject } from "@cosmjs/proto-signing"; @@ -20,8 +20,15 @@ export class OsmosisMsg extends ChainMsg { SWAP_VENUE_NAME = "osmosis-poolmanager"; ENTRY_POINT_CONTRACT = "osmo1h3jkejkcpthl45xrrm5geed3eq75p5rgfce9taufkwfr89k63muqweu2y7"; - constructor(path: Path, minimumReceive: string, receiver: string, currentChainAddress: string, memo: string = "") { - super(path, minimumReceive, receiver, currentChainAddress, memo); + constructor( + path: Path, + minimumReceive: string, + receiver: string, + currentChainAddress: string, + memo: string = "", + oraidexCommon: OraidexCommon + ) { + super(path, minimumReceive, receiver, currentChainAddress, memo, oraidexCommon); // check chainId = "osmosis-1" if (path.chainId !== "osmosis-1") { throw generateError("This path must be on Osmosis"); @@ -87,8 +94,8 @@ export class OsmosisMsg extends ChainMsg { timeout: +calculateTimeoutTimestamp(IBC_TRANSFER_TIMEOUT), fromToken: action.tokenIn, toToken: action.tokenOut, - fromChain: this.path.chainId as NetworkChainId, - toChain: this.path.tokenOutChainId as NetworkChainId + fromChain: this.path.chainId as string, + toChain: this.path.tokenOutChainId as string }; break; } diff --git a/packages/universal-swap/src/msg/msgs.ts b/packages/universal-swap/src/msg/msgs.ts index 33562d7f..62fb0c57 100644 --- a/packages/universal-swap/src/msg/msgs.ts +++ b/packages/universal-swap/src/msg/msgs.ts @@ -5,13 +5,14 @@ import { ORAI_BRIDGE_EVM_DENOM_PREFIX, ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, ORAI_BRIDGE_EVM_ETH_DENOM_PREFIX, - checkValidateAddressWithNetwork, - NetworkChainId + OraidexCommon, + checkValidateAddressWithNetwork } from "@oraichain/oraidex-common"; import { Path, Route } from "../types"; import { CosmosMsg, OraichainMsg, OsmosisMsg } from "./chains"; import { MiddlewareResponse } from "./types"; import { EncodeObject } from "@cosmjs/proto-signing"; +import { NetworkChainId } from "@oraichain/common"; const getDestPrefixForBridgeToEvmOnOrai = (chainId: string): string => { const prefixMap: { [key: string]: string } = { @@ -35,6 +36,7 @@ const buildMemoSwap = ( memo: string, addresses: { [chainId: string]: string }, slippage: number = 0.01, + oraidexCommon: OraidexCommon, previousChain?: string ): MiddlewareResponse => { let currentChain = path.chainId; @@ -45,23 +47,33 @@ const buildMemoSwap = ( let prefix = getDestPrefixForBridgeToEvmOnOrai(path.tokenOutChainId); const ORAIBRIDGE_SUBNET = "oraibridge-subnet-2"; let oBridgeAddress = addresses[ORAIBRIDGE_SUBNET]; - if (!oBridgeAddress && !isEvmChain(path.tokenOutChainId)) { + if (!oBridgeAddress && !isEvmChain(path.tokenOutChainId, oraidexCommon.evmChains)) { throw generateError(`Missing oBridge address for ${ORAIBRIDGE_SUBNET}`); } - let oraichainMsg = new OraichainMsg(path, "1", receiver, currentAddress, memo, prefix, oBridgeAddress); + let oraichainMsg = new OraichainMsg( + path, + "1", + receiver, + currentAddress, + memo, + oraidexCommon, + prefix, + oBridgeAddress + ); oraichainMsg.setMinimumReceiveForSwap(slippage); // we have 2 cases: // - Previous chain use IBC bridge to Oraichain // - Previous chain use IBC Wasm bridge to Oraichain (EVM, noble, ton) let msgInfo = - previousChain && (previousChain == "noble-1" || isEvmChain(previousChain) || isTonChain(previousChain)) + previousChain && + (previousChain == "noble-1" || isEvmChain(previousChain, oraidexCommon.evmChains) || isTonChain(previousChain)) ? oraichainMsg.genMemoForIbcWasm() : oraichainMsg.genMemoAsMiddleware(); return msgInfo; } case "osmosis-1": { - let cosmosMsg = new OsmosisMsg(path, "1", receiver, currentAddress, memo); + let cosmosMsg = new OsmosisMsg(path, "1", receiver, currentAddress, memo, oraidexCommon); cosmosMsg.setMinimumReceiveForSwap(slippage); let msgInfo = cosmosMsg.genMemoAsMiddleware(); return msgInfo; @@ -73,7 +85,7 @@ const buildMemoSwap = ( if (currentChain.startsWith("0x")) { throw generateError("Don't support universal swap in EVM"); } - let cosmosMsg = new CosmosMsg(path, "1", receiver, currentAddress, memo); + let cosmosMsg = new CosmosMsg(path, "1", receiver, currentAddress, memo, oraidexCommon); cosmosMsg.setMinimumReceiveForSwap(slippage); let msgInfo = cosmosMsg.genMemoAsMiddleware(); return msgInfo; @@ -86,7 +98,8 @@ const buildExecuteMsg = ( receiver: string, memo: string, addresses: { [chainId: string]: string }, - slippage: number = 0.01 + slippage: number = 0.01, + oraidexCommon: OraidexCommon ): EncodeObject => { let currentChain = path.chainId; let currentAddress = addresses[currentChain]; @@ -95,16 +108,25 @@ const buildExecuteMsg = ( let prefix = getDestPrefixForBridgeToEvmOnOrai(path.tokenOutChainId); const ORAIBRIDGE_SUBNET = "oraibridge-subnet-2"; let oBridgeAddress = addresses[ORAIBRIDGE_SUBNET]; - if (!oBridgeAddress && !isEvmChain(path.tokenOutChainId)) { + if (!oBridgeAddress && !isEvmChain(path.tokenOutChainId, oraidexCommon.evmChains)) { throw generateError(`Missing oBridge address for ${ORAIBRIDGE_SUBNET}`); } - let oraichainMsg = new OraichainMsg(path, "1", receiver, currentAddress, memo, prefix, oBridgeAddress); + let oraichainMsg = new OraichainMsg( + path, + "1", + receiver, + currentAddress, + memo, + oraidexCommon, + prefix, + oBridgeAddress + ); oraichainMsg.setMinimumReceiveForSwap(slippage); return oraichainMsg.genExecuteMsg(); } case "osmosis-1": { - let cosmosMsg = new OsmosisMsg(path, "1", receiver, currentAddress, memo); + let cosmosMsg = new OsmosisMsg(path, "1", receiver, currentAddress, memo, oraidexCommon); cosmosMsg.setMinimumReceiveForSwap(slippage); return cosmosMsg.genExecuteMsg(); } @@ -115,7 +137,7 @@ const buildExecuteMsg = ( if (currentChain.startsWith("0x")) { throw generateError("Don't support universal swap in EVM"); } - let cosmosMsg = new CosmosMsg(path, "1", receiver, currentAddress, memo); + let cosmosMsg = new CosmosMsg(path, "1", receiver, currentAddress, memo, oraidexCommon); cosmosMsg.setMinimumReceiveForSwap(slippage); return cosmosMsg.genExecuteMsg(); } @@ -126,6 +148,7 @@ export const generateMsgSwap = ( route: Route, slippage: number = 0.01, addresses: { [chainId: string]: string }, + oraidexCommon: OraidexCommon, recipientAddress?: string ): EncodeObject => { if (route.paths.length == 0) { @@ -136,25 +159,38 @@ export const generateMsgSwap = ( let receiver = addresses[tokenOutChainId]; if (recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(recipientAddress, tokenOutChainId as NetworkChainId); + const isValidRecipient = checkValidateAddressWithNetwork( + recipientAddress, + tokenOutChainId as NetworkChainId, + oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid) throw generateError("Recipient address invalid when generateMsgSwap!"); receiver = recipientAddress; } // generate memo for univeral swap for (let i = route.paths.length - 1; i > 0; i--) { - let swapInfo = buildMemoSwap(route.paths[i], receiver, memo, addresses, slippage, route.paths[i - 1].chainId); + let swapInfo = buildMemoSwap( + route.paths[i], + receiver, + memo, + addresses, + slippage, + oraidexCommon, + route.paths[i - 1].chainId + ); memo = swapInfo.memo; receiver = swapInfo.receiver; } - return buildExecuteMsg(route.paths[0], receiver, memo, addresses, slippage); + return buildExecuteMsg(route.paths[0], receiver, memo, addresses, slippage, oraidexCommon); }; export const generateMemoSwap = ( route: Route, slippage: number = 0.01, addresses: { [chainId: string]: string }, + oraidexCommon: OraidexCommon, recipientAddress?: string, previousChain?: string ): MiddlewareResponse => { @@ -169,16 +205,28 @@ export const generateMemoSwap = ( const tokenOutChainId = route.paths.at(-1)?.tokenOutChainId; let receiver = addresses[tokenOutChainId]; if (recipientAddress) { - const isValidRecipient = checkValidateAddressWithNetwork(recipientAddress, tokenOutChainId as NetworkChainId); + const isValidRecipient = checkValidateAddressWithNetwork( + recipientAddress, + tokenOutChainId as NetworkChainId, + oraidexCommon.cosmosChains + ); if (!isValidRecipient.isValid) throw generateError("Recipient address invalid when generateMemoSwap!"); receiver = recipientAddress; } // generate memo for univeral swap for (let i = route.paths.length - 1; i > 0; i--) { - let swapInfo = buildMemoSwap(route.paths[i], receiver, memo, addresses, slippage, route.paths[i - 1].chainId); + let swapInfo = buildMemoSwap( + route.paths[i], + receiver, + memo, + addresses, + slippage, + oraidexCommon, + route.paths[i - 1].chainId + ); memo = swapInfo.memo; receiver = swapInfo.receiver; } - return buildMemoSwap(route.paths[0], receiver, memo, addresses, slippage, previousChain); + return buildMemoSwap(route.paths[0], receiver, memo, addresses, slippage, oraidexCommon, previousChain); }; diff --git a/packages/universal-swap/src/msg/types.ts b/packages/universal-swap/src/msg/types.ts index 5b81a994..85a280e9 100644 --- a/packages/universal-swap/src/msg/types.ts +++ b/packages/universal-swap/src/msg/types.ts @@ -1,7 +1,6 @@ import { Coin } from "@cosmjs/amino"; import { JsonObject } from "@cosmjs/cosmwasm-stargate"; import { EncodeObject } from "@cosmjs/proto-signing"; -import { NetworkChainId } from "@oraichain/oraidex-common"; export interface BridgeMsgInfo { amount: string; @@ -12,9 +11,9 @@ export interface BridgeMsgInfo { memo?: string; prefix?: string; // use for bridge to evm fromToken: string; - fromChain: NetworkChainId; + fromChain: string; toToken: string; - toChain: NetworkChainId; + toChain: string; } export enum PostActionType { diff --git a/packages/universal-swap/src/swap-filter.ts b/packages/universal-swap/src/swap-filter.ts index 253c5211..f9bf8a95 100644 --- a/packages/universal-swap/src/swap-filter.ts +++ b/packages/universal-swap/src/swap-filter.ts @@ -4,7 +4,8 @@ import { KWT_BSC_CONTRACT, MILKYBSC_ORAICHAIN_DENOM, MILKY_BSC_CONTRACT, - flattenTokens + TokenItemType, + // getOraidexCommonAttribute, } from "@oraichain/oraidex-common"; export const evmDenomsMap = { @@ -12,9 +13,9 @@ export const evmDenomsMap = { milky: [MILKYBSC_ORAICHAIN_DENOM], injective: [INJECTIVE_ORAICHAIN_DENOM] }; -const notAllowSwapCoingeckoIds = []; +export const notAllowSwapCoingeckoIds = []; // universal swap. Currently we dont support from tokens that are not using the ibc wasm channel -const notAllowSwapFromChainIds = [ +export const notAllowSwapFromChainIds = [ "0x1ae6", "kawaii_6886-1", "oraibridge-subnet-2", @@ -22,18 +23,18 @@ const notAllowSwapFromChainIds = [ "Neutaro-1", "bitcoin" ]; -const notAllowDenom = Object.values(evmDenomsMap).flat(); -const notAllowBEP20Token = [KWT_BSC_CONTRACT, MILKY_BSC_CONTRACT]; -export const swapFromTokens = flattenTokens.filter((token) => { - return ( - !notAllowDenom.includes(token?.denom) && - !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && - !notAllowSwapFromChainIds.includes(token.chainId) && - !notAllowBEP20Token.includes(token?.contractAddress) - ); -}); +export const notAllowDenom = Object.values(evmDenomsMap).flat(); +export const notAllowBEP20Token = [KWT_BSC_CONTRACT, MILKY_BSC_CONTRACT]; +// export const swapFromTokens = flattenTokens.filter((token) => { +// return ( +// !notAllowDenom.includes(token?.denom) && +// !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && +// !notAllowSwapFromChainIds.includes(token.chainId) && +// !notAllowBEP20Token.includes(token?.contractAddress) +// ); +// }); // universal swap. We dont support kwt & milky & injective for simplicity. We also skip OraiBridge tokens because users dont care about them -const notAllowSwapToChainIds = [ +export const notAllowSwapToChainIds = [ "0x1ae6", "kawaii_6886-1", "oraibridge-subnet-2", @@ -41,11 +42,35 @@ const notAllowSwapToChainIds = [ "Neutaro-1", "bitcoin" ]; -export const swapToTokens = flattenTokens.filter((token) => { - return ( - !notAllowDenom.includes(token?.denom) && - !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && - !notAllowSwapToChainIds.includes(token.chainId) && - !notAllowBEP20Token.includes(token?.contractAddress) - ); -}); +// export const swapToTokens = flattenTokens.filter((token) => { +// return ( +// !notAllowDenom.includes(token?.denom) && +// !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && +// !notAllowSwapToChainIds.includes(token.chainId) && +// !notAllowBEP20Token.includes(token?.contractAddress) +// ); +// }); + +export const getSwapFromTokens = (flattenTokens: TokenItemType[]) => { + // const flattenTokens = getOraidexCommonAttribute('flattenTokens'); + return flattenTokens.filter((token) => { + return ( + !notAllowDenom.includes(token?.denom) && + !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && + !notAllowSwapFromChainIds.includes(token.chainId) && + !notAllowBEP20Token.includes(token?.contractAddress) + ); + }); +} + +export const getSwapToTokens = (flattenTokens: TokenItemType[]) => { + // const flattenTokens = getOraidexCommonAttribute('flattenTokens'); + return flattenTokens.filter((token) => { + return ( + !notAllowDenom.includes(token?.denom) && + !notAllowSwapCoingeckoIds.includes(token.coinGeckoId) && + !notAllowSwapToChainIds.includes(token.chainId) && + !notAllowBEP20Token.includes(token?.contractAddress) + ); + }); +} \ No newline at end of file diff --git a/packages/universal-swap/src/types.ts b/packages/universal-swap/src/types.ts index e77d2f61..3c485176 100644 --- a/packages/universal-swap/src/types.ts +++ b/packages/universal-swap/src/types.ts @@ -1,5 +1,5 @@ import { Coin } from "@cosmjs/amino"; -import { AmountDetails, CosmosWallet, EvmWallet, NetworkChainId, TokenItemType } from "@oraichain/oraidex-common"; +import { AmountDetails, CosmosWallet, EvmWallet, TokenItemType } from "@oraichain/oraidex-common"; import { SwapOperation, Uint128 } from "@oraichain/oraidex-contracts-sdk"; import { Affiliate } from "@oraichain/oraidex-contracts-sdk/build/OraiswapMixedRouter.types"; import TonWallet from "@oraichain/tonbridge-sdk/build/wallet"; diff --git a/packages/universal-swap/src/universal-demos/alpha-ibc-new.ts b/packages/universal-swap/src/universal-demos/alpha-ibc-new.ts index 54d424e6..11279bff 100644 --- a/packages/universal-swap/src/universal-demos/alpha-ibc-new.ts +++ b/packages/universal-swap/src/universal-demos/alpha-ibc-new.ts @@ -1,7 +1,7 @@ import "dotenv/config"; -import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { cosmosTokens, flattenTokens, generateError, getTokenOnOraichain, toAmount } from "@oraichain/oraidex-common"; +import { CosmosWalletImpl } from "./offline-wallet"; +import { generateError, OraidexCommon, toAmount } from "@oraichain/oraidex-common"; const router = { swapAmount: "16000000", @@ -45,6 +45,9 @@ const alphaSwapToOraichain = async () => { const fromAmount = 16; console.log("sender: ", sender); + + const oraidexCommon = await OraidexCommon.load(); + const flattenTokens = oraidexCommon.flattenTokens; const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "usd-coin" && t.chainId === chainId); const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "usd-coin" && t.chainId === "ton"); @@ -74,7 +77,8 @@ const alphaSwapToOraichain = async () => { { cosmosWallet: wallet, swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } - } + }, + oraidexCommon ); try { @@ -86,5 +90,7 @@ const alphaSwapToOraichain = async () => { }; (() => { - alphaSwapToOraichain(); + alphaSwapToOraichain().catch((error) => { + console.log({ error_alphaSwapToOraichain: error }); + }); })(); diff --git a/packages/universal-swap/src/universal-demos/alpha-smart-router.ts b/packages/universal-swap/src/universal-demos/alpha-smart-router.ts index f9cb1987..4327920f 100644 --- a/packages/universal-swap/src/universal-demos/alpha-smart-router.ts +++ b/packages/universal-swap/src/universal-demos/alpha-smart-router.ts @@ -1,7 +1,7 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { cosmosTokens, flattenTokens, generateError, getTokenOnOraichain, toAmount } from "@oraichain/oraidex-common"; +import { generateError, OraidexCommon } from "@oraichain/oraidex-common"; const router = { swapAmount: "1000000", @@ -45,6 +45,9 @@ const alphaSwapToOraichain = async () => { const sender = await wallet.getKeplrAddr("Oraichain"); const fromAmount = 1; console.log("sender: ", sender); + + const oraidexCommon = await OraidexCommon.load(); + const flattenTokens = oraidexCommon.flattenTokens; const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "tether" && t.chainId === "Oraichain"); const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "Oraichain"); @@ -72,7 +75,8 @@ const alphaSwapToOraichain = async () => { { cosmosWallet: wallet, swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } - } + }, + oraidexCommon ); try { @@ -83,6 +87,4 @@ const alphaSwapToOraichain = async () => { } }; -(() => { - alphaSwapToOraichain(); -})(); +alphaSwapToOraichain(); diff --git a/packages/universal-swap/src/universal-demos/evm-to-evm.ts b/packages/universal-swap/src/universal-demos/evm-to-evm.ts index bf92ec2b..8bd5db43 100644 --- a/packages/universal-swap/src/universal-demos/evm-to-evm.ts +++ b/packages/universal-swap/src/universal-demos/evm-to-evm.ts @@ -1,31 +1,30 @@ -import "dotenv/config"; -import { CosmosWalletImpl } from "./offline-wallet"; -import { UniversalSwapHandler } from "../handler"; import { - ORAI_ETH_CONTRACT, - cosmosTokens, - flattenTokens, + COSMOS_CHAIN_ID_COMMON, + EVM_CHAIN_ID_COMMON, generateError, + OraidexCommon, toAmount, - USDT_CONTRACT, - ORAI_BSC_CONTRACT, - EVM_CHAIN_ID_COMMON, - USDT_BSC_CONTRACT, - COSMOS_CHAIN_ID_COMMON + TokenItemType } from "@oraichain/oraidex-common"; +import "dotenv/config"; +import { UniversalSwapHandler } from "../handler"; +import { CosmosWalletImpl } from "./offline-wallet"; const evmToEvm = async () => { const fromAmount = 1; const wallet = new CosmosWalletImpl(process.env.MNEMONIC); const sender = await wallet.getKeplrAddr("Oraichain"); + + const oraidexCommon = await OraidexCommon.load(); + const flattenTokens = oraidexCommon.flattenTokens; let originalFromToken = flattenTokens.find( (t) => t.chainId === EVM_CHAIN_ID_COMMON.BSC_CHAIN_ID && t.coinGeckoId === "oraichain-token" ); - let originalToToken = flattenTokens.find( (t) => t.chainId === COSMOS_CHAIN_ID_COMMON.ORAICHAIN_CHAIN_ID && t.coinGeckoId === "tether" ); + const evmAddress = "0xf2846a1E4dAFaeA38C1660a618277d67605bd2B5"; if (!originalFromToken) throw generateError("Could not find original from token"); if (!originalToToken) throw generateError("Could not find original to token"); @@ -52,7 +51,8 @@ const evmToEvm = async () => { swapOptions: { isAlphaSmartRouter: true } - } + }, + oraidexCommon ); try { @@ -63,6 +63,4 @@ const evmToEvm = async () => { } }; -(() => { - return evmToEvm(); -})(); +evmToEvm(); diff --git a/packages/universal-swap/src/universal-demos/from-cosmos-to-cosmos.ts b/packages/universal-swap/src/universal-demos/from-cosmos-to-cosmos.ts index a5504500..4dbd6911 100644 --- a/packages/universal-swap/src/universal-demos/from-cosmos-to-cosmos.ts +++ b/packages/universal-swap/src/universal-demos/from-cosmos-to-cosmos.ts @@ -1,54 +1,54 @@ -import "dotenv/config"; -import { CosmosWalletImpl } from "./offline-wallet"; -import { UniversalSwapHandler } from "../handler"; -import { - ORAI_ETH_CONTRACT, - cosmosTokens, - flattenTokens, - generateError, - toAmount, - USDT_CONTRACT -} from "@oraichain/oraidex-common"; +// import "dotenv/config"; +// import { CosmosWalletImpl } from "./offline-wallet"; +// import { UniversalSwapHandler } from "../handler"; +// import { +// ORAI_ETH_CONTRACT, +// cosmosTokens, +// flattenTokens, +// generateError, +// toAmount, +// USDT_CONTRACT +// } from "@oraichain/oraidex-common"; -const cosmosToCosmos = async (chainId: "osmosis-1") => { - const wallet = new CosmosWalletImpl(process.env.MNEMONIC); +// const cosmosToCosmos = async (chainId: "osmosis-1") => { +// const wallet = new CosmosWalletImpl(process.env.MNEMONIC); - const sender = await wallet.getKeplrAddr(chainId); - const fromAmount = 1; - let originalFromToken = cosmosTokens.find((t) => t.chainId === chainId && t.coinGeckoId === "osmosis"); +// const sender = await wallet.getKeplrAddr(chainId); +// const fromAmount = 1; +// let originalFromToken = cosmosTokens.find((t) => t.chainId === chainId && t.coinGeckoId === "osmosis"); - let originalToToken = flattenTokens.find((t) => t.chainId === "Oraichain" && t.coinGeckoId === "osmosis"); - if (!originalFromToken) throw generateError("Could not find original from token"); - if (!originalToToken) throw generateError("Could not find original to token"); - const universalHandler = new UniversalSwapHandler( - { - originalFromToken, - originalToToken, - sender: { cosmos: sender }, - relayerFee: { - relayerAmount: "1000000", - relayerDecimals: 6 - }, - fromAmount, - simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() - }, - { - cosmosWallet: wallet, - swapOptions: { - isIbcWasm: false, - isAlphaSmartRouter: false - } - } - ); +// let originalToToken = flattenTokens.find((t) => t.chainId === "Oraichain" && t.coinGeckoId === "osmosis"); +// if (!originalFromToken) throw generateError("Could not find original from token"); +// if (!originalToToken) throw generateError("Could not find original to token"); +// const universalHandler = new UniversalSwapHandler( +// { +// originalFromToken, +// originalToToken, +// sender: { cosmos: sender }, +// relayerFee: { +// relayerAmount: "1000000", +// relayerDecimals: 6 +// }, +// fromAmount, +// simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() +// }, +// { +// cosmosWallet: wallet, +// swapOptions: { +// isIbcWasm: false, +// isAlphaSmartRouter: false +// } +// } +// ); - try { - const result = await universalHandler.processUniversalSwap(); - console.log("result: ", result); - } catch (error) { - console.log("error: ", error); - } -}; +// try { +// const result = await universalHandler.processUniversalSwap(); +// console.log("result: ", result); +// } catch (error) { +// console.log("error: ", error); +// } +// }; -(() => { - return cosmosToCosmos("osmosis-1"); -})(); +// (() => { +// return cosmosToCosmos("osmosis-1"); +// })(); diff --git a/packages/universal-swap/src/universal-demos/from-cosmos-to-evm.ts b/packages/universal-swap/src/universal-demos/from-cosmos-to-evm.ts index dcec032a..6d67f230 100644 --- a/packages/universal-swap/src/universal-demos/from-cosmos-to-evm.ts +++ b/packages/universal-swap/src/universal-demos/from-cosmos-to-evm.ts @@ -3,14 +3,18 @@ import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; import { ORAI_ETH_CONTRACT, - cosmosTokens, - flattenTokens, generateError, toAmount, - USDT_CONTRACT + USDT_CONTRACT, + OraidexCommon, + TokenItemType } from "@oraichain/oraidex-common"; const oraichainToEvm = async (chainId: "Oraichain") => { + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; + const flattenTokens = oraidexCommon.flattenTokens; + const wallet = new CosmosWalletImpl(process.env.MNEMONIC); const sender = await wallet.getKeplrAddr(chainId); @@ -37,7 +41,8 @@ const oraichainToEvm = async (chainId: "Oraichain") => { fromAmount, simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() }, - { cosmosWallet: wallet, swapOptions: {} } + { cosmosWallet: wallet, swapOptions: {} }, + oraidexCommon ); try { diff --git a/packages/universal-swap/src/universal-demos/from-oraichain-to-evm.ts b/packages/universal-swap/src/universal-demos/from-oraichain-to-evm.ts index 9a1a0737..b0b7c715 100644 --- a/packages/universal-swap/src/universal-demos/from-oraichain-to-evm.ts +++ b/packages/universal-swap/src/universal-demos/from-oraichain-to-evm.ts @@ -1,8 +1,7 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { flattenTokens, generateError, toAmount } from "@oraichain/oraidex-common"; -import { UniversalSwapHelper } from "../helper"; +import { generateError, OraidexCommon, toAmount, TokenItemType } from "@oraichain/oraidex-common"; const oraichainToEvm = async () => { const chainId = "Oraichain"; @@ -10,6 +9,9 @@ const oraichainToEvm = async () => { const sender = await wallet.getKeplrAddr(chainId); const fromAmount = 10000; + + const oraidexCommon = await OraidexCommon.load(); + const flattenTokens = oraidexCommon.flattenTokens; let originalToToken = flattenTokens.find((t) => t.chainId === chainId && t.coinGeckoId === "tether"); let originalFromToken = flattenTokens.find((t) => t.chainId === "0x38" && t.coinGeckoId === "tether"); @@ -44,7 +46,8 @@ const oraichainToEvm = async () => { isAlphaSmartRouter: true, isIbcWasm: true } - } + }, + oraidexCommon ); try { @@ -55,6 +58,4 @@ const oraichainToEvm = async () => { } }; -(() => { - return oraichainToEvm(); -})(); +oraichainToEvm(); diff --git a/packages/universal-swap/src/universal-demos/from-oraichain-to-oraichain.ts b/packages/universal-swap/src/universal-demos/from-oraichain-to-oraichain.ts index 43362e7d..66c865e9 100644 --- a/packages/universal-swap/src/universal-demos/from-oraichain-to-oraichain.ts +++ b/packages/universal-swap/src/universal-demos/from-oraichain-to-oraichain.ts @@ -2,14 +2,12 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; import { - ORAI_ETH_CONTRACT, - cosmosTokens, - flattenTokens, generateError, toAmount, USDT_CONTRACT, ORAI, - SCATOM_CONTRACT + SCATOM_CONTRACT, + OraidexCommon } from "@oraichain/oraidex-common"; import { UniversalSwapHelper } from "../helper"; @@ -18,6 +16,11 @@ const oraichainToOraichain = async (chainId: "Oraichain") => { const sender = await wallet.getKeplrAddr(chainId); const fromAmount = 0.01; + + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; + const flattenTokens = oraidexCommon.flattenTokens; + let originalFromToken = cosmosTokens.find( (t) => t.chainId === chainId && t.contractAddress && t.contractAddress === USDT_CONTRACT ); @@ -55,7 +58,8 @@ const oraichainToOraichain = async (chainId: "Oraichain") => { isIbcWasm: false, isAlphaIbcWasm: true } - } + }, + oraidexCommon ); try { diff --git a/packages/universal-swap/src/universal-demos/from-oraichain-to-ton.ts b/packages/universal-swap/src/universal-demos/from-oraichain-to-ton.ts index c3c1e756..5238aa7a 100644 --- a/packages/universal-swap/src/universal-demos/from-oraichain-to-ton.ts +++ b/packages/universal-swap/src/universal-demos/from-oraichain-to-ton.ts @@ -1,110 +1,110 @@ -import "dotenv/config"; -import { CosmosWalletImpl } from "./offline-wallet"; -import { UniversalSwapHandler } from "../handler"; -import { - cosmosTokens, - flattenTokens, - generateError, - getTokenOnOraichain, - toAmount, - jUSDC_TON_CONTRACT -} from "@oraichain/oraidex-common"; +// import "dotenv/config"; +// import { CosmosWalletImpl } from "./offline-wallet"; +// import { UniversalSwapHandler } from "../handler"; +// import { +// cosmosTokens, +// flattenTokens, +// generateError, +// getTokenOnOraichain, +// toAmount, +// jUSDC_TON_CONTRACT +// } from "@oraichain/oraidex-common"; -const router = { - swapAmount: "1300000", - returnAmount: "81199", - routes: [ - { - swapAmount: "1300000", - returnAmount: "81199", - paths: [ - { - chainId: "Oraichain", - tokenIn: "orai", - tokenInAmount: "1300000", - tokenOut: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", - tokenOutAmount: "81199", - tokenOutChainId: "ton", - actions: [ - { - type: "Swap", - protocol: "OraidexV3", - tokenIn: "orai", - tokenInAmount: "1300000", - tokenOut: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd", - tokenOutAmount: "15081199", - swapInfo: [ - { - poolId: "orai-orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd-3000000000-100", - tokenOut: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd" - } - ] - }, - { - type: "Bridge", - protocol: "Bridge", - tokenIn: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd", - tokenInAmount: "15081199", - tokenOut: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", - tokenOutAmount: "81199", - tokenOutChainId: "ton", - bridgeInfo: { - port: "transfer", - channel: "channel-1" - } - } - ] - } - ] - } - ] -}; +// const router = { +// swapAmount: "1300000", +// returnAmount: "81199", +// routes: [ +// { +// swapAmount: "1300000", +// returnAmount: "81199", +// paths: [ +// { +// chainId: "Oraichain", +// tokenIn: "orai", +// tokenInAmount: "1300000", +// tokenOut: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", +// tokenOutAmount: "81199", +// tokenOutChainId: "ton", +// actions: [ +// { +// type: "Swap", +// protocol: "OraidexV3", +// tokenIn: "orai", +// tokenInAmount: "1300000", +// tokenOut: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd", +// tokenOutAmount: "15081199", +// swapInfo: [ +// { +// poolId: "orai-orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd-3000000000-100", +// tokenOut: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd" +// } +// ] +// }, +// { +// type: "Bridge", +// protocol: "Bridge", +// tokenIn: "orai15un8msx3n5zf9ahlxmfeqd2kwa5wm0nrpxer304m9nd5q6qq0g6sku5pdd", +// tokenInAmount: "15081199", +// tokenOut: "EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728", +// tokenOutAmount: "81199", +// tokenOutChainId: "ton", +// bridgeInfo: { +// port: "transfer", +// channel: "channel-1" +// } +// } +// ] +// } +// ] +// } +// ] +// }; -const swapOraichainToTon = async () => { - const wallet = new CosmosWalletImpl(process.env.MNEMONIC); - const sender = await wallet.getKeplrAddr("Oraichain"); - const fromAmount = 1.3; - console.log("sender: ", sender); - const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "Oraichain"); - const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "usd-coin" && t.chainId === "ton"); +// const swapOraichainToTon = async () => { +// const wallet = new CosmosWalletImpl(process.env.MNEMONIC); +// const sender = await wallet.getKeplrAddr("Oraichain"); +// const fromAmount = 1.3; +// console.log("sender: ", sender); +// const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "Oraichain"); +// const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "usd-coin" && t.chainId === "ton"); - if (!originalToToken) throw generateError("Could not find original to token"); - if (!originalFromToken) throw generateError("Could not find original from token"); +// if (!originalToToken) throw generateError("Could not find original to token"); +// if (!originalFromToken) throw generateError("Could not find original from token"); - const universalHandler = new UniversalSwapHandler( - { - originalFromToken, - originalToToken, - sender: { - cosmos: sender, - // evm: "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", - // ton: "UQD3zsGYoDGgpambcp7SquM3wJqo6Yc-ksEtCGCDS8JwGQpp" - ton: "UQDOAHXyCPFOXAXm9c1P_NeNEeSWy6IaRHqJRnBUp0jMZ6i3" - }, - fromAmount, - userSlippage: 1, - relayerFee: { - relayerAmount: "100000", - relayerDecimals: 6 - }, - simulatePrice: "1100000", - simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString(), - alphaSmartRoutes: router - }, - { - cosmosWallet: wallet, - swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } - } - ); +// const universalHandler = new UniversalSwapHandler( +// { +// originalFromToken, +// originalToToken, +// sender: { +// cosmos: sender, +// // evm: "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", +// // ton: "UQD3zsGYoDGgpambcp7SquM3wJqo6Yc-ksEtCGCDS8JwGQpp" +// ton: "UQDOAHXyCPFOXAXm9c1P_NeNEeSWy6IaRHqJRnBUp0jMZ6i3" +// }, +// fromAmount, +// userSlippage: 1, +// relayerFee: { +// relayerAmount: "100000", +// relayerDecimals: 6 +// }, +// simulatePrice: "1100000", +// simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString(), +// alphaSmartRoutes: router +// }, +// { +// cosmosWallet: wallet, +// swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } +// } +// ); - try { - const result = await universalHandler.processUniversalSwap(); - console.log("result: ", result); - } catch (error) { - console.trace("error: ", error); - } -}; +// try { +// const result = await universalHandler.processUniversalSwap(); +// console.log("result: ", result); +// } catch (error) { +// console.trace("error: ", error); +// } +// }; -(async () => { - await swapOraichainToTon(); -})(); +// (async () => { +// await swapOraichainToTon(); +// })(); diff --git a/packages/universal-swap/src/universal-demos/from-ton-to-oraichain.ts b/packages/universal-swap/src/universal-demos/from-ton-to-oraichain.ts index 7d54c4bf..5d2c3e19 100644 --- a/packages/universal-swap/src/universal-demos/from-ton-to-oraichain.ts +++ b/packages/universal-swap/src/universal-demos/from-ton-to-oraichain.ts @@ -1,100 +1,100 @@ -import "dotenv/config"; -import { CosmosWalletImpl } from "./offline-wallet"; -import { UniversalSwapHandler } from "../handler"; -import { cosmosTokens, flattenTokens, generateError, getTokenOnOraichain, toAmount } from "@oraichain/oraidex-common"; -import TonWallet from "@oraichain/tonbridge-sdk/build/wallet"; +// import "dotenv/config"; +// import { CosmosWalletImpl } from "./offline-wallet"; +// import { UniversalSwapHandler } from "../handler"; +// import { cosmosTokens, flattenTokens, generateError, getTokenOnOraichain, toAmount } from "@oraichain/oraidex-common"; +// import TonWallet from "@oraichain/tonbridge-sdk/build/wallet"; -const router = { - swapAmount: "3000000000", - returnAmount: "1000000000", - routes: [ - { - swapAmount: "3000000000", - returnAmount: "1000000000", - paths: [ - { - chainId: "ton", - tokenIn: "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", - tokenInAmount: "3000000000", - tokenOut: "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton", - tokenOutAmount: "1000000000", - tokenOutChainId: "Oraichain", - actions: [ - { - type: "Bridge", - protocol: "Bridge", - tokenIn: "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", - tokenInAmount: "3000000000", - tokenOut: "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton", - tokenOutAmount: "1000000000", - tokenOutChainId: "Oraichain", - bridgeInfo: { - port: "transfer", - channel: "channel-1" - } - } - ] - } - ] - } - ] -}; +// const router = { +// swapAmount: "3000000000", +// returnAmount: "1000000000", +// routes: [ +// { +// swapAmount: "3000000000", +// returnAmount: "1000000000", +// paths: [ +// { +// chainId: "ton", +// tokenIn: "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", +// tokenInAmount: "3000000000", +// tokenOut: "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton", +// tokenOutAmount: "1000000000", +// tokenOutChainId: "Oraichain", +// actions: [ +// { +// type: "Bridge", +// protocol: "Bridge", +// tokenIn: "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", +// tokenInAmount: "3000000000", +// tokenOut: "factory/orai1wuvhex9xqs3r539mvc6mtm7n20fcj3qr2m0y9khx6n5vtlngfzes3k0rq9/ton", +// tokenOutAmount: "1000000000", +// tokenOutChainId: "Oraichain", +// bridgeInfo: { +// port: "transfer", +// channel: "channel-1" +// } +// } +// ] +// } +// ] +// } +// ] +// }; -const swapTonToOraichain = async () => { - const wallet = new CosmosWalletImpl(process.env.MNEMONIC); +// const swapTonToOraichain = async () => { +// const wallet = new CosmosWalletImpl(process.env.MNEMONIC); - const tonWallet = await TonWallet.create("mainnet", { - mnemonicData: { - mnemonic: process.env.TON_MNEMONIC.split(" "), - tonWalletVersion: "V4" - } - }); +// const tonWallet = await TonWallet.create("mainnet", { +// mnemonicData: { +// mnemonic: process.env.TON_MNEMONIC.split(" "), +// tonWalletVersion: "V4" +// } +// }); - const sender = await wallet.getKeplrAddr("Oraichain"); - const tonAddr = await tonWallet.sender.address.toString(); - const fromAmount = 3; - console.log("sender: ", sender); - console.log("tonAddr: ", tonAddr); - const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "the-open-network" && t.chainId === "ton"); - const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "the-open-network" && t.chainId === "Oraichain"); - if (!originalToToken) throw generateError("Could not find original to token"); - if (!originalFromToken) throw generateError("Could not find original from token"); +// const sender = await wallet.getKeplrAddr("Oraichain"); +// const tonAddr = await tonWallet.sender.address.toString(); +// const fromAmount = 3; +// console.log("sender: ", sender); +// console.log("tonAddr: ", tonAddr); +// const originalFromToken = flattenTokens.find((t) => t.coinGeckoId === "the-open-network" && t.chainId === "ton"); +// const originalToToken = flattenTokens.find((t) => t.coinGeckoId === "the-open-network" && t.chainId === "Oraichain"); +// if (!originalToToken) throw generateError("Could not find original to token"); +// if (!originalFromToken) throw generateError("Could not find original from token"); - const universalHandler = new UniversalSwapHandler( - { - originalFromToken, - originalToToken, - sender: { - cosmos: sender, - evm: "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", - // ton: "UQD3zsGYoDGgpambcp7SquM3wJqo6Yc-ksEtCGCDS8JwGQpp" - ton: "EQDOAHXyCPFOXAXm9c1P_NeNEeSWy6IaRHqJRnBUp0jMZ_Vy" - }, - fromAmount, - userSlippage: 1, - relayerFee: { - relayerAmount: "100000", - relayerDecimals: 6 - }, - simulatePrice: "1000000000", - simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString(), - alphaSmartRoutes: router - }, - { - cosmosWallet: wallet, - tonWallet, - swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } - } - ); +// const universalHandler = new UniversalSwapHandler( +// { +// originalFromToken, +// originalToToken, +// sender: { +// cosmos: sender, +// evm: "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", +// // ton: "UQD3zsGYoDGgpambcp7SquM3wJqo6Yc-ksEtCGCDS8JwGQpp" +// ton: "EQDOAHXyCPFOXAXm9c1P_NeNEeSWy6IaRHqJRnBUp0jMZ_Vy" +// }, +// fromAmount, +// userSlippage: 1, +// relayerFee: { +// relayerAmount: "100000", +// relayerDecimals: 6 +// }, +// simulatePrice: "1000000000", +// simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString(), +// alphaSmartRoutes: router +// }, +// { +// cosmosWallet: wallet, +// tonWallet, +// swapOptions: { isIbcWasm: false, isAlphaIbcWasm: true } +// } +// ); - try { - const result = await universalHandler.processUniversalSwap(); - console.log("result: ", result); - } catch (error) { - console.trace("error: ", error); - } -}; +// try { +// const result = await universalHandler.processUniversalSwap(); +// console.log("result: ", result); +// } catch (error) { +// console.trace("error: ", error); +// } +// }; -(() => { - swapTonToOraichain(); -})(); +// (() => { +// swapTonToOraichain(); +// })(); diff --git a/packages/universal-swap/src/universal-demos/handle-simulate-swap.ts b/packages/universal-swap/src/universal-demos/handle-simulate-swap.ts index 2fcc2afb..712bd90f 100644 --- a/packages/universal-swap/src/universal-demos/handle-simulate-swap.ts +++ b/packages/universal-swap/src/universal-demos/handle-simulate-swap.ts @@ -1,9 +1,13 @@ import "dotenv/config"; -import { flattenTokens, generateError } from "@oraichain/oraidex-common"; +import { generateError, OraidexCommon } from "@oraichain/oraidex-common"; import { handleSimulateSwap } from "../helper"; const simulate = async () => { const fromAmount = 1; + + const oraidexCommon = await OraidexCommon.load(); + const flattenTokens = oraidexCommon.flattenTokens; + let originalFromToken = flattenTokens.find((t) => t.chainId === "0x38" && t.coinGeckoId === "oraichain-token"); let originalToToken = flattenTokens.find((t) => t.chainId === "Oraichain" && t.coinGeckoId === "oraichain-token"); @@ -12,6 +16,8 @@ const simulate = async () => { try { const res = await handleSimulateSwap({ + flattenTokens, + oraichainTokens: oraidexCommon.oraichainTokens, originalFromInfo: originalFromToken, originalToInfo: originalToToken, originalAmount: fromAmount, diff --git a/packages/universal-swap/src/universal-demos/ibc-hooks-demo.ts b/packages/universal-swap/src/universal-demos/ibc-hooks-demo.ts index 412915fe..febcbc74 100644 --- a/packages/universal-swap/src/universal-demos/ibc-hooks-demo.ts +++ b/packages/universal-swap/src/universal-demos/ibc-hooks-demo.ts @@ -1,16 +1,7 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { - CoinGeckoId, - KWT_BSC_CONTRACT, - USDC_CONTRACT, - cosmosTokens, - flattenTokens, - generateError, - getTokenOnOraichain, - toAmount -} from "@oraichain/oraidex-common"; +import { CoinGeckoId, generateError, getTokenOnOraichain, OraidexCommon, toAmount } from "@oraichain/oraidex-common"; const cosmosToOraichain = async ( chainId: "cosmoshub-4" | "osmosis-1" | "injective-1", @@ -20,9 +11,12 @@ const cosmosToOraichain = async ( const sender = await wallet.getKeplrAddr(chainId); const fromAmount = 0.001; console.log("sender: ", sender); + + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; const originalFromToken = cosmosTokens.find((t) => t.chainId === chainId); - const originalToToken = getTokenOnOraichain(toTokenCoingeckoId); + const originalToToken = getTokenOnOraichain(toTokenCoingeckoId, oraidexCommon.oraichainTokens); if (!originalFromToken) throw generateError("Could not find original from token"); if (!originalToToken) throw generateError("Could not find original to token"); @@ -39,7 +33,8 @@ const cosmosToOraichain = async ( fromAmount, simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() }, - { cosmosWallet: wallet } + { cosmosWallet: wallet }, + oraidexCommon ); try { diff --git a/packages/universal-swap/src/universal-demos/neutaro-ibc-demo.ts b/packages/universal-swap/src/universal-demos/neutaro-ibc-demo.ts index 7080a73b..df79dd6f 100644 --- a/packages/universal-swap/src/universal-demos/neutaro-ibc-demo.ts +++ b/packages/universal-swap/src/universal-demos/neutaro-ibc-demo.ts @@ -1,12 +1,15 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { NEUTARO_ORAICHAIN_DENOM, cosmosTokens, generateError, toAmount } from "@oraichain/oraidex-common"; +import { NEUTARO_ORAICHAIN_DENOM, OraidexCommon, generateError, toAmount } from "@oraichain/oraidex-common"; const neutaroUsdcToOraiUsdc = async (chainId: "Neutaro-1" | "Oraichain") => { const wallet = new CosmosWalletImpl(process.env.MNEMONIC); const sender = await wallet.getKeplrAddr(chainId); const fromAmount = 0.01; + + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; let originalFromToken = cosmosTokens.find((t) => t.chainId === "Neutaro-1" && t.denom === "uneutaro"); let originalToToken = cosmosTokens.find( @@ -30,7 +33,8 @@ const neutaroUsdcToOraiUsdc = async (chainId: "Neutaro-1" | "Oraichain") => { fromAmount, simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() }, - { cosmosWallet: wallet, swapOptions: { ibcInfoTestMode: true } } + { cosmosWallet: wallet, swapOptions: { ibcInfoTestMode: true } }, + oraidexCommon ); try { @@ -41,7 +45,7 @@ const neutaroUsdcToOraiUsdc = async (chainId: "Neutaro-1" | "Oraichain") => { } }; -(() => { +(async () => { if (process.env.FORWARD) return neutaroUsdcToOraiUsdc("Neutaro-1"); return neutaroUsdcToOraiUsdc("Oraichain"); })(); diff --git a/packages/universal-swap/src/universal-demos/noble-ibc-demo.ts b/packages/universal-swap/src/universal-demos/noble-ibc-demo.ts index 542feb75..faf11be8 100644 --- a/packages/universal-swap/src/universal-demos/noble-ibc-demo.ts +++ b/packages/universal-swap/src/universal-demos/noble-ibc-demo.ts @@ -1,13 +1,16 @@ import "dotenv/config"; import { CosmosWalletImpl } from "./offline-wallet"; import { UniversalSwapHandler } from "../handler"; -import { USDC_CONTRACT, cosmosTokens, generateError, toAmount } from "@oraichain/oraidex-common"; +import { OraidexCommon, USDC_CONTRACT, generateError, toAmount } from "@oraichain/oraidex-common"; const nobleUsdcToOraiUsdc = async (chainId: "noble-1" | "Oraichain") => { const wallet = new CosmosWalletImpl(process.env.MNEMONIC); const sender = await wallet.getKeplrAddr(chainId); const fromAmount = 0.000001; console.log("sender: ", sender); + + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; let originalFromToken = cosmosTokens.find((t) => t.chainId === "noble-1" && t.denom === "uusdc"); let originalToToken = cosmosTokens.find( (t) => t.chainId === "Oraichain" && t.contractAddress && t.contractAddress === USDC_CONTRACT @@ -28,7 +31,8 @@ const nobleUsdcToOraiUsdc = async (chainId: "noble-1" | "Oraichain") => { fromAmount, simulateAmount: toAmount(fromAmount, originalToToken.decimals).toString() }, - { cosmosWallet: wallet, swapOptions: { ibcInfoTestMode: true } } + { cosmosWallet: wallet, swapOptions: { ibcInfoTestMode: true } }, + oraidexCommon ); try { @@ -39,7 +43,7 @@ const nobleUsdcToOraiUsdc = async (chainId: "noble-1" | "Oraichain") => { } }; -(() => { +(async () => { if (process.env.FORWARD) return nobleUsdcToOraiUsdc("noble-1"); return nobleUsdcToOraiUsdc("Oraichain"); })(); diff --git a/packages/universal-swap/src/universal-demos/offline-wallet.ts b/packages/universal-swap/src/universal-demos/offline-wallet.ts index 5a3bb21e..5327ff52 100644 --- a/packages/universal-swap/src/universal-demos/offline-wallet.ts +++ b/packages/universal-swap/src/universal-demos/offline-wallet.ts @@ -1,5 +1,6 @@ import { DirectSecp256k1HdWallet, OfflineSigner } from "@cosmjs/proto-signing"; -import { CosmosChainId, CosmosWallet, cosmosTokens, generateError } from "@oraichain/oraidex-common"; +import { CosmosChainId } from "@oraichain/common/build/constants"; +import { CosmosWallet, OraidexCommon, generateError } from "@oraichain/oraidex-common"; export class CosmosWalletImpl extends CosmosWallet { constructor(private readonly mnemonic: string) { @@ -12,6 +13,8 @@ export class CosmosWalletImpl extends CosmosWallet { return accounts[0].address; } async createCosmosSigner(chainId: CosmosChainId): Promise { + const oraidexCommon = await OraidexCommon.load(); + const cosmosTokens = oraidexCommon.cosmosTokens; const chainInfo = cosmosTokens.find((t) => t.chainId === chainId); if (!chainInfo) throw generateError(`Cannot find a matched chain info given a chain id ${chainId}`); if (!chainInfo.prefix) diff --git a/packages/universal-swap/src/wrapper.ts b/packages/universal-swap/src/wrapper.ts index a0784c52..5b417ffc 100644 --- a/packages/universal-swap/src/wrapper.ts +++ b/packages/universal-swap/src/wrapper.ts @@ -1,6 +1,7 @@ -import { CosmosChainId, CosmosWallet, EvmResponse, EvmWallet, TokenItemType } from "@oraichain/oraidex-common"; +import { CosmosWallet, EvmResponse, EvmWallet, OraidexCommon, TokenItemType } from "@oraichain/oraidex-common"; import { UniversalSwapHandler } from "./handler"; import { ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { CosmosChainId } from "@oraichain/common/build/constants"; export const swapOraichainToOraichain = async (data: { cosmosWallet: CosmosWallet; @@ -13,6 +14,7 @@ export const swapOraichainToOraichain = async (data: { }): Promise => { const { cosmosWallet, fromAmount, fromToken, toToken, simulatePrice, userSlippage, simulateAmount } = data; const sender = await cosmosWallet.getKeplrAddr("Oraichain"); + const oraidexCommon = await OraidexCommon.load(); const handler = new UniversalSwapHandler( { sender: { cosmos: sender }, @@ -23,7 +25,8 @@ export const swapOraichainToOraichain = async (data: { simulatePrice, userSlippage }, - { cosmosWallet } + { cosmosWallet }, + oraidexCommon ); return handler.swap(); }; @@ -39,6 +42,7 @@ export const swapOraichainToCosmos = async (data: { }) => { const { cosmosWallet, fromAmount, fromToken, toToken, simulatePrice, userSlippage, simulateAmount } = data; const cosmos = await cosmosWallet.getKeplrAddr(fromToken.chainId as CosmosChainId); + const oraidexCommon = await OraidexCommon.load(); const handler = new UniversalSwapHandler( { sender: { cosmos }, @@ -49,7 +53,8 @@ export const swapOraichainToCosmos = async (data: { simulateAmount, userSlippage }, - { cosmosWallet } + { cosmosWallet }, + oraidexCommon ); return handler.swapAndTransferToOtherNetworks("oraichain-to-cosmos"); }; @@ -68,6 +73,7 @@ export const swapOraichainToEvm = async (data: { const cosmos = await cosmosWallet.getKeplrAddr(fromToken.chainId as CosmosChainId); const evm = await evmWallet.getEthAddress(); const tron = evmWallet.tronWeb?.defaultAddress?.base58 as string; + const oraidexCommon = await OraidexCommon.load(); const handler = new UniversalSwapHandler( { sender: { cosmos, evm, tron }, @@ -78,7 +84,8 @@ export const swapOraichainToEvm = async (data: { simulateAmount, userSlippage }, - { cosmosWallet, evmWallet } + { cosmosWallet, evmWallet }, + oraidexCommon ); return handler.swapAndTransferToOtherNetworks("oraichain-to-evm"); }; @@ -101,6 +108,7 @@ export const swapEvmToOraichain = async (data: { const cosmos = await cosmosWallet.getKeplrAddr(fromToken.chainId as CosmosChainId); const evm = await evmWallet.getEthAddress(); const tron = evmWallet.tronWeb?.defaultAddress?.base58 as string; + const oraidexCommon = await OraidexCommon.load(); const handler = new UniversalSwapHandler( { sender: { cosmos, evm, tron }, @@ -111,7 +119,8 @@ export const swapEvmToOraichain = async (data: { simulateAmount, userSlippage }, - { cosmosWallet, evmWallet } + { cosmosWallet, evmWallet }, + oraidexCommon ); return handler.processUniversalSwap() as Promise; }; diff --git a/packages/universal-swap/tests/helper.spec.ts b/packages/universal-swap/tests/helper.spec.ts index 3882aa01..f9bf9a1d 100644 --- a/packages/universal-swap/tests/helper.spec.ts +++ b/packages/universal-swap/tests/helper.spec.ts @@ -5,15 +5,12 @@ import { AmountDetails, COSMOS_CHAIN_ID_COMMON, CoinGeckoId, - CosmosChainId, - EvmChainId, INJECTIVE_CONTRACT, INJECTIVE_ORAICHAIN_DENOM, KWT_BSC_CONTRACT, MILKY_BSC_CONTRACT, NEUTARO_INFO, NEUTARO_ORAICHAIN_DENOM, - NetworkChainId, ORAI, ORAIX_CONTRACT, ORAIX_INFO, @@ -23,6 +20,7 @@ import { ORAI_BSC_CONTRACT, ORAI_ETH_CONTRACT, ORAI_INFO, + OraidexCommon, TokenInfo, TokenItemType, USDC_CONTRACT, @@ -34,7 +32,7 @@ import { WRAP_BNB_CONTRACT, WRAP_ETH_CONTRACT, WRAP_TRON_TRX_CONTRACT, - flattenTokens, + // flattenTokens, // TODO: INIT ORAI COMMON HERE getTokenOnOraichain, getTokenOnSpecificChainId, ibcInfos, @@ -59,7 +57,6 @@ import { isEvmSwappable, isSupportedNoPoolSwapEvm, generateSwapRoute, - generateSwapOperationMsgs, UniversalSwapHelper } from "../src/helper"; import { SwapRoute, UniversalSwapType } from "../src/types"; @@ -70,6 +67,12 @@ import { expect, afterAll, beforeAll, describe, it, vi } from "vitest"; import { parseAssetInfo } from "../../oraidex-common/src"; describe("test helper functions", () => { + let oraidexCommon: OraidexCommon; + + beforeAll(async () => { + oraidexCommon = await OraidexCommon.load(); + }); + it("test-buildSwapRouterKey", () => { expect(buildSwapRouterKey("foo", "bar")).toEqual("foo-bar"); }); @@ -125,7 +128,7 @@ describe("test helper functions", () => { expect(buildIbcWasmPairKey("foo", "bar", "john-doe")).toEqual("foo/bar/john-doe"); }); - it.each<[NetworkChainId, boolean]>([ + it.each<[string, boolean]>([ ["0x01", true], ["0x38", true], ["Oraichain", false] @@ -133,25 +136,25 @@ describe("test helper functions", () => { expect(isEvmNetworkNativeSwapSupported(chainId)).toEqual(expectedResult); }); - it("test-getSourceReceiver-should-return-channel-1-plus-address", async () => { - const keplrAddress = "orai1329tg05k3snr66e2r9ytkv6hcjx6fkxcarydx6"; - const tokenAddress = ORAI_BSC_CONTRACT; - const res = getSourceReceiver(keplrAddress, tokenAddress); - expect(res).toBe(`${oraib2oraichain}/${keplrAddress}`); - }); + // it("test-getSourceReceiver-should-return-channel-1-plus-address", async () => { + // const keplrAddress = "orai1329tg05k3snr66e2r9ytkv6hcjx6fkxcarydx6"; + // const tokenAddress = ORAI_BSC_CONTRACT; + // const res = getSourceReceiver(keplrAddress, tokenAddress); + // expect(res).toBe(`${oraib2oraichain}/${keplrAddress}`); + // }); - it("test-getSourceReceiver-should-return-only-address", async () => { - const keplrAddress = "orai1329tg05k3snr66e2r9ytkv6hcjx6fkxcarydx6"; - let tokenAddress = KWT_BSC_CONTRACT; - let res = getSourceReceiver(keplrAddress, tokenAddress); - expect(res).toBe(keplrAddress); + // it("test-getSourceReceiver-should-return-only-address", async () => { + // const keplrAddress = "orai1329tg05k3snr66e2r9ytkv6hcjx6fkxcarydx6"; + // let tokenAddress = KWT_BSC_CONTRACT; + // let res = getSourceReceiver(keplrAddress, tokenAddress); + // expect(res).toBe(keplrAddress); - tokenAddress = MILKY_BSC_CONTRACT; - res = getSourceReceiver(keplrAddress, tokenAddress); - expect(res).toBe(keplrAddress); - }); + // tokenAddress = MILKY_BSC_CONTRACT; + // res = getSourceReceiver(keplrAddress, tokenAddress); + // expect(res).toBe(keplrAddress); + // }); - it.each<[CoinGeckoId, NetworkChainId, CoinGeckoId, NetworkChainId, string, SwapRoute, boolean]>([ + it.each<[CoinGeckoId, string, CoinGeckoId, string, string, SwapRoute, boolean]>([ [ "airight", "0x38", @@ -343,12 +346,14 @@ describe("test helper functions", () => { vi.spyOn(dexCommonHelper, "isEthAddress").mockImplementation((address) => address.includes("0x") ? true : false ); - const fromToken = flattenTokens.find( + const fromToken = oraidexCommon.flattenTokens.find( (item) => item.coinGeckoId === fromCoingeckoId && item.chainId === fromChainId )!; - const toToken = flattenTokens.find((item) => item.coinGeckoId === toCoingeckoId && item.chainId === toChainId); + const toToken = oraidexCommon.flattenTokens.find( + (item) => item.coinGeckoId === toCoingeckoId && item.chainId === toChainId + ); try { - const receiverAddress = UniversalSwapHelper.getRoute(fromToken, toToken, receiver); + const receiverAddress = UniversalSwapHelper.getRoute(oraidexCommon.cosmosTokens, fromToken, toToken, receiver); expect(receiverAddress).toEqual(swapRoute); expect(willThrow).toEqual(false); } catch (error) { @@ -398,7 +403,12 @@ describe("test helper functions", () => { ...evmInfo }; - const generateAddress = UniversalSwapHelper.generateAddress({ oraiAddress, injAddress, evmInfo }); + const generateAddress = UniversalSwapHelper.generateAddress({ + oraiAddress, + injAddress, + cosmosChains: oraidexCommon.cosmosChains, + evmInfo + }); expect(generateAddress).toMatchObject(expectAddresses); } catch (error) { expect(willThrow).toEqual(false); @@ -605,6 +615,7 @@ describe("test helper functions", () => { undefined as any, "0", 1, + oraidexCommon, { isSourceReceiverTest: false } @@ -619,6 +630,7 @@ describe("test helper functions", () => { undefined as any, "0", 1, + oraidexCommon, { isSourceReceiverTest: false } @@ -806,74 +818,12 @@ describe("test helper functions", () => { }); }); - it.each<[AssetInfo, AssetInfo, SwapOperation[]]>([ - [ - ORAIX_INFO, - NEUTARO_INFO, - [ - { - orai_swap: { - offer_asset_info: ORAIX_INFO, - ask_asset_info: ORAI_INFO - } - }, - { - orai_swap: { - offer_asset_info: ORAI_INFO, - ask_asset_info: USDC_INFO - } - }, - { - orai_swap: { - offer_asset_info: USDC_INFO, - ask_asset_info: NEUTARO_INFO - } - } - ] - ], - [ - NEUTARO_INFO, - ORAIX_INFO, - [ - { - orai_swap: { - offer_asset_info: NEUTARO_INFO, - ask_asset_info: USDC_INFO - } - }, - { - orai_swap: { - offer_asset_info: USDC_INFO, - ask_asset_info: ORAI_INFO - } - }, - { - orai_swap: { - offer_asset_info: ORAI_INFO, - ask_asset_info: ORAIX_INFO - } - } - ] - ] - ])("test-generateSwapOperationMsgs", (offerAsset, askAsset, expectSwapRoute) => { - const getSwapOperationMsgsRoute = generateSwapOperationMsgs(offerAsset, askAsset); - expect(getSwapOperationMsgsRoute).toEqual(expect.arrayContaining(expectSwapRoute)); - getSwapOperationMsgsRoute.forEach((swap) => { - expect(swap).toMatchObject({ - orai_swap: expect.objectContaining({ - offer_asset_info: expect.any(Object), - ask_asset_info: expect.any(Object) - }) - }); - }); - }); - - it.each<[AmountDetails, TokenItemType, Coin, number]>([ + it.each<[AmountDetails, string, Coin, number]>([ [ { injective: "10000" }, - getTokenOnOraichain("injective-protocol"), + "injective-protocol", coin(1000, INJECTIVE_ORAICHAIN_DENOM), 1 ], @@ -882,25 +832,40 @@ describe("test helper functions", () => { [INJECTIVE_ORAICHAIN_DENOM]: "1000", injective: "10000" }, - getTokenOnOraichain("injective-protocol"), + "injective-protocol", coin(1000, INJECTIVE_ORAICHAIN_DENOM), 0 ], - [{}, getTokenOnOraichain("injective-protocol"), coin(1000, INJECTIVE_ORAICHAIN_DENOM), 0] + [{}, "injective-protocol", coin(1000, INJECTIVE_ORAICHAIN_DENOM), 0] ])("test-generate-convert-msgs", async (currentBal: AmountDetails, tokenInfo, toSend, msgLength) => { - const msg = universalHelper.generateConvertCw20Erc20Message(currentBal, tokenInfo, "orai123", toSend); + const token = getTokenOnOraichain(tokenInfo, oraidexCommon.oraichainTokens); + const msg = universalHelper.generateConvertCw20Erc20Message( + currentBal, + token, + "orai123", + toSend, + oraidexCommon.tokenMap, + oraidexCommon.network + ); console.dir(msg, { depth: null }); expect(msg.length).toEqual(msgLength); }); - it.each<[AmountDetails, TokenItemType, number]>([ - [{}, getTokenOnOraichain("cosmos"), 0], - [{ [`${INJECTIVE_ORAICHAIN_DENOM}`]: "10" }, getTokenOnOraichain("injective-protocol"), 1], - [{ injective: "10" }, getTokenOnOraichain("injective-protocol"), 0] + it.each<[AmountDetails, string, number]>([ + [{}, "cosmos", 0], + [{ [`${INJECTIVE_ORAICHAIN_DENOM}`]: "10" }, "injective-protocol", 1], + [{ injective: "10" }, "injective-protocol", 0] ])( "test-generateConvertErc20Cw20Message-should-return-correct-message-length", (amountDetails, tokenInfo, expectedMessageLength) => { - const result = universalHelper.generateConvertErc20Cw20Message(amountDetails, tokenInfo, "john doe"); + const token = getTokenOnOraichain(tokenInfo, oraidexCommon.oraichainTokens); + const result = universalHelper.generateConvertErc20Cw20Message( + amountDetails, + token, + oraidexCommon.tokenMap, + oraidexCommon.network, + "john doe" + ); expect(result.length).toEqual(expectedMessageLength); } ); diff --git a/packages/universal-swap/tests/index.spec.ts b/packages/universal-swap/tests/index.spec.ts index 8ddb4c6e..22edf9bc 100644 --- a/packages/universal-swap/tests/index.spec.ts +++ b/packages/universal-swap/tests/index.spec.ts @@ -1,17 +1,13 @@ import { CosmosWallet, EvmWallet, - NetworkChainId, OSMOSIS_ORAICHAIN_DENOM, - flattenTokens, oraichain2osmosis, - oraichainTokens, USDT_CONTRACT, ROUTER_V2_CONTRACT, toDisplay, ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX, TokenItemType, - CosmosChainId, CoinGeckoId, AIRI_CONTRACT, IBC_WASM_CONTRACT, @@ -24,7 +20,7 @@ import { calculateTimeoutTimestamp, BigDecimal, OSMOSIS_ROUTER_CONTRACT, - network, + OraidexCommon, MIXED_ROUTER } from "@oraichain/oraidex-common"; import * as dexCommonHelper from "@oraichain/oraidex-common/build/helper"; // import like this to enable vi.spyOn & avoid redefine property error @@ -59,8 +55,7 @@ import { checkFeeRelayerNotOrai, getBalanceIBCOraichain, getIbcInfo, - handleSimulateSwap, - simulateSwap + handleSimulateSwap } from "../src/helper"; import { alphaSmartRoute, @@ -113,6 +108,10 @@ describe("test universal swap handler functions", () => { let routerContract: OraiswapRouterClient; let oracleContract: OraiswapOracleClient; let airiToken: OraiswapTokenClient; + let oraidexCommon: OraidexCommon; + let universalSwapData: UniversalSwapData; + let flattenTokens: TokenItemType[]; + let oraichainTokens: TokenItemType[]; const now = 1000; beforeEach(() => { @@ -121,6 +120,9 @@ describe("test universal swap handler functions", () => { beforeAll(async () => { // deploy oracle addr + oraidexCommon = await OraidexCommon.load(); + flattenTokens = oraidexCommon.flattenTokens; + oraichainTokens = oraidexCommon.oraichainTokens; const { codeId: pairCodeId } = await client.upload( testSenderAddress, readFileSync(oraidexArtifacts.getContractDir("oraiswap-pair")), @@ -254,9 +256,19 @@ describe("test universal swap handler functions", () => { remoteDecimals: 6, localChannelId: channel }); + + universalSwapData = { + sender: { cosmos: testSenderAddress, evm: "0x1234", tron: "TNJksEkvvdmae8uXYkNE9XKHbTDiSQrpbf" }, + originalFromToken: oraichainTokens[0], + originalToToken: oraichainTokens[0], + simulateAmount, + simulatePrice: "0", + userSlippage, + fromAmount: toDisplay(fromAmount) + }; }); class StubCosmosWallet extends CosmosWallet { - getKeplrAddr(chainId?: NetworkChainId | undefined): Promise { + getKeplrAddr(chainId?: string | undefined): Promise { let addr: string = "orai1g4h64yjt0fvzv5v2j8tyfnpe5kmnetejvfgs7g"; switch (chainId) { case "noble-1": @@ -305,15 +317,7 @@ describe("test universal swap handler functions", () => { const simulateAmount = "100"; const userSlippage = 1; const minimumReceive = "10000"; - const universalSwapData: UniversalSwapData = { - sender: { cosmos: testSenderAddress, evm: "0x1234", tron: "TNJksEkvvdmae8uXYkNE9XKHbTDiSQrpbf" }, - originalFromToken: oraichainTokens[0], - originalToToken: oraichainTokens[0], - simulateAmount, - simulatePrice: "0", - userSlippage, - fromAmount: toDisplay(fromAmount) - }; + class FakeUniversalSwapHandler extends UniversalSwapHandler { constructor(data?: UniversalSwapData, config?: UniversalSwapConfig) { super( @@ -327,12 +331,13 @@ describe("test universal swap handler functions", () => { fromAmount: 1 }, config ? { cosmosWallet, evmWallet, ...config } : { cosmosWallet, evmWallet }, + oraidexCommon, now ); } } - it.each<[string, CoinGeckoId, CoinGeckoId, NetworkChainId, EncodeObject[]]>([ + it.each<[string, CoinGeckoId, CoinGeckoId, string, EncodeObject[]]>([ [ "from-and-to-is-have-same-coingecko-id", "osmosis", @@ -479,12 +484,16 @@ describe("test universal swap handler functions", () => { ])( "test checkRelayerFee given token %s, chain id %s with from amount %d, is it sufficient for relayer fee?: %s", async (fromDenom, fromChainId, relayerFeeAmount, isSufficient) => { - const originalFromToken = flattenTokens.find( + const originalFromToken = oraidexCommon.flattenTokens.find( (item) => item.coinGeckoId === fromDenom && item.chainId === fromChainId ); // TODO: run tests without mocking to simulate actual swap logic - vi.spyOn(UniversalSwapHelper, "simulateSwap").mockResolvedValue({ amount: relayerFeeAmount }); - const result = await checkFeeRelayer({ + vi.spyOn(UniversalSwapHelper, "handleSimulateSwap").mockResolvedValue({ + amount: relayerFeeAmount, + displayAmount: 0 + }); + const result = await UniversalSwapHelper.checkFeeRelayer({ + oraichainTokens, originalFromToken: originalFromToken as TokenItemType, fromAmount: 1, relayerFee: { @@ -505,8 +514,12 @@ describe("test universal swap handler functions", () => { async (fromDenom, mockSimulateAmount, mockRelayerFee, isSufficient) => { const originalFromToken = oraichainTokens.find((item) => item.coinGeckoId === fromDenom); // TODO: run tests without mocking to simulate actual swap - vi.spyOn(UniversalSwapHelper, "simulateSwap").mockResolvedValue({ amount: mockSimulateAmount }); - const result = await checkFeeRelayerNotOrai({ + vi.spyOn(UniversalSwapHelper, "handleSimulateSwap").mockResolvedValue({ + amount: mockSimulateAmount, + displayAmount: 0 + }); + const result = await UniversalSwapHelper.checkFeeRelayerNotOrai({ + oraichainTokens, fromTokenInOrai: originalFromToken as TokenItemType, fromAmount: 1, relayerAmount: mockRelayerFee, @@ -516,43 +529,46 @@ describe("test universal swap handler functions", () => { } ); - it("test-getUniversalSwapToAddress", async () => { - const universalSwap = new FakeUniversalSwapHandler(); - let result = await universalSwap.getUniversalSwapToAddress("0x01", { - metamaskAddress: undefined, - tronAddress: undefined - }); - expect(result).toEqual("0x1234"); - result = await universalSwap.getUniversalSwapToAddress("cosmoshub-4", { - metamaskAddress: undefined, - tronAddress: undefined - }); - expect(result).toEqual("orai1g4h64yjt0fvzv5v2j8tyfnpe5kmnetejvfgs7g"); - result = await universalSwap.getUniversalSwapToAddress("0x2b6653dc", { - tronAddress: "TPwTVfDDvmWSawsP7Ki1t3ecSBmaFeMMXc" - }); - expect(result).toEqual("0x993d06fc97f45f16e4805883b98a6c20bab54964"); - result = await universalSwap.getUniversalSwapToAddress("0x01", { - metamaskAddress: "0x993d06fc97f45f16e4805883b98a6c20bab54964" - }); - expect(result).toEqual("0x993d06fc97f45f16e4805883b98a6c20bab54964"); - const mockTronWeb = new TronWeb("foo", "foo"); - mockTronWeb.defaultAddress.base58 = "TNJksEkvvdmae8uXYkNE9XKHbTDiSQrpbf"; - vi.spyOn(evmWallet, "tronWeb", "get").mockReturnValue(mockTronWeb); - result = await universalSwap.getUniversalSwapToAddress("0x2b6653dc", { - metamaskAddress: undefined, - tronAddress: undefined - }); - expect(result).toEqual("0x8754032ac7966a909e2e753308df56bb08dabd69"); - }); + // it("test-getUniversalSwapToAddress", async () => { + // const universalSwap = new FakeUniversalSwapHandler(); + // let result = await universalSwap.getUniversalSwapToAddress("0x01", { + // metamaskAddress: undefined, + // tronAddress: undefined + // }); + // expect(result).toEqual("0x1234"); + // result = await universalSwap.getUniversalSwapToAddress("cosmoshub-4", { + // metamaskAddress: undefined, + // tronAddress: undefined + // }); + // expect(result).toEqual("orai1g4h64yjt0fvzv5v2j8tyfnpe5kmnetejvfgs7g"); + // result = await universalSwap.getUniversalSwapToAddress("0x2b6653dc", { + // tronAddress: "TPwTVfDDvmWSawsP7Ki1t3ecSBmaFeMMXc" + // }); + // expect(result).toEqual("0x993d06fc97f45f16e4805883b98a6c20bab54964"); + // result = await universalSwap.getUniversalSwapToAddress("0x01", { + // metamaskAddress: "0x993d06fc97f45f16e4805883b98a6c20bab54964" + // }); + // expect(result).toEqual("0x993d06fc97f45f16e4805883b98a6c20bab54964"); + // const mockTronWeb = new TronWeb("foo", "foo"); + // mockTronWeb.defaultAddress.base58 = "TNJksEkvvdmae8uXYkNE9XKHbTDiSQrpbf"; + // vi.spyOn(evmWallet, "tronWeb", "get").mockReturnValue(mockTronWeb); + // result = await universalSwap.getUniversalSwapToAddress("0x2b6653dc", { + // metamaskAddress: undefined, + // tronAddress: undefined + // }); + // expect(result).toEqual("0x8754032ac7966a909e2e753308df56bb08dabd69"); + // }); it.each([ - ["0x1234", "T123456789", flattenTokens.find((t) => t.prefix === ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX)!, "0xae1ae6"], - ["0x1234", "T123456789", flattenTokens.find((t) => t.prefix !== ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX)!, "0x1234"], - ["", "", flattenTokens.find((t) => t.prefix !== ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX)!, "this-case-throw-error"] + ["0x1234", "T123456789", true, "0xae1ae6"], + ["0x1234", "T123456789", false, "0x1234"], + ["", "", false, "this-case-throw-error"] ])( "test getTranferAddress should return transferAddress correctly & throw error correctly", - (metamaskAddress: string, tronAddress: string, toToken: TokenItemType, expectedTransferAddr: string) => { + (metamaskAddress: string, tronAddress: string, isEqual, expectedTransferAddr: string) => { + const toToken = oraidexCommon.flattenTokens.find((t) => + isEqual ? t.prefix === ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX : t.prefix !== ORAI_BRIDGE_EVM_TRON_DENOM_PREFIX + )!; const universalSwap = new FakeUniversalSwapHandler({ ...universalSwapData, originalToToken: toToken @@ -571,18 +587,21 @@ describe("test universal swap handler functions", () => { ); it.each([ - ["0x1234", flattenTokens.find((t) => t.chainId !== "oraibridge-subnet-2")!, "0x38", "", ""], - ["0x1234", flattenTokens.find((t) => t.chainId === "oraibridge-subnet-2")!, "0x38", "0x12345", "oraib0x12345"], - ["0x1234", flattenTokens.find((t) => t.chainId === "oraibridge-subnet-2")!, "0x38", "", "oraib0x1234"] + ["0x1234", false, "0x38", "", ""], + ["0x1234", true, "0x38", "0x12345", "oraib0x12345"], + ["0x1234", true, "0x38", "", "oraib0x1234"] ])( "test getIbcMemo should return ibc memo correctly", ( transferAddress: string, - toToken: TokenItemType, + isEqual: boolean, originalChainId: string, recipientAddress: string, expectedIbcMemo: string ) => { + const toToken = oraidexCommon.flattenTokens.find((t) => + isEqual ? t.chainId === "oraibridge-subnet-2" : t.chainId !== "oraibridge-subnet-2" + )!; const universalSwap = new FakeUniversalSwapHandler({ ...universalSwapData, originalToToken: toToken @@ -600,7 +619,7 @@ describe("test universal swap handler functions", () => { { chainId: toToken.chainId, prefix: toToken.prefix!, - originalChainId: originalChainId as NetworkChainId + originalChainId: originalChainId as string }, recipientAddress ); @@ -608,34 +627,52 @@ describe("test universal swap handler functions", () => { } ); - it.each<[TokenItemType, TokenItemType, string, string, boolean]>([ + it.each< + [ + { chainId: string; coinGeckoId: CoinGeckoId }, + { chainId: string; coinGeckoId: CoinGeckoId }, + string, + string, + boolean + ] + >([ [ - flattenTokens.find((t) => t.chainId === "Oraichain" && t.coinGeckoId === "tether")!, - flattenTokens.find((t) => t.chainId === "0x01" && t.coinGeckoId === "oraichain-token")!, + { chainId: "Oraichain", coinGeckoId: "tether" }, + { chainId: "0x01", coinGeckoId: "oraichain-token" }, simulateAmount, channel, true ], [ - flattenTokens.find((t) => t.chainId === "Oraichain" && t.coinGeckoId === "oraichain-token")!, - flattenTokens.find((t) => t.chainId === "0x38" && t.coinGeckoId === "oraichain-token")!, + { chainId: "Oraichain", coinGeckoId: "oraichain-token" }, + { chainId: "0x38", coinGeckoId: "oraichain-token" }, simulateAmount, channel, false ] ])("test-universal-swap-checkBalanceChannelIbc-%", async (fromToken, toToken, amount, channel, willThrow) => { try { + const fromTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === fromToken.coinGeckoId && t.chainId === fromToken.chainId + )!; + + const toTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === toToken.coinGeckoId && t.chainId === toToken.chainId + )!; + await checkBalanceChannelIbc( { source: oraiPort, channel: channel, timeout: +calculateTimeoutTimestamp(IBC_TRANSFER_TIMEOUT, now) }, - fromToken, - toToken, + fromTokenInfo, + toTokenInfo, amount, client, - IBC_WASM_CONTRACT_TEST + IBC_WASM_CONTRACT_TEST, + oraidexCommon.network, + oraidexCommon.oraichainTokens ); expect(willThrow).toEqual(false); } catch (error) { @@ -644,10 +681,11 @@ describe("test universal swap handler functions", () => { }); it.each([ - [oraichainTokens.find((t) => t.coinGeckoId === "airight")!, 10000000], - [oraichainTokens.find((t) => t.coinGeckoId === "oraichain-token")!, 0] - ])("test-universal-swap-getBalanceIBCOraichain-ibc-%", async (token: TokenItemType, expectedBalance: number) => { - const mockToken = { ...token }; + ["airight", 10000000], + ["oraichain-token", 0] + ])("test-universal-swap-getBalanceIBCOraichain-ibc-%", async (token: string, expectedBalance: number) => { + const tokenInfo = oraichainTokens.find((t) => t.coinGeckoId === token)!; + const mockToken = { ...tokenInfo }; if (mockToken.contractAddress) { if (mockToken.coinGeckoId === "airight") mockToken.contractAddress = airiToken.contractAddress; } @@ -655,50 +693,73 @@ describe("test universal swap handler functions", () => { expect(balance).toEqual(expectedBalance); }); - it.each<[TokenItemType, TokenItemType, number, string, boolean]>([ + it.each< [ - oraichainTokens.find((t) => t.coinGeckoId === "oraichain-token")!, // ORAI (ORAICHAIN) - oraichainTokens.find((t) => t.coinGeckoId === "airight")!, // AIRIGHT (ORAICHAIN) + { chainId: string; coinGeckoId: CoinGeckoId }, + { chainId: string; coinGeckoId: CoinGeckoId }, + number, + string, + boolean + ] + >([ + [ + { chainId: "Oraichain", coinGeckoId: "oraichain-token" }, // ORAI (ORAICHAIN) + { chainId: "Oraichain", coinGeckoId: "airight" }, // AIRIGHT (ORAICHAIN) 0, "0", false ], [ - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x01")!, // ORAI (ETH) - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x38")!, // ORAI (BSC) + { chainId: "0x01", coinGeckoId: "oraichain-token" }, // ORAI (ETH) + { chainId: "0x38", coinGeckoId: "oraichain-token" }, // ORAI (BSC) 10000000, "10000000", true ], [ - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x01")!, // ORAI (ETH) - flattenTokens.find((t) => t.coinGeckoId === "airight" && t.chainId === "0x38")!, // AIRIGHT (BSC) + { chainId: "0x01", coinGeckoId: "oraichain-token" }, // ORAI (ETH) + { chainId: "0x38", coinGeckoId: "airight" }, // AIRIGHT (BSC) 10000000, "10000000", false ], [ - flattenTokens.find((t) => t.coinGeckoId === "pepe" && t.chainId === "0x38")!, // PEPE (BSC) - flattenTokens.find((t) => t.coinGeckoId === "pepe" && t.chainId === "Oraichain")!, // PEPE (ORAICHAIN) + { chainId: "0x38", coinGeckoId: "pepe" }, // PEPE (BSC) + { chainId: "Oraichain", coinGeckoId: "pepe" }, // PEPE (ORAICHAIN) 0, "0", false ] ])( "test-universal-swap-checkBalanceIBCOraichain", - async (from: TokenItemType, to: TokenItemType, fromAmount: number, toAmount: string, willThrow: boolean) => { + async ( + from: { chainId: string; coinGeckoId: CoinGeckoId }, + to: { chainId: string; coinGeckoId: CoinGeckoId }, + fromAmount: number, + toAmount: string, + willThrow: boolean + ) => { try { + const fromTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === from.coinGeckoId && t.chainId === from.chainId + )!; + const toTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === to.coinGeckoId && t.chainId === to.chainId + )!; + vi.spyOn(UniversalSwapHelper, "getBalanceIBCOraichain").mockReturnValue( new Promise((resolve) => resolve({ balance: +toAmount })) ); checkBalanceIBCOraichain( - to, - from, + toTokenInfo, + fromTokenInfo, fromAmount, simulateAmount, ics20Contract.client, - ics20Contract.contractAddress + ics20Contract.contractAddress, + oraidexCommon.network, + oraidexCommon.oraichainTokens ); expect(willThrow).toEqual(false); } catch (error) { @@ -733,7 +794,7 @@ describe("test universal swap handler functions", () => { expect(result).toEqual(expectedFunction); }); - it.each<[string, CoinGeckoId, CoinGeckoId, NetworkChainId, any, string, any, any]>([ + it.each<[string, CoinGeckoId, CoinGeckoId, string, any, string, any, any]>([ [ "swap-tokens-that-both-belong-to-Oraichain-from-is-native-token", "oraichain-token", @@ -1098,22 +1159,28 @@ describe("test universal swap handler functions", () => { } }); - it.each<[CoinGeckoId, CoinGeckoId, string, string]>([ - ["oraichain-token", "oraichain-token", "1000000", "1000000"], - ["tron", "airight", "100000", "100000"] - ])( - "test simulateSwap-given-fromid-%s-toid-%s-input-amount-%d-returns-%d", - async (fromCoingeckoId, toCoingeckoId, amount, expectedSimulateData) => { - const fromToken = oraichainTokens.find((t) => t.coinGeckoId === fromCoingeckoId); - const toToken = oraichainTokens.find((t) => t.coinGeckoId === toCoingeckoId); - const routerClient = new OraiswapRouterClient(client, testSenderAddress, "foo"); - vi.spyOn(routerClient, "simulateSwapOperations").mockReturnValue(new Promise((resolve) => resolve({ amount }))); - const [fromInfo, toInfo] = [toTokenInfo(fromToken!), toTokenInfo(toToken!)]; - const query = { fromInfo, toInfo, amount, routerClient }; - const simulateData = await simulateSwap(query); - expect(simulateData.amount).toEqual(expectedSimulateData); - } - ); + // it.each<[CoinGeckoId, CoinGeckoId, number, string]>([ + // ["oraichain-token", "oraichain-token", 1, "1000000"], + // ["tron", "airight", 0.1, "100000"] + // ])( + // "test handleSimulateSwap-given-fromid-%s-toid-%s-input-amount-%d-returns-%d", + // async (fromCoingeckoId, toCoingeckoId, amount, expectedSimulateData) => { + // const fromToken = oraichainTokens.find((t) => t.coinGeckoId === fromCoingeckoId); + // const toToken = oraichainTokens.find((t) => t.coinGeckoId === toCoingeckoId); + // const routerClient = new OraiswapRouterClient(client, testSenderAddress, "foo"); + // vi.spyOn(routerClient, "simulateSwapOperations").mockReturnValue( + // new Promise((resolve) => resolve({ amount: toAmount(amount).toString() })) + // ); + // const [originalFromInfo, originalToInfo] = [toTokenInfo(fromToken!), toTokenInfo(toToken!)]; + // const simulateData = await UniversalSwapHelper.handleSimulateSwap({ + // originalFromInfo, + // originalToInfo, + // originalAmount: amount, + // routerClient + // }); + // expect(simulateData.amount).toEqual(expectedSimulateData); + // } + // ); it.each<[CoinGeckoId, CoinGeckoId, string, string]>([ ["oraichain-token", "oraichain-token", "1000000", "1000000"], @@ -1144,11 +1211,9 @@ describe("test universal swap handler functions", () => { ])( "test handleSimulateSwap", async (isSupportedNoPoolSwapEvmRes, isEvmSwappableRes, useSmartRoute, expectedSimulateAmount) => { - const simulateSwapSpy = vi.spyOn(UniversalSwapHelper, "simulateSwap"); const simulateSwapEvmSpy = vi.spyOn(UniversalSwapHelper, "simulateSwapEvm"); const simulateSwapUseSmartRoute = vi.spyOn(UniversalSwapHelper, "querySmartRoute"); - simulateSwapSpy.mockResolvedValue({ amount: "1" }); simulateSwapEvmSpy.mockResolvedValue({ amount: "2", displayAmount: 2 }); simulateSwapUseSmartRoute.mockResolvedValue({ returnAmount: "3", swapAmount: "3", routes: [] }); @@ -1156,11 +1221,13 @@ describe("test universal swap handler functions", () => { const isEvmSwappableSpy = vi.spyOn(UniversalSwapHelper, "isEvmSwappable"); isSupportedNoPoolSwapEvmSpy.mockReturnValue(isSupportedNoPoolSwapEvmRes); isEvmSwappableSpy.mockReturnValue(isEvmSwappableRes); - const simulateData = await handleSimulateSwap({ + const simulateData = await UniversalSwapHelper.handleSimulateSwap({ originalFromInfo: oraichainTokens[0], originalToInfo: oraichainTokens[1], originalAmount: 0, - routerClient: new OraiswapRouterQueryClient(client, "") + routerClient: new OraiswapRouterQueryClient(client, ""), + flattenTokens: oraidexCommon.flattenTokens, + oraichainTokens: oraidexCommon.oraichainTokens }); expect(simulateData.amount).toEqual(expectedSimulateAmount); } @@ -1198,11 +1265,21 @@ describe("test universal swap handler functions", () => { expect(routesFlatten).toEqual(flattenAlphaSmartRouters); }); - it.each<[string, any, any, number, string, number, string]>([ + it.each< + [ + string, + { chainId: string; coinGeckoId: CoinGeckoId }, + { chainId: string; coinGeckoId: CoinGeckoId }, + number, + string, + number, + string + ] + >([ [ "from-orai-bnb-to-orai-oraichain", - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x38"), // 18 - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "Oraichain"), // 6 + { chainId: "0x38", coinGeckoId: "oraichain-token" }, // 18 + { chainId: "Oraichain", coinGeckoId: "oraichain-token" }, // 6 1, (1e5).toString(), 0.1, @@ -1210,8 +1287,8 @@ describe("test universal swap handler functions", () => { ], [ "from-orai-bnb-to-orai-oraichain", - flattenTokens.find((t) => t.coinGeckoId === "oraichain-token" && t.chainId === "0x38"), // 18 - flattenTokens.find((t) => t.coinGeckoId === "tether" && t.chainId === "Oraichain"), // 6 + { chainId: "0x38", coinGeckoId: "oraichain-token" }, // 18 + { chainId: "Oraichain", coinGeckoId: "tether" }, // 6 1, (1e5).toString(), 0.1, @@ -1223,13 +1300,20 @@ describe("test universal swap handler functions", () => { const isHandleSimulateSwap = vi.spyOn(UniversalSwapHelper, "handleSimulateSwap"); isHandleSimulateSwap.mockReturnValue(new Promise((resolve) => resolve({ amount: "600000", displayAmount: 0.6 }))); + const originalToTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === originalToToken.coinGeckoId && t.chainId === originalToToken.chainId + )!; + const originalFromTokenInfo = oraidexCommon.flattenTokens.find( + (t) => t.coinGeckoId === originalFromToken.coinGeckoId && t.chainId === originalFromToken.chainId + )!; + const universalSwap = new FakeUniversalSwapHandler({ ...universalSwapData, userSlippage: 1, bridgeFee, fromAmount, - originalToToken, - originalFromToken, + originalToToken: originalToTokenInfo, + originalFromToken: originalFromTokenInfo, simulateAmount: (fromAmount * 1e6).toString(), relayerFee: { relayerAmount: relayerFee, diff --git a/packages/universal-swap/tests/msg/msgs.spec.ts b/packages/universal-swap/tests/msg/msgs.spec.ts index fc93cb18..ed7eb132 100644 --- a/packages/universal-swap/tests/msg/msgs.spec.ts +++ b/packages/universal-swap/tests/msg/msgs.spec.ts @@ -1,10 +1,21 @@ import { expect, afterAll, beforeAll, describe, it, vi } from "vitest"; -import { calculateTimeoutTimestamp, generateError, IBC_TRANSFER_TIMEOUT } from "@oraichain/oraidex-common"; +import { + calculateTimeoutTimestamp, + generateError, + IBC_TRANSFER_TIMEOUT, + OraidexCommon +} from "@oraichain/oraidex-common"; import { Action } from "@oraichain/osor-api-contracts-sdk/src/EntryPoint.types"; import { generateMsgSwap } from "../../src/msg/msgs"; import { Memo } from "../../src/proto/universal_swap_memo"; describe("test build swap msg", () => { + let oraidexCommon: OraidexCommon; + + beforeAll(async () => { + oraidexCommon = await OraidexCommon.load(); + }); + it("Test build universal swap msg from cosmos-base ecosystem", () => { let route = { swapAmount: "10000000", @@ -79,7 +90,7 @@ describe("test build swap msg", () => { // case 1: missing receiver address try { - let res = generateMsgSwap(route, 0.1, {}); + let res = generateMsgSwap(route, 0.1, {}, oraidexCommon); } catch (err) { expect(err).toEqual(generateError(`Missing receiver when build msg in osmosis-1`)); } @@ -87,16 +98,26 @@ describe("test build swap msg", () => { // case 2: missing current chain address try { - let res = generateMsgSwap(route, 0.1, { Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2" }); + let res = generateMsgSwap( + route, + 0.1, + { Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2" }, + oraidexCommon + ); } catch (err) { expect(err).toEqual(generateError(`Missing address of osmosis-1`)); } - let res = generateMsgSwap(route, 0.1, { - Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", - "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", - "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t" - }); + let res = generateMsgSwap( + route, + 0.1, + { + Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", + "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", + "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t" + }, + oraidexCommon + ); expect(res).toEqual({ typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", value: { @@ -263,13 +284,18 @@ describe("test build swap msg", () => { ] }; - let res = generateMsgSwap(route, 0.1, { - "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", - "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", - Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", - "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", - "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t" - }); + let res = generateMsgSwap( + route, + 0.1, + { + "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", + "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", + Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", + "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", + "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t" + }, + oraidexCommon + ); expect(res).toEqual({ typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", @@ -412,14 +438,19 @@ describe("test build swap msg", () => { ] }; - let res = generateMsgSwap(route, 0.1, { - "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", - "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", - Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", - "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", - "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t", - "noble-1": "noble1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y8z5tfh" - }); + let res = generateMsgSwap( + route, + 0.1, + { + "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", + "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", + Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", + "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", + "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t", + "noble-1": "noble1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y8z5tfh" + }, + oraidexCommon + ); expect(res).toEqual({ typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", @@ -541,14 +572,19 @@ describe("test build swap msg", () => { ] }; - let res = generateMsgSwap(route, 0.1, { - "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", - "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", - Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", - "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", - "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t", - "noble-1": "noble1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y8z5tfh" - }); + let res = generateMsgSwap( + route, + 0.1, + { + "0x38": "0x8c7E0A841269a01c0Ab389Ce8Fb3Cf150A94E797", + "oraibridge-subnet-2": "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf", + Oraichain: "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2", + "cosmoshub-4": "cosmos1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y0ppr3e", + "osmosis-1": "osmo1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y86jn8t", + "noble-1": "noble1hvr9d72r5um9lvt0rpkd4r75vrsqtw6y8z5tfh" + }, + oraidexCommon + ); expect(res).toEqual({ typeUrl: "/ibc.applications.transfer.v1.MsgTransfer", diff --git a/packages/universal-swap/tests/msg/oraichain-msg.spec.ts b/packages/universal-swap/tests/msg/oraichain-msg.spec.ts index a983d14a..415b4476 100644 --- a/packages/universal-swap/tests/msg/oraichain-msg.spec.ts +++ b/packages/universal-swap/tests/msg/oraichain-msg.spec.ts @@ -5,7 +5,8 @@ import { generateError, IBC_TRANSFER_TIMEOUT, IBC_WASM_CONTRACT, - TON_CONTRACT + TON_CONTRACT, + OraidexCommon } from "@oraichain/oraidex-common"; import { Action } from "@oraichain/osor-api-contracts-sdk/src/EntryPoint.types"; import { OsmosisMsg } from "../../build/msg"; @@ -14,7 +15,12 @@ import { toBinary } from "@cosmjs/cosmwasm-stargate"; import { MsgExecuteContract } from "cosmjs-types/cosmwasm/wasm/v1/tx"; import { toUtf8 } from "@cosmjs/encoding"; +let oraidexCommon; describe("test build oraichain msg", () => { + beforeAll(async () => { + oraidexCommon = await OraidexCommon.load(); + }); + const validPath = { chainId: "Oraichain", tokenIn: "orai", @@ -116,7 +122,7 @@ describe("test build oraichain msg", () => { "" ] ])("oraichain test get post action", (bridgeInfo, expectedAction, expectedError) => { - let oraichain = new OraichainMsg(validPath, "1", receiver, currentAddress); + let oraichain = new OraichainMsg(validPath, "1", receiver, currentAddress, undefined, oraidexCommon); try { let postAction = oraichain.getPostAction(bridgeInfo); expect(postAction).toEqual(expectedAction); @@ -127,7 +133,7 @@ describe("test build oraichain msg", () => { it("Valid path with swap + ibc bridge", () => { const nextMemo = "{}"; - let oraichainMsg = new OraichainMsg(validPath, "1", receiver, currentAddress, nextMemo); + let oraichainMsg = new OraichainMsg(validPath, "1", receiver, currentAddress, nextMemo, oraidexCommon); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual({ @@ -251,7 +257,8 @@ describe("test build oraichain msg", () => { } ] }; - let oraichainMsg = new OraichainMsg(validPathBridgeOnly, "1", receiver, currentAddress, nextMemo); + + let oraichainMsg = new OraichainMsg(validPathBridgeOnly, "1", receiver, currentAddress, nextMemo, oraidexCommon); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual({ @@ -348,7 +355,7 @@ describe("test build oraichain msg", () => { } ] }; - let oraichainMsg = new OraichainMsg(validPathTonBridgeOnly, "1", receiver, currentAddress, nextMemo); + let oraichainMsg = new OraichainMsg(validPathTonBridgeOnly, "1", receiver, currentAddress, nextMemo, oraidexCommon); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual({ @@ -480,7 +487,7 @@ describe("test build oraichain msg", () => { } ] }; - let oraichainMsg = new OraichainMsg(validPathSwapOnly, "1", receiver, currentAddress, nextMemo); + let oraichainMsg = new OraichainMsg(validPathSwapOnly, "1", receiver, currentAddress, nextMemo, oraidexCommon); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual(undefined); @@ -602,7 +609,16 @@ describe("test build oraichain msg", () => { let receiver = "0x0000000000000000000000000000000000000000"; const currentAddress = "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2"; const oraiBridgeAddr = "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf"; - let oraichainMsg = new OraichainMsg(validPath, "1", receiver, currentAddress, nextMemo, "oraib", oraiBridgeAddr); + let oraichainMsg = new OraichainMsg( + validPath, + "1", + receiver, + currentAddress, + nextMemo, + oraidexCommon, + "oraib", + oraiBridgeAddr + ); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual({ @@ -729,7 +745,16 @@ describe("test build oraichain msg", () => { let receiver = "0x0000000000000000000000000000000000000000"; const currentAddress = "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2"; const oraiBridgeAddr = "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf"; - let oraichainMsg = new OraichainMsg(invalidPath, "1", receiver, currentAddress, nextMemo, "oraib", oraiBridgeAddr); + let oraichainMsg = new OraichainMsg( + invalidPath, + "1", + receiver, + currentAddress, + nextMemo, + oraidexCommon, + "oraib", + oraiBridgeAddr + ); try { oraichainMsg.genMemoAsMiddleware(); @@ -768,7 +793,16 @@ describe("test build oraichain msg", () => { const currentAddress = "orai1hvr9d72r5um9lvt0rpkd4r75vrsqtw6yujhqs2"; const oraiBridgeAddr = "oraib1hvr9d72r5um9lvt0rpkd4r75vrsqtw6ytnnvpf"; let destPrefix = "oraib"; - let oraichainMsg = new OraichainMsg(validPath, "1", receiver, currentAddress, nextMemo, destPrefix, oraiBridgeAddr); + let oraichainMsg = new OraichainMsg( + validPath, + "1", + receiver, + currentAddress, + nextMemo, + oraidexCommon, + destPrefix, + oraiBridgeAddr + ); let [swapOps, bridgeInfo] = oraichainMsg.getSwapAndBridgeInfo(); expect(bridgeInfo).toEqual({ @@ -864,7 +898,15 @@ describe("test build oraichain msg", () => { const destPrefix = "oraib"; // missing oraibridge address try { - let oraichainMsg = new OraichainMsg(validPath, "1", receiver, currentAddress, nextMemo, destPrefix); + let oraichainMsg = new OraichainMsg( + validPath, + "1", + receiver, + currentAddress, + nextMemo, + oraidexCommon, + destPrefix + ); oraichainMsg.genExecuteMsg(); } catch (err) { expect(err).toEqual(generateError(`Missing prefix or Obridge address for bridge to EVM`)); @@ -878,6 +920,7 @@ describe("test build oraichain msg", () => { receiver, currentAddress, nextMemo, + oraidexCommon, undefined, oraiBridgeAddr ); diff --git a/packages/universal-swap/tests/test-common.ts b/packages/universal-swap/tests/test-common.ts index 4ee07b8a..d1b36915 100644 --- a/packages/universal-swap/tests/test-common.ts +++ b/packages/universal-swap/tests/test-common.ts @@ -21,11 +21,11 @@ export const deployToken = async ( }: { symbol: string; name: string; decimals?: number; initial_balances?: Cw20Coin[] } ): Promise => { return new OraiswapTokenClient( - client, + client as any, testSenderAddress, ( await oraidexArtifacts.deployContract( - client, + client as any, testSenderAddress, { @@ -47,7 +47,7 @@ export const deployIcs20Token = async ( { swap_router_contract, gov_contract = testSenderAddress }: { gov_contract?: string; swap_router_contract: string } ): Promise => { const { contractAddress } = await commonArtifacts.deployContract( - client, + client as any, testSenderAddress, { allowlist: [], @@ -58,5 +58,5 @@ export const deployIcs20Token = async ( "cw-ics20-latest", "cw-ics20-latest" ); - return new CwIcs20LatestClient(client, testSenderAddress, contractAddress); + return new CwIcs20LatestClient(client as any, testSenderAddress, contractAddress); }; diff --git a/packages/universal-swap/tsconfig.json b/packages/universal-swap/tsconfig.json index fa0134db..7436d8bd 100644 --- a/packages/universal-swap/tsconfig.json +++ b/packages/universal-swap/tsconfig.json @@ -1,15 +1,11 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "baseUrl": ".", - "outDir": "build", - "declaration": true, - "rootDir": "src" - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "node_modules/" - ] -} \ No newline at end of file + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "declaration": true, + "rootDir": "src" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules/", "build/"] +} diff --git a/patches/@cosmjs+cosmwasm-stargate+0.32.4.patch b/patches/@cosmjs+cosmwasm-stargate+0.32.4.patch index 12b35992..4da5cf7c 100644 --- a/patches/@cosmjs+cosmwasm-stargate+0.32.4.patch +++ b/patches/@cosmjs+cosmwasm-stargate+0.32.4.patch @@ -62,3 +62,19 @@ index e5bf448..878f7e4 100644 // Use this service to get easy typed access to query methods // This cannot be used for proof verification const queryService = new query_1.QueryClientImpl(rpc); +diff --git a/node_modules/@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient.js b/node_modules/@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient.js +index 6eb95bb..24d3038 100644 +--- a/node_modules/@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient.js ++++ b/node_modules/@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient.js +@@ -397,7 +397,10 @@ class SigningCosmWasmClient extends cosmwasmclient_1.CosmWasmClient { + throw new Error("Failed to retrieve account from signer"); + } + const pubkey = (0, proto_signing_1.encodePubkey)((0, amino_1.encodeSecp256k1Pubkey)(accountFromSigner.pubkey)); +- const signMode = signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON; ++ let signMode = signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON; ++ if (this.signer.signEip191) { ++ signMode = signing_1.SignMode.SIGN_MODE_EIP_191; ++ } + const msgs = messages.map((msg) => this.aminoTypes.toAmino(msg)); + const signDoc = (0, amino_1.makeSignDoc)(msgs, fee, chainId, memo, accountNumber, sequence, timeoutHeight); + const { signature, signed } = await this.signer.signAmino(signerAddress, signDoc); diff --git a/yarn.lock b/yarn.lock index 89f07d01..0440aea7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1349,7 +1349,7 @@ "@noble/hashes" "^1.0.0" protobufjs "^6.8.8" -"@cosmjs/amino@0.31.3", "@cosmjs/amino@^0.31.0", "@cosmjs/amino@^0.31.3": +"@cosmjs/amino@0.31.3", "@cosmjs/amino@^0.31.3": version "0.31.3" resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.31.3.tgz#0f4aa6bd68331c71bd51b187fa64f00eb075db0a" integrity sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw== @@ -1379,7 +1379,7 @@ "@cosmjs/math" "^0.32.4" "@cosmjs/utils" "^0.32.4" -"@cosmjs/cosmwasm-stargate@0.31.3", "@cosmjs/cosmwasm-stargate@^0.31.0": +"@cosmjs/cosmwasm-stargate@0.31.3": version "0.31.3" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.31.3.tgz#13066822f111832d57c2c5acc9e697ed389713f8" integrity sha512-Uv9TmCn3650gdFeZm7SEfUZF3uX3lfJfFhXOk6I2ZLr/FrKximnlb+vwAfZaZnWYvlA7qrKtHIjeRNHvT23zcw== @@ -1412,7 +1412,7 @@ cosmjs-types "^0.9.0" pako "^2.0.2" -"@cosmjs/crypto@0.31.3", "@cosmjs/crypto@^0.31.0", "@cosmjs/crypto@^0.31.3": +"@cosmjs/crypto@0.31.3", "@cosmjs/crypto@^0.31.3": version "0.31.3" resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.31.3.tgz#c752cb6d682fdc735dcb45a2519f89c56ba16c26" integrity sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ== @@ -1460,7 +1460,7 @@ bech32 "^1.1.4" readonly-date "^1.0.0" -"@cosmjs/encoding@^0.31.0", "@cosmjs/encoding@^0.31.3": +"@cosmjs/encoding@^0.31.3": version "0.31.3" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.31.3.tgz#2519d9c9ae48368424971f253775c4580b54c5aa" integrity sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg== @@ -3744,10 +3744,10 @@ resolved "https://registry.yarnpkg.com/@oraichain/common-contracts-sdk/-/common-contracts-sdk-1.0.31.tgz#595f93b168438d69d64896909b37855c9afc92fb" integrity sha512-s8H20RXy5gCnu3DnM7L5ClQyj2mdQpbSBpZrXCpIAX9qY0LKsDdZG3sYaDQ8+VN333jz9Pp/qGWdFSYD+6PBsg== -"@oraichain/common@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@oraichain/common/-/common-1.2.4.tgz#1a28dc288f3ada9d802541454585839e5c275deb" - integrity sha512-/2TIpqDrJKgh/gb50s+sz5lhsffsj6QOVrJh1QrlIsRlup3yQnahm06vwsiVOX75rbdAMO5c7tJiXjKkHbfkww== +"@oraichain/common@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@oraichain/common/-/common-1.2.6.tgz#7b2f4bed1a7a93e54190a8409e289f6ebab7ba06" + integrity sha512-Ten4zmHnunmXtE4zBPO2e4zENvr/Iv1nOzDpZcdCoFJHd7Xe4JuKMWuDBfDy9FWW9AlMbnkcKB7jqaLq4uyP3A== dependencies: "@keplr-wallet/types" "0.12.141" axios "0.21.4" @@ -3757,31 +3757,59 @@ ethers "^5.5.1" lodash "^4.17.21" -"@oraichain/cosmwasm-vm-js@^0.2.82": - version "0.2.82" - resolved "https://registry.yarnpkg.com/@oraichain/cosmwasm-vm-js/-/cosmwasm-vm-js-0.2.82.tgz#3744951e64f57ca12925dccbd3e62f19d0d0932e" - integrity sha512-gUufkBuPsZXiSSWC3rXuHQGPs2utpYibItw2n+AzCcLT4Fnd7pHPIAcHc8fsoQIrf1MCO6I5TcIqT9hmEqf5PA== +"@oraichain/common@1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@oraichain/common/-/common-1.2.7.tgz#5063b20967eac14b5fc94e75f02afa6685565507" + integrity sha512-yOaEpjxtYwGkOxzSiqYwULfK0KSGdBj0ziQLZjQhM6yhW3MzTK70nAORW64ATKomSlBQFy9I/6MFsGkQBHiv3w== + dependencies: + "@keplr-wallet/types" "0.12.141" + axios "0.21.4" + axios-extensions "3.1.6" + bech32 "^1.1.4" + cosmjs-types "^0.9.0" + ethers "^5.5.1" + lodash "^4.17.21" + +"@oraichain/common@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@oraichain/common/-/common-1.2.0.tgz#201dddcff7bbb0dd90a04cacf82dc3f6b9480788" + integrity sha512-gMTBSkLtHOMUfC5d3VJmEUtN17z5wL2YUrHLXCTcE6VA/K8nZ4jRt8yoO4JU/Lzy8LhZecQ2vM8r6kgLUpg8lw== + dependencies: + "@keplr-wallet/types" "0.12.141" + axios "0.21.4" + axios-extensions "3.1.6" + bech32 "^1.1.4" + cosmjs-types "^0.8.0" + ethers "^5.5.1" + lodash "^4.17.21" + +"@oraichain/cosmwasm-vm-js@^0.2.91": + version "0.2.91" + resolved "https://registry.yarnpkg.com/@oraichain/cosmwasm-vm-js/-/cosmwasm-vm-js-0.2.91.tgz#3498cc8ff564dd12cc60af841b0535a371e51026" + integrity sha512-9kJ0PX9Rlyk4eJnqWxXupDHfDvFKIRbgn321nan1Ddv5PpiL3p25kX11XIaoF+bhHi4dpXnccjEa0H/+GD6Erw== dependencies: - "@cosmjs/amino" "^0.31.0" - "@cosmjs/crypto" "^0.31.0" - "@cosmjs/encoding" "^0.31.0" + "@cosmjs/amino" "^0.32.4" + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/encoding" "^0.32.4" "@oraichain/immutable" "^4.3.9" "@oraichain/wasm-json-toolkit" "^1.0.24" bech32 "1.1.4" elliptic "^6.5.4" secp256k1 "^4.0.3" -"@oraichain/cw-simulate@^2.8.68": - version "2.8.79" - resolved "https://registry.yarnpkg.com/@oraichain/cw-simulate/-/cw-simulate-2.8.79.tgz#f2d84595dfac52d108f2465f33df210677d31330" - integrity sha512-fkjF+L9BqKvu2SQGd5nYaL9+IdypV42PdBKnH9v8jnu+ixaoDm0cZ70rV759TsXL0T9/69FI5HMC+qdhDYW2VA== +"@oraichain/cw-simulate@^2.8.108": + version "2.8.108" + resolved "https://registry.yarnpkg.com/@oraichain/cw-simulate/-/cw-simulate-2.8.108.tgz#10032f32c52489d47ef3672f05fcc56ccfe73dff" + integrity sha512-xSgWyObUqmZldkHpv0Bf1sOVDboavAkxIXdXuH6AR58NLFAemEZcyW3EZnhC8nl7dKpvXiDSjGfpkZFPmiqOcw== dependencies: - "@cosmjs/amino" "^0.31.0" - "@cosmjs/cosmwasm-stargate" "^0.31.0" - "@cosmjs/crypto" "^0.31.0" - "@cosmjs/encoding" "^0.31.0" + "@cosmjs/amino" "^0.32.4" + "@cosmjs/cosmwasm-stargate" "^0.32.4" + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/encoding" "^0.32.4" + "@cosmjs/stargate" "^0.32.4" "@kiruse/serde" "^0.8.0-rc.6" - "@oraichain/cosmwasm-vm-js" "^0.2.82" + "@oraichain/common" "^1.2.0" + "@oraichain/cosmwasm-vm-js" "^0.2.91" eventemitter3 "^5.0.0" protobufjs "^7.2.3" ts-results "^3.3.0" @@ -3792,22 +3820,55 @@ resolved "https://registry.yarnpkg.com/@oraichain/immutable/-/immutable-4.3.9.tgz#ff8d5a7b39b5b01f3f72a902cffbfea32ccb20c3" integrity sha512-INpHnhL970OCkR7I71Kssb2aLl2l4Y/x8W6FlyRO0KmC8GHjxc/hlNB1t44BiI7lkOYmcWMRQoC8dwParsp1RQ== +"@oraichain/oraidex-common@^1.1.34": + version "1.1.34" + resolved "https://registry.yarnpkg.com/@oraichain/oraidex-common/-/oraidex-common-1.1.34.tgz#257d25408450c438dc2bf0870fa8de9125af92ed" + integrity sha512-3PzjIS7+QlhSl/5w1NDXr5hZ8LXgJP0IqMWK/ZwJNM7yySeWRui6pwzFwariW2AQ/raU/z1Umr1Bh13idfeQ4Q== + dependencies: + "@cosmjs/amino" "^0.32.4" + "@cosmjs/cosmwasm-stargate" "^0.32.4" + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/proto-signing" "^0.32.4" + "@cosmjs/stargate" "^0.32.4" + "@cosmjs/tendermint-rpc" "^0.32.4" + "@ethersproject/providers" "^5.0.10" + "@injectivelabs/sdk-ts" "1.12.1" + "@keplr-wallet/types" "^0.11.38" + "@oraichain/oraidex-contracts-sdk" latest + axios "1.7.2" + axios-extensions "3.1.7" + bignumber.js "^9.1.2" + cosmjs-types "^0.9.0" + ethers "^5.0.15" + tronweb "6.0.0-beta.4" + +"@oraichain/oraidex-common@^1.1.6": + version "1.1.40" + resolved "https://registry.yarnpkg.com/@oraichain/oraidex-common/-/oraidex-common-1.1.40.tgz#406958661ed9d5cd686e03c5f186e0d7ff862375" + integrity sha512-ZOK94Hb0HcMkQamcwuZPs1pzUgLMjIYxy76sLYBsYEngRccb1PlAmALbYGMuqKceYhTdzN0hAVJceC1rKFYLHg== + dependencies: + "@cosmjs/amino" "^0.32.4" + "@cosmjs/cosmwasm-stargate" "^0.32.4" + "@cosmjs/crypto" "^0.32.4" + "@cosmjs/proto-signing" "^0.32.4" + "@cosmjs/stargate" "^0.32.4" + "@cosmjs/tendermint-rpc" "^0.32.4" + "@ethersproject/providers" "^5.0.10" + "@injectivelabs/sdk-ts" "1.12.1" + "@keplr-wallet/types" "^0.11.38" + "@oraichain/oraidex-contracts-sdk" latest + axios "1.7.2" + axios-extensions "3.1.7" + bignumber.js "^9.1.2" + cosmjs-types "^0.9.0" + ethers "^5.0.15" + tronweb "6.0.0-beta.4" + "@oraichain/oraidex-contracts-sdk@latest": version "1.0.44" resolved "https://registry.yarnpkg.com/@oraichain/oraidex-contracts-sdk/-/oraidex-contracts-sdk-1.0.44.tgz#9ff41ec388dd92ba112c2eef545d11fd6e18c684" integrity sha512-fMY/QOzO/afPlAVkLGH1bcpJTs6V/URrJju2r4UoE9f5HUWC/6OC6+H5dWuIgq26frp8wjH23mNCQAlmHzji8g== -"@oraichain/oraidex-universal-swap@1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@oraichain/oraidex-universal-swap/-/oraidex-universal-swap-1.0.14.tgz#fd4b60e7cfc21984dbaa14a7b9a2c560f02da37d" - integrity sha512-45tq+ywD/xhP5IHXu5+KYfTJ3II1PSUWhaLEEkTxQyhhSnHatS7uose7UwSQkZc1VW7oxNdAh0Mq9yI69dG7Lg== - dependencies: - "@oraichain/oraidex-common" "^1.0.10" - "@oraichain/oraidex-contracts-sdk" "^1.0.24" - bech32 "1.1.4" - ethers "^5.0.15" - tronweb "5.3.0" - "@oraichain/osor-api-contracts-sdk@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@oraichain/osor-api-contracts-sdk/-/osor-api-contracts-sdk-1.0.2.tgz#8aec43cfdb2df93cfa50538779f8eee550b94738"