@clober/v2-sdk 0.0.9 → 0.0.10-9.dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -4
- package/dist/cjs/abis/core/book-manager-abi.js +112 -0
- package/dist/cjs/abis/core/book-manager-abi.js.map +1 -0
- package/dist/cjs/abis/core/book-viewer-abi.js +137 -5
- package/dist/cjs/abis/core/book-viewer-abi.js.map +1 -1
- package/dist/cjs/abis/core/controller-abi.js +29 -24
- package/dist/cjs/abis/core/controller-abi.js.map +1 -1
- package/dist/cjs/abis/governance/election-governor-abi.js +838 -0
- package/dist/cjs/abis/governance/election-governor-abi.js.map +1 -0
- package/dist/cjs/abis/governance/keepers-registry-abi.js +546 -0
- package/dist/cjs/abis/governance/keepers-registry-abi.js.map +1 -0
- package/dist/cjs/abis/governance/vclob-abi.js +743 -0
- package/dist/cjs/abis/governance/vclob-abi.js.map +1 -0
- package/dist/cjs/abis/rebalancer/minter-abi.js +262 -0
- package/dist/cjs/abis/rebalancer/minter-abi.js.map +1 -0
- package/dist/cjs/abis/rebalancer/mock-swap-abi.js +95 -0
- package/dist/cjs/abis/rebalancer/mock-swap-abi.js.map +1 -0
- package/dist/cjs/abis/rebalancer/operator-abi.js +401 -0
- package/dist/cjs/abis/rebalancer/operator-abi.js.map +1 -0
- package/dist/cjs/abis/rebalancer/rebalancer-abi.js +1326 -0
- package/dist/cjs/abis/rebalancer/rebalancer-abi.js.map +1 -0
- package/dist/cjs/abis/rebalancer/strategy-abi.js +895 -0
- package/dist/cjs/abis/rebalancer/strategy-abi.js.map +1 -0
- package/dist/cjs/apis/chart-logs.js +30 -13
- package/dist/cjs/apis/chart-logs.js.map +1 -1
- package/dist/cjs/apis/market.js +45 -22
- package/dist/cjs/apis/market.js.map +1 -1
- package/dist/cjs/apis/odos.js +100 -0
- package/dist/cjs/apis/odos.js.map +1 -0
- package/dist/cjs/apis/open-order.js +61 -36
- package/dist/cjs/apis/open-order.js.map +1 -1
- package/dist/cjs/apis/pool.js +96 -0
- package/dist/cjs/apis/pool.js.map +1 -0
- package/dist/cjs/apis/strategy.js +53 -0
- package/dist/cjs/apis/strategy.js.map +1 -0
- package/dist/cjs/apis/vclob.js +47 -0
- package/dist/cjs/apis/vclob.js.map +1 -0
- package/dist/cjs/approval.js +83 -26
- package/dist/cjs/approval.js.map +1 -1
- package/dist/cjs/call.js +908 -156
- package/dist/cjs/call.js.map +1 -1
- package/dist/cjs/constants/addresses.js +104 -1
- package/dist/cjs/constants/addresses.js.map +1 -1
- package/dist/cjs/constants/bera-bartio-chain.js +30 -0
- package/dist/cjs/constants/bera-bartio-chain.js.map +1 -0
- package/dist/cjs/constants/chain.js +29 -2
- package/dist/cjs/constants/chain.js.map +1 -1
- package/dist/cjs/constants/currency.js +99 -3
- package/dist/cjs/constants/currency.js.map +1 -1
- package/dist/cjs/constants/fee.js +23 -2
- package/dist/cjs/constants/fee.js.map +1 -1
- package/dist/cjs/constants/mitosis-testnet-chain.js +30 -0
- package/dist/cjs/constants/mitosis-testnet-chain.js.map +1 -0
- package/dist/cjs/constants/monad-testnet-chain.js +40 -0
- package/dist/cjs/constants/monad-testnet-chain.js.map +1 -0
- package/dist/cjs/constants/permit.js +14 -0
- package/dist/cjs/constants/permit.js.map +1 -0
- package/dist/cjs/constants/price.js +2 -1
- package/dist/cjs/constants/price.js.map +1 -1
- package/dist/cjs/constants/sonic-mainnet-chain.js +30 -0
- package/dist/cjs/constants/sonic-mainnet-chain.js.map +1 -0
- package/dist/cjs/constants/subgraph.js +38 -0
- package/dist/cjs/constants/subgraph.js.map +1 -0
- package/dist/cjs/constants/test-chain.js +50 -0
- package/dist/cjs/constants/test-chain.js.map +1 -0
- package/dist/cjs/constants/tick.js +6 -0
- package/dist/cjs/constants/tick.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/model/book.js +62 -35
- package/dist/cjs/model/book.js.map +1 -1
- package/dist/cjs/model/market.js +61 -26
- package/dist/cjs/model/market.js.map +1 -1
- package/dist/cjs/model/pool.js +240 -0
- package/dist/cjs/model/pool.js.map +1 -0
- package/dist/cjs/model/vclob.js +3 -0
- package/dist/cjs/model/vclob.js.map +1 -0
- package/dist/cjs/type.js +8 -1
- package/dist/cjs/type.js.map +1 -1
- package/dist/cjs/utils/allowance.js +39 -0
- package/dist/cjs/utils/allowance.js.map +1 -0
- package/dist/cjs/utils/approval.js +2 -3
- package/dist/cjs/utils/approval.js.map +1 -1
- package/dist/cjs/utils/bigint.js +5 -1
- package/dist/cjs/utils/bigint.js.map +1 -1
- package/dist/cjs/utils/book-id.js +7 -7
- package/dist/cjs/utils/book-id.js.map +1 -1
- package/dist/cjs/utils/build-transaction.js +9 -9
- package/dist/cjs/utils/build-transaction.js.map +1 -1
- package/dist/cjs/utils/currency.js +61 -27
- package/dist/cjs/utils/currency.js.map +1 -1
- package/dist/cjs/utils/market.js +1 -1
- package/dist/cjs/utils/market.js.map +1 -1
- package/dist/cjs/utils/math.js +3 -1
- package/dist/cjs/utils/math.js.map +1 -1
- package/dist/cjs/utils/open.js +35 -25
- package/dist/cjs/utils/open.js.map +1 -1
- package/dist/cjs/utils/order.js +68 -126
- package/dist/cjs/utils/order.js.map +1 -1
- package/dist/cjs/utils/pool-key.js +17 -0
- package/dist/cjs/utils/pool-key.js.map +1 -0
- package/dist/cjs/utils/pool.js +88 -0
- package/dist/cjs/utils/pool.js.map +1 -0
- package/dist/cjs/utils/prices.js +40 -5
- package/dist/cjs/utils/prices.js.map +1 -1
- package/dist/cjs/utils/tick.js +12 -1
- package/dist/cjs/utils/tick.js.map +1 -1
- package/dist/cjs/utils/time-series.js +31 -0
- package/dist/cjs/utils/time-series.js.map +1 -0
- package/dist/cjs/utils/unit-size.js +48 -0
- package/dist/cjs/utils/unit-size.js.map +1 -0
- package/dist/cjs/utils.js +18 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/cjs/view.js +463 -44
- package/dist/cjs/view.js.map +1 -1
- package/dist/esm/abis/core/book-manager-abi.js +109 -0
- package/dist/esm/abis/core/book-manager-abi.js.map +1 -0
- package/dist/esm/abis/core/book-viewer-abi.js +137 -5
- package/dist/esm/abis/core/book-viewer-abi.js.map +1 -1
- package/dist/esm/abis/core/controller-abi.js +29 -24
- package/dist/esm/abis/core/controller-abi.js.map +1 -1
- package/dist/esm/abis/governance/election-governor-abi.js +835 -0
- package/dist/esm/abis/governance/election-governor-abi.js.map +1 -0
- package/dist/esm/abis/governance/keepers-registry-abi.js +543 -0
- package/dist/esm/abis/governance/keepers-registry-abi.js.map +1 -0
- package/dist/esm/abis/governance/vclob-abi.js +740 -0
- package/dist/esm/abis/governance/vclob-abi.js.map +1 -0
- package/dist/esm/abis/rebalancer/minter-abi.js +259 -0
- package/dist/esm/abis/rebalancer/minter-abi.js.map +1 -0
- package/dist/esm/abis/rebalancer/mock-swap-abi.js +92 -0
- package/dist/esm/abis/rebalancer/mock-swap-abi.js.map +1 -0
- package/dist/esm/abis/rebalancer/operator-abi.js +398 -0
- package/dist/esm/abis/rebalancer/operator-abi.js.map +1 -0
- package/dist/esm/abis/rebalancer/rebalancer-abi.js +1323 -0
- package/dist/esm/abis/rebalancer/rebalancer-abi.js.map +1 -0
- package/dist/esm/abis/rebalancer/strategy-abi.js +892 -0
- package/dist/esm/abis/rebalancer/strategy-abi.js.map +1 -0
- package/dist/esm/apis/chart-logs.js +29 -12
- package/dist/esm/apis/chart-logs.js.map +1 -1
- package/dist/esm/apis/market.js +47 -24
- package/dist/esm/apis/market.js.map +1 -1
- package/dist/esm/apis/odos.js +94 -0
- package/dist/esm/apis/odos.js.map +1 -0
- package/dist/esm/apis/open-order.js +63 -37
- package/dist/esm/apis/open-order.js.map +1 -1
- package/dist/esm/apis/pool.js +91 -0
- package/dist/esm/apis/pool.js.map +1 -0
- package/dist/esm/apis/strategy.js +48 -0
- package/dist/esm/apis/strategy.js.map +1 -0
- package/dist/esm/apis/vclob.js +43 -0
- package/dist/esm/apis/vclob.js.map +1 -0
- package/dist/esm/approval.js +109 -36
- package/dist/esm/approval.js.map +1 -1
- package/dist/esm/call.js +947 -210
- package/dist/esm/call.js.map +1 -1
- package/dist/esm/constants/addresses.js +105 -2
- package/dist/esm/constants/addresses.js.map +1 -1
- package/dist/esm/constants/bera-bartio-chain.js +27 -0
- package/dist/esm/constants/bera-bartio-chain.js.map +1 -0
- package/dist/esm/constants/chain.js +28 -2
- package/dist/esm/constants/chain.js.map +1 -1
- package/dist/esm/constants/currency.js +100 -2
- package/dist/esm/constants/currency.js.map +1 -1
- package/dist/esm/constants/fee.js +23 -2
- package/dist/esm/constants/fee.js.map +1 -1
- package/dist/esm/constants/mitosis-testnet-chain.js +27 -0
- package/dist/esm/constants/mitosis-testnet-chain.js.map +1 -0
- package/dist/esm/constants/monad-testnet-chain.js +37 -0
- package/dist/esm/constants/monad-testnet-chain.js.map +1 -0
- package/dist/esm/constants/permit.js +11 -0
- package/dist/esm/constants/permit.js.map +1 -0
- package/dist/esm/constants/price.js +1 -0
- package/dist/esm/constants/price.js.map +1 -1
- package/dist/esm/constants/sonic-mainnet-chain.js +27 -0
- package/dist/esm/constants/sonic-mainnet-chain.js.map +1 -0
- package/dist/esm/constants/subgraph.js +34 -0
- package/dist/esm/constants/subgraph.js.map +1 -0
- package/dist/esm/constants/test-chain.js +47 -0
- package/dist/esm/constants/test-chain.js.map +1 -0
- package/dist/esm/constants/tick.js +3 -0
- package/dist/esm/constants/tick.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/model/book.js +62 -35
- package/dist/esm/model/book.js.map +1 -1
- package/dist/esm/model/market.js +63 -28
- package/dist/esm/model/market.js.map +1 -1
- package/dist/esm/model/pool.js +237 -0
- package/dist/esm/model/pool.js.map +1 -0
- package/dist/esm/model/vclob.js +2 -0
- package/dist/esm/model/vclob.js.map +1 -0
- package/dist/esm/type.js +7 -0
- package/dist/esm/type.js.map +1 -1
- package/dist/esm/utils/allowance.js +35 -0
- package/dist/esm/utils/allowance.js.map +1 -0
- package/dist/esm/utils/approval.js +2 -3
- package/dist/esm/utils/approval.js.map +1 -1
- package/dist/esm/utils/bigint.js +2 -0
- package/dist/esm/utils/bigint.js.map +1 -1
- package/dist/esm/utils/book-id.js +7 -7
- package/dist/esm/utils/book-id.js.map +1 -1
- package/dist/esm/utils/build-transaction.js +9 -9
- package/dist/esm/utils/build-transaction.js.map +1 -1
- package/dist/esm/utils/currency.js +59 -25
- package/dist/esm/utils/currency.js.map +1 -1
- package/dist/esm/utils/market.js +1 -1
- package/dist/esm/utils/market.js.map +1 -1
- package/dist/esm/utils/math.js +1 -0
- package/dist/esm/utils/math.js.map +1 -1
- package/dist/esm/utils/open.js +33 -23
- package/dist/esm/utils/open.js.map +1 -1
- package/dist/esm/utils/order.js +67 -125
- package/dist/esm/utils/order.js.map +1 -1
- package/dist/esm/utils/pool-key.js +12 -0
- package/dist/esm/utils/pool-key.js.map +1 -0
- package/dist/esm/utils/pool.js +84 -0
- package/dist/esm/utils/pool.js.map +1 -0
- package/dist/esm/utils/prices.js +39 -5
- package/dist/esm/utils/prices.js.map +1 -1
- package/dist/esm/utils/tick.js +11 -1
- package/dist/esm/utils/tick.js.map +1 -1
- package/dist/esm/utils/time-series.js +27 -0
- package/dist/esm/utils/time-series.js.map +1 -0
- package/dist/esm/utils/unit-size.js +44 -0
- package/dist/esm/utils/unit-size.js.map +1 -0
- package/dist/esm/utils.js +5 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/view.js +520 -61
- package/dist/esm/view.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/abis/core/book-manager-abi.d.ts +82 -0
- package/dist/types/abis/core/book-manager-abi.d.ts.map +1 -0
- package/dist/types/abis/core/book-viewer-abi.d.ts +107 -5
- package/dist/types/abis/core/book-viewer-abi.d.ts.map +1 -1
- package/dist/types/abis/core/controller-abi.d.ts +23 -19
- package/dist/types/abis/core/controller-abi.d.ts.map +1 -1
- package/dist/types/abis/governance/election-governor-abi.d.ts +648 -0
- package/dist/types/abis/governance/election-governor-abi.d.ts.map +1 -0
- package/dist/types/abis/governance/keepers-registry-abi.d.ts +417 -0
- package/dist/types/abis/governance/keepers-registry-abi.d.ts.map +1 -0
- package/dist/types/abis/governance/vclob-abi.d.ts +568 -0
- package/dist/types/abis/governance/vclob-abi.d.ts.map +1 -0
- package/dist/types/abis/rebalancer/minter-abi.d.ts +198 -0
- package/dist/types/abis/rebalancer/minter-abi.d.ts.map +1 -0
- package/dist/types/abis/rebalancer/mock-swap-abi.d.ts +70 -0
- package/dist/types/abis/rebalancer/mock-swap-abi.d.ts.map +1 -0
- package/dist/types/abis/rebalancer/operator-abi.d.ts +308 -0
- package/dist/types/abis/rebalancer/operator-abi.d.ts.map +1 -0
- package/dist/types/abis/rebalancer/rebalancer-abi.d.ts +1023 -0
- package/dist/types/abis/rebalancer/rebalancer-abi.d.ts.map +1 -0
- package/dist/types/abis/rebalancer/strategy-abi.d.ts +690 -0
- package/dist/types/abis/rebalancer/strategy-abi.d.ts.map +1 -0
- package/dist/types/apis/chart-logs.d.ts +3 -0
- package/dist/types/apis/chart-logs.d.ts.map +1 -1
- package/dist/types/apis/market.d.ts +2 -1
- package/dist/types/apis/market.d.ts.map +1 -1
- package/dist/types/apis/odos.d.ts +28 -0
- package/dist/types/apis/odos.d.ts.map +1 -0
- package/dist/types/apis/open-order.d.ts +4 -2
- package/dist/types/apis/open-order.d.ts.map +1 -1
- package/dist/types/apis/pool.d.ts +11 -0
- package/dist/types/apis/pool.d.ts.map +1 -0
- package/dist/types/apis/strategy.d.ts +6 -0
- package/dist/types/apis/strategy.d.ts.map +1 -0
- package/dist/types/apis/vclob.d.ts +5 -0
- package/dist/types/apis/vclob.d.ts.map +1 -0
- package/dist/types/approval.d.ts +35 -10
- package/dist/types/approval.d.ts.map +1 -1
- package/dist/types/call.d.ts +288 -71
- package/dist/types/call.d.ts.map +1 -1
- package/dist/types/constants/addresses.d.ts +7 -0
- package/dist/types/constants/addresses.d.ts.map +1 -1
- package/dist/types/constants/bera-bartio-chain.d.ts +33 -0
- package/dist/types/constants/bera-bartio-chain.d.ts.map +1 -0
- package/dist/types/constants/chain.d.ts +10 -2
- package/dist/types/constants/chain.d.ts.map +1 -1
- package/dist/types/constants/currency.d.ts +9 -0
- package/dist/types/constants/currency.d.ts.map +1 -1
- package/dist/types/constants/fee.d.ts +7 -2
- package/dist/types/constants/fee.d.ts.map +1 -1
- package/dist/types/constants/mitosis-testnet-chain.d.ts +33 -0
- package/dist/types/constants/mitosis-testnet-chain.d.ts.map +1 -0
- package/dist/types/constants/monad-testnet-chain.d.ts +37 -0
- package/dist/types/constants/monad-testnet-chain.d.ts.map +1 -0
- package/dist/types/constants/permit.d.ts +10 -0
- package/dist/types/constants/permit.d.ts.map +1 -0
- package/dist/types/constants/price.d.ts +1 -0
- package/dist/types/constants/price.d.ts.map +1 -1
- package/dist/types/constants/sonic-mainnet-chain.d.ts +33 -0
- package/dist/types/constants/sonic-mainnet-chain.d.ts.map +1 -0
- package/dist/types/constants/subgraph.d.ts +5 -0
- package/dist/types/constants/subgraph.d.ts.map +1 -0
- package/dist/types/constants/test-chain.d.ts +4 -0
- package/dist/types/constants/test-chain.d.ts.map +1 -0
- package/dist/types/constants/tick.d.ts +3 -0
- package/dist/types/constants/tick.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/model/book.d.ts +25 -33
- package/dist/types/model/book.d.ts.map +1 -1
- package/dist/types/model/currency.d.ts +7 -0
- package/dist/types/model/currency.d.ts.map +1 -1
- package/dist/types/model/depth.d.ts +4 -3
- package/dist/types/model/depth.d.ts.map +1 -1
- package/dist/types/model/market.d.ts +24 -13
- package/dist/types/model/market.d.ts.map +1 -1
- package/dist/types/model/open-order.d.ts +20 -27
- package/dist/types/model/open-order.d.ts.map +1 -1
- package/dist/types/model/pool.d.ts +77 -0
- package/dist/types/model/pool.d.ts.map +1 -0
- package/dist/types/model/vclob.d.ts +7 -0
- package/dist/types/model/vclob.d.ts.map +1 -0
- package/dist/types/type.d.ts +142 -6
- package/dist/types/type.d.ts.map +1 -1
- package/dist/types/utils/allowance.d.ts +3 -0
- package/dist/types/utils/allowance.d.ts.map +1 -0
- package/dist/types/utils/approval.d.ts +2 -1
- package/dist/types/utils/approval.d.ts.map +1 -1
- package/dist/types/utils/bigint.d.ts +2 -0
- package/dist/types/utils/bigint.d.ts.map +1 -1
- package/dist/types/utils/book-id.d.ts +2 -1
- package/dist/types/utils/book-id.d.ts.map +1 -1
- package/dist/types/utils/build-transaction.d.ts +3 -3
- package/dist/types/utils/build-transaction.d.ts.map +1 -1
- package/dist/types/utils/currency.d.ts +3 -2
- package/dist/types/utils/currency.d.ts.map +1 -1
- package/dist/types/utils/math.d.ts +1 -0
- package/dist/types/utils/math.d.ts.map +1 -1
- package/dist/types/utils/open.d.ts +2 -1
- package/dist/types/utils/open.d.ts.map +1 -1
- package/dist/types/utils/order.d.ts +4 -11
- package/dist/types/utils/order.d.ts.map +1 -1
- package/dist/types/utils/pool-key.d.ts +3 -0
- package/dist/types/utils/pool-key.d.ts.map +1 -0
- package/dist/types/utils/pool.d.ts +11 -0
- package/dist/types/utils/pool.d.ts.map +1 -0
- package/dist/types/utils/prices.d.ts +13 -2
- package/dist/types/utils/prices.d.ts.map +1 -1
- package/dist/types/utils/tick.d.ts +1 -0
- package/dist/types/utils/tick.d.ts.map +1 -1
- package/dist/types/utils/time-series.d.ts +4 -0
- package/dist/types/utils/time-series.d.ts.map +1 -0
- package/dist/types/utils/unit-size.d.ts +5 -0
- package/dist/types/utils/unit-size.d.ts.map +1 -0
- package/dist/types/utils.d.ts +5 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/view.d.ts +248 -30
- package/dist/types/view.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/cjs/abis/core/params-abi.js +0 -62
- package/dist/cjs/abis/core/params-abi.js.map +0 -1
- package/dist/cjs/apis/subgraph.js +0 -26
- package/dist/cjs/apis/subgraph.js.map +0 -1
- package/dist/cjs/constants/client.js +0 -14
- package/dist/cjs/constants/client.js.map +0 -1
- package/dist/cjs/constants/subgraph-url.js +0 -8
- package/dist/cjs/constants/subgraph-url.js.map +0 -1
- package/dist/cjs/signature.js +0 -146
- package/dist/cjs/signature.js.map +0 -1
- package/dist/cjs/utils/decorator.js +0 -13
- package/dist/cjs/utils/decorator.js.map +0 -1
- package/dist/cjs/utils/unit.js +0 -34
- package/dist/cjs/utils/unit.js.map +0 -1
- package/dist/esm/abis/core/params-abi.js +0 -59
- package/dist/esm/abis/core/params-abi.js.map +0 -1
- package/dist/esm/apis/subgraph.js +0 -22
- package/dist/esm/apis/subgraph.js.map +0 -1
- package/dist/esm/constants/client.js +0 -10
- package/dist/esm/constants/client.js.map +0 -1
- package/dist/esm/constants/subgraph-url.js +0 -5
- package/dist/esm/constants/subgraph-url.js.map +0 -1
- package/dist/esm/signature.js +0 -182
- package/dist/esm/signature.js.map +0 -1
- package/dist/esm/utils/decorator.js +0 -9
- package/dist/esm/utils/decorator.js.map +0 -1
- package/dist/esm/utils/unit.js +0 -30
- package/dist/esm/utils/unit.js.map +0 -1
- package/dist/types/abis/core/params-abi.d.ts +0 -21
- package/dist/types/abis/core/params-abi.d.ts.map +0 -1
- package/dist/types/apis/subgraph.d.ts +0 -3
- package/dist/types/apis/subgraph.d.ts.map +0 -1
- package/dist/types/constants/client.d.ts +0 -5
- package/dist/types/constants/client.d.ts.map +0 -1
- package/dist/types/constants/subgraph-url.d.ts +0 -5
- package/dist/types/constants/subgraph-url.d.ts.map +0 -1
- package/dist/types/signature.d.ts +0 -50
- package/dist/types/signature.d.ts.map +0 -1
- package/dist/types/utils/decorator.d.ts +0 -6
- package/dist/types/utils/decorator.d.ts.map +0 -1
- package/dist/types/utils/unit.d.ts +0 -4
- package/dist/types/utils/unit.d.ts.map +0 -1
package/dist/esm/call.js
CHANGED
|
@@ -1,68 +1,86 @@
|
|
|
1
|
-
import { formatUnits, isAddressEqual, parseUnits, zeroAddress, zeroHash, } from 'viem';
|
|
1
|
+
import { createPublicClient, formatUnits, getAddress, http, isAddressEqual, parseUnits, zeroAddress, zeroHash, } from 'viem';
|
|
2
2
|
import { CHAIN_MAP } from './constants/chain';
|
|
3
|
-
import {
|
|
3
|
+
import { calculateUnitSize } from './utils/unit-size';
|
|
4
4
|
import { CONTROLLER_ABI } from './abis/core/controller-abi';
|
|
5
5
|
import { getDeadlineTimestampInSeconds } from './utils/time';
|
|
6
6
|
import { buildTransaction } from './utils/build-transaction';
|
|
7
7
|
import { CONTRACT_ADDRESSES } from './constants/addresses';
|
|
8
8
|
import { MAKER_DEFAULT_POLICY, TAKER_DEFAULT_POLICY } from './constants/fee';
|
|
9
9
|
import { fetchMarket } from './apis/market';
|
|
10
|
-
import { parsePrice } from './utils/prices';
|
|
11
|
-
import {
|
|
12
|
-
import { getExpectedOutput } from './view';
|
|
10
|
+
import { convertHumanReadablePriceToRawPrice, formatPrice, parsePrice, } from './utils/prices';
|
|
11
|
+
import { invertTick, toPrice } from './utils/tick';
|
|
12
|
+
import { getExpectedInput, getExpectedOutput, getQuoteToken } from './view';
|
|
13
13
|
import { toBookId } from './utils/book-id';
|
|
14
14
|
import { fetchIsApprovedForAll } from './utils/approval';
|
|
15
|
-
import {
|
|
16
|
-
import { fetchOrders } from './utils/order';
|
|
17
|
-
import { quoteToBase } from './utils/decimals';
|
|
15
|
+
import { fetchOnChainOrders } from './utils/order';
|
|
18
16
|
import { applyPercent } from './utils/bigint';
|
|
17
|
+
import { fetchPool } from './apis/pool';
|
|
18
|
+
import { REBALANCER_ABI } from './abis/rebalancer/rebalancer-abi';
|
|
19
|
+
import { getExpectedMintResult, getIdealDelta } from './utils/pool';
|
|
20
|
+
import { fetchCallData, fetchQuote } from './apis/odos';
|
|
21
|
+
import { MINTER_ABI } from './abis/rebalancer/minter-abi';
|
|
22
|
+
import { emptyERC20PermitParams } from './constants/permit';
|
|
23
|
+
import { abs } from './utils/math';
|
|
24
|
+
import { toBytes32 } from './utils/pool-key';
|
|
25
|
+
import { OPERATOR_ABI } from './abis/rebalancer/operator-abi';
|
|
26
|
+
import { STRATEGY_ABI } from './abis/rebalancer/strategy-abi';
|
|
27
|
+
import { ELECTION_GOVERNOR_ABI } from './abis/governance/election-governor-abi';
|
|
28
|
+
import { VCLOB_ABI } from './abis/governance/vclob-abi';
|
|
19
29
|
/**
|
|
20
30
|
* Build a transaction to open a market.
|
|
21
31
|
*
|
|
22
32
|
* @param chainId The chain ID of the blockchain.
|
|
33
|
+
* @param userAddress The address of the user.
|
|
23
34
|
* @param inputToken The address of the input token.
|
|
24
35
|
* @param outputToken The address of the output token.
|
|
25
|
-
* @param options
|
|
26
|
-
* @param options.rpcUrl The RPC URL of the blockchain.
|
|
36
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
27
37
|
* @returns A Promise resolving to a transaction object. If the market is already open, returns undefined.
|
|
28
38
|
* @example
|
|
29
39
|
* import { openMarket } from '@clober/v2-sdk'
|
|
30
40
|
*
|
|
31
41
|
* const transaction = await openMarket({
|
|
32
42
|
* chainId: 421614,
|
|
43
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69',
|
|
33
44
|
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
34
45
|
* outputToken: '0x0000000000000000000000000000000000000000'
|
|
35
46
|
* })
|
|
36
47
|
*/
|
|
37
|
-
export const openMarket =
|
|
38
|
-
const
|
|
48
|
+
export const openMarket = async ({ chainId, userAddress, inputToken, outputToken, options, }) => {
|
|
49
|
+
const publicClient = createPublicClient({
|
|
50
|
+
chain: CHAIN_MAP[chainId],
|
|
51
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
52
|
+
});
|
|
53
|
+
const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
|
|
39
54
|
const isBid = isAddressEqual(market.quote.address, inputToken);
|
|
40
|
-
if ((isBid && !market.
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
if ((isBid && !market.bidBook.isOpened) ||
|
|
56
|
+
(!isBid && !market.askBook.isOpened)) {
|
|
57
|
+
const unitSize = await calculateUnitSize(publicClient, chainId, isBid ? market.quote : market.base);
|
|
58
|
+
return buildTransaction(publicClient, {
|
|
59
|
+
chain: CHAIN_MAP[chainId],
|
|
43
60
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
61
|
+
account: userAddress,
|
|
44
62
|
abi: CONTROLLER_ABI,
|
|
45
63
|
functionName: 'open',
|
|
46
64
|
args: [
|
|
47
65
|
[
|
|
48
66
|
{
|
|
49
67
|
key: {
|
|
50
|
-
base:
|
|
51
|
-
|
|
52
|
-
quote:
|
|
53
|
-
makerPolicy: MAKER_DEFAULT_POLICY.value,
|
|
68
|
+
base: outputToken,
|
|
69
|
+
unitSize,
|
|
70
|
+
quote: inputToken,
|
|
71
|
+
makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
|
|
54
72
|
hooks: zeroAddress,
|
|
55
|
-
takerPolicy: TAKER_DEFAULT_POLICY.value,
|
|
73
|
+
takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
|
|
56
74
|
},
|
|
57
75
|
hookData: zeroHash,
|
|
58
76
|
},
|
|
59
77
|
],
|
|
60
78
|
getDeadlineTimestampInSeconds(),
|
|
61
79
|
],
|
|
62
|
-
});
|
|
80
|
+
}, options?.gasLimit);
|
|
63
81
|
}
|
|
64
82
|
return undefined;
|
|
65
|
-
}
|
|
83
|
+
};
|
|
66
84
|
/**
|
|
67
85
|
* Places a limit order on the specified chain for trading tokens.
|
|
68
86
|
*
|
|
@@ -72,23 +90,21 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, }
|
|
|
72
90
|
* @param {`0x${string}`} outputToken The address of the token to be received as output.
|
|
73
91
|
* @param {string} amount The amount of input tokens for the order.
|
|
74
92
|
* @param {string} price The price at which the order should be executed.
|
|
75
|
-
* @param {
|
|
76
|
-
* @param {
|
|
93
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
94
|
+
* @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
|
|
77
95
|
* @param {boolean} [options.postOnly] A boolean indicating whether the order is only to be made not taken.
|
|
78
|
-
* @param {
|
|
79
|
-
* @
|
|
96
|
+
* @param {bigint} [options.makeTick] The tick for the make order.
|
|
97
|
+
* @param {bigint} [options.takeLimitTick] The tick for the take order.
|
|
98
|
+
* @param {boolean} [options.roundingUpMakeBid] A boolean indicating whether to round up the make bid.
|
|
99
|
+
* @param {boolean} [options.roundingDownMakeAsk] A boolean indicating whether to round down the make ask.
|
|
100
|
+
* @param {boolean} [options.roundingDownTakenBid] A boolean indicating whether to round down the taken bid.
|
|
101
|
+
* @param {boolean} [options.roundingUpTakenAsk] A boolean indicating whether to round up the taken ask.
|
|
102
|
+
* @returns {Promise<{ transaction: Transaction, result: { make: CurrencyFlow, take: CurrencyFlow, spent: CurrencyFlow }>}
|
|
80
103
|
* Promise resolving to the transaction object representing the limit order with the result of the order.
|
|
81
104
|
* @example
|
|
82
|
-
* import {
|
|
105
|
+
* import { limitOrder } from '@clober/v2-sdk'
|
|
83
106
|
* import { privateKeyToAccount } from 'viem/accounts'
|
|
84
107
|
*
|
|
85
|
-
* const signature = await signERC20Permit({
|
|
86
|
-
* chainId: 421614,
|
|
87
|
-
* account: privateKeyToAccount('0x...'),
|
|
88
|
-
* token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
89
|
-
* amount: '100.123'
|
|
90
|
-
* })
|
|
91
|
-
*
|
|
92
108
|
* const { transaction } = await limitOrder({
|
|
93
109
|
* chainId: 421614,
|
|
94
110
|
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
@@ -96,7 +112,6 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, }
|
|
|
96
112
|
* outputToken: '0x0000000000000000000000000000000000000000',
|
|
97
113
|
* amount: '100.123', // 100.123 USDC
|
|
98
114
|
* price: '4000.01', // price at 4000.01 (ETH/USDC)
|
|
99
|
-
* options: { signature }
|
|
100
115
|
* })
|
|
101
116
|
*
|
|
102
117
|
* @example
|
|
@@ -111,27 +126,40 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, }
|
|
|
111
126
|
* price: '4000.01', // price at 4000.01 (ETH/USDC)
|
|
112
127
|
* })
|
|
113
128
|
*/
|
|
114
|
-
export const limitOrder =
|
|
115
|
-
const
|
|
129
|
+
export const limitOrder = async ({ chainId, userAddress, inputToken, outputToken, amount, price, options, }) => {
|
|
130
|
+
const [roundingUpMakeBid, roundingDownMakeAsk, roundingDownTakenBid, roundingUpTakenAsk,] = [
|
|
131
|
+
options?.roundingUpMakeBid ? options.roundingUpMakeBid : false,
|
|
132
|
+
options?.roundingDownMakeAsk ? options.roundingDownMakeAsk : false,
|
|
133
|
+
options?.roundingDownTakenBid ? options.roundingDownTakenBid : false,
|
|
134
|
+
options?.roundingUpTakenAsk ? options.roundingUpTakenAsk : false,
|
|
135
|
+
];
|
|
136
|
+
const publicClient = createPublicClient({
|
|
137
|
+
chain: CHAIN_MAP[chainId],
|
|
138
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
139
|
+
});
|
|
140
|
+
const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
|
|
116
141
|
const isBid = isAddressEqual(market.quote.address, inputToken);
|
|
117
|
-
|
|
142
|
+
const [inputCurrency, outputCurrency] = isBid
|
|
143
|
+
? [market.quote, market.base]
|
|
144
|
+
: [market.base, market.quote];
|
|
145
|
+
if ((isBid && !market.bidBook.isOpened) ||
|
|
146
|
+
(!isBid && !market.askBook.isOpened)) {
|
|
118
147
|
throw new Error(`
|
|
119
148
|
Open the market before placing a limit order.
|
|
120
149
|
import { openMarket } from '@clober/v2-sdk'
|
|
121
150
|
|
|
122
|
-
const transaction = await openMarket(
|
|
123
|
-
${chainId},
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
)
|
|
151
|
+
const transaction = await openMarket({
|
|
152
|
+
chainId: ${chainId},
|
|
153
|
+
inputToken: '${inputToken}',
|
|
154
|
+
outputToken: '${outputToken}',
|
|
155
|
+
})
|
|
127
156
|
`);
|
|
128
157
|
}
|
|
129
|
-
const
|
|
130
|
-
const tick = isBid ? fromPrice(rawPrice) : fromPrice(invertPrice(rawPrice));
|
|
158
|
+
const { roundingDownTick, roundingUpTick } = parsePrice(Number(price), market.quote.decimals, market.base.decimals);
|
|
131
159
|
const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
|
|
132
|
-
const quoteAmount = parseUnits(amount,
|
|
133
|
-
const [
|
|
134
|
-
|
|
160
|
+
const quoteAmount = parseUnits(amount, inputCurrency.decimals);
|
|
161
|
+
const [unitSize, { takenAmount, spentAmount, bookId, events }] = await Promise.all([
|
|
162
|
+
calculateUnitSize(publicClient, chainId, inputCurrency),
|
|
135
163
|
getExpectedOutput({
|
|
136
164
|
chainId,
|
|
137
165
|
inputToken,
|
|
@@ -144,24 +172,21 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
144
172
|
}),
|
|
145
173
|
]);
|
|
146
174
|
const isETH = isAddressEqual(inputToken, zeroAddress);
|
|
147
|
-
const permitParamsList = options?.signature && !isETH
|
|
148
|
-
? [
|
|
149
|
-
{
|
|
150
|
-
token: inputToken,
|
|
151
|
-
permitAmount: quoteAmount,
|
|
152
|
-
signature: options.signature,
|
|
153
|
-
},
|
|
154
|
-
]
|
|
155
|
-
: [];
|
|
156
175
|
const makeParam = {
|
|
157
|
-
id: toBookId(inputToken, outputToken,
|
|
158
|
-
tick:
|
|
176
|
+
id: toBookId(chainId, inputToken, outputToken, unitSize),
|
|
177
|
+
tick: options?.makeTick
|
|
178
|
+
? Number(options.makeTick)
|
|
179
|
+
: Number(isBid
|
|
180
|
+
? roundingUpMakeBid
|
|
181
|
+
? roundingUpTick
|
|
182
|
+
: roundingDownTick
|
|
183
|
+
: invertTick(roundingDownMakeAsk ? roundingDownTick : roundingUpTick)),
|
|
159
184
|
quoteAmount,
|
|
160
185
|
hookData: zeroHash,
|
|
161
186
|
};
|
|
162
|
-
if (options?.postOnly === true ||
|
|
187
|
+
if (options?.postOnly === true || spentAmount === '0') {
|
|
163
188
|
return {
|
|
164
|
-
transaction: await buildTransaction(
|
|
189
|
+
transaction: await buildTransaction(publicClient, {
|
|
165
190
|
chain: CHAIN_MAP[chainId],
|
|
166
191
|
account: userAddress,
|
|
167
192
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
@@ -170,21 +195,31 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
170
195
|
args: [
|
|
171
196
|
[makeParam],
|
|
172
197
|
tokensToSettle,
|
|
173
|
-
|
|
198
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
174
199
|
getDeadlineTimestampInSeconds(),
|
|
175
200
|
],
|
|
176
201
|
value: isETH ? quoteAmount : 0n,
|
|
177
|
-
}),
|
|
202
|
+
}, options?.gasLimit),
|
|
178
203
|
result: {
|
|
179
204
|
make: {
|
|
180
|
-
amount: formatUnits(quoteAmount,
|
|
181
|
-
currency:
|
|
205
|
+
amount: formatUnits(quoteAmount, inputCurrency.decimals),
|
|
206
|
+
currency: inputCurrency,
|
|
182
207
|
direction: 'in',
|
|
208
|
+
price: formatPrice(isBid
|
|
209
|
+
? toPrice(BigInt(makeParam.tick))
|
|
210
|
+
: toPrice(invertTick(BigInt(makeParam.tick))), market.quote.decimals, market.base.decimals),
|
|
183
211
|
},
|
|
184
|
-
|
|
212
|
+
spent: {
|
|
185
213
|
amount: '0',
|
|
186
|
-
currency:
|
|
214
|
+
currency: inputCurrency,
|
|
215
|
+
direction: 'in',
|
|
216
|
+
events: [],
|
|
217
|
+
},
|
|
218
|
+
taken: {
|
|
219
|
+
amount: '0',
|
|
220
|
+
currency: outputCurrency,
|
|
187
221
|
direction: 'out',
|
|
222
|
+
events: [],
|
|
188
223
|
},
|
|
189
224
|
},
|
|
190
225
|
};
|
|
@@ -192,7 +227,7 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
192
227
|
else {
|
|
193
228
|
// take and make
|
|
194
229
|
return {
|
|
195
|
-
transaction: await buildTransaction(
|
|
230
|
+
transaction: await buildTransaction(publicClient, {
|
|
196
231
|
chain: CHAIN_MAP[chainId],
|
|
197
232
|
account: userAddress,
|
|
198
233
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
@@ -203,7 +238,15 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
203
238
|
{
|
|
204
239
|
takeBookId: bookId,
|
|
205
240
|
makeBookId: makeParam.id,
|
|
206
|
-
limitPrice:
|
|
241
|
+
limitPrice: options?.takeLimitTick
|
|
242
|
+
? toPrice(options.takeLimitTick)
|
|
243
|
+
: toPrice(isBid
|
|
244
|
+
? invertTick(roundingUpTakenAsk
|
|
245
|
+
? roundingUpTick
|
|
246
|
+
: roundingDownTick)
|
|
247
|
+
: roundingDownTakenBid
|
|
248
|
+
? roundingDownTick
|
|
249
|
+
: roundingUpTick),
|
|
207
250
|
tick: makeParam.tick,
|
|
208
251
|
quoteAmount,
|
|
209
252
|
takeHookData: zeroHash,
|
|
@@ -211,75 +254,93 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
211
254
|
},
|
|
212
255
|
],
|
|
213
256
|
tokensToSettle,
|
|
214
|
-
|
|
257
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
215
258
|
getDeadlineTimestampInSeconds(),
|
|
216
259
|
],
|
|
217
260
|
value: isETH ? quoteAmount : 0n,
|
|
218
|
-
}),
|
|
261
|
+
}, options?.gasLimit),
|
|
219
262
|
result: {
|
|
220
263
|
make: {
|
|
221
|
-
amount: formatUnits(quoteAmount
|
|
222
|
-
currency:
|
|
264
|
+
amount: formatUnits(quoteAmount - parseUnits(spentAmount, inputCurrency.decimals), inputCurrency.decimals),
|
|
265
|
+
currency: inputCurrency,
|
|
223
266
|
direction: 'in',
|
|
267
|
+
price: formatPrice(isBid
|
|
268
|
+
? toPrice(BigInt(makeParam.tick))
|
|
269
|
+
: toPrice(invertTick(BigInt(makeParam.tick))), market.quote.decimals, market.base.decimals),
|
|
224
270
|
},
|
|
225
|
-
|
|
226
|
-
amount:
|
|
227
|
-
currency:
|
|
271
|
+
spent: {
|
|
272
|
+
amount: spentAmount,
|
|
273
|
+
currency: inputCurrency,
|
|
274
|
+
direction: 'in',
|
|
275
|
+
events: events.map(({ price, spentAmount }) => ({
|
|
276
|
+
price,
|
|
277
|
+
amount: spentAmount,
|
|
278
|
+
})),
|
|
279
|
+
},
|
|
280
|
+
taken: {
|
|
281
|
+
amount: takenAmount,
|
|
282
|
+
currency: outputCurrency,
|
|
228
283
|
direction: 'out',
|
|
284
|
+
events: events.map(({ price, takenAmount }) => ({
|
|
285
|
+
price,
|
|
286
|
+
amount: takenAmount,
|
|
287
|
+
})),
|
|
229
288
|
},
|
|
230
289
|
},
|
|
231
290
|
};
|
|
232
291
|
}
|
|
233
|
-
}
|
|
292
|
+
};
|
|
234
293
|
/**
|
|
235
294
|
* Executes a market order on the specified chain for trading tokens.
|
|
295
|
+
* If only `amountIn` is provided, spend the specified amount of input tokens.
|
|
296
|
+
* If only `amountOut` is provided, take the specified amount of output tokens.
|
|
236
297
|
*
|
|
237
298
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
238
299
|
* @param {`0x${string}`} userAddress The Ethereum address of the user placing the order.
|
|
239
300
|
* @param {`0x${string}`} inputToken The address of the token to be used as input.
|
|
240
301
|
* @param {`0x${string}`} outputToken The address of the token to be received as output.
|
|
241
|
-
* @param {string}
|
|
242
|
-
* @param {
|
|
243
|
-
* @param {
|
|
244
|
-
* @param {
|
|
245
|
-
* @param {
|
|
246
|
-
*
|
|
247
|
-
* @
|
|
302
|
+
* @param {string} amountIn The amount of input tokens for the order to spend.
|
|
303
|
+
* @param {string} amountOut The amount of output tokens for the order to take.
|
|
304
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
305
|
+
* @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
|
|
306
|
+
* @param {number} [options.slippage] The maximum slippage percentage allowed for the order.
|
|
307
|
+
* @param {boolean} [options.roundingDownTakenBid] A boolean indicating whether to round down the taken bid.
|
|
308
|
+
* @param {boolean} [options.roundingUpTakenAsk] A boolean indicating whether to round up the taken ask.
|
|
309
|
+
* if the slippage is not provided, unlimited slippage is allowed.
|
|
310
|
+
* @returns {Promise<{ transaction: Transaction, result: { spent: CurrencyFlow, taken: CurrencyFlow } }>}
|
|
311
|
+
* Promise resolving to the transaction object representing the market order with the result of the order.
|
|
248
312
|
* @example
|
|
249
|
-
* import {
|
|
313
|
+
* import { marketOrder } from '@clober/v2-sdk'
|
|
250
314
|
* import { privateKeyToAccount } from 'viem/accounts'
|
|
251
315
|
*
|
|
252
|
-
* const signature = await signERC20Permit({
|
|
253
|
-
* chainId: 421614,
|
|
254
|
-
* account: privateKeyToAccount('0x...'),
|
|
255
|
-
* token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
256
|
-
* amount: '100.123'
|
|
257
|
-
* })
|
|
258
|
-
*
|
|
259
316
|
* const transaction = await marketOrder({
|
|
260
317
|
* chainId: 421614,
|
|
261
318
|
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
262
319
|
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
263
320
|
* outputToken: '0x0000000000000000000000000000000000000000',
|
|
264
321
|
* amount: '100.123', // 100.123 USDC
|
|
265
|
-
* options: {
|
|
322
|
+
* options: { erc20PermitParam }
|
|
266
323
|
* })
|
|
267
324
|
*
|
|
268
|
-
* @example
|
|
269
|
-
* import { marketOrder } from '@clober/v2-sdk'
|
|
270
|
-
*
|
|
271
|
-
* const transaction = await limitOrder(
|
|
272
|
-
* chainId: 421614,
|
|
273
|
-
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
274
|
-
* inputToken: '0x0000000000000000000000000000000000000000',
|
|
275
|
-
* outputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
276
|
-
* options: '0.13', // 0.13 ETH
|
|
277
|
-
* )
|
|
278
325
|
*/
|
|
279
|
-
export const marketOrder =
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
326
|
+
export const marketOrder = async ({ chainId, userAddress, inputToken, outputToken, amountIn, amountOut, options, }) => {
|
|
327
|
+
if (!amountIn && !amountOut) {
|
|
328
|
+
throw new Error('Either amountIn or amountOut must be provided');
|
|
329
|
+
}
|
|
330
|
+
else if (amountIn && amountOut) {
|
|
331
|
+
throw new Error('Only one of amountIn or amountOut can be provided');
|
|
332
|
+
}
|
|
333
|
+
const publicClient = createPublicClient({
|
|
334
|
+
chain: CHAIN_MAP[chainId],
|
|
335
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
336
|
+
});
|
|
337
|
+
const market = await fetchMarket(publicClient, chainId, [inputToken, outputToken], !!(options && options.useSubgraph));
|
|
338
|
+
const isTakingBid = isAddressEqual(market.base.address, inputToken);
|
|
339
|
+
const [inputCurrency, outputCurrency] = isTakingBid
|
|
340
|
+
? [market.base, market.quote]
|
|
341
|
+
: [market.quote, market.base];
|
|
342
|
+
if ((isTakingBid && !market.bidBook.isOpened) ||
|
|
343
|
+
(!isTakingBid && !market.askBook.isOpened)) {
|
|
283
344
|
throw new Error(`
|
|
284
345
|
Open the market before placing a market order.
|
|
285
346
|
import { openMarket } from '@clober/v2-sdk'
|
|
@@ -291,51 +352,135 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
|
|
|
291
352
|
)
|
|
292
353
|
`);
|
|
293
354
|
}
|
|
294
|
-
const rawLimitPrice = parsePrice(Number(options?.limitPrice ?? '0'), market.quote.decimals, market.base.decimals);
|
|
295
355
|
const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
|
|
296
|
-
const quoteAmount = parseUnits(amount, isBid ? market.quote.decimals : market.base.decimals);
|
|
297
|
-
const { bookId, takenAmount } = await getExpectedOutput({
|
|
298
|
-
chainId,
|
|
299
|
-
inputToken,
|
|
300
|
-
outputToken,
|
|
301
|
-
amountIn: amount,
|
|
302
|
-
options: {
|
|
303
|
-
...options,
|
|
304
|
-
// todo: pass limit price
|
|
305
|
-
},
|
|
306
|
-
});
|
|
307
356
|
const isETH = isAddressEqual(inputToken, zeroAddress);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
357
|
+
if (amountIn && !amountOut) {
|
|
358
|
+
const { bookId, takenAmount, spentAmount, events } = await getExpectedOutput({
|
|
359
|
+
chainId,
|
|
360
|
+
inputToken,
|
|
361
|
+
outputToken,
|
|
362
|
+
amountIn,
|
|
363
|
+
options: {
|
|
364
|
+
...options,
|
|
365
|
+
// don't need to check limit price for market order
|
|
314
366
|
},
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
367
|
+
});
|
|
368
|
+
const baseAmount = parseUnits(amountIn, inputCurrency.decimals);
|
|
369
|
+
return {
|
|
370
|
+
transaction: await buildTransaction(publicClient, {
|
|
371
|
+
chain: CHAIN_MAP[chainId],
|
|
372
|
+
account: userAddress,
|
|
373
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
374
|
+
abi: CONTROLLER_ABI,
|
|
375
|
+
functionName: 'spend',
|
|
376
|
+
args: [
|
|
377
|
+
[
|
|
378
|
+
{
|
|
379
|
+
id: bookId,
|
|
380
|
+
limitPrice: 0n,
|
|
381
|
+
baseAmount,
|
|
382
|
+
minQuoteAmount: options?.slippage
|
|
383
|
+
? applyPercent(parseUnits(takenAmount, outputCurrency.decimals), 100 - options.slippage)
|
|
384
|
+
: 0n,
|
|
385
|
+
hookData: zeroHash,
|
|
386
|
+
},
|
|
387
|
+
],
|
|
388
|
+
tokensToSettle,
|
|
389
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
390
|
+
getDeadlineTimestampInSeconds(),
|
|
391
|
+
],
|
|
392
|
+
value: isETH ? baseAmount : 0n,
|
|
393
|
+
}, options?.gasLimit),
|
|
394
|
+
result: {
|
|
395
|
+
spent: {
|
|
396
|
+
amount: spentAmount,
|
|
397
|
+
currency: inputCurrency,
|
|
398
|
+
direction: 'in',
|
|
399
|
+
events: events.map(({ price, spentAmount }) => ({
|
|
400
|
+
price,
|
|
401
|
+
amount: spentAmount,
|
|
402
|
+
})),
|
|
330
403
|
},
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
})
|
|
404
|
+
taken: {
|
|
405
|
+
amount: takenAmount,
|
|
406
|
+
currency: outputCurrency,
|
|
407
|
+
direction: 'out',
|
|
408
|
+
events: events.map(({ price, takenAmount }) => ({
|
|
409
|
+
price,
|
|
410
|
+
amount: takenAmount,
|
|
411
|
+
})),
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
else if (!amountIn && amountOut) {
|
|
417
|
+
const { bookId, spentAmount, takenAmount, events } = await getExpectedInput({
|
|
418
|
+
chainId,
|
|
419
|
+
inputToken,
|
|
420
|
+
outputToken,
|
|
421
|
+
amountOut,
|
|
422
|
+
options: {
|
|
423
|
+
...options,
|
|
424
|
+
// don't need to check limit price for market order
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
const quoteAmount = parseUnits(amountOut, outputCurrency.decimals);
|
|
428
|
+
const baseAmount = parseUnits(spentAmount, inputCurrency.decimals);
|
|
429
|
+
const maxBaseAmount = options?.erc20PermitParam?.permitAmount ??
|
|
430
|
+
(options?.slippage
|
|
431
|
+
? applyPercent(baseAmount, 100 + options.slippage)
|
|
432
|
+
: isETH
|
|
433
|
+
? baseAmount
|
|
434
|
+
: 2n ** 256n - 1n);
|
|
435
|
+
return {
|
|
436
|
+
transaction: await buildTransaction(publicClient, {
|
|
437
|
+
chain: CHAIN_MAP[chainId],
|
|
438
|
+
account: userAddress,
|
|
439
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
440
|
+
abi: CONTROLLER_ABI,
|
|
441
|
+
functionName: 'take',
|
|
442
|
+
args: [
|
|
443
|
+
[
|
|
444
|
+
{
|
|
445
|
+
id: bookId,
|
|
446
|
+
limitPrice: 0n,
|
|
447
|
+
quoteAmount,
|
|
448
|
+
maxBaseAmount,
|
|
449
|
+
hookData: zeroHash,
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
tokensToSettle,
|
|
453
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
454
|
+
getDeadlineTimestampInSeconds(),
|
|
455
|
+
],
|
|
456
|
+
value: isETH ? maxBaseAmount : 0n,
|
|
457
|
+
}, options?.gasLimit),
|
|
458
|
+
result: {
|
|
459
|
+
spent: {
|
|
460
|
+
amount: spentAmount,
|
|
461
|
+
currency: inputCurrency,
|
|
462
|
+
direction: 'in',
|
|
463
|
+
events: events.map(({ price, spentAmount }) => ({
|
|
464
|
+
price,
|
|
465
|
+
amount: spentAmount,
|
|
466
|
+
})),
|
|
467
|
+
},
|
|
468
|
+
taken: {
|
|
469
|
+
amount: takenAmount,
|
|
470
|
+
currency: outputCurrency,
|
|
471
|
+
direction: 'out',
|
|
472
|
+
events: events.map(({ price, takenAmount }) => ({
|
|
473
|
+
price,
|
|
474
|
+
amount: takenAmount,
|
|
475
|
+
})),
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
throw new Error('Either amountIn or amountOut must be provided');
|
|
482
|
+
}
|
|
483
|
+
};
|
|
339
484
|
/**
|
|
340
485
|
* Claims specified open order for settlement.
|
|
341
486
|
* [IMPORTANT] Set ApprovalForAll before calling this function.
|
|
@@ -343,8 +488,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
|
|
|
343
488
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
344
489
|
* @param {`0x${string}`} userAddress The Ethereum address of the user.
|
|
345
490
|
* @param {string} id An ID representing the open order to be claimed.
|
|
346
|
-
* @param {
|
|
347
|
-
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
491
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
348
492
|
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
|
|
349
493
|
* Promise resolving to the transaction object representing the claim action with the result of the order.
|
|
350
494
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
@@ -361,7 +505,7 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
|
|
|
361
505
|
* id: openOrders.map((order) => order.id)
|
|
362
506
|
* })
|
|
363
507
|
*/
|
|
364
|
-
export const claimOrder =
|
|
508
|
+
export const claimOrder = async ({ chainId, userAddress, id, options, }) => {
|
|
365
509
|
const { transaction, result } = await claimOrders({
|
|
366
510
|
chainId,
|
|
367
511
|
userAddress,
|
|
@@ -372,7 +516,7 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
372
516
|
transaction,
|
|
373
517
|
result: result[0],
|
|
374
518
|
};
|
|
375
|
-
}
|
|
519
|
+
};
|
|
376
520
|
/**
|
|
377
521
|
* Claims specified open orders for settlement.
|
|
378
522
|
* [IMPORTANT] Set ApprovalForAll before calling this function.
|
|
@@ -380,8 +524,7 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
380
524
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
381
525
|
* @param {`0x${string}`} userAddress The Ethereum address of the user.
|
|
382
526
|
* @param {string[]} ids An array of IDs representing the open orders to be claimed.
|
|
383
|
-
* @param {
|
|
384
|
-
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
527
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
385
528
|
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>}
|
|
386
529
|
* Promise resolving to the transaction object representing the claim action with the result of the orders.
|
|
387
530
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
@@ -398,60 +541,56 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
398
541
|
* ids: openOrders.map((order) => order.id)
|
|
399
542
|
* )
|
|
400
543
|
*/
|
|
401
|
-
export const claimOrders =
|
|
402
|
-
const
|
|
544
|
+
export const claimOrders = async ({ chainId, userAddress, ids, options, }) => {
|
|
545
|
+
const publicClient = createPublicClient({
|
|
546
|
+
chain: CHAIN_MAP[chainId],
|
|
547
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
548
|
+
});
|
|
549
|
+
const isApprovedForAll = await fetchIsApprovedForAll(publicClient, chainId, userAddress);
|
|
403
550
|
if (!isApprovedForAll) {
|
|
404
551
|
throw new Error(`
|
|
405
552
|
Set ApprovalForAll before calling this function.
|
|
406
553
|
import { setApprovalOfOpenOrdersForAll } from '@clober/v2-sdk'
|
|
407
554
|
|
|
408
|
-
const hash = await setApprovalOfOpenOrdersForAll(
|
|
409
|
-
${chainId},
|
|
410
|
-
|
|
411
|
-
)
|
|
555
|
+
const hash = await setApprovalOfOpenOrdersForAll({
|
|
556
|
+
chainId: ${chainId},
|
|
557
|
+
walletClient, // use viem
|
|
558
|
+
})
|
|
412
559
|
`);
|
|
413
560
|
}
|
|
414
|
-
const orders = (await
|
|
561
|
+
const orders = (await fetchOnChainOrders(publicClient, chainId, ids.map((id) => BigInt(id)), !!(options && options.useSubgraph))).filter((order) => isAddressEqual(order.user, userAddress) && order.claimable.value !== '0');
|
|
415
562
|
const tokensToSettle = orders
|
|
416
|
-
.map((order) => [order.
|
|
563
|
+
.map((order) => [order.inputCurrency.address, order.outputCurrency.address])
|
|
417
564
|
.flat()
|
|
418
565
|
.filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
|
|
419
566
|
.filter((address) => !isAddressEqual(address, zeroAddress));
|
|
420
567
|
return {
|
|
421
|
-
transaction: await buildTransaction(
|
|
568
|
+
transaction: await buildTransaction(publicClient, {
|
|
422
569
|
chain: CHAIN_MAP[chainId],
|
|
423
570
|
account: userAddress,
|
|
424
571
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
425
572
|
abi: CONTROLLER_ABI,
|
|
426
573
|
functionName: 'claim',
|
|
427
574
|
args: [
|
|
428
|
-
orders.map(({
|
|
429
|
-
id
|
|
575
|
+
orders.map(({ id }) => ({
|
|
576
|
+
id,
|
|
430
577
|
hookData: zeroHash,
|
|
431
578
|
})),
|
|
432
579
|
tokensToSettle,
|
|
433
580
|
[],
|
|
434
581
|
getDeadlineTimestampInSeconds(),
|
|
435
582
|
],
|
|
436
|
-
}),
|
|
437
|
-
result: orders
|
|
438
|
-
.map((order) => {
|
|
439
|
-
const amount = quoteToBase(order.tick, order.unit * order.claimable, false);
|
|
440
|
-
return {
|
|
441
|
-
currency: order.baseCurrency,
|
|
442
|
-
amount: formatUnits(amount, order.baseCurrency.decimals),
|
|
443
|
-
};
|
|
444
|
-
})
|
|
445
|
-
.reduce((acc, { currency, amount }) => {
|
|
583
|
+
}, options?.gasLimit),
|
|
584
|
+
result: orders.reduce((acc, { claimable: { currency, value } }) => {
|
|
446
585
|
const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
|
|
447
586
|
if (index === -1) {
|
|
448
|
-
return [...acc, { currency, amount, direction: 'out' }];
|
|
587
|
+
return [...acc, { currency, amount: value, direction: 'out' }];
|
|
449
588
|
}
|
|
450
|
-
acc[index].amount = (Number(acc[index].amount) + Number(
|
|
589
|
+
acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
|
|
451
590
|
return acc;
|
|
452
591
|
}, []),
|
|
453
592
|
};
|
|
454
|
-
}
|
|
593
|
+
};
|
|
455
594
|
/**
|
|
456
595
|
* Cancels specified open order if the order is not fully filled.
|
|
457
596
|
* [IMPORTANT] Set ApprovalForAll before calling this function.
|
|
@@ -459,8 +598,7 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, }) => {
|
|
|
459
598
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
460
599
|
* @param {`0x${string}`} userAddress The Ethereum address of the user.
|
|
461
600
|
* @param {string} id An ID representing the open order to be canceled
|
|
462
|
-
* @param {
|
|
463
|
-
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
601
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
464
602
|
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
|
|
465
603
|
* Promise resolving to the transaction object representing the cancel action with the result of the order.
|
|
466
604
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
@@ -477,7 +615,7 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, }) => {
|
|
|
477
615
|
* id: openOrders.map((order) => order.id)
|
|
478
616
|
* })
|
|
479
617
|
*/
|
|
480
|
-
export const cancelOrder =
|
|
618
|
+
export const cancelOrder = async ({ chainId, userAddress, id, options, }) => {
|
|
481
619
|
const { transaction, result } = await cancelOrders({
|
|
482
620
|
chainId,
|
|
483
621
|
userAddress,
|
|
@@ -488,7 +626,7 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
488
626
|
transaction,
|
|
489
627
|
result: result[0],
|
|
490
628
|
};
|
|
491
|
-
}
|
|
629
|
+
};
|
|
492
630
|
/**
|
|
493
631
|
* Cancels specified open orders if orders are not fully filled.
|
|
494
632
|
* [IMPORTANT] Set ApprovalForAll before calling this function.
|
|
@@ -496,8 +634,7 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
496
634
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
497
635
|
* @param {`0x${string}`} userAddress The Ethereum address of the user.
|
|
498
636
|
* @param {string[]} ids An array of IDs representing the open orders to be canceled.
|
|
499
|
-
* @param {
|
|
500
|
-
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
637
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
501
638
|
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>
|
|
502
639
|
* Promise resolving to the transaction object representing the cancel action with the result of the orders.
|
|
503
640
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
@@ -514,35 +651,39 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
514
651
|
* ids: openOrders.map((order) => order.id)
|
|
515
652
|
* })
|
|
516
653
|
*/
|
|
517
|
-
export const cancelOrders =
|
|
518
|
-
const
|
|
654
|
+
export const cancelOrders = async ({ chainId, userAddress, ids, options, }) => {
|
|
655
|
+
const publicClient = createPublicClient({
|
|
656
|
+
chain: CHAIN_MAP[chainId],
|
|
657
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
658
|
+
});
|
|
659
|
+
const isApprovedForAll = await fetchIsApprovedForAll(publicClient, chainId, userAddress);
|
|
519
660
|
if (!isApprovedForAll) {
|
|
520
661
|
throw new Error(`
|
|
521
662
|
Set ApprovalForAll before calling this function.
|
|
522
663
|
import { setApprovalOfOpenOrdersForAll } from '@clober/v2-sdk'
|
|
523
664
|
|
|
524
|
-
const hash = await setApprovalOfOpenOrdersForAll(
|
|
525
|
-
${chainId},
|
|
526
|
-
|
|
527
|
-
)
|
|
665
|
+
const hash = await setApprovalOfOpenOrdersForAll({
|
|
666
|
+
chainId: ${chainId},
|
|
667
|
+
walletClient, // use viem
|
|
668
|
+
})
|
|
528
669
|
`);
|
|
529
670
|
}
|
|
530
|
-
const orders = (await
|
|
671
|
+
const orders = (await fetchOnChainOrders(publicClient, chainId, ids.map((id) => BigInt(id)), !!(options && options.useSubgraph))).filter((order) => isAddressEqual(order.user, userAddress) && order.cancelable.value !== '0');
|
|
531
672
|
const tokensToSettle = orders
|
|
532
|
-
.map((order) => [order.
|
|
673
|
+
.map((order) => [order.inputCurrency.address, order.outputCurrency.address])
|
|
533
674
|
.flat()
|
|
534
675
|
.filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
|
|
535
676
|
.filter((address) => !isAddressEqual(address, zeroAddress));
|
|
536
677
|
return {
|
|
537
|
-
transaction: await buildTransaction(
|
|
678
|
+
transaction: await buildTransaction(publicClient, {
|
|
538
679
|
chain: CHAIN_MAP[chainId],
|
|
539
680
|
account: userAddress,
|
|
540
681
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
541
682
|
abi: CONTROLLER_ABI,
|
|
542
683
|
functionName: 'cancel',
|
|
543
684
|
args: [
|
|
544
|
-
orders.map(({
|
|
545
|
-
id
|
|
685
|
+
orders.map(({ id }) => ({
|
|
686
|
+
id,
|
|
546
687
|
leftQuoteAmount: 0n,
|
|
547
688
|
hookData: zeroHash,
|
|
548
689
|
})),
|
|
@@ -550,25 +691,621 @@ export const cancelOrders = decorator(async ({ chainId, userAddress, ids, }) =>
|
|
|
550
691
|
[],
|
|
551
692
|
getDeadlineTimestampInSeconds(),
|
|
552
693
|
],
|
|
553
|
-
}),
|
|
554
|
-
result: orders
|
|
555
|
-
.map((order) => {
|
|
556
|
-
const amount = applyPercent(order.unit * order.open, 100 +
|
|
557
|
-
(Number(MAKER_DEFAULT_POLICY.rate) * 100) /
|
|
558
|
-
Number(MAKER_DEFAULT_POLICY.RATE_PRECISION), 6);
|
|
559
|
-
return {
|
|
560
|
-
currency: order.quoteCurrency,
|
|
561
|
-
amount: formatUnits(amount, order.quoteCurrency.decimals),
|
|
562
|
-
};
|
|
563
|
-
})
|
|
564
|
-
.reduce((acc, { currency, amount }) => {
|
|
694
|
+
}, options?.gasLimit),
|
|
695
|
+
result: orders.reduce((acc, { cancelable: { currency, value } }) => {
|
|
565
696
|
const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
|
|
566
697
|
if (index === -1) {
|
|
567
|
-
return [...acc, { currency, amount, direction: 'out' }];
|
|
698
|
+
return [...acc, { currency, amount: value, direction: 'out' }];
|
|
568
699
|
}
|
|
569
|
-
acc[index].amount = (Number(acc[index].amount) + Number(
|
|
700
|
+
acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
|
|
570
701
|
return acc;
|
|
571
702
|
}, []),
|
|
572
703
|
};
|
|
573
|
-
}
|
|
704
|
+
};
|
|
705
|
+
/**
|
|
706
|
+
* Build a transaction to open a pool,
|
|
707
|
+
*
|
|
708
|
+
* @param chainId The chain ID of the blockchain.
|
|
709
|
+
* @param userAddress The address of the user.
|
|
710
|
+
* @param inputToken The address of the input token.
|
|
711
|
+
* @param outputToken The address of the output token.
|
|
712
|
+
* @param options {@link DefaultWriteContractOptions} options.
|
|
713
|
+
* @returns A Promise resolving to a transaction object. If the market is already open, returns undefined.
|
|
714
|
+
* @example
|
|
715
|
+
* import { openPool } from '@clober/v2-sdk'
|
|
716
|
+
*
|
|
717
|
+
* const transaction = await openPool({
|
|
718
|
+
* chainId: 421614,
|
|
719
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69',
|
|
720
|
+
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
721
|
+
* outputToken: '0x0000000000000000000000000000000000000000',
|
|
722
|
+
* salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
723
|
+
* })
|
|
724
|
+
*/
|
|
725
|
+
export const openPool = async ({ chainId, userAddress, tokenA, tokenB, salt, options, }) => {
|
|
726
|
+
const publicClient = createPublicClient({
|
|
727
|
+
chain: CHAIN_MAP[chainId],
|
|
728
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
729
|
+
});
|
|
730
|
+
const pool = await fetchPool(publicClient, chainId, [tokenA, tokenB], salt, !!(options && options.useSubgraph));
|
|
731
|
+
if (!pool.isOpened) {
|
|
732
|
+
return buildTransaction(publicClient, {
|
|
733
|
+
chain: CHAIN_MAP[chainId],
|
|
734
|
+
address: CONTRACT_ADDRESSES[chainId].Rebalancer,
|
|
735
|
+
account: userAddress,
|
|
736
|
+
abi: REBALANCER_ABI,
|
|
737
|
+
functionName: 'open',
|
|
738
|
+
args: [
|
|
739
|
+
{
|
|
740
|
+
base: pool.market.bidBook.base.address,
|
|
741
|
+
unitSize: pool.market.bidBook.unitSize,
|
|
742
|
+
quote: pool.market.bidBook.quote.address,
|
|
743
|
+
makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
|
|
744
|
+
hooks: zeroAddress,
|
|
745
|
+
takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
base: pool.market.askBook.base.address,
|
|
749
|
+
unitSize: pool.market.askBook.unitSize,
|
|
750
|
+
quote: pool.market.askBook.quote.address,
|
|
751
|
+
makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
|
|
752
|
+
hooks: zeroAddress,
|
|
753
|
+
takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
|
|
754
|
+
},
|
|
755
|
+
toBytes32(salt),
|
|
756
|
+
CONTRACT_ADDRESSES[chainId].Strategy,
|
|
757
|
+
],
|
|
758
|
+
}, options?.gasLimit);
|
|
759
|
+
}
|
|
760
|
+
return undefined;
|
|
761
|
+
};
|
|
762
|
+
export const addLiquidity = async ({ chainId, userAddress, token0, token1, salt, amount0, amount1, options, }) => {
|
|
763
|
+
if (isAddressEqual(token0, zeroAddress) ||
|
|
764
|
+
isAddressEqual(token1, zeroAddress)) {
|
|
765
|
+
throw new Error('ETH is not supported for adding liquidity');
|
|
766
|
+
}
|
|
767
|
+
const publicClient = createPublicClient({
|
|
768
|
+
chain: CHAIN_MAP[chainId],
|
|
769
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
770
|
+
});
|
|
771
|
+
const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
|
|
772
|
+
if (!pool.isOpened) {
|
|
773
|
+
throw new Error(`
|
|
774
|
+
Open the pool before adding liquidity.
|
|
775
|
+
import { openPool } from '@clober/v2-sdk'
|
|
776
|
+
|
|
777
|
+
const transaction = await openPool({
|
|
778
|
+
chainId: ${chainId},
|
|
779
|
+
tokenA: '${token0}',
|
|
780
|
+
tokenB: '${token1}',
|
|
781
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
782
|
+
})
|
|
783
|
+
`);
|
|
784
|
+
}
|
|
785
|
+
const [amountAOrigin, amountBOrigin] = isAddressEqual(pool.currencyA.address, getAddress(token0))
|
|
786
|
+
? [
|
|
787
|
+
parseUnits(amount0 ?? '0', pool.currencyA.decimals),
|
|
788
|
+
parseUnits(amount1 ?? '0', pool.currencyB.decimals),
|
|
789
|
+
]
|
|
790
|
+
: [
|
|
791
|
+
parseUnits(amount1 ?? '0', pool.currencyA.decimals),
|
|
792
|
+
parseUnits(amount0 ?? '0', pool.currencyB.decimals),
|
|
793
|
+
];
|
|
794
|
+
let [amountA, amountB] = [amountAOrigin, amountBOrigin];
|
|
795
|
+
const tokenAPermitParams = isAddressEqual(pool.currencyA.address, getAddress(token0))
|
|
796
|
+
? options?.token0PermitParams ?? emptyERC20PermitParams
|
|
797
|
+
: options?.token1PermitParams ?? emptyERC20PermitParams;
|
|
798
|
+
const tokenBPermitParams = isAddressEqual(pool.currencyA.address, getAddress(token0))
|
|
799
|
+
? options?.token1PermitParams ?? emptyERC20PermitParams
|
|
800
|
+
: options?.token0PermitParams ?? emptyERC20PermitParams;
|
|
801
|
+
let disableSwap = !!(options && options.disableSwap);
|
|
802
|
+
if (pool.totalSupply === 0n ||
|
|
803
|
+
(pool.liquidityA === 0n && pool.liquidityB === 0n)) {
|
|
804
|
+
disableSwap = true;
|
|
805
|
+
}
|
|
806
|
+
const slippageLimitPercent = options?.slippage ?? 2;
|
|
807
|
+
const swapParams = {
|
|
808
|
+
inCurrency: zeroAddress,
|
|
809
|
+
amount: 0n,
|
|
810
|
+
data: '0x',
|
|
811
|
+
};
|
|
812
|
+
if (!disableSwap) {
|
|
813
|
+
const currencyBPerCurrencyA = options?.testnetPrice
|
|
814
|
+
? isAddressEqual(getQuoteToken({
|
|
815
|
+
chainId,
|
|
816
|
+
token0,
|
|
817
|
+
token1,
|
|
818
|
+
}), pool.currencyA.address)
|
|
819
|
+
? 1 / Number(options.testnetPrice)
|
|
820
|
+
: Number(options.testnetPrice)
|
|
821
|
+
: undefined;
|
|
822
|
+
const swapAmountA = parseUnits('1', pool.currencyA.decimals);
|
|
823
|
+
const { amountOut: swapAmountB } = await fetchQuote({
|
|
824
|
+
chainId,
|
|
825
|
+
amountIn: swapAmountA,
|
|
826
|
+
tokenIn: pool.currencyA,
|
|
827
|
+
tokenOut: pool.currencyB,
|
|
828
|
+
slippageLimitPercent: 20,
|
|
829
|
+
userAddress: CONTRACT_ADDRESSES[chainId].Minter,
|
|
830
|
+
testnetPrice: currencyBPerCurrencyA,
|
|
831
|
+
});
|
|
832
|
+
const { deltaA, deltaB } = getIdealDelta(amountA, amountB, pool.liquidityA, pool.liquidityB, swapAmountA, swapAmountB);
|
|
833
|
+
if (deltaA < 0n) {
|
|
834
|
+
swapParams.inCurrency = pool.currencyA.address;
|
|
835
|
+
swapParams.amount = -deltaA;
|
|
836
|
+
const { amountOut: actualDeltaB, data: calldata } = await fetchCallData({
|
|
837
|
+
chainId,
|
|
838
|
+
amountIn: swapParams.amount,
|
|
839
|
+
tokenIn: pool.currencyA,
|
|
840
|
+
tokenOut: pool.currencyB,
|
|
841
|
+
slippageLimitPercent,
|
|
842
|
+
userAddress: CONTRACT_ADDRESSES[chainId].Minter,
|
|
843
|
+
testnetPrice: currencyBPerCurrencyA,
|
|
844
|
+
});
|
|
845
|
+
swapParams.data = calldata;
|
|
846
|
+
amountA += deltaA;
|
|
847
|
+
amountB += actualDeltaB;
|
|
848
|
+
}
|
|
849
|
+
else if (deltaB < 0n) {
|
|
850
|
+
swapParams.inCurrency = pool.currencyB.address;
|
|
851
|
+
swapParams.amount = -deltaB;
|
|
852
|
+
const { amountOut: actualDeltaA, data: calldata } = await fetchCallData({
|
|
853
|
+
chainId,
|
|
854
|
+
amountIn: swapParams.amount,
|
|
855
|
+
tokenIn: pool.currencyB,
|
|
856
|
+
tokenOut: pool.currencyA,
|
|
857
|
+
slippageLimitPercent,
|
|
858
|
+
userAddress: CONTRACT_ADDRESSES[chainId].Minter,
|
|
859
|
+
testnetPrice: currencyBPerCurrencyA
|
|
860
|
+
? 1 / currencyBPerCurrencyA
|
|
861
|
+
: undefined,
|
|
862
|
+
});
|
|
863
|
+
swapParams.data = calldata;
|
|
864
|
+
amountA += actualDeltaA;
|
|
865
|
+
amountB += deltaB;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
const { mintAmount, inAmountA, inAmountB } = getExpectedMintResult(pool.totalSupply, pool.liquidityA, pool.liquidityB, amountA, amountB, pool.currencyA, pool.currencyB);
|
|
869
|
+
if (mintAmount === 0n) {
|
|
870
|
+
return {
|
|
871
|
+
transaction: undefined,
|
|
872
|
+
result: {
|
|
873
|
+
currencyA: {
|
|
874
|
+
currency: pool.currencyA,
|
|
875
|
+
amount: '0',
|
|
876
|
+
direction: 'in',
|
|
877
|
+
},
|
|
878
|
+
currencyB: {
|
|
879
|
+
currency: pool.currencyB,
|
|
880
|
+
amount: '0',
|
|
881
|
+
direction: 'in',
|
|
882
|
+
},
|
|
883
|
+
lpCurrency: {
|
|
884
|
+
currency: pool.currencyLp,
|
|
885
|
+
amount: '0',
|
|
886
|
+
direction: 'out',
|
|
887
|
+
},
|
|
888
|
+
},
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
const minMintAmount = applyPercent(mintAmount, 100 - slippageLimitPercent);
|
|
892
|
+
const transaction = await buildTransaction(publicClient, {
|
|
893
|
+
chain: CHAIN_MAP[chainId],
|
|
894
|
+
account: userAddress,
|
|
895
|
+
address: CONTRACT_ADDRESSES[chainId].Minter,
|
|
896
|
+
abi: MINTER_ABI,
|
|
897
|
+
functionName: 'mint',
|
|
898
|
+
args: [
|
|
899
|
+
pool.key,
|
|
900
|
+
amountAOrigin,
|
|
901
|
+
amountBOrigin,
|
|
902
|
+
minMintAmount,
|
|
903
|
+
{
|
|
904
|
+
permitAmount: tokenAPermitParams.permitAmount,
|
|
905
|
+
signature: tokenAPermitParams.signature,
|
|
906
|
+
},
|
|
907
|
+
{
|
|
908
|
+
permitAmount: tokenBPermitParams.permitAmount,
|
|
909
|
+
signature: tokenBPermitParams.signature,
|
|
910
|
+
},
|
|
911
|
+
swapParams,
|
|
912
|
+
],
|
|
913
|
+
value: isAddressEqual(token0, zeroAddress)
|
|
914
|
+
? amountAOrigin
|
|
915
|
+
: isAddressEqual(token1, zeroAddress)
|
|
916
|
+
? amountBOrigin
|
|
917
|
+
: undefined,
|
|
918
|
+
}, options?.gasLimit);
|
|
919
|
+
const currencyARefund = amountA - inAmountA;
|
|
920
|
+
const currencyBRefund = amountB - inAmountB;
|
|
921
|
+
const currencyAResultAmount = amountAOrigin - currencyARefund;
|
|
922
|
+
const currencyBResultAmount = amountBOrigin - currencyBRefund;
|
|
923
|
+
return {
|
|
924
|
+
transaction,
|
|
925
|
+
result: {
|
|
926
|
+
currencyA: {
|
|
927
|
+
currency: pool.currencyA,
|
|
928
|
+
amount: formatUnits(abs(currencyAResultAmount), pool.currencyA.decimals),
|
|
929
|
+
direction: currencyAResultAmount >= 0 ? 'in' : 'out',
|
|
930
|
+
},
|
|
931
|
+
currencyB: {
|
|
932
|
+
currency: pool.currencyB,
|
|
933
|
+
amount: formatUnits(abs(currencyBResultAmount), pool.currencyB.decimals),
|
|
934
|
+
direction: currencyBResultAmount >= 0 ? 'in' : 'out',
|
|
935
|
+
},
|
|
936
|
+
lpCurrency: {
|
|
937
|
+
currency: pool.currencyLp,
|
|
938
|
+
amount: formatUnits(mintAmount, pool.currencyLp.decimals),
|
|
939
|
+
direction: 'out',
|
|
940
|
+
},
|
|
941
|
+
},
|
|
942
|
+
};
|
|
943
|
+
};
|
|
944
|
+
// @dev: Withdraw amount calculation logic is based on the contract code.
|
|
945
|
+
export const removeLiquidity = async ({ chainId, userAddress, token0, token1, salt, amount, options, }) => {
|
|
946
|
+
const publicClient = createPublicClient({
|
|
947
|
+
chain: CHAIN_MAP[chainId],
|
|
948
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
949
|
+
});
|
|
950
|
+
const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
|
|
951
|
+
if (!pool.isOpened) {
|
|
952
|
+
throw new Error(`
|
|
953
|
+
Open the pool before removing liquidity.
|
|
954
|
+
import { openPool } from '@clober/v2-sdk'
|
|
955
|
+
|
|
956
|
+
const transaction = await openPool({
|
|
957
|
+
chainId: ${chainId},
|
|
958
|
+
tokenA: '${token0}',
|
|
959
|
+
tokenB: '${token1}',
|
|
960
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
961
|
+
})
|
|
962
|
+
`);
|
|
963
|
+
}
|
|
964
|
+
const burnAmount = parseUnits(amount, pool.currencyLp.decimals);
|
|
965
|
+
const slippageLimitPercent = options?.slippage ?? 2;
|
|
966
|
+
const withdrawAmountA = (burnAmount * pool.liquidityA) / pool.totalSupply;
|
|
967
|
+
const withdrawAmountB = (burnAmount * pool.liquidityB) / pool.totalSupply;
|
|
968
|
+
const minWithdrawAmountA = applyPercent(withdrawAmountA, 100 - slippageLimitPercent);
|
|
969
|
+
const minWithdrawAmountB = applyPercent(withdrawAmountB, 100 - slippageLimitPercent);
|
|
970
|
+
if (burnAmount === 0n) {
|
|
971
|
+
return {
|
|
972
|
+
transaction: undefined,
|
|
973
|
+
result: {
|
|
974
|
+
currencyA: {
|
|
975
|
+
currency: pool.currencyA,
|
|
976
|
+
amount: '0',
|
|
977
|
+
direction: 'out',
|
|
978
|
+
},
|
|
979
|
+
currencyB: {
|
|
980
|
+
currency: pool.currencyB,
|
|
981
|
+
amount: '0',
|
|
982
|
+
direction: 'out',
|
|
983
|
+
},
|
|
984
|
+
lpCurrency: {
|
|
985
|
+
currency: pool.currencyLp,
|
|
986
|
+
amount: '0',
|
|
987
|
+
direction: 'in',
|
|
988
|
+
},
|
|
989
|
+
},
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
const transaction = await buildTransaction(publicClient, {
|
|
993
|
+
chain: CHAIN_MAP[chainId],
|
|
994
|
+
account: userAddress,
|
|
995
|
+
address: CONTRACT_ADDRESSES[chainId].Rebalancer,
|
|
996
|
+
abi: REBALANCER_ABI,
|
|
997
|
+
functionName: 'burn',
|
|
998
|
+
args: [pool.key, burnAmount, minWithdrawAmountA, minWithdrawAmountB],
|
|
999
|
+
}, options?.gasLimit);
|
|
1000
|
+
return {
|
|
1001
|
+
transaction,
|
|
1002
|
+
result: {
|
|
1003
|
+
currencyA: {
|
|
1004
|
+
currency: pool.currencyA,
|
|
1005
|
+
amount: formatUnits(withdrawAmountA, pool.currencyA.decimals),
|
|
1006
|
+
direction: 'out',
|
|
1007
|
+
},
|
|
1008
|
+
currencyB: {
|
|
1009
|
+
currency: pool.currencyB,
|
|
1010
|
+
amount: formatUnits(withdrawAmountB, pool.currencyB.decimals),
|
|
1011
|
+
direction: 'out',
|
|
1012
|
+
},
|
|
1013
|
+
lpCurrency: {
|
|
1014
|
+
currency: pool.currencyLp,
|
|
1015
|
+
amount: amount,
|
|
1016
|
+
direction: 'in',
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
};
|
|
1020
|
+
};
|
|
1021
|
+
export const refillOrder = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
|
|
1022
|
+
const publicClient = createPublicClient({
|
|
1023
|
+
chain: CHAIN_MAP[chainId],
|
|
1024
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1025
|
+
});
|
|
1026
|
+
const pool = options?.pool
|
|
1027
|
+
? options.pool
|
|
1028
|
+
: (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
|
|
1029
|
+
if (!pool.isOpened) {
|
|
1030
|
+
throw new Error(`
|
|
1031
|
+
Open the pool before rebalancing pool.
|
|
1032
|
+
import { openPool } from '@clober/v2-sdk'
|
|
1033
|
+
|
|
1034
|
+
const transaction = await openPool({
|
|
1035
|
+
chainId: ${chainId},
|
|
1036
|
+
tokenA: '${token0}',
|
|
1037
|
+
tokenB: '${token1}',
|
|
1038
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
1039
|
+
})
|
|
1040
|
+
`);
|
|
1041
|
+
}
|
|
1042
|
+
return buildTransaction(publicClient, {
|
|
1043
|
+
chain: CHAIN_MAP[chainId],
|
|
1044
|
+
account: userAddress,
|
|
1045
|
+
address: CONTRACT_ADDRESSES[chainId].Rebalancer,
|
|
1046
|
+
abi: REBALANCER_ABI,
|
|
1047
|
+
functionName: 'rebalance',
|
|
1048
|
+
args: [pool.key],
|
|
1049
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1050
|
+
};
|
|
1051
|
+
export const adjustOrderPrice = async ({ chainId, userAddress, token0, token1, salt, oraclePrice, bidPrice, askPrice, alpha, options, }) => {
|
|
1052
|
+
if (Number(alpha) <= 0 || Number(alpha) > 1) {
|
|
1053
|
+
throw new Error('Alpha value must be in the range (0, 1]');
|
|
1054
|
+
}
|
|
1055
|
+
if (Number(bidPrice) <= 0 || Number(askPrice) <= 0) {
|
|
1056
|
+
throw new Error('Price must be greater than 0');
|
|
1057
|
+
}
|
|
1058
|
+
if (Number(bidPrice) >= Number(askPrice)) {
|
|
1059
|
+
throw new Error('Bid price must be less than ask price');
|
|
1060
|
+
}
|
|
1061
|
+
const publicClient = createPublicClient({
|
|
1062
|
+
chain: CHAIN_MAP[chainId],
|
|
1063
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1064
|
+
});
|
|
1065
|
+
const pool = options?.pool
|
|
1066
|
+
? options.pool
|
|
1067
|
+
: (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
|
|
1068
|
+
if (!pool.isOpened) {
|
|
1069
|
+
throw new Error(`
|
|
1070
|
+
Open the pool before updating strategy price.
|
|
1071
|
+
import { openPool } from '@clober/v2-sdk'
|
|
1072
|
+
|
|
1073
|
+
const transaction = await openPool({
|
|
1074
|
+
chainId: ${chainId},
|
|
1075
|
+
tokenA: '${token0}',
|
|
1076
|
+
tokenB: '${token1}',
|
|
1077
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
1078
|
+
})
|
|
1079
|
+
`);
|
|
1080
|
+
}
|
|
1081
|
+
const [roundingUpBidPrice, roundingUpAskPrice] = [
|
|
1082
|
+
options?.roundingUpBidPrice ? options.roundingUpBidPrice : false,
|
|
1083
|
+
options?.roundingUpAskPrice ? options.roundingUpAskPrice : false,
|
|
1084
|
+
];
|
|
1085
|
+
const { roundingDownTick: roundingDownTickA, roundingUpTick: roundingUpTickA, } = parsePrice(Number(bidPrice), pool.currencyA.decimals, pool.currencyB.decimals);
|
|
1086
|
+
const { roundingDownTick: roundingDownTickB, roundingUpTick: roundingUpTickB, } = parsePrice(Number(askPrice), pool.currencyA.decimals, pool.currencyB.decimals);
|
|
1087
|
+
const oracleRawPrice = convertHumanReadablePriceToRawPrice(Number(oraclePrice), pool.currencyA.decimals, pool.currencyB.decimals);
|
|
1088
|
+
const tickA = options?.bidTick
|
|
1089
|
+
? Number(options.bidTick)
|
|
1090
|
+
: Number(roundingUpBidPrice ? roundingUpTickA : roundingDownTickA);
|
|
1091
|
+
let tickB = options?.askTick
|
|
1092
|
+
? Number(options.askTick)
|
|
1093
|
+
: Number(invertTick(roundingUpAskPrice ? roundingUpTickB : roundingDownTickB));
|
|
1094
|
+
if (invertTick(BigInt(tickB)) <= BigInt(tickA)) {
|
|
1095
|
+
tickB = Number(invertTick(BigInt(tickA + 1)));
|
|
1096
|
+
}
|
|
1097
|
+
const rateRaw = parseUnits(alpha, 6);
|
|
1098
|
+
return buildTransaction(publicClient, {
|
|
1099
|
+
chain: CHAIN_MAP[chainId],
|
|
1100
|
+
account: userAddress,
|
|
1101
|
+
address: CONTRACT_ADDRESSES[chainId].Operator,
|
|
1102
|
+
abi: OPERATOR_ABI,
|
|
1103
|
+
functionName: 'updatePosition',
|
|
1104
|
+
args: [pool.key, oracleRawPrice, tickA, tickB, rateRaw],
|
|
1105
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1106
|
+
};
|
|
1107
|
+
export const setStrategyConfig = async ({ chainId, userAddress, token0, token1, salt, config, options, }) => {
|
|
1108
|
+
// validate config
|
|
1109
|
+
if (Number(config.referenceThreshold) < 0 ||
|
|
1110
|
+
Number(config.referenceThreshold) > 1) {
|
|
1111
|
+
throw new Error('Reference threshold must be in the range [0, 1]');
|
|
1112
|
+
}
|
|
1113
|
+
if (Number(config.rebalanceThreshold) < 0 ||
|
|
1114
|
+
Number(config.rebalanceThreshold) > 1) {
|
|
1115
|
+
throw new Error('Rebalance threshold must be in the range [0, 1]');
|
|
1116
|
+
}
|
|
1117
|
+
if (Number(config.priceThresholdA) < 0 ||
|
|
1118
|
+
Number(config.priceThresholdA) > 1 ||
|
|
1119
|
+
Number(config.priceThresholdB) < 0 ||
|
|
1120
|
+
Number(config.priceThresholdB) > 1) {
|
|
1121
|
+
throw new Error('Price threshold must be in the range [0, 1]');
|
|
1122
|
+
}
|
|
1123
|
+
if (Number(config.rateA) < 0 ||
|
|
1124
|
+
Number(config.rateA) > 1 ||
|
|
1125
|
+
Number(config.rateB) < 0 ||
|
|
1126
|
+
Number(config.rateB) > 1) {
|
|
1127
|
+
throw new Error('Rate must be in the range [0, 1]');
|
|
1128
|
+
}
|
|
1129
|
+
if (Number(config.minRateA) < 0 ||
|
|
1130
|
+
Number(config.minRateA) > 1 ||
|
|
1131
|
+
Number(config.minRateB) < 0 ||
|
|
1132
|
+
Number(config.minRateB) > 1) {
|
|
1133
|
+
throw new Error('Min rate must be in the range [0, 1]');
|
|
1134
|
+
}
|
|
1135
|
+
if (Number(config.minRateA) > Number(config.rateA) ||
|
|
1136
|
+
Number(config.minRateB) > Number(config.rateB)) {
|
|
1137
|
+
throw new Error('Min rate must be less or equal to rate');
|
|
1138
|
+
}
|
|
1139
|
+
const publicClient = createPublicClient({
|
|
1140
|
+
chain: CHAIN_MAP[chainId],
|
|
1141
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1142
|
+
});
|
|
1143
|
+
const pool = await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph));
|
|
1144
|
+
if (!pool.isOpened) {
|
|
1145
|
+
throw new Error(`
|
|
1146
|
+
Open the pool before set strategy config.
|
|
1147
|
+
import { openPool } from '@clober/v2-sdk'
|
|
1148
|
+
|
|
1149
|
+
const transaction = await openPool({
|
|
1150
|
+
chainId: ${chainId},
|
|
1151
|
+
tokenA: '${token0}',
|
|
1152
|
+
tokenB: '${token1}',
|
|
1153
|
+
})
|
|
1154
|
+
`);
|
|
1155
|
+
}
|
|
1156
|
+
const configRaw = {
|
|
1157
|
+
referenceThreshold: parseUnits(config.referenceThreshold, 6),
|
|
1158
|
+
rebalanceThreshold: parseUnits(config.rebalanceThreshold, 6),
|
|
1159
|
+
rateA: parseUnits(config.rateA, 6),
|
|
1160
|
+
rateB: parseUnits(config.rateB, 6),
|
|
1161
|
+
minRateA: parseUnits(config.minRateA, 6),
|
|
1162
|
+
minRateB: parseUnits(config.minRateB, 6),
|
|
1163
|
+
priceThresholdA: parseUnits(config.priceThresholdA, 6),
|
|
1164
|
+
priceThresholdB: parseUnits(config.priceThresholdB, 6),
|
|
1165
|
+
};
|
|
1166
|
+
return buildTransaction(publicClient, {
|
|
1167
|
+
chain: CHAIN_MAP[chainId],
|
|
1168
|
+
account: userAddress,
|
|
1169
|
+
address: CONTRACT_ADDRESSES[chainId].Strategy,
|
|
1170
|
+
abi: STRATEGY_ABI,
|
|
1171
|
+
functionName: 'setConfig',
|
|
1172
|
+
args: [pool.key, configRaw],
|
|
1173
|
+
}, options?.gasLimit);
|
|
1174
|
+
};
|
|
1175
|
+
export const pausePool = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
|
|
1176
|
+
const publicClient = createPublicClient({
|
|
1177
|
+
chain: CHAIN_MAP[chainId],
|
|
1178
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1179
|
+
});
|
|
1180
|
+
const pool = options?.pool
|
|
1181
|
+
? options.pool
|
|
1182
|
+
: (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
|
|
1183
|
+
if (!pool.isOpened) {
|
|
1184
|
+
throw new Error(`
|
|
1185
|
+
Open the pool before trying pause.
|
|
1186
|
+
import { openPool } from '@clober/v2-sdk'
|
|
1187
|
+
|
|
1188
|
+
const transaction = await openPool({
|
|
1189
|
+
chainId: ${chainId},
|
|
1190
|
+
tokenA: '${token0}',
|
|
1191
|
+
tokenB: '${token1}',
|
|
1192
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
1193
|
+
})
|
|
1194
|
+
`);
|
|
1195
|
+
}
|
|
1196
|
+
if (pool.paused) {
|
|
1197
|
+
return undefined;
|
|
1198
|
+
}
|
|
1199
|
+
return buildTransaction(publicClient, {
|
|
1200
|
+
chain: CHAIN_MAP[chainId],
|
|
1201
|
+
account: userAddress,
|
|
1202
|
+
address: CONTRACT_ADDRESSES[chainId].Operator,
|
|
1203
|
+
abi: OPERATOR_ABI,
|
|
1204
|
+
functionName: 'pause',
|
|
1205
|
+
args: [pool.key],
|
|
1206
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1207
|
+
};
|
|
1208
|
+
export const resumePool = async ({ chainId, userAddress, token0, token1, salt, options, }) => {
|
|
1209
|
+
const publicClient = createPublicClient({
|
|
1210
|
+
chain: CHAIN_MAP[chainId],
|
|
1211
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1212
|
+
});
|
|
1213
|
+
const pool = options?.pool
|
|
1214
|
+
? options.pool
|
|
1215
|
+
: (await fetchPool(publicClient, chainId, [token0, token1], salt, !!(options && options.useSubgraph))).toJson();
|
|
1216
|
+
if (!pool.isOpened) {
|
|
1217
|
+
throw new Error(`
|
|
1218
|
+
Open the pool before trying resume.
|
|
1219
|
+
import { openPool } from '@clober/v2-sdk'
|
|
1220
|
+
|
|
1221
|
+
const transaction = await openPool({
|
|
1222
|
+
chainId: ${chainId},
|
|
1223
|
+
tokenA: '${token0}',
|
|
1224
|
+
tokenB: '${token1}',
|
|
1225
|
+
salt: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
1226
|
+
})
|
|
1227
|
+
`);
|
|
1228
|
+
}
|
|
1229
|
+
if (!pool.paused) {
|
|
1230
|
+
return undefined;
|
|
1231
|
+
}
|
|
1232
|
+
return buildTransaction(publicClient, {
|
|
1233
|
+
chain: CHAIN_MAP[chainId],
|
|
1234
|
+
account: userAddress,
|
|
1235
|
+
address: CONTRACT_ADDRESSES[chainId].Strategy,
|
|
1236
|
+
abi: STRATEGY_ABI,
|
|
1237
|
+
functionName: 'unpause',
|
|
1238
|
+
args: [pool.key],
|
|
1239
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1240
|
+
};
|
|
1241
|
+
export const vote = async ({ chainId, userAddress, candidateAddress, inFavor, options, }) => {
|
|
1242
|
+
const publicClient = createPublicClient({
|
|
1243
|
+
chain: CHAIN_MAP[chainId],
|
|
1244
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1245
|
+
});
|
|
1246
|
+
return buildTransaction(publicClient, {
|
|
1247
|
+
chain: CHAIN_MAP[chainId],
|
|
1248
|
+
account: userAddress,
|
|
1249
|
+
address: CONTRACT_ADDRESSES[chainId].ElectionGovernor,
|
|
1250
|
+
abi: ELECTION_GOVERNOR_ABI,
|
|
1251
|
+
functionName: 'vote',
|
|
1252
|
+
args: [candidateAddress, inFavor],
|
|
1253
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1254
|
+
};
|
|
1255
|
+
export const register = async ({ chainId, userAddress, options, }) => {
|
|
1256
|
+
const publicClient = createPublicClient({
|
|
1257
|
+
chain: CHAIN_MAP[chainId],
|
|
1258
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1259
|
+
});
|
|
1260
|
+
return buildTransaction(publicClient, {
|
|
1261
|
+
chain: CHAIN_MAP[chainId],
|
|
1262
|
+
account: userAddress,
|
|
1263
|
+
address: CONTRACT_ADDRESSES[chainId].ElectionGovernor,
|
|
1264
|
+
abi: ELECTION_GOVERNOR_ABI,
|
|
1265
|
+
functionName: 'register',
|
|
1266
|
+
args: [],
|
|
1267
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1268
|
+
};
|
|
1269
|
+
export const end = async ({ chainId, userAddress, options, }) => {
|
|
1270
|
+
const publicClient = createPublicClient({
|
|
1271
|
+
chain: CHAIN_MAP[chainId],
|
|
1272
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1273
|
+
});
|
|
1274
|
+
return buildTransaction(publicClient, {
|
|
1275
|
+
chain: CHAIN_MAP[chainId],
|
|
1276
|
+
account: userAddress,
|
|
1277
|
+
address: CONTRACT_ADDRESSES[chainId].ElectionGovernor,
|
|
1278
|
+
abi: ELECTION_GOVERNOR_ABI,
|
|
1279
|
+
functionName: 'end',
|
|
1280
|
+
args: [],
|
|
1281
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1282
|
+
};
|
|
1283
|
+
export const mintVCLOB = async ({ chainId, userAddress, amount, options, }) => {
|
|
1284
|
+
const publicClient = createPublicClient({
|
|
1285
|
+
chain: CHAIN_MAP[chainId],
|
|
1286
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1287
|
+
});
|
|
1288
|
+
return buildTransaction(publicClient, {
|
|
1289
|
+
chain: CHAIN_MAP[chainId],
|
|
1290
|
+
account: userAddress,
|
|
1291
|
+
address: CONTRACT_ADDRESSES[chainId].VoteLockedCloberToken,
|
|
1292
|
+
abi: VCLOB_ABI,
|
|
1293
|
+
functionName: 'mint',
|
|
1294
|
+
args: [amount, userAddress],
|
|
1295
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1296
|
+
};
|
|
1297
|
+
export const burnVCLOB = async ({ chainId, userAddress, id, options, }) => {
|
|
1298
|
+
const publicClient = createPublicClient({
|
|
1299
|
+
chain: CHAIN_MAP[chainId],
|
|
1300
|
+
transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
|
|
1301
|
+
});
|
|
1302
|
+
return buildTransaction(publicClient, {
|
|
1303
|
+
chain: CHAIN_MAP[chainId],
|
|
1304
|
+
account: userAddress,
|
|
1305
|
+
address: CONTRACT_ADDRESSES[chainId].VoteLockedCloberToken,
|
|
1306
|
+
abi: VCLOB_ABI,
|
|
1307
|
+
functionName: 'burn',
|
|
1308
|
+
args: [Number(id), userAddress],
|
|
1309
|
+
}, options?.gasLimit, options?.gasPriceLimit);
|
|
1310
|
+
};
|
|
574
1311
|
//# sourceMappingURL=call.js.map
|