diff --git a/.github/workflows/publish_package.yml b/.github/workflows/publish_package.yml new file mode 100644 index 00000000..382768ee --- /dev/null +++ b/.github/workflows/publish_package.yml @@ -0,0 +1,64 @@ +name: publish_package + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [main] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + # This workflow contains 1 job called "build" + 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 Osor API Contracts Sdk + id: publish-osor-api-contracts-sdk + continue-on-error: true + run: yarn deploy contracts-sdk + env: + CI: false + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: send result via discord + uses: appleboy/discord-action@master + with: + webhook_id: ${{ secrets.WEBHOOK_ID }} + webhook_token: ${{ secrets.WEBHOOK_TOKEN }} + username: "GitBot" + message: "Repo osor-api-contracts-sdk has just published. result: ${{ steps.publish.outcome }}." diff --git a/.gitignore b/.gitignore index ef06be0c..ebb46d8b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,33 @@ NOTICE # Python venv venv .venv -.env \ No newline at end of file +.env + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +.yarn + +dist +build \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index edcfa9bc..f7ada0fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,9 +21,9 @@ checksum = "9a03eb4d55fa21466cac727930be07f82581223ee04bcaf61f934e98b7ecb859" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "astroport" @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base16ct" @@ -114,9 +114,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -144,18 +144,18 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" dependencies = [ "proc-macro2", "quote", @@ -192,12 +192,11 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.5" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd50718a2b6830ce9eb5d465de5a018a12e71729d66b70807ce97e6dd14f931d" +checksum = "58535cbcd599b3c193e3967c8292fe1dbbb5de7c2a2d87380661091dd4744044" dependencies = [ "digest 0.10.7", - "ecdsa", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -206,18 +205,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.5" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "242e98e7a231c122e08f300d9db3262d1007b51758a8732cd6210b3e9faa4f3a" +checksum = "a8e07de16c800ac82fd188d055ecdb923ead0cf33960d3350089260bb982c09f" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.5" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7879036156092ad1c22fe0d7316efc5a5eceec2bc3906462a2560215f2a2f929" +checksum = "93d388adfa9cb449557a92e9318121ac1a481fc4f599213b03a5b62699b403b4" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -228,9 +227,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.5" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb57855fbfc83327f8445ae0d413b1a05ac0d68c396ab4d122b2abd7bb82cb6" +checksum = "2411b389e56e6484f81ba955b758d02522d620c98fc960c4bd2251d48b7aa19f" dependencies = [ "proc-macro2", "quote", @@ -239,9 +238,9 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.5" +version = "1.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" +checksum = "c21fde95ccd20044a23c0ac6fd8c941f3e8c158169dc94b5aa6491a2d9551a8d" dependencies = [ "base64", "bech32 0.9.1", @@ -271,9 +270,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -569,7 +568,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -612,7 +611,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -980,9 +979,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "k256" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa", @@ -994,9 +993,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "lido-satellite" @@ -1011,6 +1010,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + [[package]] name = "neutron-proto" version = "0.1.1" @@ -1263,7 +1268,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1316,9 +1321,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1340,9 +1345,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "regex-automata", "regex-syntax", @@ -1375,9 +1380,9 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -1415,7 +1420,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1440,9 +1445,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1485,13 +1490,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1502,16 +1507,17 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1735,6 +1741,7 @@ dependencies = [ "dexter-weighted-pool", "oraiswap 0.2.0 (git+https://github.com/oraichain/oraiswap.git?rev=843b39ca6c02ae8f2de628f4ddd444173d4de3ba)", "oraiswap-v3", + "serde-json-wasm 0.5.2", "skip", "test-case", "thiserror", @@ -1838,7 +1845,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1869,9 +1876,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -1932,7 +1939,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -1943,28 +1950,28 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", "test-case-core", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.79", ] [[package]] @@ -2016,21 +2023,21 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" diff --git a/contracts-sdk/package.json b/contracts-sdk/package.json new file mode 100644 index 00000000..8af35c8d --- /dev/null +++ b/contracts-sdk/package.json @@ -0,0 +1,23 @@ +{ + "name": "@oraichain/osor-api-contracts-sdk", + "version": "1.0.2", + "main": "build/index.js", + "files": [ + "build/", + "@types", + "src/**/*.ts", + "@types/**/*.ts" + ], + "scripts": { + "build": "tsc -p tsconfig.json", + "build:test": "tsc --project tsconfig.json", + "deploy": "yarn publish --access public" + }, + "license": "MIT", + "dependencies": { + "@cosmjs/amino": "0.31.3", + "@cosmjs/cosmwasm-stargate": "0.31.3", + "@cosmjs/crypto": "0.31.3", + "@cosmjs/proto-signing": "0.31.3" + } +} diff --git a/contracts-sdk/src/EntryPoint.client.ts b/contracts-sdk/src/EntryPoint.client.ts new file mode 100644 index 00000000..b323dbfa --- /dev/null +++ b/contracts-sdk/src/EntryPoint.client.ts @@ -0,0 +1,293 @@ +/** +* This file was automatically generated by @oraichain/ts-codegen@0.35.9. +* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, +* and run the @oraichain/ts-codegen generate command to regenerate this file. +*/ + +import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { StdFee } from "@cosmjs/amino"; +import {Uint128, Binary, Asset, Addr, Cw20ReceiveMsg, Coin, Cw20Coin, SwapOperation, IbcInfo, IbcFee, TransferBackMsg, Route} from "./types"; +import {InstantiateMsg, SwapVenue, ExecuteMsg, Action, Swap, Affiliate, SwapExactAssetOut, SwapExactAssetIn, SmartSwapExactAssetIn, QueryMsg} from "./EntryPoint.types"; +export interface EntryPointReadOnlyInterface { + contractAddress: string; + swapVenueAdapterContract: ({ + name + }: { + name: string; + }) => Promise; + ibcTransferAdapterContract: () => Promise; +} +export class EntryPointQueryClient implements EntryPointReadOnlyInterface { + client: CosmWasmClient; + contractAddress: string; + + constructor(client: CosmWasmClient, contractAddress: string) { + this.client = client; + this.contractAddress = contractAddress; + this.swapVenueAdapterContract = this.swapVenueAdapterContract.bind(this); + this.ibcTransferAdapterContract = this.ibcTransferAdapterContract.bind(this); + } + + swapVenueAdapterContract = async ({ + name + }: { + name: string; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + swap_venue_adapter_contract: { + name + } + }); + }; + ibcTransferAdapterContract = async (): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + ibc_transfer_adapter_contract: {} + }); + }; +} +export interface EntryPointInterface extends EntryPointReadOnlyInterface { + contractAddress: string; + sender: string; + receive: ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + swapAndActionWithRecover: ({ + affiliates, + minAsset, + postSwapAction, + recoveryAddr, + sentAsset, + timeoutTimestamp, + userSwap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + postSwapAction: Action; + recoveryAddr: Addr; + sentAsset?: Asset; + timeoutTimestamp: number; + userSwap: Swap; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + swapAndAction: ({ + affiliates, + minAsset, + postSwapAction, + sentAsset, + timeoutTimestamp, + userSwap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + postSwapAction: Action; + sentAsset?: Asset; + timeoutTimestamp: number; + userSwap: Swap; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + userSwap: ({ + affiliates, + minAsset, + remainingAsset, + swap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + remainingAsset: Asset; + swap: Swap; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + postSwapAction: ({ + exactOut, + minAsset, + postSwapAction, + timeoutTimestamp + }: { + exactOut: boolean; + minAsset: Asset; + postSwapAction: Action; + timeoutTimestamp: number; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + updateConfig: ({ + ibcTransferContractAddress, + ibcWasmContractAddress, + owner, + swapVenues + }: { + ibcTransferContractAddress?: string; + ibcWasmContractAddress?: string; + owner?: Addr; + swapVenues?: SwapVenue[]; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + universalSwap: ({ + memo + }: { + memo: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; +} +export class EntryPointClient extends EntryPointQueryClient implements EntryPointInterface { + client: SigningCosmWasmClient; + sender: string; + contractAddress: string; + + constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) { + super(client, contractAddress); + this.client = client; + this.sender = sender; + this.contractAddress = contractAddress; + this.receive = this.receive.bind(this); + this.swapAndActionWithRecover = this.swapAndActionWithRecover.bind(this); + this.swapAndAction = this.swapAndAction.bind(this); + this.userSwap = this.userSwap.bind(this); + this.postSwapAction = this.postSwapAction.bind(this); + this.updateConfig = this.updateConfig.bind(this); + this.universalSwap = this.universalSwap.bind(this); + } + + receive = async ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + receive: { + amount, + msg, + sender + } + }, _fee, _memo, _funds); + }; + swapAndActionWithRecover = async ({ + affiliates, + minAsset, + postSwapAction, + recoveryAddr, + sentAsset, + timeoutTimestamp, + userSwap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + postSwapAction: Action; + recoveryAddr: Addr; + sentAsset?: Asset; + timeoutTimestamp: number; + userSwap: Swap; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + swap_and_action_with_recover: { + affiliates, + min_asset: minAsset, + post_swap_action: postSwapAction, + recovery_addr: recoveryAddr, + sent_asset: sentAsset, + timeout_timestamp: timeoutTimestamp, + user_swap: userSwap + } + }, _fee, _memo, _funds); + }; + swapAndAction = async ({ + affiliates, + minAsset, + postSwapAction, + sentAsset, + timeoutTimestamp, + userSwap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + postSwapAction: Action; + sentAsset?: Asset; + timeoutTimestamp: number; + userSwap: Swap; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + swap_and_action: { + affiliates, + min_asset: minAsset, + post_swap_action: postSwapAction, + sent_asset: sentAsset, + timeout_timestamp: timeoutTimestamp, + user_swap: userSwap + } + }, _fee, _memo, _funds); + }; + userSwap = async ({ + affiliates, + minAsset, + remainingAsset, + swap + }: { + affiliates: Affiliate[]; + minAsset: Asset; + remainingAsset: Asset; + swap: Swap; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + user_swap: { + affiliates, + min_asset: minAsset, + remaining_asset: remainingAsset, + swap + } + }, _fee, _memo, _funds); + }; + postSwapAction = async ({ + exactOut, + minAsset, + postSwapAction, + timeoutTimestamp + }: { + exactOut: boolean; + minAsset: Asset; + postSwapAction: Action; + timeoutTimestamp: number; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + post_swap_action: { + exact_out: exactOut, + min_asset: minAsset, + post_swap_action: postSwapAction, + timeout_timestamp: timeoutTimestamp + } + }, _fee, _memo, _funds); + }; + updateConfig = async ({ + ibcTransferContractAddress, + ibcWasmContractAddress, + owner, + swapVenues + }: { + ibcTransferContractAddress?: string; + ibcWasmContractAddress?: string; + owner?: Addr; + swapVenues?: SwapVenue[]; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + update_config: { + ibc_transfer_contract_address: ibcTransferContractAddress, + ibc_wasm_contract_address: ibcWasmContractAddress, + owner, + swap_venues: swapVenues + } + }, _fee, _memo, _funds); + }; + universalSwap = async ({ + memo + }: { + memo: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + universal_swap: { + memo + } + }, _fee, _memo, _funds); + }; +} \ No newline at end of file diff --git a/contracts-sdk/src/EntryPoint.types.ts b/contracts-sdk/src/EntryPoint.types.ts new file mode 100644 index 00000000..c7bc7feb --- /dev/null +++ b/contracts-sdk/src/EntryPoint.types.ts @@ -0,0 +1,108 @@ +import {Uint128, Binary, Asset, Addr, Cw20ReceiveMsg, Coin, Cw20Coin, SwapOperation, IbcInfo, IbcFee, TransferBackMsg, Route} from "./types"; +export interface InstantiateMsg { + ibc_transfer_contract_address?: string | null; + ibc_wasm_contract_address?: string | null; + swap_venues?: SwapVenue[] | null; +} +export interface SwapVenue { + adapter_contract_address: string; + name: string; +} +export type ExecuteMsg = { + receive: Cw20ReceiveMsg; +} | { + swap_and_action_with_recover: { + affiliates: Affiliate[]; + min_asset: Asset; + post_swap_action: Action; + recovery_addr: Addr; + sent_asset?: Asset | null; + timeout_timestamp: number; + user_swap: Swap; + }; +} | { + swap_and_action: { + affiliates: Affiliate[]; + min_asset: Asset; + post_swap_action: Action; + sent_asset?: Asset | null; + timeout_timestamp: number; + user_swap: Swap; + }; +} | { + user_swap: { + affiliates: Affiliate[]; + min_asset: Asset; + remaining_asset: Asset; + swap: Swap; + }; +} | { + post_swap_action: { + exact_out: boolean; + min_asset: Asset; + post_swap_action: Action; + timeout_timestamp: number; + }; +} | { + update_config: { + ibc_transfer_contract_address?: string | null; + ibc_wasm_contract_address?: string | null; + owner?: Addr | null; + swap_venues?: SwapVenue[] | null; + }; +} | { + universal_swap: { + memo: string; + }; +}; +export type Action = { + transfer: { + to_address: string; + }; +} | { + ibc_transfer: { + fee_swap?: SwapExactAssetOut | null; + ibc_info: IbcInfo; + }; +} | { + contract_call: { + contract_address: string; + msg: Binary; + }; +} | { + ibc_wasm_transfer: { + fee_swap?: SwapExactAssetOut | null; + ibc_wasm_info: TransferBackMsg; + }; +}; +export type Swap = { + swap_exact_asset_in: SwapExactAssetIn; +} | { + swap_exact_asset_out: SwapExactAssetOut; +} | { + smart_swap_exact_asset_in: SmartSwapExactAssetIn; +}; +export interface Affiliate { + address: string; + basis_points_fee: Uint128; +} +export interface SwapExactAssetOut { + operations: SwapOperation[]; + refund_address?: string | null; + swap_venue_name: string; +} +export interface SwapExactAssetIn { + operations: SwapOperation[]; + swap_venue_name: string; +} +export interface SmartSwapExactAssetIn { + routes: Route[]; + swap_venue_name: string; +} +export type QueryMsg = { + swap_venue_adapter_contract: { + name: string; + }; +} | { + ibc_transfer_adapter_contract: {}; +}; \ No newline at end of file diff --git a/contracts-sdk/src/IbcHooks.client.ts b/contracts-sdk/src/IbcHooks.client.ts new file mode 100644 index 00000000..3d3f864a --- /dev/null +++ b/contracts-sdk/src/IbcHooks.client.ts @@ -0,0 +1,89 @@ +/** +* This file was automatically generated by @oraichain/ts-codegen@0.35.9. +* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, +* and run the @oraichain/ts-codegen generate command to regenerate this file. +*/ + +import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { StdFee } from "@cosmjs/amino"; +import {Uint128, Coin, IbcInfo, IbcFee} from "./types"; +import {InstantiateMsg, ExecuteMsg, QueryMsg, String} from "./IbcHooks.types"; +export interface IbcHooksReadOnlyInterface { + contractAddress: string; + inProgressRecoverAddress: ({ + channelId, + sequenceId + }: { + channelId: string; + sequenceId: number; + }) => Promise; +} +export class IbcHooksQueryClient implements IbcHooksReadOnlyInterface { + client: CosmWasmClient; + contractAddress: string; + + constructor(client: CosmWasmClient, contractAddress: string) { + this.client = client; + this.contractAddress = contractAddress; + this.inProgressRecoverAddress = this.inProgressRecoverAddress.bind(this); + } + + inProgressRecoverAddress = async ({ + channelId, + sequenceId + }: { + channelId: string; + sequenceId: number; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + in_progress_recover_address: { + channel_id: channelId, + sequence_id: sequenceId + } + }); + }; +} +export interface IbcHooksInterface extends IbcHooksReadOnlyInterface { + contractAddress: string; + sender: string; + ibcTransfer: ({ + coin, + info, + timeoutTimestamp + }: { + coin: Coin; + info: IbcInfo; + timeoutTimestamp: number; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; +} +export class IbcHooksClient extends IbcHooksQueryClient implements IbcHooksInterface { + client: SigningCosmWasmClient; + sender: string; + contractAddress: string; + + constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) { + super(client, contractAddress); + this.client = client; + this.sender = sender; + this.contractAddress = contractAddress; + this.ibcTransfer = this.ibcTransfer.bind(this); + } + + ibcTransfer = async ({ + coin, + info, + timeoutTimestamp + }: { + coin: Coin; + info: IbcInfo; + timeoutTimestamp: number; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + ibc_transfer: { + coin, + info, + timeout_timestamp: timeoutTimestamp + } + }, _fee, _memo, _funds); + }; +} \ No newline at end of file diff --git a/contracts-sdk/src/IbcHooks.types.ts b/contracts-sdk/src/IbcHooks.types.ts new file mode 100644 index 00000000..dd6fcd79 --- /dev/null +++ b/contracts-sdk/src/IbcHooks.types.ts @@ -0,0 +1,18 @@ +import {Uint128, Coin, IbcInfo, IbcFee} from "./types"; +export interface InstantiateMsg { + entry_point_contract_address: string; +} +export type ExecuteMsg = { + ibc_transfer: { + coin: Coin; + info: IbcInfo; + timeout_timestamp: number; + }; +}; +export type QueryMsg = { + in_progress_recover_address: { + channel_id: string; + sequence_id: number; + }; +}; +export type String = string; \ No newline at end of file diff --git a/contracts-sdk/src/OraiIbcWasm.client.ts b/contracts-sdk/src/OraiIbcWasm.client.ts new file mode 100644 index 00000000..b3126d4a --- /dev/null +++ b/contracts-sdk/src/OraiIbcWasm.client.ts @@ -0,0 +1,128 @@ +/** +* This file was automatically generated by @oraichain/ts-codegen@0.35.9. +* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, +* and run the @oraichain/ts-codegen generate command to regenerate this file. +*/ + +import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { StdFee } from "@cosmjs/amino"; +import {Asset, Uint128, Binary, Addr, Coin, Cw20Coin, TransferBackMsg, Cw20ReceiveMsg} from "./types"; +import {InstantiateMsg, ExecuteMsg, QueryMsg} from "./OraiIbcWasm.types"; +export interface OraiIbcWasmReadOnlyInterface { + contractAddress: string; +} +export class OraiIbcWasmQueryClient implements OraiIbcWasmReadOnlyInterface { + client: CosmWasmClient; + contractAddress: string; + + constructor(client: CosmWasmClient, contractAddress: string) { + this.client = client; + this.contractAddress = contractAddress; + } + +} +export interface OraiIbcWasmInterface extends OraiIbcWasmReadOnlyInterface { + contractAddress: string; + sender: string; + ibcWasmTransfer: ({ + coin, + ibcWasmInfo + }: { + coin: Asset; + ibcWasmInfo: TransferBackMsg; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + receive: ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + updateOwner: ({ + newOwner + }: { + newOwner: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + withdrawAsset: ({ + coin, + receiver + }: { + coin: Asset; + receiver?: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; +} +export class OraiIbcWasmClient extends OraiIbcWasmQueryClient implements OraiIbcWasmInterface { + client: SigningCosmWasmClient; + sender: string; + contractAddress: string; + + constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) { + super(client, contractAddress); + this.client = client; + this.sender = sender; + this.contractAddress = contractAddress; + this.ibcWasmTransfer = this.ibcWasmTransfer.bind(this); + this.receive = this.receive.bind(this); + this.updateOwner = this.updateOwner.bind(this); + this.withdrawAsset = this.withdrawAsset.bind(this); + } + + ibcWasmTransfer = async ({ + coin, + ibcWasmInfo + }: { + coin: Asset; + ibcWasmInfo: TransferBackMsg; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + ibc_wasm_transfer: { + coin, + ibc_wasm_info: ibcWasmInfo + } + }, _fee, _memo, _funds); + }; + receive = async ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + receive: { + amount, + msg, + sender + } + }, _fee, _memo, _funds); + }; + updateOwner = async ({ + newOwner + }: { + newOwner: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + update_owner: { + new_owner: newOwner + } + }, _fee, _memo, _funds); + }; + withdrawAsset = async ({ + coin, + receiver + }: { + coin: Asset; + receiver?: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + withdraw_asset: { + coin, + receiver + } + }, _fee, _memo, _funds); + }; +} \ No newline at end of file diff --git a/contracts-sdk/src/OraiIbcWasm.types.ts b/contracts-sdk/src/OraiIbcWasm.types.ts new file mode 100644 index 00000000..9b54b638 --- /dev/null +++ b/contracts-sdk/src/OraiIbcWasm.types.ts @@ -0,0 +1,23 @@ +import {Asset, Uint128, Binary, Addr, Coin, Cw20Coin, TransferBackMsg, Cw20ReceiveMsg} from "./types"; +export interface InstantiateMsg { + entry_point_contract_address: string; + ibc_wasm_contract_address: string; +} +export type ExecuteMsg = { + ibc_wasm_transfer: { + coin: Asset; + ibc_wasm_info: TransferBackMsg; + }; +} | { + receive: Cw20ReceiveMsg; +} | { + update_owner: { + new_owner: Addr; + }; +} | { + withdraw_asset: { + coin: Asset; + receiver?: Addr | null; + }; +}; +export type QueryMsg = string; \ No newline at end of file diff --git a/contracts-sdk/src/Oraidex.client.ts b/contracts-sdk/src/Oraidex.client.ts new file mode 100644 index 00000000..1dea1379 --- /dev/null +++ b/contracts-sdk/src/Oraidex.client.ts @@ -0,0 +1,209 @@ +/** +* This file was automatically generated by @oraichain/ts-codegen@0.35.9. +* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, +* and run the @oraichain/ts-codegen generate command to regenerate this file. +*/ + +import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { Coin, StdFee } from "@cosmjs/amino"; +import {Uint128, Binary, SwapOperation, Addr, Cw20ReceiveMsg} from "./types"; +import {InstantiateMsg, ExecuteMsg, AssetInfo, Percentage, PoolKey, FeeTier, QueryMsg, ConfigResponse, SimulateSwapOperationsResponse} from "./Oraidex.types"; +export interface OraidexReadOnlyInterface { + contractAddress: string; + config: () => Promise; + simulateSwapOperations: ({ + offerAmount, + operations + }: { + offerAmount: Uint128; + operations: SwapOperation[]; + }) => Promise; +} +export class OraidexQueryClient implements OraidexReadOnlyInterface { + client: CosmWasmClient; + contractAddress: string; + + constructor(client: CosmWasmClient, contractAddress: string) { + this.client = client; + this.contractAddress = contractAddress; + this.config = this.config.bind(this); + this.simulateSwapOperations = this.simulateSwapOperations.bind(this); + } + + config = async (): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + config: {} + }); + }; + simulateSwapOperations = async ({ + offerAmount, + operations + }: { + offerAmount: Uint128; + operations: SwapOperation[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_swap_operations: { + offer_amount: offerAmount, + operations + } + }); + }; +} +export interface OraidexInterface extends OraidexReadOnlyInterface { + contractAddress: string; + sender: string; + receive: ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + executeSwapOperations: ({ + minimumReceive, + operations, + to + }: { + minimumReceive?: Uint128; + operations: SwapOperation[]; + to?: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + executeSwapOperation: ({ + operation, + sender, + to + }: { + operation: SwapOperation; + sender: Addr; + to?: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + assertMinimumReceiveAndTransfer: ({ + assetInfo, + minimumReceive, + receiver + }: { + assetInfo: AssetInfo; + minimumReceive: Uint128; + receiver: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + updateConfig: ({ + factoryAddr, + factoryAddrV2, + oraiswapV3, + owner + }: { + factoryAddr?: string; + factoryAddrV2?: string; + oraiswapV3?: string; + owner?: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; +} +export class OraidexClient extends OraidexQueryClient implements OraidexInterface { + client: SigningCosmWasmClient; + sender: string; + contractAddress: string; + + constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) { + super(client, contractAddress); + this.client = client; + this.sender = sender; + this.contractAddress = contractAddress; + this.receive = this.receive.bind(this); + this.executeSwapOperations = this.executeSwapOperations.bind(this); + this.executeSwapOperation = this.executeSwapOperation.bind(this); + this.assertMinimumReceiveAndTransfer = this.assertMinimumReceiveAndTransfer.bind(this); + this.updateConfig = this.updateConfig.bind(this); + } + + receive = async ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + receive: { + amount, + msg, + sender + } + }, _fee, _memo, _funds); + }; + executeSwapOperations = async ({ + minimumReceive, + operations, + to + }: { + minimumReceive?: Uint128; + operations: SwapOperation[]; + to?: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + execute_swap_operations: { + minimum_receive: minimumReceive, + operations, + to + } + }, _fee, _memo, _funds); + }; + executeSwapOperation = async ({ + operation, + sender, + to + }: { + operation: SwapOperation; + sender: Addr; + to?: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + execute_swap_operation: { + operation, + sender, + to + } + }, _fee, _memo, _funds); + }; + assertMinimumReceiveAndTransfer = async ({ + assetInfo, + minimumReceive, + receiver + }: { + assetInfo: AssetInfo; + minimumReceive: Uint128; + receiver: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + assert_minimum_receive_and_transfer: { + asset_info: assetInfo, + minimum_receive: minimumReceive, + receiver + } + }, _fee, _memo, _funds); + }; + updateConfig = async ({ + factoryAddr, + factoryAddrV2, + oraiswapV3, + owner + }: { + factoryAddr?: string; + factoryAddrV2?: string; + oraiswapV3?: string; + owner?: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + update_config: { + factory_addr: factoryAddr, + factory_addr_v2: factoryAddrV2, + oraiswap_v3: oraiswapV3, + owner + } + }, _fee, _memo, _funds); + }; +} \ No newline at end of file diff --git a/contracts-sdk/src/Oraidex.types.ts b/contracts-sdk/src/Oraidex.types.ts new file mode 100644 index 00000000..4b4da04c --- /dev/null +++ b/contracts-sdk/src/Oraidex.types.ts @@ -0,0 +1,68 @@ +import {Uint128, Binary, SwapOperation, Addr, Cw20ReceiveMsg} from "./types"; +export interface InstantiateMsg { + entry_point_contract_address: string; + oraidex_router_contract_address: string; +} +export type ExecuteMsg = { + receive: Cw20ReceiveMsg; +} | { + execute_swap_operations: { + minimum_receive?: Uint128 | null; + operations: SwapOperation[]; + to?: Addr | null; + }; +} | { + execute_swap_operation: { + operation: SwapOperation; + sender: Addr; + to?: Addr | null; + }; +} | { + assert_minimum_receive_and_transfer: { + asset_info: AssetInfo; + minimum_receive: Uint128; + receiver: Addr; + }; +} | { + update_config: { + factory_addr?: string | null; + factory_addr_v2?: string | null; + oraiswap_v3?: string | null; + owner?: string | null; + }; +}; +export type AssetInfo = { + token: { + contract_addr: Addr; + }; +} | { + native_token: { + denom: string; + }; +}; +export type Percentage = number; +export interface PoolKey { + fee_tier: FeeTier; + token_x: string; + token_y: string; +} +export interface FeeTier { + fee: Percentage; + tick_spacing: number; +} +export type QueryMsg = { + config: {}; +} | { + simulate_swap_operations: { + offer_amount: Uint128; + operations: SwapOperation[]; + }; +}; +export interface ConfigResponse { + factory_addr: Addr; + factory_addr_v2: Addr; + oraiswap_v3: Addr; +} +export interface SimulateSwapOperationsResponse { + amount: Uint128; +} \ No newline at end of file diff --git a/contracts-sdk/src/OsmosisPoolmanager.client.ts b/contracts-sdk/src/OsmosisPoolmanager.client.ts new file mode 100644 index 00000000..a4c274cd --- /dev/null +++ b/contracts-sdk/src/OsmosisPoolmanager.client.ts @@ -0,0 +1,304 @@ +/** +* This file was automatically generated by @oraichain/ts-codegen@0.35.9. +* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, +* and run the @oraichain/ts-codegen generate command to regenerate this file. +*/ + +import { CosmWasmClient, SigningCosmWasmClient, ExecuteResult } from "@cosmjs/cosmwasm-stargate"; +import { StdFee } from "@cosmjs/amino"; +import {Uint128, Binary, Addr, Cw20ReceiveMsg, SwapOperation, Asset, Coin, Cw20Coin, Route} from "./types"; +import {InstantiateMsg, ExecuteMsg, QueryMsg, Decimal, SimulateSmartSwapExactAssetInResponse, SimulateSwapExactAssetInResponse, SimulateSwapExactAssetOutResponse} from "./OsmosisPoolmanager.types"; +export interface OsmosisPoolmanagerReadOnlyInterface { + contractAddress: string; + simulateSwapExactAssetOut: ({ + assetOut, + swapOperations + }: { + assetOut: Asset; + swapOperations: SwapOperation[]; + }) => Promise; + simulateSwapExactAssetIn: ({ + assetIn, + swapOperations + }: { + assetIn: Asset; + swapOperations: SwapOperation[]; + }) => Promise; + simulateSwapExactAssetOutWithMetadata: ({ + assetOut, + includeSpotPrice, + swapOperations + }: { + assetOut: Asset; + includeSpotPrice: boolean; + swapOperations: SwapOperation[]; + }) => Promise; + simulateSwapExactAssetInWithMetadata: ({ + assetIn, + includeSpotPrice, + swapOperations + }: { + assetIn: Asset; + includeSpotPrice: boolean; + swapOperations: SwapOperation[]; + }) => Promise; + simulateSmartSwapExactAssetIn: ({ + assetIn, + routes + }: { + assetIn: Asset; + routes: Route[]; + }) => Promise; + simulateSmartSwapExactAssetInWithMetadata: ({ + assetIn, + includeSpotPrice, + routes + }: { + assetIn: Asset; + includeSpotPrice: boolean; + routes: Route[]; + }) => Promise; +} +export class OsmosisPoolmanagerQueryClient implements OsmosisPoolmanagerReadOnlyInterface { + client: CosmWasmClient; + contractAddress: string; + + constructor(client: CosmWasmClient, contractAddress: string) { + this.client = client; + this.contractAddress = contractAddress; + this.simulateSwapExactAssetOut = this.simulateSwapExactAssetOut.bind(this); + this.simulateSwapExactAssetIn = this.simulateSwapExactAssetIn.bind(this); + this.simulateSwapExactAssetOutWithMetadata = this.simulateSwapExactAssetOutWithMetadata.bind(this); + this.simulateSwapExactAssetInWithMetadata = this.simulateSwapExactAssetInWithMetadata.bind(this); + this.simulateSmartSwapExactAssetIn = this.simulateSmartSwapExactAssetIn.bind(this); + this.simulateSmartSwapExactAssetInWithMetadata = this.simulateSmartSwapExactAssetInWithMetadata.bind(this); + } + + simulateSwapExactAssetOut = async ({ + assetOut, + swapOperations + }: { + assetOut: Asset; + swapOperations: SwapOperation[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_swap_exact_asset_out: { + asset_out: assetOut, + swap_operations: swapOperations + } + }); + }; + simulateSwapExactAssetIn = async ({ + assetIn, + swapOperations + }: { + assetIn: Asset; + swapOperations: SwapOperation[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_swap_exact_asset_in: { + asset_in: assetIn, + swap_operations: swapOperations + } + }); + }; + simulateSwapExactAssetOutWithMetadata = async ({ + assetOut, + includeSpotPrice, + swapOperations + }: { + assetOut: Asset; + includeSpotPrice: boolean; + swapOperations: SwapOperation[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_swap_exact_asset_out_with_metadata: { + asset_out: assetOut, + include_spot_price: includeSpotPrice, + swap_operations: swapOperations + } + }); + }; + simulateSwapExactAssetInWithMetadata = async ({ + assetIn, + includeSpotPrice, + swapOperations + }: { + assetIn: Asset; + includeSpotPrice: boolean; + swapOperations: SwapOperation[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_swap_exact_asset_in_with_metadata: { + asset_in: assetIn, + include_spot_price: includeSpotPrice, + swap_operations: swapOperations + } + }); + }; + simulateSmartSwapExactAssetIn = async ({ + assetIn, + routes + }: { + assetIn: Asset; + routes: Route[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_smart_swap_exact_asset_in: { + asset_in: assetIn, + routes + } + }); + }; + simulateSmartSwapExactAssetInWithMetadata = async ({ + assetIn, + includeSpotPrice, + routes + }: { + assetIn: Asset; + includeSpotPrice: boolean; + routes: Route[]; + }): Promise => { + return this.client.queryContractSmart(this.contractAddress, { + simulate_smart_swap_exact_asset_in_with_metadata: { + asset_in: assetIn, + include_spot_price: includeSpotPrice, + routes + } + }); + }; +} +export interface OsmosisPoolmanagerInterface extends OsmosisPoolmanagerReadOnlyInterface { + contractAddress: string; + sender: string; + receive: ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + swap: ({ + operations + }: { + operations: SwapOperation[]; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + transferFundsBack: ({ + returnDenom, + swapper + }: { + returnDenom: string; + swapper: Addr; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + astroportPoolSwap: ({ + operation + }: { + operation: SwapOperation; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + whiteWhalePoolSwap: ({ + operation + }: { + operation: SwapOperation; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; + oraidexPoolSwap: ({ + operation + }: { + operation: SwapOperation; + }, _fee?: number | StdFee | "auto", _memo?: string, _funds?: Coin[]) => Promise; +} +export class OsmosisPoolmanagerClient extends OsmosisPoolmanagerQueryClient implements OsmosisPoolmanagerInterface { + client: SigningCosmWasmClient; + sender: string; + contractAddress: string; + + constructor(client: SigningCosmWasmClient, sender: string, contractAddress: string) { + super(client, contractAddress); + this.client = client; + this.sender = sender; + this.contractAddress = contractAddress; + this.receive = this.receive.bind(this); + this.swap = this.swap.bind(this); + this.transferFundsBack = this.transferFundsBack.bind(this); + this.astroportPoolSwap = this.astroportPoolSwap.bind(this); + this.whiteWhalePoolSwap = this.whiteWhalePoolSwap.bind(this); + this.oraidexPoolSwap = this.oraidexPoolSwap.bind(this); + } + + receive = async ({ + amount, + msg, + sender + }: { + amount: Uint128; + msg: Binary; + sender: string; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + receive: { + amount, + msg, + sender + } + }, _fee, _memo, _funds); + }; + swap = async ({ + operations + }: { + operations: SwapOperation[]; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + swap: { + operations + } + }, _fee, _memo, _funds); + }; + transferFundsBack = async ({ + returnDenom, + swapper + }: { + returnDenom: string; + swapper: Addr; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + transfer_funds_back: { + return_denom: returnDenom, + swapper + } + }, _fee, _memo, _funds); + }; + astroportPoolSwap = async ({ + operation + }: { + operation: SwapOperation; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + astroport_pool_swap: { + operation + } + }, _fee, _memo, _funds); + }; + whiteWhalePoolSwap = async ({ + operation + }: { + operation: SwapOperation; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + white_whale_pool_swap: { + operation + } + }, _fee, _memo, _funds); + }; + oraidexPoolSwap = async ({ + operation + }: { + operation: SwapOperation; + }, _fee: number | StdFee | "auto" = "auto", _memo?: string, _funds?: Coin[]): Promise => { + return await this.client.execute(this.sender, this.contractAddress, { + oraidex_pool_swap: { + operation + } + }, _fee, _memo, _funds); + }; +} \ No newline at end of file diff --git a/contracts-sdk/src/OsmosisPoolmanager.types.ts b/contracts-sdk/src/OsmosisPoolmanager.types.ts new file mode 100644 index 00000000..785c4114 --- /dev/null +++ b/contracts-sdk/src/OsmosisPoolmanager.types.ts @@ -0,0 +1,75 @@ +import {Uint128, Binary, Addr, Cw20ReceiveMsg, SwapOperation, Asset, Coin, Cw20Coin, Route} from "./types"; +export interface InstantiateMsg { + entry_point_contract_address: string; +} +export type ExecuteMsg = { + receive: Cw20ReceiveMsg; +} | { + swap: { + operations: SwapOperation[]; + }; +} | { + transfer_funds_back: { + return_denom: string; + swapper: Addr; + }; +} | { + astroport_pool_swap: { + operation: SwapOperation; + }; +} | { + white_whale_pool_swap: { + operation: SwapOperation; + }; +} | { + oraidex_pool_swap: { + operation: SwapOperation; + }; +}; +export type QueryMsg = { + simulate_swap_exact_asset_out: { + asset_out: Asset; + swap_operations: SwapOperation[]; + }; +} | { + simulate_swap_exact_asset_in: { + asset_in: Asset; + swap_operations: SwapOperation[]; + }; +} | { + simulate_swap_exact_asset_out_with_metadata: { + asset_out: Asset; + include_spot_price: boolean; + swap_operations: SwapOperation[]; + }; +} | { + simulate_swap_exact_asset_in_with_metadata: { + asset_in: Asset; + include_spot_price: boolean; + swap_operations: SwapOperation[]; + }; +} | { + simulate_smart_swap_exact_asset_in: { + asset_in: Asset; + routes: Route[]; + }; +} | { + simulate_smart_swap_exact_asset_in_with_metadata: { + asset_in: Asset; + include_spot_price: boolean; + routes: Route[]; + }; +}; +export type Decimal = string; +export interface SimulateSmartSwapExactAssetInResponse { + asset_out: Asset; + spot_price?: Decimal | null; +} +export interface SimulateSwapExactAssetInResponse { + asset_out: Asset; + spot_price?: Decimal | null; +} +export interface SimulateSwapExactAssetOutResponse { + asset_in: Asset; + spot_price?: Decimal | null; +} \ No newline at end of file diff --git a/contracts-sdk/src/index.ts b/contracts-sdk/src/index.ts new file mode 100644 index 00000000..c48c335b --- /dev/null +++ b/contracts-sdk/src/index.ts @@ -0,0 +1,11 @@ +export * as EntryPointTypes from './EntryPoint.types'; +export * from './EntryPoint.client'; +export * as IbcHooksTypes from './IbcHooks.types'; +export * from './IbcHooks.client'; +export * as OraiIbcWasmTypes from './OraiIbcWasm.types'; +export * from './OraiIbcWasm.client'; +export * as OraidexTypes from './Oraidex.types'; +export * from './Oraidex.client'; +export * as OsmosisPoolmanagerTypes from './OsmosisPoolmanager.types'; +export * from './OsmosisPoolmanager.client'; +export * from "./types"; \ No newline at end of file diff --git a/contracts-sdk/src/types.ts b/contracts-sdk/src/types.ts new file mode 100644 index 00000000..744c20f7 --- /dev/null +++ b/contracts-sdk/src/types.ts @@ -0,0 +1,50 @@ +export type Uint128 = string; +export type Binary = string; +export type Asset = { + native: Coin; +} | { + cw20: Cw20Coin; +}; +export type Addr = string; +export interface Cw20ReceiveMsg { + amount: Uint128; + msg: Binary; + sender: string; +} +export interface Coin { + amount: Uint128; + denom: string; +} +export interface Cw20Coin { + address: string; + amount: Uint128; +} +export interface IbcInfo { + fee?: IbcFee | null; + memo: string; + receiver: string; + recover_address: string; + source_channel: string; +} +export interface IbcFee { + ack_fee: Coin[]; + recv_fee: Coin[]; + timeout_fee: Coin[]; +} +export interface TransferBackMsg { + local_channel_id: string; + memo?: string | null; + remote_address: string; + remote_denom: string; + timeout?: number | null; +} +export interface Route { + offer_asset: Asset; + operations: SwapOperation[]; +} +export interface SwapOperation { + denom_in: string; + denom_out: string; + interface?: Binary | null; + pool: string; +} \ No newline at end of file diff --git a/contracts-sdk/tsconfig.json b/contracts-sdk/tsconfig.json new file mode 100644 index 00000000..45882a18 --- /dev/null +++ b/contracts-sdk/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["ES2020", "dom"], + "module": "commonjs", + "moduleResolution": "node", + "skipLibCheck": true, + "sourceMap": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "declaration": false, + "outDir": "build", + "typeRoots": ["node_modules/@types"], + "allowJs": true, + "esModuleInterop": true + } +} diff --git a/contracts-sdk/yarn.lock b/contracts-sdk/yarn.lock new file mode 100644 index 00000000..1869bc1c --- /dev/null +++ b/contracts-sdk/yarn.lock @@ -0,0 +1,468 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@confio/ics23@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" + integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== + dependencies: + "@noble/hashes" "^1.0.0" + protobufjs "^6.8.8" + +"@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== + dependencies: + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + +"@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== + dependencies: + "@cosmjs/amino" "^0.31.3" + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/proto-signing" "^0.31.3" + "@cosmjs/stargate" "^0.31.3" + "@cosmjs/tendermint-rpc" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + cosmjs-types "^0.8.0" + long "^4.0.0" + pako "^2.0.2" + +"@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== + dependencies: + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + +"@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== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/json-rpc@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.31.3.tgz#11e5cf0f6d9ab426dff470bb8d68d5d31cd6ab13" + integrity sha512-7LVYerXjnm69qqYR3uA6LGCrBW2EO5/F7lfJxAmY+iII2C7xO3a0vAjMSt5zBBh29PXrJVS6c2qRP22W1Le2Wg== + dependencies: + "@cosmjs/stream" "^0.31.3" + xstream "^11.14.0" + +"@cosmjs/math@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.31.3.tgz#767f7263d12ba1b9ed2f01f68d857597839fd957" + integrity sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A== + dependencies: + bn.js "^5.2.0" + +"@cosmjs/proto-signing@0.31.3", "@cosmjs/proto-signing@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.31.3.tgz#20440b7b96fb2cd924256a10e656fd8d4481cdcd" + integrity sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA== + dependencies: + "@cosmjs/amino" "^0.31.3" + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + cosmjs-types "^0.8.0" + long "^4.0.0" + +"@cosmjs/socket@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.31.3.tgz#52086380f4de2fc3514b90b0484b4b1c4c50e39e" + integrity sha512-aqrDGGi7os/hsz5p++avI4L0ZushJ+ItnzbqA7C6hamFSCJwgOkXaOUs+K9hXZdX4rhY7rXO4PH9IH8q09JkTw== + dependencies: + "@cosmjs/stream" "^0.31.3" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + +"@cosmjs/stargate@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.31.3.tgz#a2b38e398097a00f897dbd8f02d4d347d8fed818" + integrity sha512-53NxnzmB9FfXpG4KjOUAYAvWLYKdEmZKsutcat/u2BrDXNZ7BN8jim/ENcpwXfs9/Og0K24lEIdvA4gsq3JDQw== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/proto-signing" "^0.31.3" + "@cosmjs/stream" "^0.31.3" + "@cosmjs/tendermint-rpc" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + cosmjs-types "^0.8.0" + long "^4.0.0" + protobufjs "~6.11.3" + xstream "^11.14.0" + +"@cosmjs/stream@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.31.3.tgz#53428fd62487ec08fc3886a50a3feeb8b2af2e66" + integrity sha512-8keYyI7X0RjsLyVcZuBeNjSv5FA4IHwbFKx7H60NHFXszN8/MvXL6aZbNIvxtcIHHsW7K9QSQos26eoEWlAd+w== + dependencies: + xstream "^11.14.0" + +"@cosmjs/tendermint-rpc@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.3.tgz#d1a2bc5b3c98743631c9b55888589d352403c9b3" + integrity sha512-s3TiWkPCW4QceTQjpYqn4xttUJH36mTPqplMl+qyocdqk5+X5mergzExU/pHZRWQ4pbby8bnR7kMvG4OC1aZ8g== + dependencies: + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/json-rpc" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/socket" "^0.31.3" + "@cosmjs/stream" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + axios "^0.21.2" + readonly-date "^1.0.0" + xstream "^11.14.0" + +"@cosmjs/utils@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.31.3.tgz#f97bbfda35ad69e80cd5c7fe0a270cbda16db1ed" + integrity sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA== + +"@noble/hashes@^1", "@noble/hashes@^1.0.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + +"@types/node@>=13.7.0": + version "22.7.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.4.tgz#e35d6f48dca3255ce44256ddc05dee1c23353fcc" + integrity sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg== + dependencies: + undici-types "~6.19.2" + +axios@^0.21.2: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +base64-js@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bech32@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +cosmjs-types@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.8.0.tgz#2ed78f3e990f770229726f95f3ef5bf9e2b6859b" + integrity sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg== + dependencies: + long "^4.0.0" + protobufjs "~6.11.2" + +define-data-property@^1.0.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +elliptic@^6.5.4: + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +follow-redirects@^1.14.0: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +globalthis@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +has-property-descriptors@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + +libsodium-sumo@^0.7.15: + version "0.7.15" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.15.tgz#91c1d863fe3fbce6d6b9db1aadaa622733a1d007" + integrity sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw== + +libsodium-wrappers-sumo@^0.7.11: + version "0.7.15" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.15.tgz#0ef2a99b4b17e8385aa7e6850593660dbaf5fb40" + integrity sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA== + dependencies: + libsodium-sumo "^0.7.15" + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +pako@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +readonly-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" + integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== + +symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +ws@^7: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== + +xstream@^11.14.0: + version "11.14.0" + resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" + integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== + dependencies: + globalthis "^1.0.1" + symbol-observable "^2.0.3" diff --git a/contracts/adapters/swap/oraidex/Cargo.toml b/contracts/adapters/swap/oraidex/Cargo.toml index a91ccacb..df21bf4b 100644 --- a/contracts/adapters/swap/oraidex/Cargo.toml +++ b/contracts/adapters/swap/oraidex/Cargo.toml @@ -30,6 +30,7 @@ skip = { workspace = true } thiserror = { workspace = true } oraiswap = { workspace = true } oraiswap-v3 = { workspace = true } +serde-json-wasm = { workspace = true } [dev-dependencies] cw-multi-test = { workspace = true } diff --git a/contracts/adapters/swap/oraidex/src/contract.rs b/contracts/adapters/swap/oraidex/src/contract.rs index 7dc97a29..e0f77e30 100644 --- a/contracts/adapters/swap/oraidex/src/contract.rs +++ b/contracts/adapters/swap/oraidex/src/contract.rs @@ -1,22 +1,22 @@ use crate::{ error::{ContractError, ContractResult}, - helper::{convert_pool_id_to_v3_pool_key, denom_to_asset_info}, + helper::{convert_pool_id_to_v3_pool_key, denom_to_asset_info, parse_to_swap_msg}, state::{ENTRY_POINT_CONTRACT_ADDRESS, ORAIDEX_ROUTER_ADDRESS}, }; use cosmwasm_std::{ - entry_point, from_json, to_json_binary, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, + entry_point, from_json, to_json_binary, Binary, Decimal, Deps, DepsMut, Env, MessageInfo, Response, Uint128, WasmMsg, }; use cw2::set_contract_version; -use cw20::{Cw20Coin, Cw20ExecuteMsg, Cw20ReceiveMsg}; +use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw_utils::one_coin; use oraiswap::mixed_router::{ - ExecuteMsg as OraidexRouterExecuteMsg, QueryMsg as OraidexQueryMsg, - SimulateSwapOperationsResponse, SwapOperation as OraidexSwapOperation, + QueryMsg as OraidexQueryMsg, SimulateSwapOperationsResponse, + SwapOperation as OraidexSwapOperation, }; use skip::{ - asset::Asset, + asset::{get_current_asset_available, Asset}, swap::{ execute_transfer_funds_back, get_ask_denom_for_routes, Cw20HookMsg, ExecuteMsg, MigrateMsg, OraidexInstantiateMsg, QueryMsg, Route, SimulateSmartSwapExactAssetInResponse, @@ -24,9 +24,6 @@ use skip::{ }, }; -// const DEXTER_VAULT_ADDRESS: &str = "persistence1k8re7jwz6rnnwrktnejdwkwnncte7ek7gt29gvnl3sdrg9mtnqkstujtpg"; -// const DEXTER_ROUTER_ADDRESS: &str = "persistence132xmxm33vwjlur2pszl4hu9r32lqmqagvunnuc5hq4htps7rr3kqsf4dsk"; - /////////////// /// MIGRATE /// /////////////// @@ -97,7 +94,7 @@ pub fn receive_cw20( info.sender = deps.api.addr_validate(&cw20_msg.sender)?; match from_json(&cw20_msg.msg)? { - Cw20HookMsg::Swap { operations } => execute_swap(deps, env, info, sent_asset, operations), + Cw20HookMsg::Swap { operations } => execute_swap(deps, env, info, operations), } } @@ -115,19 +112,19 @@ pub fn execute( match msg { ExecuteMsg::Receive(cw20_msg) => receive_cw20(deps, env, info, cw20_msg), ExecuteMsg::Swap { operations } => { + let coin = one_coin(&info)?; + // validate that there's at least one swap operation if operations.is_empty() { return Err(ContractError::SwapOperationsEmpty); } - let coin = one_coin(&info)?; - // validate that the one coin is the same as the first swap operation's denom in if coin.denom != operations.first().unwrap().denom_in { return Err(ContractError::CoinInDenomMismatch); } - execute_swap(deps, env, info, Asset::Native(coin), operations) + execute_swap(deps, env, info, operations) } ExecuteMsg::TransferFundsBack { swapper, @@ -139,8 +136,11 @@ pub fn execute( swapper, return_denom, )?), + ExecuteMsg::OraidexPoolSwap { operation } => { + execute_oraidex_pool_swap(deps, env, info, operation) + } _ => { - panic!("NOT IMPLEMENTED"); + unimplemented!() } } } @@ -149,12 +149,10 @@ fn execute_swap( deps: DepsMut, env: Env, info: MessageInfo, - sent_asset: Asset, operations: Vec, ) -> ContractResult { // Get entry point contract address from storage let entry_point_contract_address = ENTRY_POINT_CONTRACT_ADDRESS.load(deps.storage)?; - let oraidex_router_contract_address = ORAIDEX_ROUTER_ADDRESS.load(deps.storage)?; // Enforce the caller is the entry point contract if info.sender != entry_point_contract_address { @@ -162,59 +160,69 @@ fn execute_swap( } // Create a response object to return - let response: Response = Response::new().add_attribute("action", "execute_swap"); - - let mut hop_swap_requests: Vec = vec![]; + let mut response: Response = Response::new().add_attribute("action", "execute_swap"); + // Add an oraidex pool swap message to the response for each swap operation for operation in &operations { - if operation.pool.contains("-") { - // v3 - let pool_key = convert_pool_id_to_v3_pool_key(&operation.pool)?; - let x_to_y = pool_key.token_x == operation.denom_in; - - hop_swap_requests.push(OraidexSwapOperation::SwapV3 { pool_key, x_to_y }) - } else { - // v2 - hop_swap_requests.push(OraidexSwapOperation::OraiSwap { - offer_asset_info: denom_to_asset_info(deps.api, &operation.denom_in), - ask_asset_info: denom_to_asset_info(deps.api, &operation.denom_out), - }) - } + let swap_msg = WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: operation.clone(), + })?, + funds: vec![], + }; + response = response.add_message(swap_msg); } - let oraidex_router_msg = OraidexRouterExecuteMsg::ExecuteSwapOperations { - operations: hop_swap_requests, - minimum_receive: None, - to: Some(entry_point_contract_address), + let return_denom = match operations.last() { + Some(last_op) => last_op.denom_out.clone(), + None => return Err(ContractError::SwapOperationsEmpty), }; - let denom_in = operations.first().unwrap().denom_in.clone(); - - let oraidex_router_wasm_msg = match sent_asset { - Asset::Cw20(coin) => WasmMsg::Execute { - contract_addr: coin.address, - msg: to_json_binary(&Cw20ExecuteMsg::Send { - contract: oraidex_router_contract_address.to_string(), - amount: coin.amount, - msg: to_json_binary(&oraidex_router_msg)?, - })?, - funds: vec![], - }, - Asset::Native(coin) => WasmMsg::Execute { - contract_addr: oraidex_router_contract_address.to_string(), - msg: to_json_binary(&oraidex_router_msg)?, - funds: vec![Coin { - denom: denom_in, - amount: coin.amount, - }], - }, + // Create the transfer funds back message + let transfer_funds_back_msg = WasmMsg::Execute { + contract_addr: env.contract.address.to_string(), + msg: to_json_binary(&ExecuteMsg::TransferFundsBack { + swapper: entry_point_contract_address, + return_denom, + })?, + funds: vec![], }; Ok(response - .add_message(oraidex_router_wasm_msg) + .add_message(transfer_funds_back_msg) .add_attribute("action", "dispatch_swaps_and_transfer_back")) } +fn execute_oraidex_pool_swap( + deps: DepsMut, + env: Env, + info: MessageInfo, + operation: SwapOperation, +) -> ContractResult { + // Ensure the caller is the contract itself + if info.sender != env.contract.address { + return Err(ContractError::Unauthorized); + } + + // Get the current asset available on contract to swap in + let offer_asset = get_current_asset_available(&deps, &env, &operation.denom_in)?; + // Error if the offer asset amount is zero + if offer_asset.amount().is_zero() { + return Err(ContractError::NoOfferAssetAmount); + } + + // Create the oraidex pool swap msg depending on the offer asset type + let (contract_addr, msg) = parse_to_swap_msg(&deps.as_ref(), operation)?; + + // Create the wasm oraidex pool swap message + let swap_msg = offer_asset.into_wasm_msg(contract_addr.to_string(), msg)?; + + Ok(Response::new() + .add_message(swap_msg) + .add_attribute("action", "dispatch_oraidex_pool_swap")) +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> ContractResult { match msg { @@ -467,9 +475,9 @@ fn simulate_swap_exact_asset_in( // Simulates a swap exact amount out request, returning the asset in needed and optionally the reverse simulation responses fn simulate_swap_exact_asset_out( - deps: Deps, - asset_out: Asset, - swap_operations: Vec, + _deps: Deps, + _asset_out: Asset, + _swap_operations: Vec, ) -> ContractResult { panic!("not implemented") // let dexter_router_address = DEXTER_ROUTER_ADDRESS.load(deps.storage)?; @@ -534,8 +542,8 @@ fn simulate_smart_swap_exact_asset_in( // find spot prices for all the pools in the swap operations fn calculate_spot_price( - deps: Deps, - swap_operations: Vec, + _deps: Deps, + _swap_operations: Vec, ) -> ContractResult { panic!("not implemented") // let dexter_vault_address = DEXTER_VAULT_ADDRESS.load(deps.storage)?; diff --git a/contracts/adapters/swap/oraidex/src/helper.rs b/contracts/adapters/swap/oraidex/src/helper.rs index 29a9dbc7..0344224e 100644 --- a/contracts/adapters/swap/oraidex/src/helper.rs +++ b/contracts/adapters/swap/oraidex/src/helper.rs @@ -1,9 +1,13 @@ -use cosmwasm_std::{Api, StdError}; +use cosmwasm_std::{from_json, to_json_binary, Addr, Api, Binary, Deps, StdError}; use oraiswap::asset::AssetInfo; +use oraiswap::mixed_router::{ + ExecuteMsg as OraidexRouterExecuteMsg, SwapOperation as OraidexSwapOperation, +}; use oraiswap_v3::{percentage::Percentage, FeeTier, PoolKey}; +use skip::swap::{PoolMsg, SwapOperation}; -use crate::error::ContractError; +use crate::{error::ContractError, state::ORAIDEX_ROUTER_ADDRESS}; pub fn denom_to_asset_info(api: &dyn Api, denom: &str) -> AssetInfo { if let Ok(contract_addr) = api.addr_validate(denom) { @@ -52,3 +56,49 @@ pub fn convert_pool_id_to_v3_pool_key(pool_id: &str) -> Result Result<(Addr, Binary), ContractError> { + match from_json(&Binary::from_base64(&operation.pool).unwrap_or_default()) { + Ok(PoolMsg { contract, msg }) => { + return Ok(( + deps.api.addr_validate(&contract)?, + Binary::from_base64(&msg)?, + )) + } + _ => { + // swap on Oraidex + let mut hop_swap_requests: Vec = vec![]; + let oraidex_router_contract_address = ORAIDEX_ROUTER_ADDRESS.load(deps.storage)?; + + // case 2: Swap v3 + if operation.pool.contains("-") { + let pool_key = convert_pool_id_to_v3_pool_key(&operation.pool)?; + let x_to_y = pool_key.token_x == operation.denom_in; + hop_swap_requests.push(OraidexSwapOperation::SwapV3 { pool_key, x_to_y }); + } else { + // case 3: Swap v2 + hop_swap_requests.push(OraidexSwapOperation::OraiSwap { + offer_asset_info: denom_to_asset_info(deps.api, &operation.denom_in), + ask_asset_info: denom_to_asset_info(deps.api, &operation.denom_out), + }) + }; + + return Ok(( + oraidex_router_contract_address, + to_json_binary(&OraidexRouterExecuteMsg::ExecuteSwapOperations { + operations: hop_swap_requests, + minimum_receive: None, + to: None, + })?, + )); + } + } +} diff --git a/contracts/adapters/swap/oraidex/tests/test_execute_oraidex_pool_swap.rs b/contracts/adapters/swap/oraidex/tests/test_execute_oraidex_pool_swap.rs new file mode 100644 index 00000000..ce55ff37 --- /dev/null +++ b/contracts/adapters/swap/oraidex/tests/test_execute_oraidex_pool_swap.rs @@ -0,0 +1,301 @@ +use std::vec; + +use cosmwasm_std::{ + testing::{mock_dependencies_with_balances, mock_env, mock_info}, + to_json_binary, Addr, Coin, QuerierResult, + ReplyOn::Never, + SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, +}; +use cw20::{BalanceResponse, Cw20ExecuteMsg}; +use oraiswap::{ + asset::AssetInfo, + mixed_router::{ + ExecuteMsg as OraidexRouterExecuteMsg, + SwapOperation as OraidexSwapOperation, + }, + converter::{ExecuteMsg as ConverterExecuteMsg, Cw20HookMsg as ConverterCw20HookMsg} +}; +use skip::swap::{ExecuteMsg, PoolMsg, SwapOperation}; +use skip_api_swap_adapter_oraidex::{ + error::{ContractError, ContractResult}, + state::{ENTRY_POINT_CONTRACT_ADDRESS, ORAIDEX_ROUTER_ADDRESS}, +}; +use oraiswap_v3::{percentage::Percentage, FeeTier, PoolKey}; +use test_case::test_case; + +/* +Test Cases: + +Expect Success + - Swap Oraidex V2 Operation + - Swap Oraidex V3 Operation + - Convert Operation + - Convert Reverse Operation + +Expect Error + - No Native Offer Asset In Contract Balance To Swap + - No Cw20 Offer Asset In Contract Balance To Swap + - Unauthorized Caller + + */ + +// Define test parameters +struct Params { + caller: String, + contract_balance: Vec, + swap_operation: SwapOperation, + expected_message: Option, + expected_error: Option, +} + +// Test execute_swap +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "orai123".to_string(), + denom_out: "atom".to_string(), + interface: None, + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "orai123".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "oraidex_router".to_string(), + amount: Uint128::new(100u128), + msg: to_json_binary(&OraidexRouterExecuteMsg::ExecuteSwapOperations { operations: vec![OraidexSwapOperation::OraiSwap { offer_asset_info: AssetInfo::Token { contract_addr: Addr::unchecked("orai123") }, ask_asset_info:AssetInfo::Token { contract_addr: Addr::unchecked("atom") } } ], minimum_receive: None, to: None })?, + })?, + + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "Swap oraidex v2")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + swap_operation: SwapOperation { + pool: "orai123-atom-3000000000-10".to_string(), + denom_in: "orai123".to_string(), + denom_out: "atom".to_string(), + interface: None, + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "orai123".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "oraidex_router".to_string(), + amount: Uint128::new(100u128), + msg: to_json_binary(&OraidexRouterExecuteMsg::ExecuteSwapOperations { + operations: vec![ + OraidexSwapOperation::SwapV3 { pool_key: PoolKey{token_x: "orai123".to_string(), token_y: "atom".to_string(), fee_tier: FeeTier {fee: Percentage(3000000000), tick_spacing: 10}}, x_to_y: true } + ], + minimum_receive: None, + to: None })?, + })?, + + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "Swap oraidex v3")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + swap_operation: SwapOperation { + pool: to_json_binary(&PoolMsg{ contract: "orai1converter".to_string(), msg: to_json_binary(&ConverterExecuteMsg::Convert {})?.to_string()})?.to_string(), + denom_in: "orai123".to_string(), + denom_out: "orai123_converted".to_string(), + interface: None, + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "orai123".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "orai1converter".to_string(), + amount: Uint128::new(100u128), + msg: to_json_binary(&ConverterExecuteMsg::Convert {})?, + })?, + + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "convert operation")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + swap_operation: SwapOperation { + pool: to_json_binary(&PoolMsg{ contract: "orai1converter".to_string(), msg: to_json_binary(&ConverterCw20HookMsg::ConvertReverse { from: AssetInfo::Token { contract_addr: Addr::unchecked("orai123_converted") } } )?.to_string()})?.to_string(), + denom_in: "orai123".to_string(), + denom_out: "orai123_converted".to_string(), + interface: None, + }, + expected_message: Some(SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "orai123".to_string(), + msg: to_json_binary(&Cw20ExecuteMsg::Send { + contract: "orai1converter".to_string(), + amount: Uint128::new(100u128), + msg: to_json_binary(&ConverterCw20HookMsg::ConvertReverse { from: AssetInfo::Token { contract_addr: Addr::unchecked("orai123_converted") } } )?, + })?, + + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }), + expected_error: None, + }; + "convert reverse operation")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + interface: None, + }, + expected_message: None, + expected_error: Some(ContractError::NoOfferAssetAmount), + }; + "No Native Offer Asset In Contract Balance To Swap")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + swap_operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "randomcw20".to_string(), + denom_out: "ua".to_string(), + interface: None, + }, + expected_message: None, + expected_error: Some(ContractError::NoOfferAssetAmount), + }; + "No Cw20 Offer Asset In Contract Balance To Swap")] +#[test_case( + Params { + caller: "random".to_string(), + contract_balance: vec![ + Coin::new(100, "un"), + ], + swap_operation: SwapOperation{ + pool: "".to_string(), + denom_in: "".to_string(), + denom_out: "".to_string(), + interface: None, + }, + expected_message: None, + expected_error: Some(ContractError::Unauthorized), + }; + "Unauthorized Caller - Expect Error")] +fn test_execute_oraidex_pool_swap(params: Params) -> ContractResult<()> { + // Create mock dependencies + let mut deps = + mock_dependencies_with_balances(&[("swap_contract_address", ¶ms.contract_balance)]); + + // Create mock wasm handler to handle the cw20 balance queries + let wasm_handler = |query: &WasmQuery| -> QuerierResult { + match query { + WasmQuery::Smart { contract_addr, .. } => { + if contract_addr == "orai123" { + SystemResult::Ok( + ContractResult::Ok( + to_json_binary(&BalanceResponse { + balance: Uint128::from(100u128), + }) + .unwrap(), + ) + .into(), + ) + } else { + SystemResult::Ok( + ContractResult::Ok( + to_json_binary(&BalanceResponse { + balance: Uint128::from(0u128), + }) + .unwrap(), + ) + .into(), + ) + } + } + _ => panic!("Unsupported query: {:?}", query), + } + }; + deps.querier.update_wasm(wasm_handler); + + // Create mock env + let mut env = mock_env(); + env.contract.address = Addr::unchecked("swap_contract_address"); + + // Create mock info + let info = mock_info(¶ms.caller, &[]); + + // Store the entry point contract address + ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; + ORAIDEX_ROUTER_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("oraidex_router"))?; + + // Call execute_astroport_pool_swap with the given test parameters + let res = skip_api_swap_adapter_oraidex::contract::execute( + deps.as_mut(), + env, + info, + ExecuteMsg::OraidexPoolSwap { + operation: params.swap_operation, + }, + ); + + // Assert the behavior is correct + match res { + Ok(res) => { + // Assert the test did not expect an error + assert!( + params.expected_error.is_none(), + "expected test to error with {:?}, but it succeeded", + params.expected_error + ); + + // Assert the messages are correct + assert_eq!(res.messages[0], params.expected_message.unwrap()); + } + Err(err) => { + // Assert the test expected an error + assert!( + params.expected_error.is_some(), + "expected test to succeed, but it errored with {:?}", + err + ); + + // Assert the error is correct + assert_eq!(err, params.expected_error.unwrap()); + } + } + + Ok(()) +} diff --git a/contracts/adapters/swap/oraidex/tests/test_execute_receive.rs b/contracts/adapters/swap/oraidex/tests/test_execute_receive.rs new file mode 100644 index 00000000..277fbbdb --- /dev/null +++ b/contracts/adapters/swap/oraidex/tests/test_execute_receive.rs @@ -0,0 +1,244 @@ +use core::panic; +use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + to_json_binary, Addr, Coin, ContractResult as SystemContractResult, QuerierResult, + ReplyOn::Never, + SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, +}; +use cw20::{BalanceResponse, Cw20Coin, Cw20ReceiveMsg}; +use cw_utils::PaymentError::NonPayable; +use skip::{ + asset::Asset, + error::SkipError::Payment, + swap::{ExecuteMsg, SwapOperation}, +}; +use skip_api_swap_adapter_oraidex::{ + error::{ContractError, ContractResult}, + state::ENTRY_POINT_CONTRACT_ADDRESS, +}; +use test_case::test_case; + +/* +Test Cases: + +Expect Success + - One Swap Operation - Cw20 In + - One Swap Operation - Cw20 In And Out + +Expect Error + - Coin sent with cw20 + + */ + +// Define test parameters +struct Params { + caller: String, + info_funds: Vec, + sent_asset: Asset, + swap_operations: Vec, + expected_messages: Vec, + expected_error: Option, +} + +// Test execute_swap +#[test_case( + Params { + caller: "entry_point".to_string(), + info_funds: vec![], + sent_asset: Asset::Cw20(Cw20Coin { + address: "neutron123".to_string(), + amount: Uint128::from(100u128) + }), + swap_operations: vec![ + SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "ua".to_string(), + interface: None, + } + ], + expected_messages: vec![ + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "ua".to_string(), + interface: None, + } + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::TransferFundsBack { + return_denom: "ua".to_string(), + swapper: Addr::unchecked("entry_point"), + })?, + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: None, + }; + "One Swap Operation - Cw20 In")] +#[test_case( + Params { + caller: "entry_point".to_string(), + info_funds: vec![], + sent_asset: Asset::Cw20(Cw20Coin { + address: "neutron123".to_string(), + amount: Uint128::from(100u128) + }), + swap_operations: vec![ + SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "neutron987".to_string(), + interface: None, + } + ], + expected_messages: vec![ + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "neutron123".to_string(), + denom_out: "neutron987".to_string(), + interface: None, + } + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::TransferFundsBack { + return_denom: "neutron987".to_string(), + swapper: Addr::unchecked("entry_point"), + })?, + funds: vec![], + } + .into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: None, + }; + "One Swap Operation - Cw20 In And Out")] +#[test_case( + Params { + caller: "entry_point".to_string(), + info_funds: vec![ + Coin::new(100, "un"), + ], + sent_asset: Asset::Cw20(Cw20Coin { + address: "neutron123".to_string(), + amount: Uint128::from(100u128) + }), + swap_operations: vec![], + expected_messages: vec![], + expected_error: Some(ContractError::Skip(Payment(NonPayable{}))), + }; + "Coin sent with cw20 - Expect Error")] +fn test_execute_swap(params: Params) -> ContractResult<()> { + // Create mock dependencies + let mut deps = mock_dependencies(); + + // Create mock wasm handler to handle the swap adapter contract query + let wasm_handler = |query: &WasmQuery| -> QuerierResult { + match query { + WasmQuery::Smart { contract_addr, .. } => { + if contract_addr == "neutron123" { + SystemResult::Ok(SystemContractResult::Ok( + to_json_binary(&BalanceResponse { + balance: Uint128::from(100u128), + }) + .unwrap(), + )) + } else { + panic!("Unsupported contract: {:?}", query); + } + } + _ => panic!("Unsupported query: {:?}", query), + } + }; + + // Update querier with mock wasm handler + deps.querier.update_wasm(wasm_handler); + + // Create mock env + let mut env = mock_env(); + env.contract.address = Addr::unchecked("swap_contract_address"); + + // Convert info funds vector into a slice of Coin objects + let info_funds: &[Coin] = ¶ms.info_funds; + + // Create mock info with entry point contract address + let info = mock_info(params.sent_asset.denom(), info_funds); + + // Store the entry point contract address + ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; + + // Call execute_swap with the given test parameters + let res = skip_api_swap_adapter_oraidex::contract::execute( + deps.as_mut(), + env, + info, + ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: params.caller, + amount: params.sent_asset.amount(), + msg: to_json_binary(&ExecuteMsg::Swap { + operations: params.swap_operations, + }) + .unwrap(), + }), + ); + + // Assert the behavior is correct + match res { + Ok(res) => { + // Assert the test did not expect an error + assert!( + params.expected_error.is_none(), + "expected test to error with {:?}, but it succeeded", + params.expected_error + ); + + // Assert the messages are correct + assert_eq!(res.messages, params.expected_messages); + } + Err(err) => { + // Assert the test expected an error + assert!( + params.expected_error.is_some(), + "expected test to succeed, but it errored with {:?}", + err + ); + + // Assert the error is correct + assert_eq!(err, params.expected_error.unwrap()); + } + } + + Ok(()) +} diff --git a/contracts/adapters/swap/oraidex/tests/test_execute_swap.rs b/contracts/adapters/swap/oraidex/tests/test_execute_swap.rs index 05aa2194..0f4f2482 100644 --- a/contracts/adapters/swap/oraidex/tests/test_execute_swap.rs +++ b/contracts/adapters/swap/oraidex/tests/test_execute_swap.rs @@ -2,18 +2,12 @@ use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info}, to_json_binary, Addr, Coin, ReplyOn::Never, - SubMsg, WasmMsg, + SubMsg, WasmMsg, }; -use oraiswap_v3::{percentage::Percentage, FeeTier, PoolKey}; use skip::swap::{ExecuteMsg, SwapOperation}; use skip_api_swap_adapter_oraidex::{ - error::ContractResult, - state::{ENTRY_POINT_CONTRACT_ADDRESS, ORAIDEX_ROUTER_ADDRESS}, -}; - -use oraiswap::{ - asset::AssetInfo, - mixed_router::{ExecuteMsg as OraidexRouterExecuteMsg, SwapOperation as OraidexSwapOperation}, + error::{ContractError, ContractResult}, + state::ENTRY_POINT_CONTRACT_ADDRESS, }; use test_case::test_case; @@ -23,13 +17,12 @@ Test Cases: Expect Success - One Swap Operation - Multiple Swap Operations - - No Swap Operations (This is prevented in the entry point contract; and will fail on Osmosis module if attempted) + - No Swap Operations (This is prevented in the entry point contract; and will not add any swap messages to the response) Expect Error - Unauthorized Caller (Only the stored entry point contract can call this function) - No Coin Sent - More Than One Coin Sent - - Invalid Pool ID Conversion For Swap Operations */ @@ -39,19 +32,19 @@ struct Params { info_funds: Vec, swap_operations: Vec, expected_messages: Vec, - expected_error_string: String, + expected_error: Option, } // Test execute_swap #[test_case( Params { caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "orai")], + info_funds: vec![Coin::new(100, "os")], swap_operations: vec![ SwapOperation { - pool: "1".to_string(), - denom_in: "orai".to_string(), - denom_out: "atom".to_string(), + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), interface: None, } ], @@ -59,35 +52,53 @@ struct Params { SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "oraidex_router".to_string(), - msg: to_json_binary(&OraidexRouterExecuteMsg::ExecuteSwapOperations { operations: vec![OraidexSwapOperation::OraiSwap { offer_asset_info: AssetInfo::Token { contract_addr: Addr::unchecked("orai") }, ask_asset_info:AssetInfo::Token { contract_addr: Addr::unchecked("atom") } } ], minimum_receive: None, to: Some(Addr::unchecked("entry_point")) })?, - funds: vec![ - Coin::new(100, "orai") - ], + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + interface: None, + } + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::TransferFundsBack { + return_denom: "ua".to_string(), + swapper: Addr::unchecked("entry_point"), + })?, + funds: vec![], } .into(), gas_limit: None, reply_on: Never, - } + }, ], - expected_error_string: "".to_string(), + expected_error: None, }; -"One Swap Operation")] + "One Swap Operation")] #[test_case( Params { caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "orai")], + info_funds: vec![Coin::new(100, "os")], swap_operations: vec![ SwapOperation { - pool: "1".to_string(), - denom_in: "orai".to_string(), - denom_out: "uatom".to_string(), + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), interface: None, }, SwapOperation { - pool: "uatom-usdt-3000000000-10".to_string(), - denom_in: "uatom".to_string(), - denom_out: "usdt".to_string(), + pool: "pool_2".to_string(), + denom_in: "ua".to_string(), + denom_out: "un".to_string(), interface: None, } ], @@ -95,119 +106,100 @@ struct Params { SubMsg { id: 0, msg: WasmMsg::Execute { - contract_addr: "oraidex_router".to_string(), - msg: to_json_binary(&OraidexRouterExecuteMsg::ExecuteSwapOperations { - operations: vec![ - OraidexSwapOperation::OraiSwap { offer_asset_info: AssetInfo::Token { contract_addr: Addr::unchecked("orai") }, ask_asset_info:AssetInfo::Token { contract_addr: Addr::unchecked("uatom") } }, - OraidexSwapOperation::SwapV3 { pool_key: PoolKey{token_x: "uatom".to_string(), token_y: "usdt".to_string(), fee_tier: FeeTier {fee: Percentage(3000000000), tick_spacing: 10}}, x_to_y: true }], - minimum_receive: None, - to: Some(Addr::unchecked("entry_point")) })?, - funds: vec![ - Coin::new(100, "orai") - ], + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: SwapOperation { + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), + interface: None, + } + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::OraidexPoolSwap { + operation: SwapOperation { + pool: "pool_2".to_string(), + denom_in: "ua".to_string(), + denom_out: "un".to_string(), + interface: None, + } + })?, + funds: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + SubMsg { + id: 0, + msg: WasmMsg::Execute { + contract_addr: "swap_contract_address".to_string(), + msg: to_json_binary(&ExecuteMsg::TransferFundsBack { + return_denom: "un".to_string(), + swapper: Addr::unchecked("entry_point"), + })?, + funds: vec![], } .into(), gas_limit: None, reply_on: Never, }, ], - expected_error_string: "".to_string(), + expected_error: None, }; -"Multiple Swap Operations")] + "Multiple Swap Operations")] #[test_case( Params { caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "orai")], + info_funds: vec![Coin::new(100, "os")], swap_operations: vec![], - expected_messages: vec![ - ], - expected_error_string: "swap_operations cannot be empty".to_string(), + expected_messages: vec![], + expected_error: Some(ContractError::SwapOperationsEmpty), }; -"No Swap Operations")] + "No Swap Operations")] #[test_case( Params { caller: "entry_point".to_string(), info_funds: vec![], - swap_operations: vec![ - SwapOperation { - pool: "1".to_string(), - denom_in: "os".to_string(), - denom_out: "uatom".to_string(), - interface: None, - } - ], + swap_operations: vec![], expected_messages: vec![], - expected_error_string: "No funds sent".to_string(), + expected_error: Some(ContractError::Payment(cw_utils::PaymentError::NoFunds{})), }; "No Coin Sent - Expect Error")] #[test_case( Params { caller: "entry_point".to_string(), info_funds: vec![ + Coin::new(100, "un"), Coin::new(100, "os"), - Coin::new(100, "uatom"), - ], - swap_operations: vec![ - SwapOperation { - pool: "1".to_string(), - denom_in: "os".to_string(), - denom_out: "uatom".to_string(), - interface: None, - } ], + swap_operations: vec![], expected_messages: vec![], - expected_error_string: "Sent more than one denomination".to_string(), + expected_error: Some(ContractError::Payment(cw_utils::PaymentError::MultipleDenoms{})), }; "More Than One Coin Sent - Expect Error")] -#[test_case( - Params { - caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "os")], - swap_operations: vec![ - SwapOperation { - pool: "tokenx-tokeny-100".to_string(), - denom_in: "os".to_string(), - denom_out: "uatom".to_string(), - interface: None, - } - ], - expected_messages: vec![], - expected_error_string: "Generic error: Invalid v3 pool_id, require exactly 4 fields".to_string(), - }; - "Invalid Pool ID Conversion For Swap Operations - Expect Error")] -#[test_case( - Params { - caller: "entry_point".to_string(), - info_funds: vec![Coin::new(100, "os")], - swap_operations: vec![ - SwapOperation { - pool: "tokenx-tokeny-abc-def".to_string(), - denom_in: "os".to_string(), - denom_out: "uatom".to_string(), - interface: None, - } - ], - expected_messages: vec![], - expected_error_string: "Generic error: Invalid fee in v3 pool".to_string(), - }; - "Invalid Pool ID Conversion For Swap Operations, cannot parse string to uint - Expect Error")] #[test_case( Params { caller: "random".to_string(), info_funds: vec![ - Coin::new(100, "uxprt"), - // Coin::new(100, "os"), + Coin::new(100, "os"), ], - swap_operations: vec![ + swap_operations: vec![ SwapOperation { - pool: "1".to_string(), - denom_in: "uxprt".to_string(), - denom_out: "stk/uxprt".to_string(), + pool: "pool_1".to_string(), + denom_in: "os".to_string(), + denom_out: "ua".to_string(), interface: None, - } - ], + }], expected_messages: vec![], - expected_error_string: "Unauthorized".to_string(), + expected_error: Some(ContractError::Unauthorized), }; "Unauthorized Caller - Expect Error")] fn test_execute_swap(params: Params) -> ContractResult<()> { @@ -226,7 +218,6 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { // Store the entry point contract address ENTRY_POINT_CONTRACT_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("entry_point"))?; - ORAIDEX_ROUTER_ADDRESS.save(deps.as_mut().storage, &Addr::unchecked("oraidex_router"))?; // Call execute_swap with the given test parameters let res = skip_api_swap_adapter_oraidex::contract::execute( @@ -237,16 +228,15 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { operations: params.swap_operations.clone(), }, ); - println!("{:?}", res); // Assert the behavior is correct match res { Ok(res) => { // Assert the test did not expect an error assert!( - params.expected_error_string.is_empty(), + params.expected_error.is_none(), "expected test to error with {:?}, but it succeeded", - params.expected_error_string + params.expected_error ); // Assert the messages are correct @@ -255,13 +245,13 @@ fn test_execute_swap(params: Params) -> ContractResult<()> { Err(err) => { // Assert the test expected an error assert!( - !params.expected_error_string.is_empty(), + params.expected_error.is_some(), "expected test to succeed, but it errored with {:?}", err ); // Assert the error is correct - assert_eq!(err.to_string(), params.expected_error_string); + assert_eq!(err, params.expected_error.unwrap()); } } diff --git a/contracts/adapters/swap/oraidex/tests/test_execute_transfer_funds_back.rs b/contracts/adapters/swap/oraidex/tests/test_execute_transfer_funds_back.rs new file mode 100644 index 00000000..c7eea30f --- /dev/null +++ b/contracts/adapters/swap/oraidex/tests/test_execute_transfer_funds_back.rs @@ -0,0 +1,167 @@ +use cosmwasm_std::{ + testing::{mock_dependencies_with_balances, mock_env, mock_info}, + Addr, BankMsg, Coin, + ReplyOn::Never, + SubMsg, +}; +use skip::{error::SkipError, swap::ExecuteMsg}; +use skip_api_swap_adapter_oraidex::error::{ContractError, ContractResult}; +use test_case::test_case; + +/* +Test Cases: + +Expect Success + - One Coin Balance + - Multiple Coin Balance + - No Coin Balance (This will fail at the bank module if attempted) + +Expect Error + - Unauthorized Caller (Only contract itself can call this function) + */ + +// Define test parameters +struct Params { + caller: String, + contract_balance: Vec, + return_denom: String, + expected_messages: Vec, + expected_error: Option, +} + +// Test execute_transfer_funds_back +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![Coin::new(100, "os")], + return_denom: "os".to_string(), + expected_messages: vec![ + SubMsg { + id: 0, + msg: BankMsg::Send { + to_address: "swapper".to_string(), + amount: vec![Coin::new(100, "os")], + }.into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: None, + }; + "Transfers One Coin Balance")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![ + Coin::new(100, "os"), + Coin::new(100, "uatom"), + ], + return_denom: "os".to_string(), + expected_messages: vec![ + SubMsg { + id: 0, + msg: BankMsg::Send { + to_address: "swapper".to_string(), + amount: vec![ + Coin::new(100, "os"), + Coin::new(100, "uatom") + ], + }.into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: None, + }; + "Transfers Multiple Coin Balance")] +#[test_case( + Params { + caller: "swap_contract_address".to_string(), + contract_balance: vec![], + return_denom: "os".to_string(), + expected_messages: vec![ + SubMsg { + id: 0, + msg: BankMsg::Send { + to_address: "swapper".to_string(), + amount: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: None, + }; + "Transfers No Coin Balance")] +#[test_case( + Params { + caller: "random".to_string(), + contract_balance: vec![], + return_denom: "os".to_string(), + expected_messages: vec![ + SubMsg { + id: 0, + msg: BankMsg::Send { + to_address: "swapper".to_string(), + amount: vec![], + }.into(), + gas_limit: None, + reply_on: Never, + }, + ], + expected_error: Some(ContractError::Skip(SkipError::Unauthorized)), + }; + "Unauthorized Caller")] +fn test_execute_transfer_funds_back(params: Params) -> ContractResult<()> { + // Convert params contract balance to a slice + let contract_balance: &[Coin] = ¶ms.contract_balance; + + // Create mock dependencies + let mut deps = mock_dependencies_with_balances(&[("swap_contract_address", contract_balance)]); + + // Create mock env + let mut env = mock_env(); + env.contract.address = Addr::unchecked("swap_contract_address"); + + // Create mock info + let info = mock_info(¶ms.caller, &[]); + + // Call execute_swap with the given test parameters + let res = skip_api_swap_adapter_oraidex::contract::execute( + deps.as_mut(), + env, + info, + ExecuteMsg::TransferFundsBack { + return_denom: params.return_denom, + swapper: Addr::unchecked("swapper"), + }, + ); + + // Assert the behavior is correct + match res { + Ok(res) => { + // Assert the test did not expect an error + assert!( + params.expected_error.is_none(), + "expected test to error with {:?}, but it succeeded", + params.expected_error + ); + + // Assert the messages are correct + assert_eq!(res.messages, params.expected_messages); + } + Err(err) => { + // Assert the test expected an error + assert!( + params.expected_error.is_some(), + "expected test to succeed, but it errored with {:?}", + err + ); + + // Assert the error is correct + assert_eq!(err, params.expected_error.unwrap()); + } + } + + Ok(()) +} diff --git a/contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs b/contracts/adapters/swap/osmosis-poolmanager/src/bin/schema.rs similarity index 100% rename from contracts/adapters/swap/osmosis-poolmanager/src/bin/osmosis-poolmanager-schema.rs rename to contracts/adapters/swap/osmosis-poolmanager/src/bin/schema.rs diff --git a/packages/skip/src/swap.rs b/packages/skip/src/swap.rs index 566cb6c3..4ae43b16 100644 --- a/packages/skip/src/swap.rs +++ b/packages/skip/src/swap.rs @@ -5,7 +5,7 @@ use std::{convert::TryFrom, num::ParseIntError}; use astroport::{asset::AssetInfo, router::SwapOperation as AstroportSwapOperation}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_json_binary, StdError, StdResult, WasmMsg}; +use cosmwasm_std::{to_json_binary, StdError, StdResult}; use cosmwasm_std::{ Addr, Api, BankMsg, Binary, CosmosMsg, Decimal, DepsMut, Env, MessageInfo, Response, Uint128, }; @@ -78,6 +78,7 @@ pub enum ExecuteMsg { TransferFundsBack { swapper: Addr, return_denom: String }, AstroportPoolSwap { operation: SwapOperation }, // Only used for the astroport swap adapter contract WhiteWhalePoolSwap { operation: SwapOperation }, // Only used for the white whale swap adapter contract + OraidexPoolSwap { operation: SwapOperation }, // Only used for the oraidex swap adapter contract } #[cw_serde] @@ -213,6 +214,12 @@ pub struct SwapOperation { pub interface: Option, } +#[cw_serde] +pub struct PoolMsg { + pub contract: String, + pub msg: String, // base64 +} + // ORAICHAIN universal swap conversion impl SwapOperation { pub fn from(operations: Vec) -> Vec {