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