@velora-dex/sdk 8.0.0

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 (284) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +494 -0
  3. package/dist/constants.d.ts +7 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/examples/customFetcher.d.ts +3 -0
  6. package/dist/examples/customFetcher.d.ts.map +1 -0
  7. package/dist/examples/delta.d.ts +2 -0
  8. package/dist/examples/delta.d.ts.map +1 -0
  9. package/dist/examples/ethersV6.d.ts +2 -0
  10. package/dist/examples/ethersV6.d.ts.map +1 -0
  11. package/dist/examples/limitOrders_all.d.ts +2 -0
  12. package/dist/examples/limitOrders_all.d.ts.map +1 -0
  13. package/dist/examples/limitOrders_partial.d.ts +2 -0
  14. package/dist/examples/limitOrders_partial.d.ts.map +1 -0
  15. package/dist/examples/limitOrders_postOrder.d.ts +2 -0
  16. package/dist/examples/limitOrders_postOrder.d.ts.map +1 -0
  17. package/dist/examples/partial.d.ts +2 -0
  18. package/dist/examples/partial.d.ts.map +1 -0
  19. package/dist/examples/quote.d.ts +2 -0
  20. package/dist/examples/quote.d.ts.map +1 -0
  21. package/dist/examples/sdk.d.ts +2 -0
  22. package/dist/examples/sdk.d.ts.map +1 -0
  23. package/dist/examples/simple.d.ts +2 -0
  24. package/dist/examples/simple.d.ts.map +1 -0
  25. package/dist/examples/simpleQuote.d.ts +2 -0
  26. package/dist/examples/simpleQuote.d.ts.map +1 -0
  27. package/dist/examples/viem.d.ts +2 -0
  28. package/dist/examples/viem.d.ts.map +1 -0
  29. package/dist/examples/wagmi.d.ts +43 -0
  30. package/dist/examples/wagmi.d.ts.map +1 -0
  31. package/dist/examples/web3.d.ts +2 -0
  32. package/dist/examples/web3.d.ts.map +1 -0
  33. package/dist/gas.d.ts +8 -0
  34. package/dist/gas.d.ts.map +1 -0
  35. package/dist/helpers/approve.d.ts +8 -0
  36. package/dist/helpers/approve.d.ts.map +1 -0
  37. package/dist/helpers/fetchers/axios.d.ts +5 -0
  38. package/dist/helpers/fetchers/axios.d.ts.map +1 -0
  39. package/dist/helpers/fetchers/fetch.d.ts +5 -0
  40. package/dist/helpers/fetchers/fetch.d.ts.map +1 -0
  41. package/dist/helpers/index.d.ts +13 -0
  42. package/dist/helpers/index.d.ts.map +1 -0
  43. package/dist/helpers/misc.d.ts +48 -0
  44. package/dist/helpers/misc.d.ts.map +1 -0
  45. package/dist/helpers/providers/ethers.d.ts +10 -0
  46. package/dist/helpers/providers/ethers.d.ts.map +1 -0
  47. package/dist/helpers/providers/ethersV6.d.ts +8 -0
  48. package/dist/helpers/providers/ethersV6.d.ts.map +1 -0
  49. package/dist/helpers/providers/helpers.d.ts +3 -0
  50. package/dist/helpers/providers/helpers.d.ts.map +1 -0
  51. package/dist/helpers/providers/viem.d.ts +23 -0
  52. package/dist/helpers/providers/viem.d.ts.map +1 -0
  53. package/dist/helpers/providers/web3.d.ts +9 -0
  54. package/dist/helpers/providers/web3.d.ts.map +1 -0
  55. package/dist/helpers/token.d.ts +38 -0
  56. package/dist/helpers/token.d.ts.map +1 -0
  57. package/dist/index.d.ts +64 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +8 -0
  60. package/dist/methods/common/orders/buildOrderData.d.ts +27 -0
  61. package/dist/methods/common/orders/buildOrderData.d.ts.map +1 -0
  62. package/dist/methods/common/orders/encoding.d.ts +23 -0
  63. package/dist/methods/common/orders/encoding.d.ts.map +1 -0
  64. package/dist/methods/common/orders/misc.d.ts +27 -0
  65. package/dist/methods/common/orders/misc.d.ts.map +1 -0
  66. package/dist/methods/common/orders/signature.d.ts +9 -0
  67. package/dist/methods/common/orders/signature.d.ts.map +1 -0
  68. package/dist/methods/common/orders/types.d.ts +8 -0
  69. package/dist/methods/common/orders/types.d.ts.map +1 -0
  70. package/dist/methods/delta/approveForDelta.d.ts +8 -0
  71. package/dist/methods/delta/approveForDelta.d.ts.map +1 -0
  72. package/dist/methods/delta/buildCrosschainOrderBridge.d.ts +23 -0
  73. package/dist/methods/delta/buildCrosschainOrderBridge.d.ts.map +1 -0
  74. package/dist/methods/delta/buildDeltaOrder.d.ts +49 -0
  75. package/dist/methods/delta/buildDeltaOrder.d.ts.map +1 -0
  76. package/dist/methods/delta/getBridgeInfo.d.ts +9 -0
  77. package/dist/methods/delta/getBridgeInfo.d.ts.map +1 -0
  78. package/dist/methods/delta/getDeltaContract.d.ts +9 -0
  79. package/dist/methods/delta/getDeltaContract.d.ts.map +1 -0
  80. package/dist/methods/delta/getDeltaOrders.d.ts +22 -0
  81. package/dist/methods/delta/getDeltaOrders.d.ts.map +1 -0
  82. package/dist/methods/delta/getDeltaPrice.d.ts +58 -0
  83. package/dist/methods/delta/getDeltaPrice.d.ts.map +1 -0
  84. package/dist/methods/delta/getMulticallHandlers.d.ts +9 -0
  85. package/dist/methods/delta/getMulticallHandlers.d.ts.map +1 -0
  86. package/dist/methods/delta/getPartnerFee.d.ts +16 -0
  87. package/dist/methods/delta/getPartnerFee.d.ts.map +1 -0
  88. package/dist/methods/delta/helpers/across.d.ts +22 -0
  89. package/dist/methods/delta/helpers/across.d.ts.map +1 -0
  90. package/dist/methods/delta/helpers/buildDeltaOrderData.d.ts +35 -0
  91. package/dist/methods/delta/helpers/buildDeltaOrderData.d.ts.map +1 -0
  92. package/dist/methods/delta/helpers/composePermit.d.ts +5 -0
  93. package/dist/methods/delta/helpers/composePermit.d.ts.map +1 -0
  94. package/dist/methods/delta/helpers/misc.d.ts +3 -0
  95. package/dist/methods/delta/helpers/misc.d.ts.map +1 -0
  96. package/dist/methods/delta/helpers/types.d.ts +96 -0
  97. package/dist/methods/delta/helpers/types.d.ts.map +1 -0
  98. package/dist/methods/delta/index.d.ts +28 -0
  99. package/dist/methods/delta/index.d.ts.map +1 -0
  100. package/dist/methods/delta/isTokenSupportedInDelta.d.ts +8 -0
  101. package/dist/methods/delta/isTokenSupportedInDelta.d.ts.map +1 -0
  102. package/dist/methods/delta/postDeltaOrder.d.ts +23 -0
  103. package/dist/methods/delta/postDeltaOrder.d.ts.map +1 -0
  104. package/dist/methods/delta/signDeltaOrder.d.ts +12 -0
  105. package/dist/methods/delta/signDeltaOrder.d.ts.map +1 -0
  106. package/dist/methods/limitOrders/approveForOrder.d.ts +12 -0
  107. package/dist/methods/limitOrders/approveForOrder.d.ts.map +1 -0
  108. package/dist/methods/limitOrders/buildOrder.d.ts +11 -0
  109. package/dist/methods/limitOrders/buildOrder.d.ts.map +1 -0
  110. package/dist/methods/limitOrders/cancelOrder.d.ts +9 -0
  111. package/dist/methods/limitOrders/cancelOrder.d.ts.map +1 -0
  112. package/dist/methods/limitOrders/fillOrderDirectly.d.ts +30 -0
  113. package/dist/methods/limitOrders/fillOrderDirectly.d.ts.map +1 -0
  114. package/dist/methods/limitOrders/getOrders.d.ts +39 -0
  115. package/dist/methods/limitOrders/getOrders.d.ts.map +1 -0
  116. package/dist/methods/limitOrders/getOrdersContract.d.ts +8 -0
  117. package/dist/methods/limitOrders/getOrdersContract.d.ts.map +1 -0
  118. package/dist/methods/limitOrders/helpers/buildOrderData.d.ts +43 -0
  119. package/dist/methods/limitOrders/helpers/buildOrderData.d.ts.map +1 -0
  120. package/dist/methods/limitOrders/helpers/misc.d.ts +9 -0
  121. package/dist/methods/limitOrders/helpers/misc.d.ts.map +1 -0
  122. package/dist/methods/limitOrders/helpers/types.d.ts +49 -0
  123. package/dist/methods/limitOrders/helpers/types.d.ts.map +1 -0
  124. package/dist/methods/limitOrders/index.d.ts +30 -0
  125. package/dist/methods/limitOrders/index.d.ts.map +1 -0
  126. package/dist/methods/limitOrders/postOrder.d.ts +10 -0
  127. package/dist/methods/limitOrders/postOrder.d.ts.map +1 -0
  128. package/dist/methods/limitOrders/signOrder.d.ts +7 -0
  129. package/dist/methods/limitOrders/signOrder.d.ts.map +1 -0
  130. package/dist/methods/limitOrders/transaction.d.ts +23 -0
  131. package/dist/methods/limitOrders/transaction.d.ts.map +1 -0
  132. package/dist/methods/nftOrders/approveForOrder.d.ts +12 -0
  133. package/dist/methods/nftOrders/approveForOrder.d.ts.map +1 -0
  134. package/dist/methods/nftOrders/buildOrder.d.ts +11 -0
  135. package/dist/methods/nftOrders/buildOrder.d.ts.map +1 -0
  136. package/dist/methods/nftOrders/cancelOrder.d.ts +8 -0
  137. package/dist/methods/nftOrders/cancelOrder.d.ts.map +1 -0
  138. package/dist/methods/nftOrders/getOrders.d.ts +18 -0
  139. package/dist/methods/nftOrders/getOrders.d.ts.map +1 -0
  140. package/dist/methods/nftOrders/getOrdersContract.d.ts +8 -0
  141. package/dist/methods/nftOrders/getOrdersContract.d.ts.map +1 -0
  142. package/dist/methods/nftOrders/helpers/buildOrderData.d.ts +52 -0
  143. package/dist/methods/nftOrders/helpers/buildOrderData.d.ts.map +1 -0
  144. package/dist/methods/nftOrders/helpers/misc.d.ts +13 -0
  145. package/dist/methods/nftOrders/helpers/misc.d.ts.map +1 -0
  146. package/dist/methods/nftOrders/helpers/types.d.ts +39 -0
  147. package/dist/methods/nftOrders/helpers/types.d.ts.map +1 -0
  148. package/dist/methods/nftOrders/index.d.ts +23 -0
  149. package/dist/methods/nftOrders/index.d.ts.map +1 -0
  150. package/dist/methods/nftOrders/postOrder.d.ts +10 -0
  151. package/dist/methods/nftOrders/postOrder.d.ts.map +1 -0
  152. package/dist/methods/nftOrders/signOrder.d.ts +7 -0
  153. package/dist/methods/nftOrders/signOrder.d.ts.map +1 -0
  154. package/dist/methods/nftOrders/transaction.d.ts +23 -0
  155. package/dist/methods/nftOrders/transaction.d.ts.map +1 -0
  156. package/dist/methods/quote/getQuote.d.ts +51 -0
  157. package/dist/methods/quote/getQuote.d.ts.map +1 -0
  158. package/dist/methods/swap/adapters.d.ts +8 -0
  159. package/dist/methods/swap/adapters.d.ts.map +1 -0
  160. package/dist/methods/swap/approve.d.ts +10 -0
  161. package/dist/methods/swap/approve.d.ts.map +1 -0
  162. package/dist/methods/swap/balance.d.ts +23 -0
  163. package/dist/methods/swap/balance.d.ts.map +1 -0
  164. package/dist/methods/swap/helpers/normalizeRateOptions.d.ts +12 -0
  165. package/dist/methods/swap/helpers/normalizeRateOptions.d.ts.map +1 -0
  166. package/dist/methods/swap/index.d.ts +13 -0
  167. package/dist/methods/swap/index.d.ts.map +1 -0
  168. package/dist/methods/swap/rates.d.ts +52 -0
  169. package/dist/methods/swap/rates.d.ts.map +1 -0
  170. package/dist/methods/swap/spender.d.ts +21 -0
  171. package/dist/methods/swap/spender.d.ts.map +1 -0
  172. package/dist/methods/swap/swapTx.d.ts +158 -0
  173. package/dist/methods/swap/swapTx.d.ts.map +1 -0
  174. package/dist/methods/swap/token.d.ts +8 -0
  175. package/dist/methods/swap/token.d.ts.map +1 -0
  176. package/dist/methods/swap/transaction.d.ts +115 -0
  177. package/dist/methods/swap/transaction.d.ts.map +1 -0
  178. package/dist/sdk/full.d.ts +17 -0
  179. package/dist/sdk/full.d.ts.map +1 -0
  180. package/dist/sdk/partial.d.ts +31 -0
  181. package/dist/sdk/partial.d.ts.map +1 -0
  182. package/dist/sdk/simple.d.ts +75 -0
  183. package/dist/sdk/simple.d.ts.map +1 -0
  184. package/dist/sdk.cjs.development.js +5182 -0
  185. package/dist/sdk.cjs.development.js.map +1 -0
  186. package/dist/sdk.cjs.production.min.js +2 -0
  187. package/dist/sdk.cjs.production.min.js.map +1 -0
  188. package/dist/sdk.esm.js +5102 -0
  189. package/dist/sdk.esm.js.map +1 -0
  190. package/dist/types.d.ts +161 -0
  191. package/dist/types.d.ts.map +1 -0
  192. package/docs/DELTA.md +207 -0
  193. package/package.json +126 -0
  194. package/src/constants.ts +16 -0
  195. package/src/examples/customFetcher.ts +44 -0
  196. package/src/examples/delta.ts +127 -0
  197. package/src/examples/ethersV6.ts +38 -0
  198. package/src/examples/limitOrders_all.ts +135 -0
  199. package/src/examples/limitOrders_partial.ts +171 -0
  200. package/src/examples/limitOrders_postOrder.ts +77 -0
  201. package/src/examples/partial.ts +34 -0
  202. package/src/examples/quote.ts +205 -0
  203. package/src/examples/sdk.ts +39 -0
  204. package/src/examples/simple.ts +44 -0
  205. package/src/examples/simpleQuote.ts +98 -0
  206. package/src/examples/viem.ts +120 -0
  207. package/src/examples/wagmi.ts +68 -0
  208. package/src/examples/web3.ts +32 -0
  209. package/src/gas.ts +7 -0
  210. package/src/helpers/approve.ts +60 -0
  211. package/src/helpers/fetchers/axios.ts +34 -0
  212. package/src/helpers/fetchers/fetch.ts +67 -0
  213. package/src/helpers/index.ts +27 -0
  214. package/src/helpers/misc.ts +160 -0
  215. package/src/helpers/providers/ethers.ts +192 -0
  216. package/src/helpers/providers/ethersV6.ts +121 -0
  217. package/src/helpers/providers/helpers.ts +36 -0
  218. package/src/helpers/providers/viem.ts +205 -0
  219. package/src/helpers/providers/web3.ts +154 -0
  220. package/src/helpers/token.ts +75 -0
  221. package/src/index.ts +425 -0
  222. package/src/methods/common/orders/buildOrderData.ts +29 -0
  223. package/src/methods/common/orders/encoding.ts +216 -0
  224. package/src/methods/common/orders/misc.ts +86 -0
  225. package/src/methods/common/orders/signature.ts +68 -0
  226. package/src/methods/common/orders/types.ts +13 -0
  227. package/src/methods/delta/approveForDelta.ts +38 -0
  228. package/src/methods/delta/buildCrosschainOrderBridge.ts +84 -0
  229. package/src/methods/delta/buildDeltaOrder.ts +192 -0
  230. package/src/methods/delta/getBridgeInfo.ts +38 -0
  231. package/src/methods/delta/getDeltaContract.ts +29 -0
  232. package/src/methods/delta/getDeltaOrders.ts +102 -0
  233. package/src/methods/delta/getDeltaPrice.ts +122 -0
  234. package/src/methods/delta/getMulticallHandlers.ts +44 -0
  235. package/src/methods/delta/getPartnerFee.ts +58 -0
  236. package/src/methods/delta/helpers/across.ts +255 -0
  237. package/src/methods/delta/helpers/buildDeltaOrderData.ts +153 -0
  238. package/src/methods/delta/helpers/composePermit.ts +76 -0
  239. package/src/methods/delta/helpers/misc.ts +32 -0
  240. package/src/methods/delta/helpers/types.ts +110 -0
  241. package/src/methods/delta/index.ts +146 -0
  242. package/src/methods/delta/isTokenSupportedInDelta.ts +54 -0
  243. package/src/methods/delta/postDeltaOrder.ts +50 -0
  244. package/src/methods/delta/signDeltaOrder.ts +41 -0
  245. package/src/methods/limitOrders/approveForOrder.ts +36 -0
  246. package/src/methods/limitOrders/buildOrder.ts +56 -0
  247. package/src/methods/limitOrders/cancelOrder.ts +111 -0
  248. package/src/methods/limitOrders/fillOrderDirectly.ts +277 -0
  249. package/src/methods/limitOrders/getOrders.ts +151 -0
  250. package/src/methods/limitOrders/getOrdersContract.ts +20 -0
  251. package/src/methods/limitOrders/helpers/buildOrderData.ts +121 -0
  252. package/src/methods/limitOrders/helpers/misc.ts +64 -0
  253. package/src/methods/limitOrders/helpers/types.ts +70 -0
  254. package/src/methods/limitOrders/index.ts +154 -0
  255. package/src/methods/limitOrders/postOrder.ts +74 -0
  256. package/src/methods/limitOrders/signOrder.ts +29 -0
  257. package/src/methods/limitOrders/transaction.ts +231 -0
  258. package/src/methods/nftOrders/approveForOrder.ts +79 -0
  259. package/src/methods/nftOrders/buildOrder.ts +52 -0
  260. package/src/methods/nftOrders/cancelOrder.ts +23 -0
  261. package/src/methods/nftOrders/getOrders.ts +84 -0
  262. package/src/methods/nftOrders/getOrdersContract.ts +24 -0
  263. package/src/methods/nftOrders/helpers/buildOrderData.ts +131 -0
  264. package/src/methods/nftOrders/helpers/misc.ts +92 -0
  265. package/src/methods/nftOrders/helpers/types.ts +50 -0
  266. package/src/methods/nftOrders/index.ts +139 -0
  267. package/src/methods/nftOrders/postOrder.ts +71 -0
  268. package/src/methods/nftOrders/signOrder.ts +29 -0
  269. package/src/methods/nftOrders/transaction.ts +234 -0
  270. package/src/methods/quote/getQuote.ts +131 -0
  271. package/src/methods/swap/adapters.ts +49 -0
  272. package/src/methods/swap/approve.ts +51 -0
  273. package/src/methods/swap/balance.ts +147 -0
  274. package/src/methods/swap/helpers/normalizeRateOptions.ts +55 -0
  275. package/src/methods/swap/index.ts +38 -0
  276. package/src/methods/swap/rates.ts +276 -0
  277. package/src/methods/swap/spender.ts +76 -0
  278. package/src/methods/swap/swapTx.ts +266 -0
  279. package/src/methods/swap/token.ts +35 -0
  280. package/src/methods/swap/transaction.ts +310 -0
  281. package/src/sdk/full.ts +54 -0
  282. package/src/sdk/partial.ts +107 -0
  283. package/src/sdk/simple.ts +429 -0
  284. package/src/types.ts +240 -0
@@ -0,0 +1,160 @@
1
+ import type { Primitive } from 'ts-essentials';
2
+
3
+ export const objectToFilledEntries = <T extends Record<string, unknown>>(
4
+ object: T
5
+ ): [string, string][] => {
6
+ return (
7
+ Object.entries(object)
8
+ // removes keys with undefined values
9
+ .filter(([, value]) => value !== undefined)
10
+ .map(([key, value]) => [key, String(value)])
11
+ );
12
+ };
13
+
14
+ export const constructSearchString = <
15
+ // not arrays or mappings
16
+ U extends Record<string, Exclude<Primitive, symbol>>
17
+ >(
18
+ queryOptions: U
19
+ ): `?${string}` | '' => {
20
+ const queryEntries = objectToFilledEntries(queryOptions);
21
+
22
+ const queryString = new URLSearchParams(queryEntries).toString();
23
+
24
+ // returns empty string or `?${string}`
25
+ return queryString && `?${queryString}`;
26
+ };
27
+
28
+ type MinAxiosError = {
29
+ code?: string;
30
+ request?: any;
31
+ isAxiosError: boolean;
32
+ message: string;
33
+ };
34
+
35
+ type MinAxiosResponse = {
36
+ data: any;
37
+ status: number;
38
+ statusText: string;
39
+ headers: Record<string, any>;
40
+ config: { url?: string; method?: string };
41
+ };
42
+
43
+ type FetcherErrorConstructorInput = MinAxiosError & {
44
+ response?: MinAxiosResponse;
45
+ };
46
+
47
+ export interface FetcherErrorInterface extends FetcherErrorConstructorInput {
48
+ status?: number;
49
+ code?: string;
50
+ }
51
+
52
+ export const isFetcherError = (error: unknown): error is FetcherError => {
53
+ return error instanceof FetcherError;
54
+ };
55
+
56
+ export class FetcherError extends Error implements FetcherErrorInterface {
57
+ code;
58
+ status;
59
+ request;
60
+ response;
61
+ isAxiosError = false;
62
+
63
+ public constructor({
64
+ code,
65
+ request,
66
+ response,
67
+ isAxiosError,
68
+ message,
69
+ }: FetcherErrorConstructorInput) {
70
+ super();
71
+
72
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
73
+ if (Error.captureStackTrace) {
74
+ Error.captureStackTrace(this, FetcherError);
75
+ }
76
+
77
+ this.name = this.constructor.name;
78
+ this.code = code;
79
+ this.request = request;
80
+ this.isAxiosError = isAxiosError;
81
+
82
+ // no response on AxiosError
83
+ if (!response) {
84
+ this.message = message;
85
+ return;
86
+ }
87
+
88
+ this.response = response;
89
+
90
+ const { data, status } = response;
91
+ this.status = status;
92
+ this.message = isDataWithError(data) ? data.error : message;
93
+ }
94
+ }
95
+ // to turn `object -> Record` for indexed variable access
96
+ function isObject(obj: unknown): obj is Record<string | symbol, any> {
97
+ return !!obj && typeof obj === 'object';
98
+ }
99
+
100
+ export function isDataWithError(data: unknown): data is { error: string } {
101
+ return isObject(data) && typeof data['error'] === 'string';
102
+ }
103
+
104
+ export type ExtractAbiMethodNames<T extends readonly { name: string }[]> =
105
+ T[number]['name'];
106
+
107
+ // reduce element[] to Object{key: prop, val?: element}
108
+ // for example
109
+ // gatherObjectsByProp(Token[], token => token.address) => Record<address, Token|undefined>
110
+ export function gatherObjectsByProp<T>(
111
+ elements: T[],
112
+ pickProp: (elem: T, index: number) => string
113
+ ): Record<string, T>;
114
+ export function gatherObjectsByProp<T, U>(
115
+ elements: T[],
116
+ pickProp: (elem: T, index: number) => string,
117
+ transfrom: (elem: T, accumElem: U | undefined, index: number) => U
118
+ ): Record<string, U>;
119
+ export function gatherObjectsByProp<T, U>(
120
+ elements: T[],
121
+ pickProp: (elem: T, index: number) => string,
122
+ transform?: (elem: T, accumElem: U | undefined, index: number) => U
123
+ ): Record<string, T> | Record<string, U> {
124
+ return elements.reduce<Record<string, T> | Record<string, U>>(
125
+ (accum, element, index) => {
126
+ const key = pickProp(element, index);
127
+
128
+ const accumElem: T | U | undefined = accum[key];
129
+ const transformedElement = transform
130
+ ? // if transform is available, can only be U | undefined
131
+ transform(element, accumElem as U | undefined, index)
132
+ : element;
133
+
134
+ accum[key] = transformedElement;
135
+
136
+ return accum;
137
+ },
138
+ {}
139
+ );
140
+ }
141
+
142
+ // checks that array has at least one element
143
+ export const isFilledArray = <T>(array: T[]): array is [T, ...T[]] => {
144
+ return array.length > 0;
145
+ };
146
+
147
+ export function getRandomInt(): number {
148
+ return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
149
+ }
150
+
151
+ export function runOnceAndCache<T, Args extends any[]>(
152
+ // can pass `(...any[]) => any but null | undefined`
153
+ func: (...args: Args) => NonNullable<T>
154
+ ): (...args: Args) => NonNullable<T> {
155
+ let result: NonNullable<T>;
156
+
157
+ return (...args) => {
158
+ return result ?? (result = func(...args));
159
+ };
160
+ }
@@ -0,0 +1,192 @@
1
+ import type {
2
+ Address,
3
+ ContractCallerFunctions,
4
+ NoExtraKeysCheck,
5
+ SignTypedDataContractCallerFn,
6
+ StaticContractCallerFn,
7
+ TransactionContractCallerFn,
8
+ } from '../../types';
9
+ import type {
10
+ JsonRpcProvider,
11
+ BaseProvider,
12
+ JsonRpcSigner,
13
+ } from '@ethersproject/providers';
14
+ import type { Signer } from '@ethersproject/abstract-signer';
15
+ import type {
16
+ Contract as EthersV5Contract,
17
+ ContractFunction as EthersContractFunctionV5,
18
+ PopulatedTransaction as EthersPopulatedTransactionV5,
19
+ PayableOverrides,
20
+ CallOverrides,
21
+ ContractTransaction,
22
+ } from '@ethersproject/contracts';
23
+
24
+ import type { BigNumber as EthersBigNumberV5 } from '@ethersproject/bignumber';
25
+
26
+ import { assert } from 'ts-essentials';
27
+
28
+ export interface EthersV5ProviderDeps {
29
+ ethersProviderOrSigner: BaseProvider | Signer;
30
+ EthersContract: typeof EthersV5Contract; // passing Contract in allows not to include ethers as dependency
31
+ }
32
+
33
+ export const constructEthersV5ContractCaller = (
34
+ {
35
+ ethersProviderOrSigner: providerOrSigner,
36
+ EthersContract: Contract,
37
+ }: EthersV5ProviderDeps,
38
+ account?: Address
39
+ ): ContractCallerFunctions<ContractTransaction> => {
40
+ const staticCall: StaticContractCallerFn = async (params) => {
41
+ const { address, abi, contractMethod, args, overrides } = params;
42
+
43
+ const contract = new Contract(address, abi, providerOrSigner);
44
+
45
+ assertEthersContractHasMethodsV5(contract, contractMethod);
46
+ // drop keys not in CallOverrides
47
+ const { block, gas, ...restOverrides } = overrides;
48
+ // reassign values to keys in CallOverrides
49
+ const normalizedOverrides = {
50
+ ...restOverrides,
51
+ blockTag: block,
52
+ gasLimit: gas,
53
+ };
54
+
55
+ // type FinalCallOverrides = normalizedOverrides has extra props ? never : normalizedOverrides
56
+ type FinalCallOverrides = NoExtraKeysCheck<
57
+ typeof normalizedOverrides,
58
+ CallOverrides
59
+ >;
60
+
61
+ // enforce overrides shape ethers accepts
62
+ // TS will break if normalizedOverrides type has any keys not also present in CallOverrides
63
+ const callOverrides: FinalCallOverrides = normalizedOverrides;
64
+ // returns whatever the Contract.method returns: BigNumber, string, boolean
65
+ return contract.callStatic[contractMethod](...args, callOverrides);
66
+ };
67
+
68
+ const transactCall: TransactionContractCallerFn<ContractTransaction> = async (
69
+ params
70
+ ) => {
71
+ assert(account, 'account must be specified to create a signer');
72
+ assert(
73
+ isEthersProviderWithSigner(providerOrSigner) ||
74
+ isEthersSigner(providerOrSigner),
75
+ 'ethers must be an instance of Signer or JsonRpcProvider to create a signer'
76
+ );
77
+
78
+ const { address, abi, contractMethod, args, overrides } = params;
79
+
80
+ const signer =
81
+ 'getSigner' in providerOrSigner
82
+ ? providerOrSigner.getSigner(account)
83
+ : providerOrSigner;
84
+
85
+ const contract = new Contract(address, abi, signer);
86
+
87
+ assertEthersContractHasMethodsV5(contract, contractMethod);
88
+ // drop keys not in PayableOverrides
89
+ const { gas, from, ...restOverrides } = overrides;
90
+ // reassign values to keys in PayableOverrides
91
+ const normalizedOverrides = {
92
+ ...restOverrides,
93
+ gasLimit: gas,
94
+ };
95
+
96
+ // type FinalPayableOverrides = normalizedOverrides has extra props ? never : normalizedOverrides
97
+ type FinalPayableOverrides = NoExtraKeysCheck<
98
+ typeof normalizedOverrides,
99
+ PayableOverrides
100
+ >;
101
+
102
+ // enforce overrides shape ethers accepts
103
+ // TS will break if normalizedOverrides type has any keys not also present in PayableOverrides
104
+ const txOverrides: FinalPayableOverrides = normalizedOverrides;
105
+ const txResponse: ContractTransaction = await contract[contractMethod](
106
+ ...args,
107
+ txOverrides
108
+ );
109
+
110
+ return txResponse;
111
+ };
112
+
113
+ const signTypedDataCall: SignTypedDataContractCallerFn = async (
114
+ typedData
115
+ ) => {
116
+ assert(account, 'account must be specified to create a signer');
117
+ assert(
118
+ isEthersProviderWithSigner(providerOrSigner) ||
119
+ isEthersSigner(providerOrSigner),
120
+ 'ethers must be an instance of Signer or JsonRpcProvider to create a signer'
121
+ );
122
+
123
+ const signer =
124
+ 'getSigner' in providerOrSigner
125
+ ? providerOrSigner.getSigner(account)
126
+ : providerOrSigner;
127
+
128
+ assert(isTypedDataCapableSigner(signer), 'Signer can sign typed data');
129
+
130
+ const { data, domain, types } = typedData;
131
+
132
+ return signer._signTypedData(domain, types, data);
133
+ };
134
+
135
+ return { staticCall, transactCall, signTypedDataCall };
136
+ };
137
+
138
+ function isEthersProvider(
139
+ providerOrSigner: BaseProvider | Signer
140
+ ): providerOrSigner is BaseProvider {
141
+ return '_isProvider' in providerOrSigner && providerOrSigner._isProvider;
142
+ }
143
+
144
+ function isEthersProviderWithSigner(
145
+ providerOrSigner: JsonRpcProvider | BaseProvider | Signer
146
+ ): providerOrSigner is JsonRpcProvider {
147
+ return isEthersProvider(providerOrSigner) && 'getSigner' in providerOrSigner;
148
+ }
149
+
150
+ function isEthersSigner(
151
+ providerOrSigner: BaseProvider | Signer
152
+ ): providerOrSigner is Signer {
153
+ return '_isSigner' in providerOrSigner && providerOrSigner._isSigner;
154
+ }
155
+
156
+ function isTypedDataCapableSigner(
157
+ signer: Signer
158
+ ): signer is Signer & Pick<JsonRpcSigner, '_signTypedData'> {
159
+ return '_signTypedData' in signer;
160
+ }
161
+
162
+ /// ethers v5
163
+ type EthersContractWithMethodV5<T extends string> = EthersV5Contract & {
164
+ readonly [method in T]: EthersContractFunctionV5;
165
+ } & {
166
+ readonly functions: { [method in T]: EthersContractFunctionV5 };
167
+
168
+ readonly callStatic: { [method in T]: EthersContractFunctionV5 };
169
+ readonly estimateGas: {
170
+ [method in T]: EthersContractFunctionV5<EthersBigNumberV5>;
171
+ };
172
+ readonly populateTransaction: {
173
+ [method in T]: EthersContractFunctionV5<EthersPopulatedTransactionV5>;
174
+ };
175
+ };
176
+
177
+ function ethersContractHasMethodsV5<T extends string>(
178
+ contract: EthersV5Contract,
179
+ ...methods: T[]
180
+ ): contract is EthersContractWithMethodV5<T> {
181
+ return methods.every((method) => typeof contract[method] === 'function');
182
+ }
183
+
184
+ function assertEthersContractHasMethodsV5<T extends string>(
185
+ contract: EthersV5Contract,
186
+ ...methods: T[]
187
+ ): asserts contract is EthersContractWithMethodV5<T> {
188
+ assert(
189
+ ethersContractHasMethodsV5(contract, ...methods),
190
+ `Contract must have methods: ${methods.join(', ')}`
191
+ );
192
+ }
@@ -0,0 +1,121 @@
1
+ import type {
2
+ Address,
3
+ ContractCallerFunctions,
4
+ SignTypedDataContractCallerFn,
5
+ StaticContractCallerFn,
6
+ TransactionContractCallerFn,
7
+ } from '../../types';
8
+ import { assert } from 'ts-essentials';
9
+ import type {
10
+ JsonRpcProvider,
11
+ Signer,
12
+ ContractRunner,
13
+ Contract as EthersContract,
14
+ Overrides,
15
+ ContractTransactionResponse,
16
+ } from 'ethers';
17
+
18
+ export interface EthersV6ProviderDeps {
19
+ ethersV6ProviderOrSigner: ContractRunner | Signer;
20
+ EthersV6Contract: typeof EthersContract; // passing Contract in allows not to include ethers as dependency
21
+ }
22
+
23
+ export const constructContractCaller = (
24
+ {
25
+ ethersV6ProviderOrSigner: providerOrSigner,
26
+ EthersV6Contract: Contract,
27
+ }: EthersV6ProviderDeps,
28
+ account?: Address
29
+ ): ContractCallerFunctions<ContractTransactionResponse> => {
30
+ const staticCall: StaticContractCallerFn = async (params) => {
31
+ const { address, abi, contractMethod, args, overrides } = params;
32
+
33
+ const contract = new Contract(address, abi, providerOrSigner);
34
+
35
+ // drop keys not in CallOverrides
36
+ const { block, gas, ...restOverrides } = overrides;
37
+ // reassign values to keys in CallOverrides
38
+ const normalizedOverrides: Overrides = {
39
+ ...restOverrides,
40
+ blockTag: block,
41
+ gasLimit: gas,
42
+ };
43
+
44
+ const callableContractFunction = contract.getFunction(contractMethod);
45
+
46
+ // returns whatever the Contract["method"].staticCall returns: BigNumber, string, boolean
47
+ return callableContractFunction.staticCall(...args, normalizedOverrides);
48
+ };
49
+
50
+ const transactCall: TransactionContractCallerFn<
51
+ ContractTransactionResponse
52
+ > = async (params) => {
53
+ assert(account, 'account must be specified to create a signer');
54
+ assert(
55
+ isEthersProviderWithSigner(providerOrSigner) ||
56
+ isEthersSigner(providerOrSigner),
57
+ 'ethers must be an instance of Signer or JsonRpcProvider to create a signer'
58
+ );
59
+
60
+ const { address, abi, contractMethod, args, overrides } = params;
61
+
62
+ const signer =
63
+ 'getSigner' in providerOrSigner
64
+ ? await providerOrSigner.getSigner(account)
65
+ : providerOrSigner;
66
+
67
+ const contract = new Contract(address, abi, signer);
68
+
69
+ // drop keys not in PayableOverrides
70
+ const { gas, from, ...restOverrides } = overrides;
71
+ // reassign values to keys in PayableOverrides
72
+ const normalizedOverrides: Overrides = {
73
+ ...restOverrides,
74
+ gasLimit: gas,
75
+ };
76
+
77
+ // if no method for contractMethod, ethers will throw
78
+ const callableContractFunction = contract.getFunction(contractMethod);
79
+
80
+ const txResponse = await callableContractFunction.send(
81
+ ...args,
82
+ normalizedOverrides
83
+ );
84
+
85
+ return txResponse;
86
+ };
87
+
88
+ const signTypedDataCall: SignTypedDataContractCallerFn = async (
89
+ typedData
90
+ ) => {
91
+ assert(account, 'account must be specified to create a signer');
92
+ assert(
93
+ isEthersProviderWithSigner(providerOrSigner) ||
94
+ isEthersSigner(providerOrSigner),
95
+ 'ethers must be an instance of Signer or JsonRpcProvider to create a signer'
96
+ );
97
+
98
+ const signer =
99
+ 'getSigner' in providerOrSigner
100
+ ? await providerOrSigner.getSigner(account)
101
+ : providerOrSigner;
102
+
103
+ const { data, domain, types } = typedData;
104
+
105
+ return signer.signTypedData(domain, types, data);
106
+ };
107
+
108
+ return { staticCall, transactCall, signTypedDataCall };
109
+ };
110
+
111
+ function isEthersProviderWithSigner(
112
+ providerOrSigner: JsonRpcProvider | ContractRunner | Signer
113
+ ): providerOrSigner is JsonRpcProvider {
114
+ return 'getSigner' in providerOrSigner;
115
+ }
116
+
117
+ function isEthersSigner(
118
+ providerOrSigner: ContractRunner | Signer
119
+ ): providerOrSigner is Signer {
120
+ return 'getAddress' in providerOrSigner;
121
+ }
@@ -0,0 +1,36 @@
1
+ import { assert } from 'ts-essentials';
2
+ import { TypedDataField } from '../../methods/common/orders/buildOrderData';
3
+
4
+ // regex from @ethersproject/hash TypedDataEncoder.constructor
5
+ // may be overly strict, but reliable
6
+ const baseTypeRegex = /^([^\x5b]*)(\x5b|$)/;
7
+
8
+ export function findPrimaryType(
9
+ types: Record<string, TypedDataField[]>
10
+ ): string {
11
+ const candidates = Object.keys(types);
12
+ const candidatesSet = new Set(candidates);
13
+
14
+ candidates.forEach((candidate) => {
15
+ const typedDataFields = types[candidate];
16
+ if (!typedDataFields) return;
17
+
18
+ typedDataFields.forEach(({ type }) => {
19
+ // Get the base type (drop any array specifiers)
20
+ const baseType = type.match(baseTypeRegex)?.[1];
21
+ if (!baseType) return;
22
+
23
+ // if type was referred to as a child of another type, it can't be the primaryType
24
+ candidatesSet.delete(baseType);
25
+ });
26
+ });
27
+
28
+ const [primaryType] = Array.from(candidatesSet);
29
+
30
+ assert(
31
+ primaryType,
32
+ `No primary type found in SignableTypedData types, ${JSON.stringify(types)}`
33
+ );
34
+
35
+ return primaryType;
36
+ }
@@ -0,0 +1,205 @@
1
+ import type {
2
+ Address,
3
+ ContractCallerFunctions,
4
+ ContractCallStaticInput,
5
+ SignTypedDataContractCallerFn,
6
+ StaticContractCallerFn,
7
+ TransactionContractCallerFn,
8
+ } from '../../types';
9
+ import { assert, MarkOptional } from 'ts-essentials';
10
+
11
+ import type {
12
+ PublicActions,
13
+ WalletActions,
14
+ Hex,
15
+ BlockTag,
16
+ Chain,
17
+ Transport,
18
+ TypedDataDomain,
19
+ Account,
20
+ } from 'viem';
21
+ import { findPrimaryType } from './helpers';
22
+ import { TransactionParams } from '../../methods/swap/transaction';
23
+
24
+ export type MinViemClient = Partial<
25
+ Pick<PublicActions<Transport, Chain>, 'readContract'> &
26
+ Pick<WalletActions<Chain>, 'writeContract' | 'signTypedData'>
27
+ > & { account?: Account };
28
+
29
+ export const constructContractCaller = (
30
+ viemClient: MinViemClient,
31
+ account?: Address
32
+ ): ContractCallerFunctions<Hex> => {
33
+ const staticCall: StaticContractCallerFn = async <
34
+ T,
35
+ M extends string = string
36
+ >(
37
+ params: ContractCallStaticInput<M>
38
+ ): Promise<T> => {
39
+ assert(
40
+ viemClient.readContract,
41
+ 'Viem client must have readContract Public Action'
42
+ );
43
+ const { address, abi, contractMethod, args, overrides } = params;
44
+
45
+ const { block } = overrides;
46
+
47
+ const { blockNumber, blockTag } =
48
+ typeof block === 'number'
49
+ ? { blockNumber: BigInt(block) }
50
+ : { blockTag: block as BlockTag };
51
+
52
+ const result = viemClient.readContract({
53
+ account: viemClient.account || (account as Hex),
54
+ address: address as Hex,
55
+ abi,
56
+ functionName: contractMethod,
57
+ args,
58
+ blockTag,
59
+ blockNumber,
60
+ });
61
+
62
+ return result as T; // can't get specific type for generic abi & method
63
+ };
64
+
65
+ const transactCall: TransactionContractCallerFn<Hex> = async (params) => {
66
+ assert(account, 'account must be specified sign transactions');
67
+ assert(
68
+ viemClient.writeContract,
69
+ 'Viem client must have writeContract Wallet Action'
70
+ );
71
+
72
+ const { address, abi, contractMethod, args, overrides } = params;
73
+
74
+ const viemTxParams = txParamsToViemTxParams({
75
+ ...overrides,
76
+ to: address,
77
+ gas: overrides.gas?.toString(10),
78
+ value: overrides.value?.toString(10),
79
+ });
80
+
81
+ const gasPriceParams =
82
+ 'maxFeePerGas' in viemTxParams
83
+ ? {
84
+ maxFeePerGas: viemTxParams.maxFeePerGas,
85
+ maxPriorityFeePerGas: viemTxParams.maxPriorityFeePerGas,
86
+ }
87
+ : 'gasPrice' in viemTxParams
88
+ ? { gasPrice: viemTxParams.gasPrice }
89
+ : {};
90
+
91
+ const txHash = await viemClient.writeContract({
92
+ // either `viemClient` has account assigned to it,
93
+ // or the provider `viemClient` was created with must control `account` (viemClient.getAddresses()[0]===account);
94
+ // otherwise breaks with ` ProviderError: Unknown account 0x...`
95
+ account: viemClient.account || (account as Hex),
96
+ address: address as Hex,
97
+ abi,
98
+ functionName: contractMethod,
99
+ args: argsToViemArgs(args),
100
+ value: viemTxParams.value,
101
+ gas: viemTxParams.gas,
102
+ // ...viemTxParams,
103
+ // account: (overrides.from || account) as Hex,
104
+ nonce: overrides.nonce,
105
+ ...gasPriceParams,
106
+ });
107
+
108
+ return txHash;
109
+ };
110
+
111
+ const signTypedDataCall: SignTypedDataContractCallerFn = async (
112
+ typedData
113
+ ) => {
114
+ assert(account, 'account must be specified to create a signer');
115
+ assert(
116
+ viemClient.signTypedData,
117
+ 'Viem client must have signTypedData Wallet Action'
118
+ );
119
+
120
+ const { data, domain, types } = typedData;
121
+
122
+ const primaryType = findPrimaryType(types);
123
+
124
+ const chainId =
125
+ domain.chainId === undefined ? undefined : Number(domain.chainId);
126
+ const viemDomain: TypedDataDomain = {
127
+ chainId,
128
+ name: domain.name,
129
+ version: domain.version,
130
+ verifyingContract: domain.verifyingContract as Hex,
131
+ salt: domain.salt as Hex,
132
+ };
133
+
134
+ const signature = await viemClient.signTypedData({
135
+ // either `viemClient` has account assigned to it,
136
+ // or the provider `viemClient` was created with must control `account` (viemClient.getAddresses()[0]===account)
137
+ account: viemClient.account || (account as Hex),
138
+ domain: viemDomain,
139
+ types,
140
+ primaryType,
141
+ message: data,
142
+ });
143
+
144
+ return signature;
145
+ };
146
+
147
+ return { staticCall, transactCall, signTypedDataCall };
148
+ };
149
+
150
+ type ViemTxParams = {
151
+ to: Hex;
152
+ data?: Hex;
153
+ value?: bigint;
154
+ nonce?: number;
155
+ gas?: bigint;
156
+ } & (
157
+ | { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint }
158
+ | { gasPrice?: bigint }
159
+ );
160
+
161
+ export function txParamsToViemTxParams(
162
+ txParams: Omit<
163
+ MarkOptional<TransactionParams, 'data' | 'value'>,
164
+ 'chainId' | 'from'
165
+ >
166
+ ): ViemTxParams {
167
+ const gas = txParams.gas !== undefined ? BigInt(txParams.gas) : undefined;
168
+ const gasPrice =
169
+ txParams.gasPrice !== undefined ? BigInt(txParams.gasPrice) : undefined;
170
+ const maxFeePerGas =
171
+ txParams.maxFeePerGas !== undefined
172
+ ? BigInt(txParams.maxFeePerGas)
173
+ : undefined;
174
+ const maxPriorityFeePerGas =
175
+ txParams.maxPriorityFeePerGas !== undefined
176
+ ? BigInt(txParams.maxPriorityFeePerGas)
177
+ : undefined;
178
+
179
+ const viemTxParams = {
180
+ to: txParams.to as Hex,
181
+ data: txParams.data as Hex,
182
+ value: txParams.value !== undefined ? BigInt(txParams.value) : undefined,
183
+ gas,
184
+ ...(txParams.maxFeePerGas !== undefined
185
+ ? { maxFeePerGas, maxPriorityFeePerGas }
186
+ : { gasPrice }),
187
+ };
188
+ return viemTxParams;
189
+ }
190
+
191
+ function argsToViemArgs(args: any[]): any[] {
192
+ return args.map((arg) => {
193
+ if (typeof arg === 'string') {
194
+ if (arg.startsWith('0x')) {
195
+ return arg;
196
+ }
197
+ const asNumber = Number(arg);
198
+ if (Number.isNaN(asNumber)) {
199
+ return arg;
200
+ }
201
+ return BigInt(asNumber);
202
+ }
203
+ return arg;
204
+ });
205
+ }