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