-
-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathsignDelegation.ts
More file actions
134 lines (125 loc) · 3.35 KB
/
Copy pathsignDelegation.ts
File metadata and controls
134 lines (125 loc) · 3.35 KB
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
import type {
Account,
Address,
Chain,
Client,
Hex,
Transport,
WalletClient,
} from 'viem';
import { BaseError } from 'viem';
import { parseAccount } from 'viem/accounts';
import { prepareSignDelegationTypedData } from '../delegation';
import type { Delegation } from '../types';
export type SignDelegationParameters = {
/** Account to sign with */
account?: Account | Address;
/** The delegation to sign */
delegation: Omit<Delegation, 'signature'>;
/** The address of the delegation manager contract */
delegationManager: Address;
/** The chain ID for the signature */
chainId: number;
/** The name of the contract */
name?: string;
/** The version of the contract */
version?: string;
/** Whether to allow insecure unrestricted delegation */
allowInsecureUnrestrictedDelegation?: boolean;
};
export type SignDelegationReturnType = Hex;
/**
* Signs a delegation using a wallet client.
* @param client - The wallet client to use for signing.
* @param parameters - The parameters for signing the delegation.
* @returns The signature of the delegation.
* @example
* ```ts
* const signature = await signDelegation(walletClient, {
* delegation: {
* delegate: '0x...',
* delegator: '0x...',
* authority: '0x...',
* caveats: [],
* salt: '0x'
* },
* delegationManager: '0x...',
* chainId: 1
* });
* ```
*/
export async function signDelegation<
TChain extends Chain | undefined,
TAccount extends Account | undefined,
>(
client: Client<Transport, TChain, TAccount> & {
signTypedData: WalletClient['signTypedData'];
},
parameters: SignDelegationParameters,
): Promise<SignDelegationReturnType> {
const {
account: accountParam = client.account,
delegation,
delegationManager,
chainId,
name = 'DelegationManager',
version = '1',
allowInsecureUnrestrictedDelegation = false,
} = parameters;
if (!accountParam) {
throw new BaseError('Account not found. Please provide an account.');
}
const account = parseAccount(accountParam);
const typedData = prepareSignDelegationTypedData({
delegation,
delegationManager,
chainId,
name,
version,
allowInsecureUnrestrictedDelegation,
});
return client.signTypedData({
account,
...typedData,
});
}
/**
* Creates a sign delegation action that can be used to extend a wallet client.
* @returns A function that can be used with wallet client extend method.
* @example
* ```ts
* const walletClient = createWalletClient({
* chain: mainnet,
* transport: http()
* }).extend(signDelegationActions());
* ```
*/
export function signDelegationActions() {
return <
TChain extends Chain | undefined,
TAccount extends Account | undefined,
>(
client: Client<Transport, TChain, TAccount> & {
signTypedData: WalletClient['signTypedData'];
},
) => ({
signDelegation: async (
parameters: Omit<SignDelegationParameters, 'chainId'> & {
chainId?: number;
},
) =>
signDelegation(client, {
chainId:
parameters.chainId ??
(() => {
if (!client.chain?.id) {
throw new BaseError(
'Chain ID is required. Either provide it in parameters or configure the client with a chain.',
);
}
return client.chain.id;
})(),
...parameters,
}),
});
}