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