@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.
- package/LICENSE +7 -0
- package/README.md +494 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/examples/customFetcher.d.ts +3 -0
- package/dist/examples/customFetcher.d.ts.map +1 -0
- package/dist/examples/delta.d.ts +2 -0
- package/dist/examples/delta.d.ts.map +1 -0
- package/dist/examples/ethersV6.d.ts +2 -0
- package/dist/examples/ethersV6.d.ts.map +1 -0
- package/dist/examples/limitOrders_all.d.ts +2 -0
- package/dist/examples/limitOrders_all.d.ts.map +1 -0
- package/dist/examples/limitOrders_partial.d.ts +2 -0
- package/dist/examples/limitOrders_partial.d.ts.map +1 -0
- package/dist/examples/limitOrders_postOrder.d.ts +2 -0
- package/dist/examples/limitOrders_postOrder.d.ts.map +1 -0
- package/dist/examples/partial.d.ts +2 -0
- package/dist/examples/partial.d.ts.map +1 -0
- package/dist/examples/quote.d.ts +2 -0
- package/dist/examples/quote.d.ts.map +1 -0
- package/dist/examples/sdk.d.ts +2 -0
- package/dist/examples/sdk.d.ts.map +1 -0
- package/dist/examples/simple.d.ts +2 -0
- package/dist/examples/simple.d.ts.map +1 -0
- package/dist/examples/simpleQuote.d.ts +2 -0
- package/dist/examples/simpleQuote.d.ts.map +1 -0
- package/dist/examples/viem.d.ts +2 -0
- package/dist/examples/viem.d.ts.map +1 -0
- package/dist/examples/wagmi.d.ts +43 -0
- package/dist/examples/wagmi.d.ts.map +1 -0
- package/dist/examples/web3.d.ts +2 -0
- package/dist/examples/web3.d.ts.map +1 -0
- package/dist/gas.d.ts +8 -0
- package/dist/gas.d.ts.map +1 -0
- package/dist/helpers/approve.d.ts +8 -0
- package/dist/helpers/approve.d.ts.map +1 -0
- package/dist/helpers/fetchers/axios.d.ts +5 -0
- package/dist/helpers/fetchers/axios.d.ts.map +1 -0
- package/dist/helpers/fetchers/fetch.d.ts +5 -0
- package/dist/helpers/fetchers/fetch.d.ts.map +1 -0
- package/dist/helpers/index.d.ts +13 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/misc.d.ts +48 -0
- package/dist/helpers/misc.d.ts.map +1 -0
- package/dist/helpers/providers/ethers.d.ts +10 -0
- package/dist/helpers/providers/ethers.d.ts.map +1 -0
- package/dist/helpers/providers/ethersV6.d.ts +8 -0
- package/dist/helpers/providers/ethersV6.d.ts.map +1 -0
- package/dist/helpers/providers/helpers.d.ts +3 -0
- package/dist/helpers/providers/helpers.d.ts.map +1 -0
- package/dist/helpers/providers/viem.d.ts +23 -0
- package/dist/helpers/providers/viem.d.ts.map +1 -0
- package/dist/helpers/providers/web3.d.ts +9 -0
- package/dist/helpers/providers/web3.d.ts.map +1 -0
- package/dist/helpers/token.d.ts +38 -0
- package/dist/helpers/token.d.ts.map +1 -0
- package/dist/index.d.ts +64 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/methods/common/orders/buildOrderData.d.ts +27 -0
- package/dist/methods/common/orders/buildOrderData.d.ts.map +1 -0
- package/dist/methods/common/orders/encoding.d.ts +23 -0
- package/dist/methods/common/orders/encoding.d.ts.map +1 -0
- package/dist/methods/common/orders/misc.d.ts +27 -0
- package/dist/methods/common/orders/misc.d.ts.map +1 -0
- package/dist/methods/common/orders/signature.d.ts +9 -0
- package/dist/methods/common/orders/signature.d.ts.map +1 -0
- package/dist/methods/common/orders/types.d.ts +8 -0
- package/dist/methods/common/orders/types.d.ts.map +1 -0
- package/dist/methods/delta/approveForDelta.d.ts +8 -0
- package/dist/methods/delta/approveForDelta.d.ts.map +1 -0
- package/dist/methods/delta/buildCrosschainOrderBridge.d.ts +23 -0
- package/dist/methods/delta/buildCrosschainOrderBridge.d.ts.map +1 -0
- package/dist/methods/delta/buildDeltaOrder.d.ts +49 -0
- package/dist/methods/delta/buildDeltaOrder.d.ts.map +1 -0
- package/dist/methods/delta/getBridgeInfo.d.ts +9 -0
- package/dist/methods/delta/getBridgeInfo.d.ts.map +1 -0
- package/dist/methods/delta/getDeltaContract.d.ts +9 -0
- package/dist/methods/delta/getDeltaContract.d.ts.map +1 -0
- package/dist/methods/delta/getDeltaOrders.d.ts +22 -0
- package/dist/methods/delta/getDeltaOrders.d.ts.map +1 -0
- package/dist/methods/delta/getDeltaPrice.d.ts +58 -0
- package/dist/methods/delta/getDeltaPrice.d.ts.map +1 -0
- package/dist/methods/delta/getMulticallHandlers.d.ts +9 -0
- package/dist/methods/delta/getMulticallHandlers.d.ts.map +1 -0
- package/dist/methods/delta/getPartnerFee.d.ts +16 -0
- package/dist/methods/delta/getPartnerFee.d.ts.map +1 -0
- package/dist/methods/delta/helpers/across.d.ts +22 -0
- package/dist/methods/delta/helpers/across.d.ts.map +1 -0
- package/dist/methods/delta/helpers/buildDeltaOrderData.d.ts +35 -0
- package/dist/methods/delta/helpers/buildDeltaOrderData.d.ts.map +1 -0
- package/dist/methods/delta/helpers/composePermit.d.ts +5 -0
- package/dist/methods/delta/helpers/composePermit.d.ts.map +1 -0
- package/dist/methods/delta/helpers/misc.d.ts +3 -0
- package/dist/methods/delta/helpers/misc.d.ts.map +1 -0
- package/dist/methods/delta/helpers/types.d.ts +96 -0
- package/dist/methods/delta/helpers/types.d.ts.map +1 -0
- package/dist/methods/delta/index.d.ts +28 -0
- package/dist/methods/delta/index.d.ts.map +1 -0
- package/dist/methods/delta/isTokenSupportedInDelta.d.ts +8 -0
- package/dist/methods/delta/isTokenSupportedInDelta.d.ts.map +1 -0
- package/dist/methods/delta/postDeltaOrder.d.ts +23 -0
- package/dist/methods/delta/postDeltaOrder.d.ts.map +1 -0
- package/dist/methods/delta/signDeltaOrder.d.ts +12 -0
- package/dist/methods/delta/signDeltaOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/approveForOrder.d.ts +12 -0
- package/dist/methods/limitOrders/approveForOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/buildOrder.d.ts +11 -0
- package/dist/methods/limitOrders/buildOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/cancelOrder.d.ts +9 -0
- package/dist/methods/limitOrders/cancelOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/fillOrderDirectly.d.ts +30 -0
- package/dist/methods/limitOrders/fillOrderDirectly.d.ts.map +1 -0
- package/dist/methods/limitOrders/getOrders.d.ts +39 -0
- package/dist/methods/limitOrders/getOrders.d.ts.map +1 -0
- package/dist/methods/limitOrders/getOrdersContract.d.ts +8 -0
- package/dist/methods/limitOrders/getOrdersContract.d.ts.map +1 -0
- package/dist/methods/limitOrders/helpers/buildOrderData.d.ts +43 -0
- package/dist/methods/limitOrders/helpers/buildOrderData.d.ts.map +1 -0
- package/dist/methods/limitOrders/helpers/misc.d.ts +9 -0
- package/dist/methods/limitOrders/helpers/misc.d.ts.map +1 -0
- package/dist/methods/limitOrders/helpers/types.d.ts +49 -0
- package/dist/methods/limitOrders/helpers/types.d.ts.map +1 -0
- package/dist/methods/limitOrders/index.d.ts +30 -0
- package/dist/methods/limitOrders/index.d.ts.map +1 -0
- package/dist/methods/limitOrders/postOrder.d.ts +10 -0
- package/dist/methods/limitOrders/postOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/signOrder.d.ts +7 -0
- package/dist/methods/limitOrders/signOrder.d.ts.map +1 -0
- package/dist/methods/limitOrders/transaction.d.ts +23 -0
- package/dist/methods/limitOrders/transaction.d.ts.map +1 -0
- package/dist/methods/nftOrders/approveForOrder.d.ts +12 -0
- package/dist/methods/nftOrders/approveForOrder.d.ts.map +1 -0
- package/dist/methods/nftOrders/buildOrder.d.ts +11 -0
- package/dist/methods/nftOrders/buildOrder.d.ts.map +1 -0
- package/dist/methods/nftOrders/cancelOrder.d.ts +8 -0
- package/dist/methods/nftOrders/cancelOrder.d.ts.map +1 -0
- package/dist/methods/nftOrders/getOrders.d.ts +18 -0
- package/dist/methods/nftOrders/getOrders.d.ts.map +1 -0
- package/dist/methods/nftOrders/getOrdersContract.d.ts +8 -0
- package/dist/methods/nftOrders/getOrdersContract.d.ts.map +1 -0
- package/dist/methods/nftOrders/helpers/buildOrderData.d.ts +52 -0
- package/dist/methods/nftOrders/helpers/buildOrderData.d.ts.map +1 -0
- package/dist/methods/nftOrders/helpers/misc.d.ts +13 -0
- package/dist/methods/nftOrders/helpers/misc.d.ts.map +1 -0
- package/dist/methods/nftOrders/helpers/types.d.ts +39 -0
- package/dist/methods/nftOrders/helpers/types.d.ts.map +1 -0
- package/dist/methods/nftOrders/index.d.ts +23 -0
- package/dist/methods/nftOrders/index.d.ts.map +1 -0
- package/dist/methods/nftOrders/postOrder.d.ts +10 -0
- package/dist/methods/nftOrders/postOrder.d.ts.map +1 -0
- package/dist/methods/nftOrders/signOrder.d.ts +7 -0
- package/dist/methods/nftOrders/signOrder.d.ts.map +1 -0
- package/dist/methods/nftOrders/transaction.d.ts +23 -0
- package/dist/methods/nftOrders/transaction.d.ts.map +1 -0
- package/dist/methods/quote/getQuote.d.ts +51 -0
- package/dist/methods/quote/getQuote.d.ts.map +1 -0
- package/dist/methods/swap/adapters.d.ts +8 -0
- package/dist/methods/swap/adapters.d.ts.map +1 -0
- package/dist/methods/swap/approve.d.ts +10 -0
- package/dist/methods/swap/approve.d.ts.map +1 -0
- package/dist/methods/swap/balance.d.ts +23 -0
- package/dist/methods/swap/balance.d.ts.map +1 -0
- package/dist/methods/swap/helpers/normalizeRateOptions.d.ts +12 -0
- package/dist/methods/swap/helpers/normalizeRateOptions.d.ts.map +1 -0
- package/dist/methods/swap/index.d.ts +13 -0
- package/dist/methods/swap/index.d.ts.map +1 -0
- package/dist/methods/swap/rates.d.ts +52 -0
- package/dist/methods/swap/rates.d.ts.map +1 -0
- package/dist/methods/swap/spender.d.ts +21 -0
- package/dist/methods/swap/spender.d.ts.map +1 -0
- package/dist/methods/swap/swapTx.d.ts +158 -0
- package/dist/methods/swap/swapTx.d.ts.map +1 -0
- package/dist/methods/swap/token.d.ts +8 -0
- package/dist/methods/swap/token.d.ts.map +1 -0
- package/dist/methods/swap/transaction.d.ts +115 -0
- package/dist/methods/swap/transaction.d.ts.map +1 -0
- package/dist/sdk/full.d.ts +17 -0
- package/dist/sdk/full.d.ts.map +1 -0
- package/dist/sdk/partial.d.ts +31 -0
- package/dist/sdk/partial.d.ts.map +1 -0
- package/dist/sdk/simple.d.ts +75 -0
- package/dist/sdk/simple.d.ts.map +1 -0
- package/dist/sdk.cjs.development.js +5182 -0
- package/dist/sdk.cjs.development.js.map +1 -0
- package/dist/sdk.cjs.production.min.js +2 -0
- package/dist/sdk.cjs.production.min.js.map +1 -0
- package/dist/sdk.esm.js +5102 -0
- package/dist/sdk.esm.js.map +1 -0
- package/dist/types.d.ts +161 -0
- package/dist/types.d.ts.map +1 -0
- package/docs/DELTA.md +207 -0
- package/package.json +126 -0
- package/src/constants.ts +16 -0
- package/src/examples/customFetcher.ts +44 -0
- package/src/examples/delta.ts +127 -0
- package/src/examples/ethersV6.ts +38 -0
- package/src/examples/limitOrders_all.ts +135 -0
- package/src/examples/limitOrders_partial.ts +171 -0
- package/src/examples/limitOrders_postOrder.ts +77 -0
- package/src/examples/partial.ts +34 -0
- package/src/examples/quote.ts +205 -0
- package/src/examples/sdk.ts +39 -0
- package/src/examples/simple.ts +44 -0
- package/src/examples/simpleQuote.ts +98 -0
- package/src/examples/viem.ts +120 -0
- package/src/examples/wagmi.ts +68 -0
- package/src/examples/web3.ts +32 -0
- package/src/gas.ts +7 -0
- package/src/helpers/approve.ts +60 -0
- package/src/helpers/fetchers/axios.ts +34 -0
- package/src/helpers/fetchers/fetch.ts +67 -0
- package/src/helpers/index.ts +27 -0
- package/src/helpers/misc.ts +160 -0
- package/src/helpers/providers/ethers.ts +192 -0
- package/src/helpers/providers/ethersV6.ts +121 -0
- package/src/helpers/providers/helpers.ts +36 -0
- package/src/helpers/providers/viem.ts +205 -0
- package/src/helpers/providers/web3.ts +154 -0
- package/src/helpers/token.ts +75 -0
- package/src/index.ts +425 -0
- package/src/methods/common/orders/buildOrderData.ts +29 -0
- package/src/methods/common/orders/encoding.ts +216 -0
- package/src/methods/common/orders/misc.ts +86 -0
- package/src/methods/common/orders/signature.ts +68 -0
- package/src/methods/common/orders/types.ts +13 -0
- package/src/methods/delta/approveForDelta.ts +38 -0
- package/src/methods/delta/buildCrosschainOrderBridge.ts +84 -0
- package/src/methods/delta/buildDeltaOrder.ts +192 -0
- package/src/methods/delta/getBridgeInfo.ts +38 -0
- package/src/methods/delta/getDeltaContract.ts +29 -0
- package/src/methods/delta/getDeltaOrders.ts +102 -0
- package/src/methods/delta/getDeltaPrice.ts +122 -0
- package/src/methods/delta/getMulticallHandlers.ts +44 -0
- package/src/methods/delta/getPartnerFee.ts +58 -0
- package/src/methods/delta/helpers/across.ts +255 -0
- package/src/methods/delta/helpers/buildDeltaOrderData.ts +153 -0
- package/src/methods/delta/helpers/composePermit.ts +76 -0
- package/src/methods/delta/helpers/misc.ts +32 -0
- package/src/methods/delta/helpers/types.ts +110 -0
- package/src/methods/delta/index.ts +146 -0
- package/src/methods/delta/isTokenSupportedInDelta.ts +54 -0
- package/src/methods/delta/postDeltaOrder.ts +50 -0
- package/src/methods/delta/signDeltaOrder.ts +41 -0
- package/src/methods/limitOrders/approveForOrder.ts +36 -0
- package/src/methods/limitOrders/buildOrder.ts +56 -0
- package/src/methods/limitOrders/cancelOrder.ts +111 -0
- package/src/methods/limitOrders/fillOrderDirectly.ts +277 -0
- package/src/methods/limitOrders/getOrders.ts +151 -0
- package/src/methods/limitOrders/getOrdersContract.ts +20 -0
- package/src/methods/limitOrders/helpers/buildOrderData.ts +121 -0
- package/src/methods/limitOrders/helpers/misc.ts +64 -0
- package/src/methods/limitOrders/helpers/types.ts +70 -0
- package/src/methods/limitOrders/index.ts +154 -0
- package/src/methods/limitOrders/postOrder.ts +74 -0
- package/src/methods/limitOrders/signOrder.ts +29 -0
- package/src/methods/limitOrders/transaction.ts +231 -0
- package/src/methods/nftOrders/approveForOrder.ts +79 -0
- package/src/methods/nftOrders/buildOrder.ts +52 -0
- package/src/methods/nftOrders/cancelOrder.ts +23 -0
- package/src/methods/nftOrders/getOrders.ts +84 -0
- package/src/methods/nftOrders/getOrdersContract.ts +24 -0
- package/src/methods/nftOrders/helpers/buildOrderData.ts +131 -0
- package/src/methods/nftOrders/helpers/misc.ts +92 -0
- package/src/methods/nftOrders/helpers/types.ts +50 -0
- package/src/methods/nftOrders/index.ts +139 -0
- package/src/methods/nftOrders/postOrder.ts +71 -0
- package/src/methods/nftOrders/signOrder.ts +29 -0
- package/src/methods/nftOrders/transaction.ts +234 -0
- package/src/methods/quote/getQuote.ts +131 -0
- package/src/methods/swap/adapters.ts +49 -0
- package/src/methods/swap/approve.ts +51 -0
- package/src/methods/swap/balance.ts +147 -0
- package/src/methods/swap/helpers/normalizeRateOptions.ts +55 -0
- package/src/methods/swap/index.ts +38 -0
- package/src/methods/swap/rates.ts +276 -0
- package/src/methods/swap/spender.ts +76 -0
- package/src/methods/swap/swapTx.ts +266 -0
- package/src/methods/swap/token.ts +35 -0
- package/src/methods/swap/transaction.ts +310 -0
- package/src/sdk/full.ts +54 -0
- package/src/sdk/partial.ts +107 -0
- package/src/sdk/simple.ts +429 -0
- 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
|
+
}
|