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