This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 56
/
keyHelpers.ts
151 lines (133 loc) Β· 4.85 KB
/
keyHelpers.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { Provider } from '@ethersproject/providers';
import { BaseContract, Event, Signer } from 'ethers';
import { Result } from 'ethers/lib/utils';
import { QueryClient } from 'react-query';
import { invariant } from 'ts-invariant';
import { isValidEthersAdaptor } from '~~/functions';
import { TEthersAdaptor, TEthersProvider, TEthersProviderOrSigner, TypedEvent } from '~~/models';
export type TRequiredKeys = {
namespace: string;
key: string;
};
export type TKeyTypes = {
provider?: string;
adaptor?: string;
contract?: string;
contractFunc?: string;
};
/**
* Get a react-query query key fo ethers provider
* @param providerOrSigner
* @returns
*/
export const providerKey = (
providerOrSigner: TEthersProviderOrSigner | undefined
): Record<'provider' | 'signer', string> => {
if (providerOrSigner == null) return { provider: 'undefined provider', signer: 'undefined signer' };
if (Provider.isProvider(providerOrSigner)) {
const provider = providerOrSigner as TEthersProvider;
return {
provider: `${provider?.network?.chainId}_${provider?.network?.name}_${provider?.connection.url.substring(0, 25)}`,
signer: 'isProvider',
};
} else {
const provider = (providerOrSigner as Signer).provider as TEthersProvider;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const signerStr: string = (providerOrSigner as any)?.address ?? '';
if (provider && provider?.network && Signer.isSigner(providerOrSigner)) {
return {
signer: `isSigner_${providerOrSigner._isSigner}_${signerStr}`,
provider: `${provider?.network?.chainId}_${provider?.network?.name}_${provider?.connection.url.substring(
0,
25
)}`,
};
}
}
return { provider: 'unknown provider', signer: 'unknown signer' };
};
/**
* Get a react-query query key
* @param adaptor
* @returns
*/
export const adaptorKey = (adaptor: TEthersAdaptor | undefined): Partial<Record<'adaptor' | 'provider', string>> => {
if (adaptor == null && !isValidEthersAdaptor(adaptor)) return { adaptor: 'undefined adaptor' };
if (adaptor?.signer != null && adaptor.account != null && adaptor.provider != null) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
return { adaptor: `${adaptor.chainId?.toString()}_${adaptor?.account}_${providerKey(adaptor?.provider ?? '')}` };
} else if (adaptor?.provider) {
return providerKey(adaptor?.provider);
}
return { adaptor: 'unknown adaptor' };
};
/**
* Get a react-query query key
* @param m
* @returns
*/
export const eventKey = (m: Event | TypedEvent<Result>): string => {
return `${m.transactionHash}_${m.logIndex}`;
};
/**
* Get a react-query query key
* @param contract
* @returns
*/
export const contractKey = (contract: BaseContract | undefined): Partial<Record<'contract' | 'provider', string>> => {
if (contract == null) return { contract: 'undefined contract' };
const address = contract.address;
const provider = providerKey(contract.provider as TEthersProvider | undefined);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const signerStr: string = (contract.signer as any)?.address ?? '';
const fragments = contract.interface.fragments
.map((m) => m.name)
.reduce((oldValue, current) => {
let newValue = oldValue;
if (newValue == null) {
newValue = '';
}
newValue += `${current},`;
return newValue;
}, '');
return { contract: `${address}_${signerStr}_${fragments}`, ...provider };
};
/**
* Get a react-query query key
* @param contract
* @param func
* @returns
*/
export const contractFuncKey = (
contract: BaseContract | undefined,
func: ((...args: any[]) => Promise<any>) | undefined
): Record<'contractFunc', string> => {
if (contract == null || func == null) return { contractFunc: 'undefined contract or contractFunc' };
let methodName: string | undefined = undefined;
Object.getOwnPropertyNames(contract).forEach((prop) => {
// @ts-expect-error
if (contract[prop] === func) {
methodName = prop;
}
});
if (methodName !== null) {
return { contractFunc: methodName ?? 'unknown contractFunc', ...contractKey(contract) };
}
return { contractFunc: 'unknown contractFunc', ...contractKey(contract) };
};
export const invalidateCache = (
queryClient: QueryClient,
namespace: string,
otherKeys: TKeyTypes & { key?: string } = {},
variables: Record<string, any> = {}
): void => {
void queryClient?.invalidateQueries?.([{ namespace, ...otherKeys }, variables]);
};
export const logQueryCache = (
queryClient: QueryClient,
namespace: string,
otherKeys: TKeyTypes & { key?: string } = {},
variables: Record<string, any> = {}
): void => {
invariant.log(queryClient.getQueriesData([{ namespace, ...otherKeys }, variables]));
};