@clober/v2-sdk 0.0.4 → 0.0.5-0.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 +321 -0
- package/dist/cjs/abis/core/book-viewer-abi.js.map +1 -0
- package/dist/cjs/abis/core/controller-abi.js +29 -24
- package/dist/cjs/abis/core/controller-abi.js.map +1 -1
- package/dist/cjs/apis/chart-logs.js +154 -0
- package/dist/cjs/apis/chart-logs.js.map +1 -0
- package/dist/cjs/apis/market.js +61 -32
- package/dist/cjs/apis/market.js.map +1 -1
- package/dist/cjs/apis/open-order.js +56 -21
- package/dist/cjs/apis/open-order.js.map +1 -1
- package/dist/cjs/approval.js +77 -30
- package/dist/cjs/approval.js.map +1 -1
- package/dist/cjs/call.js +313 -206
- package/dist/cjs/call.js.map +1 -1
- package/dist/cjs/constants/addresses.js +26 -1
- package/dist/cjs/constants/addresses.js.map +1 -1
- package/dist/cjs/constants/chain.js +19 -1
- package/dist/cjs/constants/chain.js.map +1 -1
- package/dist/cjs/constants/client.js +4 -0
- package/dist/cjs/constants/client.js.map +1 -1
- package/dist/cjs/constants/currency.js +28 -2
- package/dist/cjs/constants/currency.js.map +1 -1
- package/dist/cjs/constants/fee.js +17 -2
- package/dist/cjs/constants/fee.js.map +1 -1
- package/dist/cjs/constants/subgraph.js +57 -0
- package/dist/cjs/constants/subgraph.js.map +1 -0
- package/dist/cjs/constants/test-chain.js +27 -0
- package/dist/cjs/constants/test-chain.js.map +1 -0
- package/dist/cjs/index.js +20 -6
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/model/book.js +47 -29
- package/dist/cjs/model/book.js.map +1 -1
- package/dist/cjs/model/chart-log.js +3 -0
- package/dist/cjs/model/chart-log.js.map +1 -0
- package/dist/cjs/model/market.js +45 -182
- package/dist/cjs/model/market.js.map +1 -1
- package/dist/cjs/signature.js +20 -16
- package/dist/cjs/signature.js.map +1 -1
- package/dist/cjs/type.js +16 -1
- package/dist/cjs/type.js.map +1 -1
- package/dist/cjs/utils/allowance.js +40 -0
- package/dist/cjs/utils/allowance.js.map +1 -0
- package/dist/cjs/utils/bigint.js +9 -0
- package/dist/cjs/utils/bigint.js.map +1 -0
- package/dist/cjs/utils/bignumber.js +9 -0
- package/dist/cjs/utils/bignumber.js.map +1 -0
- package/dist/cjs/utils/book-id.js +7 -7
- package/dist/cjs/utils/book-id.js.map +1 -1
- package/dist/cjs/utils/build-transaction.js +8 -7
- package/dist/cjs/utils/build-transaction.js.map +1 -1
- package/dist/cjs/utils/currency.js +166 -0
- package/dist/cjs/utils/currency.js.map +1 -0
- package/dist/cjs/utils/decorator.js +3 -1
- package/dist/cjs/utils/decorator.js.map +1 -1
- package/dist/cjs/utils/open.js +36 -0
- package/dist/cjs/utils/open.js.map +1 -0
- package/dist/cjs/utils/order.js +102 -0
- package/dist/cjs/utils/order.js.map +1 -0
- package/dist/cjs/utils/prices.js +25 -3
- package/dist/cjs/utils/prices.js.map +1 -1
- package/dist/cjs/utils/unit-size.js +49 -0
- package/dist/cjs/utils/unit-size.js.map +1 -0
- package/dist/cjs/utils.js +15 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/cjs/view.js +102 -33
- 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 +318 -0
- package/dist/esm/abis/core/book-viewer-abi.js.map +1 -0
- package/dist/esm/abis/core/controller-abi.js +29 -24
- package/dist/esm/abis/core/controller-abi.js.map +1 -1
- package/dist/esm/apis/chart-logs.js +150 -0
- package/dist/esm/apis/chart-logs.js.map +1 -0
- package/dist/esm/apis/market.js +61 -32
- package/dist/esm/apis/market.js.map +1 -1
- package/dist/esm/apis/open-order.js +57 -21
- package/dist/esm/apis/open-order.js.map +1 -1
- package/dist/esm/approval.js +116 -44
- package/dist/esm/approval.js.map +1 -1
- package/dist/esm/call.js +430 -309
- package/dist/esm/call.js.map +1 -1
- package/dist/esm/constants/addresses.js +26 -1
- package/dist/esm/constants/addresses.js.map +1 -1
- package/dist/esm/constants/chain.js +20 -2
- package/dist/esm/constants/chain.js.map +1 -1
- package/dist/esm/constants/client.js +5 -1
- package/dist/esm/constants/client.js.map +1 -1
- package/dist/esm/constants/currency.js +28 -2
- package/dist/esm/constants/currency.js.map +1 -1
- package/dist/esm/constants/fee.js +17 -2
- package/dist/esm/constants/fee.js.map +1 -1
- package/dist/esm/constants/subgraph.js +53 -0
- package/dist/esm/constants/subgraph.js.map +1 -0
- package/dist/esm/constants/test-chain.js +24 -0
- package/dist/esm/constants/test-chain.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/model/book.js +47 -29
- package/dist/esm/model/book.js.map +1 -1
- package/dist/esm/model/chart-log.js +2 -0
- package/dist/esm/model/chart-log.js.map +1 -0
- package/dist/esm/model/market.js +46 -187
- package/dist/esm/model/market.js.map +1 -1
- package/dist/esm/signature.js +35 -37
- package/dist/esm/signature.js.map +1 -1
- package/dist/esm/type.js +15 -0
- package/dist/esm/type.js.map +1 -1
- package/dist/esm/utils/allowance.js +36 -0
- package/dist/esm/utils/allowance.js.map +1 -0
- package/dist/esm/utils/bigint.js +5 -0
- package/dist/esm/utils/bigint.js.map +1 -0
- package/dist/esm/utils/bignumber.js +6 -0
- package/dist/esm/utils/bignumber.js.map +1 -0
- package/dist/esm/utils/book-id.js +7 -7
- package/dist/esm/utils/book-id.js.map +1 -1
- package/dist/esm/utils/build-transaction.js +8 -7
- package/dist/esm/utils/build-transaction.js.map +1 -1
- package/dist/esm/utils/currency.js +161 -0
- package/dist/esm/utils/currency.js.map +1 -0
- package/dist/esm/utils/decorator.js +3 -1
- package/dist/esm/utils/decorator.js.map +1 -1
- package/dist/esm/utils/open.js +32 -0
- package/dist/esm/utils/open.js.map +1 -0
- package/dist/esm/utils/order.js +98 -0
- package/dist/esm/utils/order.js.map +1 -0
- package/dist/esm/utils/prices.js +24 -2
- package/dist/esm/utils/prices.js.map +1 -1
- package/dist/esm/utils/unit-size.js +45 -0
- package/dist/esm/utils/unit-size.js.map +1 -0
- package/dist/esm/utils.js +4 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/view.js +215 -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 +243 -0
- package/dist/types/abis/core/book-viewer-abi.d.ts.map +1 -0
- 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/apis/chart-logs.d.ts +5 -0
- package/dist/types/apis/chart-logs.d.ts.map +1 -0
- package/dist/types/apis/market.d.ts +1 -1
- package/dist/types/apis/market.d.ts.map +1 -1
- package/dist/types/apis/open-order.d.ts +3 -2
- package/dist/types/apis/open-order.d.ts.map +1 -1
- package/dist/types/approval.d.ts +48 -16
- package/dist/types/approval.d.ts.map +1 -1
- package/dist/types/call.d.ts +151 -109
- package/dist/types/call.d.ts.map +1 -1
- package/dist/types/constants/addresses.d.ts.map +1 -1
- package/dist/types/constants/chain.d.ts +6 -2
- package/dist/types/constants/chain.d.ts.map +1 -1
- package/dist/types/constants/client.d.ts +1 -1
- package/dist/types/constants/client.d.ts.map +1 -1
- 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/subgraph.d.ts +10 -0
- package/dist/types/constants/subgraph.d.ts.map +1 -0
- package/dist/types/constants/test-chain.d.ts +3 -0
- package/dist/types/constants/test-chain.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/model/book.d.ts +13 -29
- package/dist/types/model/book.d.ts.map +1 -1
- package/dist/types/model/chart-log.d.ts +9 -0
- package/dist/types/model/chart-log.d.ts.map +1 -0
- package/dist/types/model/depth.d.ts +4 -5
- package/dist/types/model/depth.d.ts.map +1 -1
- package/dist/types/model/market.d.ts +15 -19
- package/dist/types/model/market.d.ts.map +1 -1
- package/dist/types/model/open-order.d.ts +16 -8
- package/dist/types/model/open-order.d.ts.map +1 -1
- package/dist/types/signature.d.ts +18 -24
- package/dist/types/signature.d.ts.map +1 -1
- package/dist/types/type.d.ts +52 -8
- 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/bigint.d.ts +2 -0
- package/dist/types/utils/bigint.d.ts.map +1 -0
- package/dist/types/utils/bignumber.d.ts +3 -0
- package/dist/types/utils/bignumber.d.ts.map +1 -0
- 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/{apis → utils}/currency.d.ts +3 -0
- package/dist/types/utils/currency.d.ts.map +1 -0
- package/dist/types/utils/decorator.d.ts +1 -1
- package/dist/types/utils/decorator.d.ts.map +1 -1
- package/dist/types/utils/open.d.ts +3 -0
- package/dist/types/utils/open.d.ts.map +1 -0
- package/dist/types/utils/order.d.ts +8 -0
- package/dist/types/utils/order.d.ts.map +1 -0
- package/dist/types/utils/prices.d.ts +8 -1
- package/dist/types/utils/prices.d.ts.map +1 -1
- package/dist/types/utils/unit-size.d.ts +4 -0
- package/dist/types/utils/unit-size.d.ts.map +1 -0
- package/dist/types/utils.d.ts +4 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/view.d.ts +184 -41
- package/dist/types/view.d.ts.map +1 -1
- package/package.json +1 -1
- 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/currency.js +0 -83
- package/dist/cjs/apis/currency.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/subgraph-url.js +0 -8
- package/dist/cjs/constants/subgraph-url.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/currency.js +0 -79
- package/dist/esm/apis/currency.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/subgraph-url.js +0 -5
- package/dist/esm/constants/subgraph-url.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/currency.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/subgraph-url.d.ts +0 -5
- package/dist/types/constants/subgraph-url.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,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { formatUnits, 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';
|
|
@@ -8,17 +8,18 @@ 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
10
|
import { parsePrice } from './utils/prices';
|
|
11
|
-
import { fromPrice, invertPrice } from './utils/tick';
|
|
12
|
-
import {
|
|
11
|
+
import { fromPrice, invertPrice, toPrice } from './utils/tick';
|
|
12
|
+
import { getExpectedInput, getExpectedOutput } from './view';
|
|
13
13
|
import { toBookId } from './utils/book-id';
|
|
14
|
-
import { MAKE_ORDER_PARAMS_ABI, TAKE_ORDER_PARAMS_ABI, } from './abis/core/params-abi';
|
|
15
|
-
import { Action } from './constants/action';
|
|
16
14
|
import { fetchIsApprovedForAll } from './utils/approval';
|
|
17
15
|
import { decorator } from './utils/decorator';
|
|
16
|
+
import { fetchOrders } from './utils/order';
|
|
17
|
+
import { applyPercent } from './utils/bigint';
|
|
18
18
|
/**
|
|
19
19
|
* Build a transaction to open a market.
|
|
20
20
|
*
|
|
21
21
|
* @param chainId The chain ID of the blockchain.
|
|
22
|
+
* @param userAddress The address of the user.
|
|
22
23
|
* @param inputToken The address of the input token.
|
|
23
24
|
* @param outputToken The address of the output token.
|
|
24
25
|
* @param options
|
|
@@ -27,38 +28,42 @@ import { decorator } from './utils/decorator';
|
|
|
27
28
|
* @example
|
|
28
29
|
* import { openMarket } from '@clober/v2-sdk'
|
|
29
30
|
*
|
|
30
|
-
* const transaction = await openMarket(
|
|
31
|
-
* 421614,
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* const transaction = await openMarket({
|
|
32
|
+
* chainId: 421614,
|
|
33
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69',
|
|
34
|
+
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
35
|
+
* outputToken: '0x0000000000000000000000000000000000000000'
|
|
36
|
+
* })
|
|
35
37
|
*/
|
|
36
|
-
export const openMarket = decorator(async ({ chainId, inputToken, outputToken, }) => {
|
|
38
|
+
export const openMarket = decorator(async ({ chainId, userAddress, inputToken, outputToken, options, }) => {
|
|
37
39
|
const market = await fetchMarket(chainId, [inputToken, outputToken]);
|
|
38
40
|
const isBid = isAddressEqual(market.quote.address, inputToken);
|
|
39
|
-
if ((isBid && !market.
|
|
40
|
-
|
|
41
|
+
if ((isBid && !market.bidBook.isOpened) ||
|
|
42
|
+
(!isBid && !market.askBook.isOpened)) {
|
|
43
|
+
const unitSize = await calculateUnitSize(chainId, isBid ? market.quote : market.base);
|
|
41
44
|
return buildTransaction(chainId, {
|
|
45
|
+
chain: CHAIN_MAP[chainId],
|
|
42
46
|
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
47
|
+
account: userAddress,
|
|
43
48
|
abi: CONTROLLER_ABI,
|
|
44
49
|
functionName: 'open',
|
|
45
50
|
args: [
|
|
46
51
|
[
|
|
47
52
|
{
|
|
48
53
|
key: {
|
|
49
|
-
base:
|
|
50
|
-
|
|
51
|
-
quote:
|
|
52
|
-
makerPolicy: MAKER_DEFAULT_POLICY.value,
|
|
54
|
+
base: outputToken,
|
|
55
|
+
unitSize,
|
|
56
|
+
quote: inputToken,
|
|
57
|
+
makerPolicy: MAKER_DEFAULT_POLICY[chainId].value,
|
|
53
58
|
hooks: zeroAddress,
|
|
54
|
-
takerPolicy: TAKER_DEFAULT_POLICY.value,
|
|
59
|
+
takerPolicy: TAKER_DEFAULT_POLICY[chainId].value,
|
|
55
60
|
},
|
|
56
61
|
hookData: zeroHash,
|
|
57
62
|
},
|
|
58
63
|
],
|
|
59
64
|
getDeadlineTimestampInSeconds(),
|
|
60
65
|
],
|
|
61
|
-
});
|
|
66
|
+
}, options?.gasLimit);
|
|
62
67
|
}
|
|
63
68
|
return undefined;
|
|
64
69
|
});
|
|
@@ -72,63 +77,70 @@ export const openMarket = decorator(async ({ chainId, inputToken, outputToken, }
|
|
|
72
77
|
* @param {string} amount The amount of input tokens for the order.
|
|
73
78
|
* @param {string} price The price at which the order should be executed.
|
|
74
79
|
* @param {Object} [options] Optional parameters for the limit order.
|
|
75
|
-
* @param {
|
|
80
|
+
* @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
|
|
76
81
|
* @param {boolean} [options.postOnly] A boolean indicating whether the order is only to be made not taken.
|
|
77
82
|
* @param {string} [options.rpcUrl] The RPC URL of the blockchain.
|
|
78
|
-
* @
|
|
83
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
84
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
85
|
+
* @returns {Promise<{ transaction: Transaction, result: { make: CurrencyFlow, take: CurrencyFlow, spent: CurrencyFlow }>}
|
|
86
|
+
* Promise resolving to the transaction object representing the limit order with the result of the order.
|
|
79
87
|
* @example
|
|
80
88
|
* import { signERC20Permit, limitOrder } from '@clober/v2-sdk'
|
|
81
89
|
* import { privateKeyToAccount } from 'viem/accounts'
|
|
82
90
|
*
|
|
83
|
-
* const
|
|
84
|
-
* 421614,
|
|
85
|
-
*
|
|
86
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
87
|
-
* '100.123'
|
|
88
|
-
* )
|
|
91
|
+
* const erc20PermitParam = await signERC20Permit({
|
|
92
|
+
* chainId: 421614,
|
|
93
|
+
* walletClient,
|
|
94
|
+
* token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
95
|
+
* amount: '100.123'
|
|
96
|
+
* })
|
|
89
97
|
*
|
|
90
|
-
* const transaction = await limitOrder(
|
|
91
|
-
* 421614,
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* )
|
|
98
|
+
* const { transaction } = await limitOrder({
|
|
99
|
+
* chainId: 421614,
|
|
100
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
101
|
+
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
102
|
+
* outputToken: '0x0000000000000000000000000000000000000000',
|
|
103
|
+
* amount: '100.123', // 100.123 USDC
|
|
104
|
+
* price: '4000.01', // price at 4000.01 (ETH/USDC)
|
|
105
|
+
* options: { erc20PermitParam }
|
|
106
|
+
* })
|
|
99
107
|
*
|
|
100
108
|
* @example
|
|
101
109
|
* import { limitOrder } from '@clober/v2-sdk'
|
|
102
110
|
*
|
|
103
|
-
* const transaction = await limitOrder(
|
|
104
|
-
* 421614,
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* )
|
|
111
|
+
* const { transaction } = await limitOrder({
|
|
112
|
+
* chainId: 421614,
|
|
113
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
114
|
+
* inputToken: '0x0000000000000000000000000000000000000000',
|
|
115
|
+
* outputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
116
|
+
* amount: '0.13', // 0.13 ETH
|
|
117
|
+
* price: '4000.01', // price at 4000.01 (ETH/USDC)
|
|
118
|
+
* })
|
|
111
119
|
*/
|
|
112
120
|
export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, outputToken, amount, price, options, }) => {
|
|
113
121
|
const market = await fetchMarket(chainId, [inputToken, outputToken]);
|
|
114
122
|
const isBid = isAddressEqual(market.quote.address, inputToken);
|
|
115
|
-
|
|
123
|
+
const [inputCurrency, outputCurrency] = isBid
|
|
124
|
+
? [market.quote, market.base]
|
|
125
|
+
: [market.base, market.quote];
|
|
126
|
+
if ((isBid && !market.bidBook.isOpened) ||
|
|
127
|
+
(!isBid && !market.askBook.isOpened)) {
|
|
116
128
|
throw new Error(`
|
|
129
|
+
Open the market before placing a limit order.
|
|
117
130
|
import { openMarket } from '@clober/v2-sdk'
|
|
118
131
|
|
|
119
|
-
const transaction = await openMarket(
|
|
120
|
-
${chainId},
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
132
|
+
const transaction = await openMarket({
|
|
133
|
+
chainId: ${chainId},
|
|
134
|
+
inputToken: '${inputToken}',
|
|
135
|
+
outputToken: '${outputToken}',
|
|
136
|
+
})
|
|
124
137
|
`);
|
|
125
138
|
}
|
|
126
139
|
const rawPrice = parsePrice(Number(price), market.quote.decimals, market.base.decimals);
|
|
127
|
-
const tick = isBid ? fromPrice(rawPrice) : fromPrice(invertPrice(rawPrice));
|
|
128
140
|
const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
|
|
129
|
-
const quoteAmount = parseUnits(amount,
|
|
130
|
-
const [
|
|
131
|
-
|
|
141
|
+
const quoteAmount = parseUnits(amount, inputCurrency.decimals);
|
|
142
|
+
const [unitSize, { takenAmount, spentAmount, bookId }] = await Promise.all([
|
|
143
|
+
calculateUnitSize(chainId, inputCurrency),
|
|
132
144
|
getExpectedOutput({
|
|
133
145
|
chainId,
|
|
134
146
|
inputToken,
|
|
@@ -136,162 +148,162 @@ export const limitOrder = decorator(async ({ chainId, userAddress, inputToken, o
|
|
|
136
148
|
amountIn: amount,
|
|
137
149
|
options: {
|
|
138
150
|
...options,
|
|
151
|
+
limitPrice: price,
|
|
139
152
|
},
|
|
140
153
|
}),
|
|
141
154
|
]);
|
|
142
155
|
const isETH = isAddressEqual(inputToken, zeroAddress);
|
|
143
|
-
const permitParamsList = options?.signature && !isETH
|
|
144
|
-
? [
|
|
145
|
-
{
|
|
146
|
-
token: inputToken,
|
|
147
|
-
permitAmount: quoteAmount,
|
|
148
|
-
signature: options.signature,
|
|
149
|
-
},
|
|
150
|
-
]
|
|
151
|
-
: [];
|
|
152
156
|
const makeParam = {
|
|
153
|
-
id: toBookId(inputToken, outputToken,
|
|
154
|
-
tick:
|
|
157
|
+
id: toBookId(chainId, inputToken, outputToken, unitSize),
|
|
158
|
+
tick: options?.makeTick
|
|
159
|
+
? Number(options.makeTick)
|
|
160
|
+
: Number(isBid ? fromPrice(rawPrice) : fromPrice(invertPrice(rawPrice))),
|
|
155
161
|
quoteAmount,
|
|
156
162
|
hookData: zeroHash,
|
|
157
163
|
};
|
|
158
|
-
if (options?.postOnly === true ||
|
|
159
|
-
return
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
[
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
value: isETH ? quoteAmount : 0n,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
else if (result.length === 1) {
|
|
175
|
-
// take and make
|
|
176
|
-
return buildTransaction(chainId, {
|
|
177
|
-
chain: CHAIN_MAP[chainId],
|
|
178
|
-
account: userAddress,
|
|
179
|
-
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
180
|
-
abi: CONTROLLER_ABI,
|
|
181
|
-
functionName: 'limit',
|
|
182
|
-
args: [
|
|
183
|
-
[
|
|
184
|
-
{
|
|
185
|
-
takeBookId: result[0].bookId,
|
|
186
|
-
makeBookId: makeParam.id,
|
|
187
|
-
limitPrice: rawPrice,
|
|
188
|
-
tick: makeParam.tick,
|
|
189
|
-
quoteAmount,
|
|
190
|
-
takeHookData: zeroHash,
|
|
191
|
-
makeHookData: makeParam.hookData,
|
|
192
|
-
},
|
|
164
|
+
if (options?.postOnly === true || spentAmount === '0') {
|
|
165
|
+
return {
|
|
166
|
+
transaction: await buildTransaction(chainId, {
|
|
167
|
+
chain: CHAIN_MAP[chainId],
|
|
168
|
+
account: userAddress,
|
|
169
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
170
|
+
abi: CONTROLLER_ABI,
|
|
171
|
+
functionName: 'make',
|
|
172
|
+
args: [
|
|
173
|
+
[makeParam],
|
|
174
|
+
tokensToSettle,
|
|
175
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
176
|
+
getDeadlineTimestampInSeconds(),
|
|
193
177
|
],
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
178
|
+
value: isETH ? quoteAmount : 0n,
|
|
179
|
+
}, options?.gasLimit),
|
|
180
|
+
result: {
|
|
181
|
+
make: {
|
|
182
|
+
amount: formatUnits(quoteAmount, inputCurrency.decimals),
|
|
183
|
+
currency: inputCurrency,
|
|
184
|
+
direction: 'in',
|
|
185
|
+
},
|
|
186
|
+
spent: {
|
|
187
|
+
amount: '0',
|
|
188
|
+
currency: inputCurrency,
|
|
189
|
+
direction: 'in',
|
|
190
|
+
},
|
|
191
|
+
taken: {
|
|
192
|
+
amount: '0',
|
|
193
|
+
currency: outputCurrency,
|
|
194
|
+
direction: 'out',
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
};
|
|
200
198
|
}
|
|
201
199
|
else {
|
|
202
|
-
// take
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
[
|
|
213
|
-
...result.map(() => Action.TAKE),
|
|
214
|
-
...(makeAmount > 0n ? [Action.MAKE] : []),
|
|
215
|
-
],
|
|
216
|
-
[
|
|
217
|
-
...result.map(({ bookId, takenAmount }) => encodeAbiParameters(TAKE_ORDER_PARAMS_ABI, [
|
|
200
|
+
// take and make
|
|
201
|
+
return {
|
|
202
|
+
transaction: await buildTransaction(chainId, {
|
|
203
|
+
chain: CHAIN_MAP[chainId],
|
|
204
|
+
account: userAddress,
|
|
205
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
206
|
+
abi: CONTROLLER_ABI,
|
|
207
|
+
functionName: 'limit',
|
|
208
|
+
args: [
|
|
209
|
+
[
|
|
218
210
|
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
211
|
+
takeBookId: bookId,
|
|
212
|
+
makeBookId: makeParam.id,
|
|
213
|
+
limitPrice: options?.takeLimitTick
|
|
214
|
+
? toPrice(options.takeLimitTick)
|
|
215
|
+
: isBid
|
|
216
|
+
? invertPrice(rawPrice)
|
|
217
|
+
: rawPrice,
|
|
218
|
+
tick: makeParam.tick,
|
|
219
|
+
quoteAmount,
|
|
220
|
+
takeHookData: zeroHash,
|
|
221
|
+
makeHookData: makeParam.hookData,
|
|
223
222
|
},
|
|
224
|
-
]
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
{
|
|
229
|
-
...makeParam,
|
|
230
|
-
quoteAmount: makeAmount,
|
|
231
|
-
},
|
|
232
|
-
]),
|
|
233
|
-
]
|
|
234
|
-
: []),
|
|
223
|
+
],
|
|
224
|
+
tokensToSettle,
|
|
225
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
226
|
+
getDeadlineTimestampInSeconds(),
|
|
235
227
|
],
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
228
|
+
value: isETH ? quoteAmount : 0n,
|
|
229
|
+
}, options?.gasLimit),
|
|
230
|
+
result: {
|
|
231
|
+
make: {
|
|
232
|
+
amount: formatUnits(quoteAmount - parseUnits(spentAmount, inputCurrency.decimals), inputCurrency.decimals),
|
|
233
|
+
currency: inputCurrency,
|
|
234
|
+
direction: 'in',
|
|
235
|
+
},
|
|
236
|
+
spent: {
|
|
237
|
+
amount: spentAmount,
|
|
238
|
+
currency: inputCurrency,
|
|
239
|
+
direction: 'in',
|
|
240
|
+
},
|
|
241
|
+
taken: {
|
|
242
|
+
amount: takenAmount,
|
|
243
|
+
currency: outputCurrency,
|
|
244
|
+
direction: 'out',
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
};
|
|
243
248
|
}
|
|
244
249
|
});
|
|
245
250
|
/**
|
|
246
251
|
* Executes a market order on the specified chain for trading tokens.
|
|
252
|
+
* If only `amountIn` is provided, spend the specified amount of input tokens.
|
|
253
|
+
* If only `amountOut` is provided, take the specified amount of output tokens.
|
|
247
254
|
*
|
|
248
255
|
* @param {CHAIN_IDS} chainId The chain ID.
|
|
249
256
|
* @param {`0x${string}`} userAddress The Ethereum address of the user placing the order.
|
|
250
257
|
* @param {`0x${string}`} inputToken The address of the token to be used as input.
|
|
251
258
|
* @param {`0x${string}`} outputToken The address of the token to be received as output.
|
|
252
|
-
* @param {string}
|
|
253
|
-
* @param {
|
|
254
|
-
* @param {
|
|
259
|
+
* @param {string} amountIn The amount of input tokens for the order to spend.
|
|
260
|
+
* @param {string} amountOut The amount of output tokens for the order to take.
|
|
261
|
+
* @param {Object} [options] Optional parameters for the market order.
|
|
262
|
+
* @param {erc20PermitParam} [options.erc20PermitParam] The permit signature for token approval.
|
|
255
263
|
* @param {string} [options.rpcUrl] The RPC URL of the blockchain.
|
|
256
|
-
* @param {
|
|
257
|
-
*
|
|
258
|
-
* @
|
|
264
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
265
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
266
|
+
* @param {number} [options.slippage] The maximum slippage percentage allowed for the order.
|
|
267
|
+
* if the slippage is not provided, unlimited slippage is allowed.
|
|
268
|
+
* @returns {Promise<{ transaction: Transaction, result: { spent: CurrencyFlow, taken: CurrencyFlow } }>}
|
|
269
|
+
* Promise resolving to the transaction object representing the market order with the result of the order.
|
|
259
270
|
* @example
|
|
260
271
|
* import { signERC20Permit, marketOrder } from '@clober/v2-sdk'
|
|
261
272
|
* import { privateKeyToAccount } from 'viem/accounts'
|
|
262
273
|
*
|
|
263
|
-
* const
|
|
264
|
-
* 421614,
|
|
265
|
-
*
|
|
266
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
267
|
-
* '100.123'
|
|
268
|
-
* )
|
|
269
|
-
*
|
|
270
|
-
* const transaction = await marketOrder(
|
|
271
|
-
* 421614,
|
|
272
|
-
* '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
273
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
274
|
-
* '0x0000000000000000000000000000000000000000',
|
|
275
|
-
* '100.123', // 100.123 USDC
|
|
276
|
-
* { signature }
|
|
277
|
-
* )
|
|
274
|
+
* const erc20PermitParam = await signERC20Permit({
|
|
275
|
+
* chainId: 421614,
|
|
276
|
+
* walletClient,
|
|
277
|
+
* token: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
278
|
+
* amount: '100.123'
|
|
279
|
+
* })
|
|
278
280
|
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
+
* const transaction = await marketOrder({
|
|
282
|
+
* chainId: 421614,
|
|
283
|
+
* userAddress: '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
284
|
+
* inputToken: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
285
|
+
* outputToken: '0x0000000000000000000000000000000000000000',
|
|
286
|
+
* amount: '100.123', // 100.123 USDC
|
|
287
|
+
* options: { erc20PermitParam }
|
|
288
|
+
* })
|
|
281
289
|
*
|
|
282
|
-
* const transaction = await limitOrder(
|
|
283
|
-
* 421614,
|
|
284
|
-
* '0xF8c1869Ecd4df136693C45EcE1b67f85B6bDaE69
|
|
285
|
-
* '0x0000000000000000000000000000000000000000',
|
|
286
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
287
|
-
* '0.13', // 0.13 ETH
|
|
288
|
-
* )
|
|
289
290
|
*/
|
|
290
|
-
export const marketOrder = decorator(async ({ chainId, userAddress, inputToken, outputToken,
|
|
291
|
+
export const marketOrder = decorator(async ({ chainId, userAddress, inputToken, outputToken, amountIn, amountOut, options, }) => {
|
|
292
|
+
if (!amountIn && !amountOut) {
|
|
293
|
+
throw new Error('Either amountIn or amountOut must be provided');
|
|
294
|
+
}
|
|
295
|
+
else if (amountIn && amountOut) {
|
|
296
|
+
throw new Error('Only one of amountIn or amountOut can be provided');
|
|
297
|
+
}
|
|
291
298
|
const market = await fetchMarket(chainId, [inputToken, outputToken]);
|
|
292
|
-
const
|
|
293
|
-
|
|
299
|
+
const isTakingBid = isAddressEqual(market.base.address, inputToken);
|
|
300
|
+
const [inputCurrency, outputCurrency] = isTakingBid
|
|
301
|
+
? [market.base, market.quote]
|
|
302
|
+
: [market.quote, market.base];
|
|
303
|
+
if ((isTakingBid && !market.bidBook.isOpened) ||
|
|
304
|
+
(!isTakingBid && !market.askBook.isOpened)) {
|
|
294
305
|
throw new Error(`
|
|
306
|
+
Open the market before placing a market order.
|
|
295
307
|
import { openMarket } from '@clober/v2-sdk'
|
|
296
308
|
|
|
297
309
|
const transaction = await openMarket(
|
|
@@ -301,47 +313,118 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
|
|
|
301
313
|
)
|
|
302
314
|
`);
|
|
303
315
|
}
|
|
304
|
-
const rawLimitPrice = parsePrice(Number(options?.limitPrice ?? '0'), market.quote.decimals, market.base.decimals);
|
|
305
316
|
const tokensToSettle = [inputToken, outputToken].filter((address) => !isAddressEqual(address, zeroAddress));
|
|
306
|
-
const quoteAmount = parseUnits(amount, isBid ? market.quote.decimals : market.base.decimals);
|
|
307
|
-
const { result } = await getExpectedOutput({
|
|
308
|
-
chainId,
|
|
309
|
-
inputToken,
|
|
310
|
-
outputToken,
|
|
311
|
-
amountIn: amount,
|
|
312
|
-
options: {
|
|
313
|
-
...options,
|
|
314
|
-
},
|
|
315
|
-
});
|
|
316
317
|
const isETH = isAddressEqual(inputToken, zeroAddress);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
318
|
+
if (amountIn && !amountOut) {
|
|
319
|
+
const { bookId, takenAmount, spentAmount } = await getExpectedOutput({
|
|
320
|
+
chainId,
|
|
321
|
+
inputToken,
|
|
322
|
+
outputToken,
|
|
323
|
+
amountIn,
|
|
324
|
+
options: {
|
|
325
|
+
...options,
|
|
326
|
+
// don't need to check limit price for market order
|
|
323
327
|
},
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
328
|
+
});
|
|
329
|
+
const baseAmount = parseUnits(amountIn, inputCurrency.decimals);
|
|
330
|
+
return {
|
|
331
|
+
transaction: await buildTransaction(chainId, {
|
|
332
|
+
chain: CHAIN_MAP[chainId],
|
|
333
|
+
account: userAddress,
|
|
334
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
335
|
+
abi: CONTROLLER_ABI,
|
|
336
|
+
functionName: 'spend',
|
|
337
|
+
args: [
|
|
338
|
+
[
|
|
339
|
+
{
|
|
340
|
+
id: bookId,
|
|
341
|
+
limitPrice: 0n,
|
|
342
|
+
baseAmount,
|
|
343
|
+
minQuoteAmount: options?.slippage
|
|
344
|
+
? applyPercent(parseUnits(takenAmount, outputCurrency.decimals), 100 - options.slippage)
|
|
345
|
+
: 0n,
|
|
346
|
+
hookData: zeroHash,
|
|
347
|
+
},
|
|
348
|
+
],
|
|
349
|
+
tokensToSettle,
|
|
350
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
351
|
+
getDeadlineTimestampInSeconds(),
|
|
352
|
+
],
|
|
353
|
+
value: isETH ? baseAmount : 0n,
|
|
354
|
+
}, options?.gasLimit),
|
|
355
|
+
result: {
|
|
356
|
+
spent: {
|
|
357
|
+
amount: spentAmount,
|
|
358
|
+
currency: inputCurrency,
|
|
359
|
+
direction: 'in',
|
|
360
|
+
},
|
|
361
|
+
taken: {
|
|
362
|
+
amount: takenAmount,
|
|
363
|
+
currency: outputCurrency,
|
|
364
|
+
direction: 'out',
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
else if (!amountIn && amountOut) {
|
|
370
|
+
const { bookId, spentAmount, takenAmount } = await getExpectedInput({
|
|
371
|
+
chainId,
|
|
372
|
+
inputToken,
|
|
373
|
+
outputToken,
|
|
374
|
+
amountOut,
|
|
375
|
+
options: {
|
|
376
|
+
...options,
|
|
377
|
+
// don't need to check limit price for market order
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
const quoteAmount = parseUnits(amountOut, outputCurrency.decimals);
|
|
381
|
+
const baseAmount = parseUnits(spentAmount, inputCurrency.decimals);
|
|
382
|
+
const maxBaseAmount = options?.erc20PermitParam?.permitAmount ??
|
|
383
|
+
(options?.slippage
|
|
384
|
+
? applyPercent(baseAmount, 100 + options.slippage)
|
|
385
|
+
: isETH
|
|
386
|
+
? baseAmount
|
|
387
|
+
: 2n ** 256n - 1n);
|
|
388
|
+
return {
|
|
389
|
+
transaction: await buildTransaction(chainId, {
|
|
390
|
+
chain: CHAIN_MAP[chainId],
|
|
391
|
+
account: userAddress,
|
|
392
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
393
|
+
abi: CONTROLLER_ABI,
|
|
394
|
+
functionName: 'take',
|
|
395
|
+
args: [
|
|
396
|
+
[
|
|
397
|
+
{
|
|
398
|
+
id: bookId,
|
|
399
|
+
limitPrice: 0n,
|
|
400
|
+
quoteAmount,
|
|
401
|
+
maxBaseAmount,
|
|
402
|
+
hookData: zeroHash,
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
tokensToSettle,
|
|
406
|
+
options?.erc20PermitParam ? [options.erc20PermitParam] : [],
|
|
407
|
+
getDeadlineTimestampInSeconds(),
|
|
408
|
+
],
|
|
409
|
+
value: isETH ? maxBaseAmount : 0n,
|
|
410
|
+
}, options?.gasLimit),
|
|
411
|
+
result: {
|
|
412
|
+
spent: {
|
|
413
|
+
amount: spentAmount,
|
|
414
|
+
currency: inputCurrency,
|
|
415
|
+
direction: 'in',
|
|
416
|
+
},
|
|
417
|
+
taken: {
|
|
418
|
+
amount: takenAmount,
|
|
419
|
+
currency: outputCurrency,
|
|
420
|
+
direction: 'out',
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
throw new Error('Either amountIn or amountOut must be provided');
|
|
427
|
+
}
|
|
345
428
|
});
|
|
346
429
|
/**
|
|
347
430
|
* Claims specified open order for settlement.
|
|
@@ -352,28 +435,35 @@ export const marketOrder = decorator(async ({ chainId, userAddress, inputToken,
|
|
|
352
435
|
* @param {string} id An ID representing the open order to be claimed.
|
|
353
436
|
* @param {Object} [options] Optional parameters for claiming orders.
|
|
354
437
|
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
355
|
-
* @
|
|
438
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
439
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
440
|
+
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
|
|
441
|
+
* Promise resolving to the transaction object representing the claim action with the result of the order.
|
|
356
442
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
357
443
|
* @example
|
|
358
444
|
* import { getOpenOrders, claimOrders } from '@clober/v2-sdk'
|
|
359
445
|
*
|
|
360
|
-
* const openOrders = await getOpenOrders(
|
|
361
|
-
* 421614,
|
|
362
|
-
*
|
|
363
|
-
* )
|
|
364
|
-
* const transaction = await claimOrders(
|
|
365
|
-
* 421614,
|
|
366
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
367
|
-
* openOrders.map((order) => order.id)
|
|
368
|
-
* )
|
|
446
|
+
* const openOrders = await getOpenOrders({
|
|
447
|
+
* chainId: 421614,
|
|
448
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0'
|
|
449
|
+
* })
|
|
450
|
+
* const transaction = await claimOrders({
|
|
451
|
+
* chainId: 421614,
|
|
452
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
453
|
+
* id: openOrders.map((order) => order.id)
|
|
454
|
+
* })
|
|
369
455
|
*/
|
|
370
456
|
export const claimOrder = decorator(async ({ chainId, userAddress, id, options, }) => {
|
|
371
|
-
|
|
457
|
+
const { transaction, result } = await claimOrders({
|
|
372
458
|
chainId,
|
|
373
459
|
userAddress,
|
|
374
460
|
ids: [id],
|
|
375
461
|
options: { ...options },
|
|
376
462
|
});
|
|
463
|
+
return {
|
|
464
|
+
transaction,
|
|
465
|
+
result: result[0],
|
|
466
|
+
};
|
|
377
467
|
});
|
|
378
468
|
/**
|
|
379
469
|
* Claims specified open orders for settlement.
|
|
@@ -384,61 +474,73 @@ export const claimOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
384
474
|
* @param {string[]} ids An array of IDs representing the open orders to be claimed.
|
|
385
475
|
* @param {Object} [options] Optional parameters for claiming orders.
|
|
386
476
|
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
387
|
-
* @
|
|
477
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
478
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
479
|
+
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>}
|
|
480
|
+
* Promise resolving to the transaction object representing the claim action with the result of the orders.
|
|
388
481
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
389
482
|
* @example
|
|
390
483
|
* import { getOpenOrders, claimOrders } from '@clober/v2-sdk'
|
|
391
484
|
*
|
|
392
|
-
* const openOrders = await getOpenOrders(
|
|
393
|
-
* 421614,
|
|
394
|
-
*
|
|
395
|
-
* )
|
|
485
|
+
* const openOrders = await getOpenOrders({
|
|
486
|
+
* chainId: 421614,
|
|
487
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0'
|
|
488
|
+
* })
|
|
396
489
|
* const transaction = await claimOrders(
|
|
397
|
-
* 421614,
|
|
398
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
399
|
-
* openOrders.map((order) => order.id)
|
|
490
|
+
* chainId: 421614,
|
|
491
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
492
|
+
* ids: openOrders.map((order) => order.id)
|
|
400
493
|
* )
|
|
401
494
|
*/
|
|
402
495
|
export const claimOrders = decorator(async ({ chainId, userAddress, ids, options, }) => {
|
|
403
496
|
const isApprovedForAll = await fetchIsApprovedForAll(chainId, userAddress);
|
|
404
497
|
if (!isApprovedForAll) {
|
|
405
498
|
throw new Error(`
|
|
499
|
+
Set ApprovalForAll before calling this function.
|
|
406
500
|
import { setApprovalOfOpenOrdersForAll } from '@clober/v2-sdk'
|
|
407
501
|
|
|
408
|
-
const hash = await setApprovalOfOpenOrdersForAll(
|
|
409
|
-
${chainId},
|
|
410
|
-
|
|
411
|
-
)
|
|
502
|
+
const hash = await setApprovalOfOpenOrdersForAll({
|
|
503
|
+
chainId: ${chainId},
|
|
504
|
+
walletClient, // use viem
|
|
505
|
+
})
|
|
412
506
|
`);
|
|
413
507
|
}
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
const tokensToSettle = openOrders
|
|
508
|
+
const orders = (await fetchOrders(chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.user, userAddress) &&
|
|
509
|
+
order.claimable.value !== '0');
|
|
510
|
+
const tokensToSettle = orders
|
|
419
511
|
.map((order) => [
|
|
420
|
-
order.outputCurrency.address,
|
|
421
512
|
order.inputCurrency.address,
|
|
513
|
+
order.outputCurrency.address,
|
|
422
514
|
])
|
|
423
515
|
.flat()
|
|
424
516
|
.filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
|
|
425
517
|
.filter((address) => !isAddressEqual(address, zeroAddress));
|
|
426
|
-
return
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
id
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
518
|
+
return {
|
|
519
|
+
transaction: await buildTransaction(chainId, {
|
|
520
|
+
chain: CHAIN_MAP[chainId],
|
|
521
|
+
account: userAddress,
|
|
522
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
523
|
+
abi: CONTROLLER_ABI,
|
|
524
|
+
functionName: 'claim',
|
|
525
|
+
args: [
|
|
526
|
+
orders.map(({ id }) => ({
|
|
527
|
+
id,
|
|
528
|
+
hookData: zeroHash,
|
|
529
|
+
})),
|
|
530
|
+
tokensToSettle,
|
|
531
|
+
[],
|
|
532
|
+
getDeadlineTimestampInSeconds(),
|
|
533
|
+
],
|
|
534
|
+
}, options?.gasLimit),
|
|
535
|
+
result: orders.reduce((acc, { claimable: { currency, value } }) => {
|
|
536
|
+
const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
|
|
537
|
+
if (index === -1) {
|
|
538
|
+
return [...acc, { currency, amount: value, direction: 'out' }];
|
|
539
|
+
}
|
|
540
|
+
acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
|
|
541
|
+
return acc;
|
|
542
|
+
}, []),
|
|
543
|
+
};
|
|
442
544
|
});
|
|
443
545
|
/**
|
|
444
546
|
* Cancels specified open order if the order is not fully filled.
|
|
@@ -449,28 +551,35 @@ export const claimOrders = decorator(async ({ chainId, userAddress, ids, options
|
|
|
449
551
|
* @param {string} id An ID representing the open order to be canceled
|
|
450
552
|
* @param {Object} [options] Optional parameters for canceling orders.
|
|
451
553
|
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
452
|
-
* @
|
|
554
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
555
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
556
|
+
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow }>}
|
|
557
|
+
* Promise resolving to the transaction object representing the cancel action with the result of the order.
|
|
453
558
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
454
559
|
* @example
|
|
455
560
|
* import { getOpenOrders, cancelOrders } from '@clober/v2-sdk'
|
|
456
561
|
*
|
|
457
|
-
* const openOrders = await getOpenOrders(
|
|
458
|
-
* 421614,
|
|
459
|
-
*
|
|
460
|
-
* )
|
|
461
|
-
* const transaction = await cancelOrders(
|
|
462
|
-
* 421614,
|
|
463
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
464
|
-
* openOrders.map((order) => order.id)
|
|
465
|
-
* )
|
|
562
|
+
* const openOrders = await getOpenOrders({
|
|
563
|
+
* chainId: 421614,
|
|
564
|
+
* userAddress:'0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0'
|
|
565
|
+
* })
|
|
566
|
+
* const transaction = await cancelOrders({
|
|
567
|
+
* chainId: 421614,
|
|
568
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
569
|
+
* id: openOrders.map((order) => order.id)
|
|
570
|
+
* })
|
|
466
571
|
*/
|
|
467
572
|
export const cancelOrder = decorator(async ({ chainId, userAddress, id, options, }) => {
|
|
468
|
-
|
|
573
|
+
const { transaction, result } = await cancelOrders({
|
|
469
574
|
chainId,
|
|
470
575
|
userAddress,
|
|
471
576
|
ids: [id],
|
|
472
577
|
options: { ...options },
|
|
473
578
|
});
|
|
579
|
+
return {
|
|
580
|
+
transaction,
|
|
581
|
+
result: result[0],
|
|
582
|
+
};
|
|
474
583
|
});
|
|
475
584
|
/**
|
|
476
585
|
* Cancels specified open orders if orders are not fully filled.
|
|
@@ -481,61 +590,73 @@ export const cancelOrder = decorator(async ({ chainId, userAddress, id, options,
|
|
|
481
590
|
* @param {string[]} ids An array of IDs representing the open orders to be canceled.
|
|
482
591
|
* @param {Object} [options] Optional parameters for canceling orders.
|
|
483
592
|
* @param {string} [options.rpcUrl] The RPC URL to use for executing the transaction.
|
|
484
|
-
* @
|
|
593
|
+
* @param {number} [options.gasLimit] The gas limit to use for the transaction.
|
|
594
|
+
* @param {boolean} [options.useSubgraph] A boolean indicating whether to use the subgraph for fetching orders.
|
|
595
|
+
* @returns {Promise<{ transaction: Transaction, result: CurrencyFlow[] }>
|
|
596
|
+
* Promise resolving to the transaction object representing the cancel action with the result of the orders.
|
|
485
597
|
* @throws {Error} Throws an error if no open orders are found for the specified user.
|
|
486
598
|
* @example
|
|
487
599
|
* import { getOpenOrders, cancelOrders } from '@clober/v2-sdk'
|
|
488
600
|
*
|
|
489
|
-
* const openOrders = await getOpenOrders(
|
|
490
|
-
* 421614,
|
|
491
|
-
*
|
|
492
|
-
* )
|
|
493
|
-
* const transaction = await cancelOrders(
|
|
494
|
-
* 421614,
|
|
495
|
-
* '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
496
|
-
* openOrders.map((order) => order.id)
|
|
497
|
-
* )
|
|
601
|
+
* const openOrders = await getOpenOrders({
|
|
602
|
+
* chainId: 421614,
|
|
603
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0'
|
|
604
|
+
* })
|
|
605
|
+
* const transaction = await cancelOrders({
|
|
606
|
+
* chainId: 421614,
|
|
607
|
+
* userAddress: '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
|
|
608
|
+
* ids: openOrders.map((order) => order.id)
|
|
609
|
+
* })
|
|
498
610
|
*/
|
|
499
611
|
export const cancelOrders = decorator(async ({ chainId, userAddress, ids, options, }) => {
|
|
500
612
|
const isApprovedForAll = await fetchIsApprovedForAll(chainId, userAddress);
|
|
501
613
|
if (!isApprovedForAll) {
|
|
502
614
|
throw new Error(`
|
|
615
|
+
Set ApprovalForAll before calling this function.
|
|
503
616
|
import { setApprovalOfOpenOrdersForAll } from '@clober/v2-sdk'
|
|
504
617
|
|
|
505
|
-
const hash = await setApprovalOfOpenOrdersForAll(
|
|
506
|
-
${chainId},
|
|
507
|
-
|
|
508
|
-
)
|
|
618
|
+
const hash = await setApprovalOfOpenOrdersForAll({
|
|
619
|
+
chainId: ${chainId},
|
|
620
|
+
walletClient, // use viem
|
|
621
|
+
})
|
|
509
622
|
`);
|
|
510
623
|
}
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
}
|
|
515
|
-
const tokensToSettle = openOrders
|
|
624
|
+
const orders = (await fetchOrders(chainId, ids.map((id) => BigInt(id)))).filter((order) => isAddressEqual(order.user, userAddress) &&
|
|
625
|
+
order.cancelable.value !== '0');
|
|
626
|
+
const tokensToSettle = orders
|
|
516
627
|
.map((order) => [
|
|
517
|
-
order.outputCurrency.address,
|
|
518
628
|
order.inputCurrency.address,
|
|
629
|
+
order.outputCurrency.address,
|
|
519
630
|
])
|
|
520
631
|
.flat()
|
|
521
632
|
.filter((address, index, self) => self.findIndex((c) => isAddressEqual(c, address)) === index)
|
|
522
633
|
.filter((address) => !isAddressEqual(address, zeroAddress));
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
id
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
634
|
+
return {
|
|
635
|
+
transaction: await buildTransaction(chainId, {
|
|
636
|
+
chain: CHAIN_MAP[chainId],
|
|
637
|
+
account: userAddress,
|
|
638
|
+
address: CONTRACT_ADDRESSES[chainId].Controller,
|
|
639
|
+
abi: CONTROLLER_ABI,
|
|
640
|
+
functionName: 'cancel',
|
|
641
|
+
args: [
|
|
642
|
+
orders.map(({ id }) => ({
|
|
643
|
+
id,
|
|
644
|
+
leftQuoteAmount: 0n,
|
|
645
|
+
hookData: zeroHash,
|
|
646
|
+
})),
|
|
647
|
+
tokensToSettle,
|
|
648
|
+
[],
|
|
649
|
+
getDeadlineTimestampInSeconds(),
|
|
650
|
+
],
|
|
651
|
+
}, options?.gasLimit),
|
|
652
|
+
result: orders.reduce((acc, { cancelable: { currency, value } }) => {
|
|
653
|
+
const index = acc.findIndex((c) => isAddressEqual(c.currency.address, currency.address));
|
|
654
|
+
if (index === -1) {
|
|
655
|
+
return [...acc, { currency, amount: value, direction: 'out' }];
|
|
656
|
+
}
|
|
657
|
+
acc[index].amount = (Number(acc[index].amount) + Number(value)).toString();
|
|
658
|
+
return acc;
|
|
659
|
+
}, []),
|
|
660
|
+
};
|
|
540
661
|
});
|
|
541
662
|
//# sourceMappingURL=call.js.map
|