@clober/v2-sdk 0.0.1-a → 0.0.1-b

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.
Files changed (297) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc.yaml +34 -0
  3. package/.github/workflows/ci.yaml +88 -0
  4. package/.github/workflows/deployer.yaml +19 -0
  5. package/.nvmrc +1 -0
  6. package/.prettierignore +6 -0
  7. package/.prettierrc +7 -0
  8. package/package.json +8 -4
  9. package/src/.graphclient/index.ts +1695 -0
  10. package/src/.graphclient/schema.graphql +1116 -0
  11. package/src/.graphclient/sources/clober-v2/introspectionSchema.ts +14481 -0
  12. package/src/.graphclient/sources/clober-v2/schema.graphql +1116 -0
  13. package/src/.graphclient/sources/clober-v2/types.ts +1133 -0
  14. package/src/.graphclientrc.yml +12 -0
  15. package/src/abis/core/controller-abi.ts +985 -0
  16. package/src/abis/core/params-abi.ts +59 -0
  17. package/src/apis/currency.ts +92 -0
  18. package/src/apis/graphql/books.graphql +25 -0
  19. package/src/apis/graphql/open-order.graphql +29 -0
  20. package/src/apis/graphql/open-orders.graphql +29 -0
  21. package/src/apis/market.ts +85 -0
  22. package/src/apis/open-order.ts +145 -0
  23. package/src/approval.ts +82 -0
  24. package/src/call.ts +705 -0
  25. package/src/constants/action.ts +9 -0
  26. package/src/constants/addresses.ts +17 -0
  27. package/src/constants/chain.ts +12 -0
  28. package/src/constants/currency.ts +15 -0
  29. package/src/constants/fee.ts +4 -0
  30. package/src/constants/price.ts +3 -0
  31. package/src/constants/subgraph-url.ts +8 -0
  32. package/src/index.ts +5 -0
  33. package/src/model/book.ts +166 -0
  34. package/src/model/currency.ts +6 -0
  35. package/src/model/depth.ts +11 -0
  36. package/src/model/fee-policy.ts +51 -0
  37. package/src/model/market.ts +320 -0
  38. package/src/model/open-order.ts +16 -0
  39. package/src/signature.ts +196 -0
  40. package/src/type.ts +38 -0
  41. package/src/utils/approval.ts +48 -0
  42. package/{dist/esm/utils/book-id.js → src/utils/book-id.ts} +19 -9
  43. package/src/utils/build-transaction.ts +39 -0
  44. package/src/utils/decimals.ts +22 -0
  45. package/src/utils/market.ts +74 -0
  46. package/src/utils/math.ts +117 -0
  47. package/src/utils/prices.ts +29 -0
  48. package/src/utils/tick.ts +104 -0
  49. package/src/utils/time.ts +6 -0
  50. package/src/utils/unit.ts +43 -0
  51. package/src/view.ts +258 -0
  52. package/test/book-id.test.ts +101 -0
  53. package/test/fee-policy.test.ts +228 -0
  54. package/test/get-expected-input.test.ts +206 -0
  55. package/test/get-expected-output.test.ts +206 -0
  56. package/test/limit-order.test.ts +279 -0
  57. package/test/market-order.test.ts +245 -0
  58. package/test/market.test.ts +68 -0
  59. package/test/math.test.ts +91 -0
  60. package/test/open-order.test.ts +112 -0
  61. package/test/open.test.ts +15 -0
  62. package/test/tick.test.ts +230 -0
  63. package/test/tsconfig.json +12 -0
  64. package/test/utils/chain.ts +12 -0
  65. package/test/utils/constants.ts +25 -0
  66. package/test/utils/currency.ts +44 -0
  67. package/test/utils/depth.ts +148 -0
  68. package/test/utils/test-chain.ts +26 -0
  69. package/test/vitest.config.ts +15 -0
  70. package/tsconfig.base.json +37 -0
  71. package/tsconfig.build.json +9 -0
  72. package/tsconfig.json +9 -0
  73. package/dist/cjs/.graphclient/index.js +0 -243
  74. package/dist/cjs/.graphclient/index.js.map +0 -1
  75. package/dist/cjs/.graphclient/sources/clober-v2/introspectionSchema.js +0 -14482
  76. package/dist/cjs/.graphclient/sources/clober-v2/introspectionSchema.js.map +0 -1
  77. package/dist/cjs/.graphclient/sources/clober-v2/types.js +0 -4
  78. package/dist/cjs/.graphclient/sources/clober-v2/types.js.map +0 -1
  79. package/dist/cjs/abis/core/controller-abi.js +0 -989
  80. package/dist/cjs/abis/core/controller-abi.js.map +0 -1
  81. package/dist/cjs/abis/core/params-abi.js +0 -62
  82. package/dist/cjs/abis/core/params-abi.js.map +0 -1
  83. package/dist/cjs/apis/currency.js +0 -87
  84. package/dist/cjs/apis/currency.js.map +0 -1
  85. package/dist/cjs/apis/market.js +0 -63
  86. package/dist/cjs/apis/market.js.map +0 -1
  87. package/dist/cjs/apis/open-order.js +0 -90
  88. package/dist/cjs/apis/open-order.js.map +0 -1
  89. package/dist/cjs/approval.js +0 -74
  90. package/dist/cjs/approval.js.map +0 -1
  91. package/dist/cjs/call.js +0 -545
  92. package/dist/cjs/call.js.map +0 -1
  93. package/dist/cjs/constants/action.js +0 -14
  94. package/dist/cjs/constants/action.js.map +0 -1
  95. package/dist/cjs/constants/addresses.js +0 -13
  96. package/dist/cjs/constants/addresses.js.map +0 -1
  97. package/dist/cjs/constants/chain.js +0 -13
  98. package/dist/cjs/constants/chain.js.map +0 -1
  99. package/dist/cjs/constants/currency.js +0 -12
  100. package/dist/cjs/constants/currency.js.map +0 -1
  101. package/dist/cjs/constants/fee.js +0 -7
  102. package/dist/cjs/constants/fee.js.map +0 -1
  103. package/dist/cjs/constants/price.js +0 -6
  104. package/dist/cjs/constants/price.js.map +0 -1
  105. package/dist/cjs/constants/subgraph-url.js +0 -8
  106. package/dist/cjs/constants/subgraph-url.js.map +0 -1
  107. package/dist/cjs/index.js +0 -22
  108. package/dist/cjs/index.js.map +0 -1
  109. package/dist/cjs/model/book.js +0 -130
  110. package/dist/cjs/model/book.js.map +0 -1
  111. package/dist/cjs/model/currency.js +0 -3
  112. package/dist/cjs/model/currency.js.map +0 -1
  113. package/dist/cjs/model/depth.js +0 -3
  114. package/dist/cjs/model/depth.js.map +0 -1
  115. package/dist/cjs/model/fee-policy.js +0 -42
  116. package/dist/cjs/model/fee-policy.js.map +0 -1
  117. package/dist/cjs/model/market.js +0 -215
  118. package/dist/cjs/model/market.js.map +0 -1
  119. package/dist/cjs/model/open-order.js +0 -3
  120. package/dist/cjs/model/open-order.js.map +0 -1
  121. package/dist/cjs/package.json +0 -1
  122. package/dist/cjs/signature.js +0 -178
  123. package/dist/cjs/signature.js.map +0 -1
  124. package/dist/cjs/tsconfig.build.tsbuildinfo +0 -1
  125. package/dist/cjs/type.js +0 -6
  126. package/dist/cjs/type.js.map +0 -1
  127. package/dist/cjs/utils/approval.js +0 -46
  128. package/dist/cjs/utils/approval.js.map +0 -1
  129. package/dist/cjs/utils/book-id.js +0 -25
  130. package/dist/cjs/utils/book-id.js.map +0 -1
  131. package/dist/cjs/utils/build-transaction.js +0 -31
  132. package/dist/cjs/utils/build-transaction.js.map +0 -1
  133. package/dist/cjs/utils/decimals.js +0 -17
  134. package/dist/cjs/utils/decimals.js.map +0 -1
  135. package/dist/cjs/utils/market.js +0 -53
  136. package/dist/cjs/utils/market.js.map +0 -1
  137. package/dist/cjs/utils/math.js +0 -83
  138. package/dist/cjs/utils/math.js.map +0 -1
  139. package/dist/cjs/utils/prices.js +0 -22
  140. package/dist/cjs/utils/prices.js.map +0 -1
  141. package/dist/cjs/utils/tick.js +0 -106
  142. package/dist/cjs/utils/tick.js.map +0 -1
  143. package/dist/cjs/utils/time.js +0 -9
  144. package/dist/cjs/utils/time.js.map +0 -1
  145. package/dist/cjs/utils/unit.js +0 -38
  146. package/dist/cjs/utils/unit.js.map +0 -1
  147. package/dist/cjs/view.js +0 -185
  148. package/dist/cjs/view.js.map +0 -1
  149. package/dist/esm/.graphclient/index.js +0 -233
  150. package/dist/esm/.graphclient/index.js.map +0 -1
  151. package/dist/esm/.graphclient/sources/clober-v2/introspectionSchema.js +0 -14480
  152. package/dist/esm/.graphclient/sources/clober-v2/introspectionSchema.js.map +0 -1
  153. package/dist/esm/.graphclient/sources/clober-v2/types.js +0 -3
  154. package/dist/esm/.graphclient/sources/clober-v2/types.js.map +0 -1
  155. package/dist/esm/abis/core/controller-abi.js +0 -986
  156. package/dist/esm/abis/core/controller-abi.js.map +0 -1
  157. package/dist/esm/abis/core/params-abi.js +0 -59
  158. package/dist/esm/abis/core/params-abi.js.map +0 -1
  159. package/dist/esm/apis/currency.js +0 -83
  160. package/dist/esm/apis/currency.js.map +0 -1
  161. package/dist/esm/apis/market.js +0 -59
  162. package/dist/esm/apis/market.js.map +0 -1
  163. package/dist/esm/apis/open-order.js +0 -85
  164. package/dist/esm/apis/open-order.js.map +0 -1
  165. package/dist/esm/approval.js +0 -70
  166. package/dist/esm/approval.js.map +0 -1
  167. package/dist/esm/call.js +0 -535
  168. package/dist/esm/call.js.map +0 -1
  169. package/dist/esm/constants/action.js +0 -11
  170. package/dist/esm/constants/action.js.map +0 -1
  171. package/dist/esm/constants/addresses.js +0 -10
  172. package/dist/esm/constants/addresses.js.map +0 -1
  173. package/dist/esm/constants/chain.js +0 -10
  174. package/dist/esm/constants/chain.js.map +0 -1
  175. package/dist/esm/constants/currency.js +0 -9
  176. package/dist/esm/constants/currency.js.map +0 -1
  177. package/dist/esm/constants/fee.js +0 -4
  178. package/dist/esm/constants/fee.js.map +0 -1
  179. package/dist/esm/constants/price.js +0 -3
  180. package/dist/esm/constants/price.js.map +0 -1
  181. package/dist/esm/constants/subgraph-url.js +0 -5
  182. package/dist/esm/constants/subgraph-url.js.map +0 -1
  183. package/dist/esm/index.js +0 -6
  184. package/dist/esm/index.js.map +0 -1
  185. package/dist/esm/model/book.js +0 -126
  186. package/dist/esm/model/book.js.map +0 -1
  187. package/dist/esm/model/currency.js +0 -2
  188. package/dist/esm/model/currency.js.map +0 -1
  189. package/dist/esm/model/depth.js +0 -2
  190. package/dist/esm/model/depth.js.map +0 -1
  191. package/dist/esm/model/fee-policy.js +0 -38
  192. package/dist/esm/model/fee-policy.js.map +0 -1
  193. package/dist/esm/model/market.js +0 -211
  194. package/dist/esm/model/market.js.map +0 -1
  195. package/dist/esm/model/open-order.js +0 -2
  196. package/dist/esm/model/open-order.js.map +0 -1
  197. package/dist/esm/package.json +0 -1
  198. package/dist/esm/signature.js +0 -174
  199. package/dist/esm/signature.js.map +0 -1
  200. package/dist/esm/tsconfig.build.tsbuildinfo +0 -1
  201. package/dist/esm/type.js +0 -2
  202. package/dist/esm/type.js.map +0 -1
  203. package/dist/esm/utils/approval.js +0 -42
  204. package/dist/esm/utils/approval.js.map +0 -1
  205. package/dist/esm/utils/book-id.js.map +0 -1
  206. package/dist/esm/utils/build-transaction.js +0 -27
  207. package/dist/esm/utils/build-transaction.js.map +0 -1
  208. package/dist/esm/utils/decimals.js +0 -12
  209. package/dist/esm/utils/decimals.js.map +0 -1
  210. package/dist/esm/utils/market.js +0 -49
  211. package/dist/esm/utils/market.js.map +0 -1
  212. package/dist/esm/utils/math.js +0 -78
  213. package/dist/esm/utils/math.js.map +0 -1
  214. package/dist/esm/utils/prices.js +0 -17
  215. package/dist/esm/utils/prices.js.map +0 -1
  216. package/dist/esm/utils/tick.js +0 -100
  217. package/dist/esm/utils/tick.js.map +0 -1
  218. package/dist/esm/utils/time.js +0 -5
  219. package/dist/esm/utils/time.js.map +0 -1
  220. package/dist/esm/utils/unit.js +0 -34
  221. package/dist/esm/utils/unit.js.map +0 -1
  222. package/dist/esm/view.js +0 -177
  223. package/dist/esm/view.js.map +0 -1
  224. package/dist/types/.graphclient/index.d.ts +0 -1281
  225. package/dist/types/.graphclient/index.d.ts.map +0 -1
  226. package/dist/types/.graphclient/sources/clober-v2/introspectionSchema.d.ts +0 -3
  227. package/dist/types/.graphclient/sources/clober-v2/introspectionSchema.d.ts.map +0 -1
  228. package/dist/types/.graphclient/sources/clober-v2/types.d.ts +0 -984
  229. package/dist/types/.graphclient/sources/clober-v2/types.d.ts.map +0 -1
  230. package/dist/types/abis/core/controller-abi.d.ts +0 -757
  231. package/dist/types/abis/core/controller-abi.d.ts.map +0 -1
  232. package/dist/types/abis/core/params-abi.d.ts +0 -21
  233. package/dist/types/abis/core/params-abi.d.ts.map +0 -1
  234. package/dist/types/apis/currency.d.ts +0 -4
  235. package/dist/types/apis/currency.d.ts.map +0 -1
  236. package/dist/types/apis/market.d.ts +0 -4
  237. package/dist/types/apis/market.d.ts.map +0 -1
  238. package/dist/types/apis/open-order.d.ts +0 -5
  239. package/dist/types/apis/open-order.d.ts.map +0 -1
  240. package/dist/types/approval.d.ts +0 -32
  241. package/dist/types/approval.d.ts.map +0 -1
  242. package/dist/types/call.d.ts +0 -234
  243. package/dist/types/call.d.ts.map +0 -1
  244. package/dist/types/constants/action.d.ts +0 -10
  245. package/dist/types/constants/action.d.ts.map +0 -1
  246. package/dist/types/constants/addresses.d.ts +0 -9
  247. package/dist/types/constants/addresses.d.ts.map +0 -1
  248. package/dist/types/constants/chain.d.ts +0 -9
  249. package/dist/types/constants/chain.d.ts.map +0 -1
  250. package/dist/types/constants/currency.d.ts +0 -8
  251. package/dist/types/constants/currency.d.ts.map +0 -1
  252. package/dist/types/constants/fee.d.ts +0 -4
  253. package/dist/types/constants/fee.d.ts.map +0 -1
  254. package/dist/types/constants/price.d.ts +0 -3
  255. package/dist/types/constants/price.d.ts.map +0 -1
  256. package/dist/types/constants/subgraph-url.d.ts +0 -5
  257. package/dist/types/constants/subgraph-url.d.ts.map +0 -1
  258. package/dist/types/index.d.ts +0 -6
  259. package/dist/types/index.d.ts.map +0 -1
  260. package/dist/types/model/book.d.ts +0 -31
  261. package/dist/types/model/book.d.ts.map +0 -1
  262. package/dist/types/model/currency.d.ts +0 -7
  263. package/dist/types/model/currency.d.ts.map +0 -1
  264. package/dist/types/model/depth.d.ts +0 -11
  265. package/dist/types/model/depth.d.ts.map +0 -1
  266. package/dist/types/model/fee-policy.d.ts +0 -15
  267. package/dist/types/model/fee-policy.d.ts.map +0 -1
  268. package/dist/types/model/market.d.ts +0 -44
  269. package/dist/types/model/market.d.ts.map +0 -1
  270. package/dist/types/model/open-order.d.ts +0 -28
  271. package/dist/types/model/open-order.d.ts.map +0 -1
  272. package/dist/types/signature.d.ts +0 -40
  273. package/dist/types/signature.d.ts.map +0 -1
  274. package/dist/types/type.d.ts +0 -34
  275. package/dist/types/type.d.ts.map +0 -1
  276. package/dist/types/utils/approval.d.ts +0 -3
  277. package/dist/types/utils/approval.d.ts.map +0 -1
  278. package/dist/types/utils/book-id.d.ts +0 -2
  279. package/dist/types/utils/book-id.d.ts.map +0 -1
  280. package/dist/types/utils/build-transaction.d.ts +0 -5
  281. package/dist/types/utils/build-transaction.d.ts.map +0 -1
  282. package/dist/types/utils/decimals.d.ts +0 -3
  283. package/dist/types/utils/decimals.d.ts.map +0 -1
  284. package/dist/types/utils/market.d.ts +0 -7
  285. package/dist/types/utils/market.d.ts.map +0 -1
  286. package/dist/types/utils/math.d.ts +0 -3
  287. package/dist/types/utils/math.d.ts.map +0 -1
  288. package/dist/types/utils/prices.d.ts +0 -3
  289. package/dist/types/utils/prices.d.ts.map +0 -1
  290. package/dist/types/utils/tick.d.ts +0 -4
  291. package/dist/types/utils/tick.d.ts.map +0 -1
  292. package/dist/types/utils/time.d.ts +0 -2
  293. package/dist/types/utils/time.d.ts.map +0 -1
  294. package/dist/types/utils/unit.d.ts +0 -4
  295. package/dist/types/utils/unit.d.ts.map +0 -1
  296. package/dist/types/view.d.ts +0 -129
  297. package/dist/types/view.d.ts.map +0 -1
@@ -0,0 +1,196 @@
1
+ import {
2
+ createPublicClient,
3
+ HDAccount,
4
+ hexToSignature,
5
+ http,
6
+ parseUnits,
7
+ PrivateKeyAccount,
8
+ verifyTypedData,
9
+ zeroHash,
10
+ } from 'viem'
11
+
12
+ import { CHAIN_IDS, CHAIN_MAP } from './constants/chain'
13
+ import { getDeadlineTimestampInSeconds } from './utils/time'
14
+ import { CONTRACT_ADDRESSES } from './constants/addresses'
15
+ import { fetchCurrency } from './apis/currency'
16
+ import { PermitSignature } from './type'
17
+
18
+ const _abi = [
19
+ {
20
+ inputs: [],
21
+ name: 'version',
22
+ outputs: [
23
+ {
24
+ internalType: 'string',
25
+ name: '',
26
+ type: 'string',
27
+ },
28
+ ],
29
+ stateMutability: 'view',
30
+ type: 'function',
31
+ },
32
+ {
33
+ inputs: [
34
+ {
35
+ internalType: 'address',
36
+ name: 'owner',
37
+ type: 'address',
38
+ },
39
+ ],
40
+ name: 'nonces',
41
+ outputs: [
42
+ {
43
+ internalType: 'uint256',
44
+ name: '',
45
+ type: 'uint256',
46
+ },
47
+ ],
48
+ stateMutability: 'view',
49
+ type: 'function',
50
+ },
51
+ {
52
+ inputs: [],
53
+ name: 'name',
54
+ outputs: [
55
+ {
56
+ internalType: 'string',
57
+ name: '',
58
+ type: 'string',
59
+ },
60
+ ],
61
+ stateMutability: 'view',
62
+ type: 'function',
63
+ },
64
+ ] as const
65
+
66
+ /**
67
+ * Signs an ERC20 permit using EIP-712 encoding.
68
+ *
69
+ * @param {CHAIN_IDS} chainId The chain ID.
70
+ * @param {HDAccount | PrivateKeyAccount} account The Ethereum account used for signing using
71
+ * [viem - Local Accounts (Private Key, Mnemonic, etc)](https://viem.sh/docs/accounts/local#local-accounts-private-key-mnemonic-etc).
72
+ * @param {`0x${string}`} token The ERC20 token address.
73
+ * @param {string} amount The amount of tokens to permit.
74
+ * @param options
75
+ * @param options.rpcUrl The RPC URL of the blockchain.
76
+ * @returns {Promise<PermitSignature>} Promise resolving to the permit signature.
77
+ * @example
78
+ * import { signERC20Permit } from '@clober/v2-sdk'
79
+ * import { privateKeyToAccount } from 'viem/accounts'
80
+ *
81
+ * const { deadline, r, s, v } = await signERC20Permit(
82
+ * 421614,
83
+ * privateKeyToAccount('0x...')
84
+ * '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
85
+ * '1000.123', // spend 1000.123 USDC
86
+ * )
87
+ *
88
+ * @example
89
+ * import { signERC20Permit } from '@clober/v2-sdk'
90
+ * import { mnemonicToAccount } from 'viem/accounts'
91
+ *
92
+ * const { deadline, r, s, v } = await signERC20Permit(
93
+ * 421614,
94
+ * mnemonicToAccount('legal ...')
95
+ * '0x00bfd44e79fb7f6dd5887a9426c8ef85a0cd23e0',
96
+ * '1000.123', // spend 1000.123 USDC
97
+ * )
98
+ */
99
+ export const signERC20Permit = async (
100
+ chainId: CHAIN_IDS,
101
+ account: HDAccount | PrivateKeyAccount,
102
+ token: `0x${string}`,
103
+ amount: string,
104
+ options?: {
105
+ rpcUrl: string
106
+ },
107
+ ): Promise<PermitSignature> => {
108
+ const currency = await fetchCurrency(chainId, token, options?.rpcUrl)
109
+ const spender = CONTRACT_ADDRESSES[chainId]!.Controller
110
+ const publicClient = createPublicClient({
111
+ chain: CHAIN_MAP[chainId],
112
+ transport: options?.rpcUrl ? http(options.rpcUrl) : http(),
113
+ })
114
+ const value = parseUnits(amount, currency.decimals)
115
+ const [{ result: nonce }, { result: version }, { result: name }] =
116
+ await publicClient.multicall({
117
+ allowFailure: true,
118
+ contracts: [
119
+ {
120
+ address: token,
121
+ abi: _abi,
122
+ functionName: 'nonces',
123
+ args: [account.address],
124
+ },
125
+ {
126
+ address: token,
127
+ abi: _abi,
128
+ functionName: 'version',
129
+ },
130
+ {
131
+ address: token,
132
+ abi: _abi,
133
+ functionName: 'name',
134
+ },
135
+ ],
136
+ })
137
+
138
+ if (nonce === undefined || !name) {
139
+ return {
140
+ r: zeroHash,
141
+ s: zeroHash,
142
+ v: 0,
143
+ deadline: 0n,
144
+ }
145
+ }
146
+ const deadline = getDeadlineTimestampInSeconds()
147
+ const data = {
148
+ domain: {
149
+ name: name,
150
+ version: (version || '1').toString(),
151
+ chainId: BigInt(chainId),
152
+ verifyingContract: currency.address,
153
+ },
154
+ message: {
155
+ owner: account.address,
156
+ spender,
157
+ value,
158
+ nonce,
159
+ deadline,
160
+ },
161
+ primaryType: 'Permit',
162
+ types: {
163
+ Permit: [
164
+ { name: 'owner', type: 'address' },
165
+ { name: 'spender', type: 'address' },
166
+ { name: 'value', type: 'uint256' },
167
+ { name: 'nonce', type: 'uint256' },
168
+ { name: 'deadline', type: 'uint256' },
169
+ ],
170
+ EIP712Domain: [
171
+ { name: 'name', type: 'string' },
172
+ { name: 'version', type: 'string' },
173
+ { name: 'chainId', type: 'uint256' },
174
+ { name: 'verifyingContract', type: 'address' },
175
+ ],
176
+ },
177
+ } as const
178
+ const signature = await account.signTypedData({
179
+ ...data,
180
+ })
181
+ const valid = await verifyTypedData({
182
+ ...data,
183
+ signature,
184
+ address: account.address,
185
+ })
186
+ if (!valid) {
187
+ throw new Error('Invalid signature')
188
+ }
189
+ const { v, s, r } = hexToSignature(signature)
190
+ return {
191
+ v: Number(v),
192
+ s,
193
+ r,
194
+ deadline,
195
+ }
196
+ }
package/src/type.ts ADDED
@@ -0,0 +1,38 @@
1
+ import { Account } from 'viem'
2
+
3
+ import { CHAIN_IDS } from './constants/chain'
4
+ import { Currency } from './model/currency'
5
+ import { Depth } from './model/depth'
6
+
7
+ export { CHAIN_IDS } from './constants/chain'
8
+ export { Currency } from './model/currency'
9
+ export { Depth } from './model/depth'
10
+ export { OpenOrder } from './model/open-order'
11
+
12
+ export type Market = {
13
+ chainId: CHAIN_IDS
14
+ quote: Currency
15
+ base: Currency
16
+ makerFee: number
17
+ takerFee: number
18
+ bids: Depth[]
19
+ bidBookOpen: boolean
20
+ asks: Depth[]
21
+ askBookOpen: boolean
22
+ }
23
+
24
+ export type Transaction = {
25
+ data: `0x${string}`
26
+ gas: bigint
27
+ gasPrice: bigint
28
+ value: bigint
29
+ to: `0x${string}`
30
+ from: `0x${string}` | Account | undefined
31
+ }
32
+
33
+ export type PermitSignature = {
34
+ deadline: bigint
35
+ v: number
36
+ r: `0x${string}`
37
+ s: `0x${string}`
38
+ }
@@ -0,0 +1,48 @@
1
+ import { createPublicClient, http } from 'viem'
2
+
3
+ import { CHAIN_IDS, CHAIN_MAP } from '../constants/chain'
4
+ import { CONTRACT_ADDRESSES } from '../constants/addresses'
5
+
6
+ const _abi = [
7
+ {
8
+ inputs: [
9
+ {
10
+ internalType: 'address',
11
+ name: 'owner',
12
+ type: 'address',
13
+ },
14
+ {
15
+ internalType: 'address',
16
+ name: 'operator',
17
+ type: 'address',
18
+ },
19
+ ],
20
+ name: 'isApprovedForAll',
21
+ outputs: [
22
+ {
23
+ internalType: 'bool',
24
+ name: '',
25
+ type: 'bool',
26
+ },
27
+ ],
28
+ stateMutability: 'view',
29
+ type: 'function',
30
+ },
31
+ ] as const
32
+
33
+ export async function fetchIsApprovedForAll(
34
+ chainId: CHAIN_IDS,
35
+ owner: `0x${string}`,
36
+ rpcUrl?: string,
37
+ ): Promise<boolean> {
38
+ const publicClient = createPublicClient({
39
+ chain: CHAIN_MAP[chainId],
40
+ transport: rpcUrl ? http(rpcUrl) : http(),
41
+ })
42
+ return publicClient.readContract({
43
+ address: CONTRACT_ADDRESSES[chainId]!.BookManager,
44
+ abi: _abi,
45
+ functionName: 'isApprovedForAll',
46
+ args: [owner, CONTRACT_ADDRESSES[chainId]!.Controller],
47
+ })
48
+ }
@@ -1,21 +1,31 @@
1
- import { encodeAbiParameters, keccak256, zeroAddress } from 'viem';
2
- import { MAKER_DEFAULT_POLICY, TAKER_DEFAULT_POLICY } from '../constants/fee';
3
- export const toBookId = (inputToken, outputToken, unit) => {
4
- const value = keccak256(encodeAbiParameters([
1
+ import { encodeAbiParameters, keccak256, zeroAddress } from 'viem'
2
+
3
+ import { MAKER_DEFAULT_POLICY, TAKER_DEFAULT_POLICY } from '../constants/fee'
4
+
5
+ export const toBookId = (
6
+ inputToken: `0x${string}`,
7
+ outputToken: `0x${string}`,
8
+ unit: bigint,
9
+ ) => {
10
+ const value = keccak256(
11
+ encodeAbiParameters(
12
+ [
5
13
  { name: 'base', type: 'address' },
6
14
  { name: 'unit', type: 'uint64' },
7
15
  { name: 'quote', type: 'address' },
8
16
  { name: 'makerPolicy', type: 'uint24' },
9
17
  { name: 'hooks', type: 'address' },
10
18
  { name: 'takerPolicy', type: 'uint24' },
11
- ], [
19
+ ],
20
+ [
12
21
  outputToken,
13
22
  unit,
14
23
  inputToken,
15
24
  Number(MAKER_DEFAULT_POLICY.value),
16
25
  zeroAddress,
17
26
  Number(TAKER_DEFAULT_POLICY.value),
18
- ]));
19
- return BigInt(value) & (2n ** 192n - 1n);
20
- };
21
- //# sourceMappingURL=book-id.js.map
27
+ ],
28
+ ),
29
+ )
30
+ return BigInt(value) & (2n ** 192n - 1n)
31
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ createPublicClient,
3
+ encodeFunctionData,
4
+ http,
5
+ SimulateContractParameters,
6
+ WriteContractParameters,
7
+ } from 'viem'
8
+
9
+ import { CHAIN_IDS, CHAIN_MAP } from '../constants/chain'
10
+ import { Transaction } from '../type'
11
+
12
+ export const buildTransaction = async (
13
+ chainId: CHAIN_IDS,
14
+ args: WriteContractParameters | SimulateContractParameters,
15
+ rpcUrl?: string,
16
+ ): Promise<Transaction> => {
17
+ const publicClient = createPublicClient({
18
+ chain: CHAIN_MAP[chainId],
19
+ transport: rpcUrl ? http(rpcUrl) : http(),
20
+ })
21
+ const data = encodeFunctionData(args)
22
+ const [gas, gasPrice] = await Promise.all([
23
+ publicClient.estimateGas({
24
+ account: args.account,
25
+ data,
26
+ to: args.address,
27
+ value: args.value || 0n,
28
+ }),
29
+ publicClient.getGasPrice(),
30
+ ])
31
+ return {
32
+ gas,
33
+ gasPrice,
34
+ data,
35
+ value: args.value || 0n,
36
+ to: args.address,
37
+ from: args.account,
38
+ }
39
+ }
@@ -0,0 +1,22 @@
1
+ import { PRICE_PRECISION } from '../constants/price'
2
+
3
+ import { divide } from './math'
4
+ import { toPrice } from './tick'
5
+
6
+ export const baseToQuote = (
7
+ tick: bigint,
8
+ base: bigint,
9
+ roundingUp: boolean,
10
+ ): bigint => {
11
+ const y = 1n << PRICE_PRECISION
12
+ return divide(base * toPrice(tick), y, roundingUp)
13
+ }
14
+
15
+ export const quoteToBase = (
16
+ tick: bigint,
17
+ quote: bigint,
18
+ roundingUp: boolean,
19
+ ): bigint => {
20
+ const x = quote << PRICE_PRECISION
21
+ return divide(x, toPrice(tick), roundingUp)
22
+ }
@@ -0,0 +1,74 @@
1
+ import { getAddress, isAddressEqual, zeroAddress } from 'viem'
2
+
3
+ import { STABLE_COIN_ADDRESSES, WETH_ADDRESSES } from '../constants/currency'
4
+ import { CHAIN_IDS } from '../constants/chain'
5
+
6
+ export const getMarketId = (
7
+ chainId: CHAIN_IDS,
8
+ tokenAddresses: `0x${string}`[],
9
+ ): {
10
+ baseTokenAddress: `0x${string}`
11
+ quoteTokenAddress: `0x${string}`
12
+ marketId: string
13
+ } => {
14
+ if (tokenAddresses.length !== 2) {
15
+ throw new Error('Invalid token pair')
16
+ }
17
+ tokenAddresses = tokenAddresses.map((address) => getAddress(address))
18
+
19
+ // include stable coin
20
+ const stable = tokenAddresses.find((address) => {
21
+ return STABLE_COIN_ADDRESSES[chainId]!.map((addresses) =>
22
+ getAddress(addresses),
23
+ ).some((addresses) => addresses.includes(address))
24
+ })
25
+ if (stable) {
26
+ const other = tokenAddresses.find(
27
+ (address) => !isAddressEqual(address, stable),
28
+ )!
29
+ return {
30
+ marketId: `${other}/${stable}`,
31
+ quoteTokenAddress: stable,
32
+ baseTokenAddress: other,
33
+ }
34
+ }
35
+
36
+ // include eth
37
+ const eth = tokenAddresses.find((address) =>
38
+ isAddressEqual(address, zeroAddress),
39
+ )
40
+ if (eth) {
41
+ const other = tokenAddresses.find(
42
+ (address) => !isAddressEqual(address, zeroAddress),
43
+ )!
44
+ return {
45
+ marketId: `${other}/${eth}`,
46
+ quoteTokenAddress: eth,
47
+ baseTokenAddress: other,
48
+ }
49
+ }
50
+
51
+ // include weth
52
+ const weth = tokenAddresses.find((address) => {
53
+ return WETH_ADDRESSES[chainId]!.map((addresses) =>
54
+ getAddress(addresses),
55
+ ).some((addresses) => addresses.includes(address))
56
+ })
57
+ if (weth) {
58
+ const other = tokenAddresses.find(
59
+ (address) => !isAddressEqual(address, weth),
60
+ )!
61
+ return {
62
+ marketId: `${other}/${weth}`,
63
+ quoteTokenAddress: weth,
64
+ baseTokenAddress: other,
65
+ }
66
+ }
67
+
68
+ const _tokens = tokenAddresses.sort((a, b) => a.localeCompare(b))
69
+ return {
70
+ marketId: `${_tokens[0]}/${_tokens[1]}`,
71
+ quoteTokenAddress: _tokens[0]!,
72
+ baseTokenAddress: _tokens[1]!,
73
+ }
74
+ }
@@ -0,0 +1,117 @@
1
+ export const divide = (x: bigint, y: bigint, roundUp: boolean): bigint => {
2
+ if (roundUp) {
3
+ if (x === 0n) {
4
+ return 0n
5
+ } else {
6
+ return (x - 1n) / y + 1n
7
+ }
8
+ } else {
9
+ return x / y
10
+ }
11
+ }
12
+
13
+ export const lnWad = (x: bigint): bigint => {
14
+ const or = (a: bigint, b: bigint) => a | b
15
+ const xor = (a: bigint, b: bigint) => a ^ b
16
+ const and = (a: bigint, b: bigint) => a & b
17
+ const add = (a: bigint, b: bigint) => a + b
18
+ const sub = (a: bigint, b: bigint) => a - b
19
+ const mul = (a: bigint, b: bigint) => a * b
20
+ const sdiv = (a: bigint, b: bigint) => a / b
21
+ const lt = (a: bigint, b: bigint) => (a < b ? 1n : 0n)
22
+ const shl = (x: bigint, y: bigint) => y << x
23
+ const shr = (x: bigint, y: bigint) => y >> x
24
+ const sar = (x: bigint, y: bigint) => y >> x
25
+ const byte = (i: bigint, x: bigint) => (x >> (248n - i * 8n)) & 0xffn
26
+
27
+ // We want to convert `x` from `10**18` fixed point to `2**96` fixed point.
28
+ // We do this by multiplying by `2**96 / 10**18`. But since
29
+ // `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here
30
+ // and add `ln(2**96 / 10**18)` at the end.
31
+
32
+ // Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.
33
+ let r = shl(7n, lt(0xffffffffffffffffffffffffffffffffn, x))
34
+ r = or(r, shl(6n, lt(0xffffffffffffffffn, shr(r, x))))
35
+ r = or(r, shl(5n, lt(0xffffffffn, shr(r, x))))
36
+ r = or(r, shl(4n, lt(0xffffn, shr(r, x))))
37
+ r = or(r, shl(3n, lt(0xffn, shr(r, x))))
38
+ // forgefmt: disable-next-item
39
+ r = xor(
40
+ r,
41
+ byte(
42
+ and(0x1fn, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54ben)),
43
+ 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffffn,
44
+ ),
45
+ )
46
+
47
+ // Reduce range of x to (1, 2) * 2**96
48
+ // ln(2^k * x) = k * ln(2) + ln(x)
49
+ x = shr(159n, shl(r, x))
50
+
51
+ // Evaluate using a (8, 8)-term rational approximation.
52
+ // `p` is made monic, we will multiply by a scale factor later.
53
+ // forgefmt: disable-next-item
54
+ let p = sub(
55
+ // This heavily nested expression is to avoid stack-too-deep for via-ir.
56
+ sar(
57
+ 96n,
58
+ mul(
59
+ add(
60
+ 43456485725739037958740375743393n,
61
+ sar(
62
+ 96n,
63
+ mul(
64
+ add(
65
+ 24828157081833163892658089445524n,
66
+ sar(96n, mul(add(3273285459638523848632254066296n, x), x)),
67
+ ),
68
+ x,
69
+ ),
70
+ ),
71
+ ),
72
+ x,
73
+ ),
74
+ ),
75
+ 11111509109440967052023855526967n,
76
+ )
77
+ p = sub(sar(96n, mul(p, x)), 45023709667254063763336534515857n)
78
+ p = sub(sar(96n, mul(p, x)), 14706773417378608786704636184526n)
79
+ p = sub(mul(p, x), shl(96n, 795164235651350426258249787498n))
80
+ // We leave `p` in `2**192` basis so we don't need to scale it back up for the division.
81
+
82
+ // `q` is monic by convention.
83
+ let q = add(5573035233440673466300451813936n, x)
84
+ q = add(71694874799317883764090561454958n, sar(96n, mul(x, q)))
85
+ q = add(283447036172924575727196451306956n, sar(96n, mul(x, q)))
86
+ q = add(401686690394027663651624208769553n, sar(96n, mul(x, q)))
87
+ q = add(204048457590392012362485061816622n, sar(96n, mul(x, q)))
88
+ q = add(31853899698501571402653359427138n, sar(96n, mul(x, q)))
89
+ q = add(909429971244387300277376558375n, sar(96n, mul(x, q)))
90
+
91
+ // `p / q` is in the range `(0, 0.125) * 2**96`.
92
+
93
+ // Finalization, we need to:
94
+ // - Multiply by the scale factor `s = 5.549…`.
95
+ // - Add `ln(2**96 / 10**18)`.
96
+ // - Add `k * ln(2)`.
97
+ // - Multiply by `10**18 / 2**96 = 5**18 >> 78`.
98
+
99
+ // The q polynomial is known not to have zeros in the domain.
100
+ // No scaling required because p is already `2**96` too large.
101
+ p = sdiv(p, q)
102
+ // Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.
103
+ p = mul(1677202110996718588342820967067443963516166n, p)
104
+ // Add `ln(2) * k * 5**18 * 2**192`.
105
+ // forgefmt: disable-next-item
106
+ p = add(
107
+ mul(
108
+ 16597577552685614221487285958193947469193820559219878177908093499208371n,
109
+ sub(159n, r),
110
+ ),
111
+ p,
112
+ )
113
+ // Base conversion: mul `2**96 / (5**18 * 2**192)`.
114
+ r = sdiv(p, 302231454903657293676544000000000000000000n)
115
+
116
+ return r
117
+ }
@@ -0,0 +1,29 @@
1
+ import BigNumber from 'bignumber.js'
2
+
3
+ import { PRICE_PRECISION } from '../constants/price'
4
+
5
+ export const formatPrice = (
6
+ price: bigint,
7
+ quoteDecimals: number,
8
+ baseDecimals: number,
9
+ ): number => {
10
+ return new BigNumber(price.toString())
11
+ .div(new BigNumber(2).pow(PRICE_PRECISION.toString()))
12
+ .times(new BigNumber(10).pow(baseDecimals))
13
+ .div(new BigNumber(10).pow(quoteDecimals))
14
+ .toNumber()
15
+ }
16
+
17
+ export const parsePrice = (
18
+ price: number,
19
+ quoteDecimals: number,
20
+ baseDecimals: number,
21
+ ): bigint => {
22
+ const value = new BigNumber(price)
23
+ .times(new BigNumber(2).pow(PRICE_PRECISION.toString()))
24
+ .times(new BigNumber(10).pow(quoteDecimals))
25
+ .div(new BigNumber(10).pow(baseDecimals))
26
+ return BigInt(
27
+ value.isInteger() ? value.toFixed() : value.integerValue().toFixed(),
28
+ )
29
+ }