@account-kit/smart-contracts 4.39.0 → 4.41.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/dist/esm/src/light-account/accounts/base.js +49 -31
- package/dist/esm/src/light-account/accounts/base.js.map +1 -1
- package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.d.ts +1 -1
- package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.js.map +1 -1
- package/dist/esm/src/ma-v2/account/nativeSMASigner.d.ts +3 -1
- package/dist/esm/src/ma-v2/account/nativeSMASigner.js +64 -38
- package/dist/esm/src/ma-v2/account/nativeSMASigner.js.map +1 -1
- package/dist/esm/src/ma-v2/modules/single-signer-validation/signer.d.ts +3 -1
- package/dist/esm/src/ma-v2/modules/single-signer-validation/signer.js +58 -39
- package/dist/esm/src/ma-v2/modules/single-signer-validation/signer.js.map +1 -1
- package/dist/esm/src/ma-v2/utils.d.ts +1 -0
- package/dist/esm/src/ma-v2/utils.js +3 -0
- package/dist/esm/src/ma-v2/utils.js.map +1 -1
- package/dist/esm/src/msca/plugins/multi-owner/signer.d.ts +3 -1
- package/dist/esm/src/msca/plugins/multi-owner/signer.js +33 -7
- package/dist/esm/src/msca/plugins/multi-owner/signer.js.map +1 -1
- package/dist/esm/src/msca/plugins/multisig/signer.d.ts +3 -1
- package/dist/esm/src/msca/plugins/multisig/signer.js +33 -7
- package/dist/esm/src/msca/plugins/multisig/signer.js.map +1 -1
- package/dist/types/src/light-account/accounts/base.d.ts.map +1 -1
- package/dist/types/src/ma-v2/account/common/modularAccountV2Base.d.ts +1 -1
- package/dist/types/src/ma-v2/account/common/modularAccountV2Base.d.ts.map +1 -1
- package/dist/types/src/ma-v2/account/nativeSMASigner.d.ts +3 -1
- package/dist/types/src/ma-v2/account/nativeSMASigner.d.ts.map +1 -1
- package/dist/types/src/ma-v2/modules/single-signer-validation/signer.d.ts +3 -1
- package/dist/types/src/ma-v2/modules/single-signer-validation/signer.d.ts.map +1 -1
- package/dist/types/src/ma-v2/utils.d.ts +1 -0
- package/dist/types/src/ma-v2/utils.d.ts.map +1 -1
- package/dist/types/src/msca/plugins/multi-owner/signer.d.ts +3 -1
- package/dist/types/src/msca/plugins/multi-owner/signer.d.ts.map +1 -1
- package/dist/types/src/msca/plugins/multisig/signer.d.ts +3 -1
- package/dist/types/src/msca/plugins/multisig/signer.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/light-account/accounts/base.ts +73 -44
- package/src/ma-v2/account/common/modularAccountV2Base.ts +2 -0
- package/src/ma-v2/account/nativeSMASigner.ts +87 -43
- package/src/ma-v2/modules/single-signer-validation/signer.ts +81 -44
- package/src/ma-v2/utils.ts +4 -0
- package/src/msca/plugins/multi-owner/signer.ts +47 -8
- package/src/msca/plugins/multisig/signer.ts +47 -8
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
type Address,
|
|
20
20
|
type Chain,
|
|
21
21
|
type Hex,
|
|
22
|
-
type SignTypedDataParameters,
|
|
23
22
|
type Transport,
|
|
23
|
+
type TypedData,
|
|
24
|
+
type TypedDataDefinition,
|
|
24
25
|
} from "viem";
|
|
25
26
|
import type {
|
|
26
27
|
LightAccountEntryPointVersion,
|
|
@@ -28,6 +29,7 @@ import type {
|
|
|
28
29
|
LightAccountVersion,
|
|
29
30
|
} from "../types.js";
|
|
30
31
|
import { AccountVersionRegistry } from "../utils.js";
|
|
32
|
+
import type { SignatureRequest } from "@aa-sdk/core";
|
|
31
33
|
|
|
32
34
|
enum SignatureType {
|
|
33
35
|
EOA = "0x00",
|
|
@@ -142,11 +144,11 @@ export async function createLightAccountBase<
|
|
|
142
144
|
});
|
|
143
145
|
};
|
|
144
146
|
|
|
145
|
-
const
|
|
147
|
+
const get1271Wrapper = (
|
|
146
148
|
hashedMessage: Hex,
|
|
147
149
|
version: string,
|
|
148
|
-
):
|
|
149
|
-
return
|
|
150
|
+
): TypedDataDefinition => {
|
|
151
|
+
return {
|
|
150
152
|
// EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)
|
|
151
153
|
// https://github.com/alchemyplatform/light-account/blob/main/src/LightAccount.sol#L236
|
|
152
154
|
domain: {
|
|
@@ -162,7 +164,45 @@ export async function createLightAccountBase<
|
|
|
162
164
|
message: hashedMessage,
|
|
163
165
|
},
|
|
164
166
|
primaryType: "LightAccountMessage",
|
|
165
|
-
}
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const prepareSign = async (
|
|
171
|
+
params: SignatureRequest,
|
|
172
|
+
): Promise<SignatureRequest> => {
|
|
173
|
+
const messageHash =
|
|
174
|
+
params.type === "personal_sign"
|
|
175
|
+
? hashMessage(params.data)
|
|
176
|
+
: hashTypedData(params.data);
|
|
177
|
+
|
|
178
|
+
switch (version as string) {
|
|
179
|
+
case "v1.0.1":
|
|
180
|
+
return params;
|
|
181
|
+
case "v1.0.2":
|
|
182
|
+
throw new Error(
|
|
183
|
+
`Version ${String(version)} of LightAccount doesn't support 1271`,
|
|
184
|
+
);
|
|
185
|
+
case "v1.1.0":
|
|
186
|
+
return {
|
|
187
|
+
type: "eth_signTypedData_v4",
|
|
188
|
+
data: get1271Wrapper(messageHash, "1"),
|
|
189
|
+
};
|
|
190
|
+
case "v2.0.0":
|
|
191
|
+
return {
|
|
192
|
+
type: "eth_signTypedData_v4",
|
|
193
|
+
data: get1271Wrapper(messageHash, "2"),
|
|
194
|
+
};
|
|
195
|
+
default:
|
|
196
|
+
throw new Error(`Unknown version ${String(version)} of LightAccount`);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const formatSign = async (
|
|
201
|
+
signature: `0x${string}`,
|
|
202
|
+
): Promise<`0x${string}`> => {
|
|
203
|
+
return version === "v2.0.0"
|
|
204
|
+
? concat([SignatureType.EOA, signature])
|
|
205
|
+
: signature;
|
|
166
206
|
};
|
|
167
207
|
|
|
168
208
|
const account = await toSmartContractAccount({
|
|
@@ -172,6 +212,8 @@ export async function createLightAccountBase<
|
|
|
172
212
|
accountAddress,
|
|
173
213
|
source: type,
|
|
174
214
|
getAccountInitCode,
|
|
215
|
+
prepareSign,
|
|
216
|
+
formatSign,
|
|
175
217
|
encodeExecute: async ({ target, data, value }) => {
|
|
176
218
|
return encodeFunctionData({
|
|
177
219
|
abi,
|
|
@@ -207,46 +249,33 @@ export async function createLightAccountBase<
|
|
|
207
249
|
}
|
|
208
250
|
},
|
|
209
251
|
async signMessage({ message }) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
);
|
|
222
|
-
// TODO: handle case where signer is an SCA.
|
|
223
|
-
return concat([SignatureType.EOA, signature]);
|
|
224
|
-
default:
|
|
225
|
-
throw new Error(`Unknown version ${type} of ${String(version)}`);
|
|
226
|
-
}
|
|
252
|
+
const { type, data } = await prepareSign({
|
|
253
|
+
type: "personal_sign",
|
|
254
|
+
data: message,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const sig =
|
|
258
|
+
type === "personal_sign"
|
|
259
|
+
? await signer.signMessage(data)
|
|
260
|
+
: await signer.signTypedData(data);
|
|
261
|
+
|
|
262
|
+
return formatSign(sig);
|
|
227
263
|
},
|
|
228
|
-
async signTypedData
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
"2",
|
|
244
|
-
);
|
|
245
|
-
// TODO: handle case where signer is an SCA.
|
|
246
|
-
return concat([SignatureType.EOA, signature]);
|
|
247
|
-
default:
|
|
248
|
-
throw new Error(`Unknown version ${String(version)} of LightAccount`);
|
|
249
|
-
}
|
|
264
|
+
async signTypedData<
|
|
265
|
+
const typedData extends TypedData | Record<string, unknown>,
|
|
266
|
+
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
|
|
267
|
+
>(params: TypedDataDefinition<typedData, primaryType>) {
|
|
268
|
+
const { type, data } = await prepareSign({
|
|
269
|
+
type: "eth_signTypedData_v4",
|
|
270
|
+
data: params as TypedDataDefinition,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const sig =
|
|
274
|
+
type === "personal_sign"
|
|
275
|
+
? await signer.signMessage(data)
|
|
276
|
+
: await signer.signTypedData(data);
|
|
277
|
+
|
|
278
|
+
return formatSign(sig);
|
|
250
279
|
},
|
|
251
280
|
getDummySignature: (): Hex => {
|
|
252
281
|
const signature =
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
SmartAccountSigner,
|
|
3
|
+
SigningMethods,
|
|
4
|
+
SignatureRequest,
|
|
5
|
+
} from "@aa-sdk/core";
|
|
2
6
|
import {
|
|
3
7
|
type Address,
|
|
4
8
|
type Chain,
|
|
@@ -11,13 +15,14 @@ import {
|
|
|
11
15
|
type TypedData,
|
|
12
16
|
type TypedDataDefinition,
|
|
13
17
|
} from "viem";
|
|
14
|
-
|
|
15
|
-
import { SignatureType } from "../modules/utils.js";
|
|
16
18
|
import {
|
|
17
|
-
DEFAULT_OWNER_ENTITY_ID,
|
|
18
|
-
pack1271Signature,
|
|
19
19
|
packUOSignature,
|
|
20
|
+
pack1271Signature,
|
|
21
|
+
DEFAULT_OWNER_ENTITY_ID,
|
|
22
|
+
assertNeverSignatureRequestType,
|
|
20
23
|
} from "../utils.js";
|
|
24
|
+
import { SignatureType } from "../modules/utils.js";
|
|
25
|
+
|
|
21
26
|
/**
|
|
22
27
|
* Creates an object with methods for generating a dummy signature, signing user operation hashes, signing messages, and signing typed data.
|
|
23
28
|
*
|
|
@@ -47,7 +52,60 @@ export const nativeSMASigner = (
|
|
|
47
52
|
accountAddress: Address,
|
|
48
53
|
deferredActionData?: Hex,
|
|
49
54
|
) => {
|
|
55
|
+
const signingMethods: SigningMethods = {
|
|
56
|
+
prepareSign: async (
|
|
57
|
+
request: SignatureRequest,
|
|
58
|
+
): Promise<SignatureRequest> => {
|
|
59
|
+
let hash;
|
|
60
|
+
|
|
61
|
+
switch (request.type) {
|
|
62
|
+
case "personal_sign":
|
|
63
|
+
hash = hashMessage(request.data);
|
|
64
|
+
break;
|
|
65
|
+
|
|
66
|
+
case "eth_signTypedData_v4":
|
|
67
|
+
const isDeferredAction =
|
|
68
|
+
request.data?.primaryType === "DeferredAction" &&
|
|
69
|
+
request.data?.domain?.verifyingContract === accountAddress;
|
|
70
|
+
|
|
71
|
+
if (isDeferredAction) {
|
|
72
|
+
return request;
|
|
73
|
+
} else {
|
|
74
|
+
hash = await hashTypedData(request.data);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
assertNeverSignatureRequestType();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
type: "eth_signTypedData_v4",
|
|
84
|
+
data: {
|
|
85
|
+
domain: {
|
|
86
|
+
chainId: Number(chain.id),
|
|
87
|
+
verifyingContract: accountAddress,
|
|
88
|
+
},
|
|
89
|
+
types: {
|
|
90
|
+
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
91
|
+
},
|
|
92
|
+
message: {
|
|
93
|
+
hash,
|
|
94
|
+
},
|
|
95
|
+
primaryType: "ReplaySafeHash",
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
formatSign: async (signature: Hex) => {
|
|
100
|
+
return pack1271Signature({
|
|
101
|
+
validationSignature: signature,
|
|
102
|
+
entityId: DEFAULT_OWNER_ENTITY_ID,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
50
107
|
return {
|
|
108
|
+
...signingMethods,
|
|
51
109
|
getDummySignature: (): Hex => {
|
|
52
110
|
const sig = packUOSignature({
|
|
53
111
|
// orderedHookData: [],
|
|
@@ -78,24 +136,18 @@ export const nativeSMASigner = (
|
|
|
78
136
|
|
|
79
137
|
// we apply the expected 1271 packing here since the account contract will expect it
|
|
80
138
|
async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
validationSignature: await signer.signTypedData({
|
|
85
|
-
domain: {
|
|
86
|
-
chainId: Number(chain.id),
|
|
87
|
-
verifyingContract: accountAddress,
|
|
88
|
-
},
|
|
89
|
-
types: {
|
|
90
|
-
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
91
|
-
},
|
|
92
|
-
message: {
|
|
93
|
-
hash,
|
|
94
|
-
},
|
|
95
|
-
primaryType: "ReplaySafeHash",
|
|
96
|
-
}),
|
|
97
|
-
entityId: DEFAULT_OWNER_ENTITY_ID,
|
|
139
|
+
const { type, data } = await signingMethods.prepareSign({
|
|
140
|
+
type: "personal_sign",
|
|
141
|
+
data: message,
|
|
98
142
|
});
|
|
143
|
+
|
|
144
|
+
if (type !== "eth_signTypedData_v4") {
|
|
145
|
+
throw new Error("Invalid signature request type");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const sig = await signer.signTypedData(data);
|
|
149
|
+
|
|
150
|
+
return signingMethods.formatSign(sig);
|
|
99
151
|
},
|
|
100
152
|
|
|
101
153
|
// TODO: maybe move "sign deferred actions" to a separate function?
|
|
@@ -106,7 +158,17 @@ export const nativeSMASigner = (
|
|
|
106
158
|
>(
|
|
107
159
|
typedDataDefinition: TypedDataDefinition<typedData, primaryType>,
|
|
108
160
|
): Promise<Hex> => {
|
|
109
|
-
|
|
161
|
+
const { type, data } = await signingMethods.prepareSign({
|
|
162
|
+
type: "eth_signTypedData_v4",
|
|
163
|
+
data: typedDataDefinition as TypedDataDefinition,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (type !== "eth_signTypedData_v4") {
|
|
167
|
+
throw new Error("Invalid signature request type");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const sig = await signer.signTypedData(data);
|
|
171
|
+
|
|
110
172
|
const isDeferredAction =
|
|
111
173
|
typedDataDefinition.primaryType === "DeferredAction" &&
|
|
112
174
|
typedDataDefinition.domain != null &&
|
|
@@ -115,26 +177,8 @@ export const nativeSMASigner = (
|
|
|
115
177
|
typedDataDefinition.domain.verifyingContract === accountAddress;
|
|
116
178
|
|
|
117
179
|
return isDeferredAction
|
|
118
|
-
? concat([
|
|
119
|
-
|
|
120
|
-
await signer.signTypedData(typedDataDefinition),
|
|
121
|
-
])
|
|
122
|
-
: pack1271Signature({
|
|
123
|
-
validationSignature: await signer.signTypedData({
|
|
124
|
-
domain: {
|
|
125
|
-
chainId: Number(chain.id),
|
|
126
|
-
verifyingContract: accountAddress,
|
|
127
|
-
},
|
|
128
|
-
types: {
|
|
129
|
-
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
130
|
-
},
|
|
131
|
-
message: {
|
|
132
|
-
hash: await hashTypedData(typedDataDefinition),
|
|
133
|
-
},
|
|
134
|
-
primaryType: "ReplaySafeHash",
|
|
135
|
-
}),
|
|
136
|
-
entityId: DEFAULT_OWNER_ENTITY_ID,
|
|
137
|
-
});
|
|
180
|
+
? concat([SignatureType.EOA, sig])
|
|
181
|
+
: signingMethods.formatSign(sig);
|
|
138
182
|
},
|
|
139
183
|
};
|
|
140
184
|
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
SmartAccountSigner,
|
|
3
|
+
SigningMethods,
|
|
4
|
+
SignatureRequest,
|
|
5
|
+
} from "@aa-sdk/core";
|
|
2
6
|
import {
|
|
3
7
|
type Address,
|
|
4
8
|
type Chain,
|
|
@@ -15,8 +19,12 @@ import {
|
|
|
15
19
|
getDefaultSingleSignerValidationModuleAddress,
|
|
16
20
|
SignatureType,
|
|
17
21
|
} from "../utils.js";
|
|
22
|
+
import {
|
|
23
|
+
packUOSignature,
|
|
24
|
+
pack1271Signature,
|
|
25
|
+
assertNeverSignatureRequestType,
|
|
26
|
+
} from "../../utils.js";
|
|
18
27
|
|
|
19
|
-
import { pack1271Signature, packUOSignature } from "../../utils.js";
|
|
20
28
|
/**
|
|
21
29
|
* Creates an object with methods for generating a dummy signature, signing user operation hashes, signing messages, and signing typed data.
|
|
22
30
|
*
|
|
@@ -49,7 +57,54 @@ export const singleSignerMessageSigner = (
|
|
|
49
57
|
entityId: number,
|
|
50
58
|
deferredActionData?: Hex,
|
|
51
59
|
) => {
|
|
60
|
+
const signingMethods: SigningMethods = {
|
|
61
|
+
prepareSign: async (
|
|
62
|
+
request: SignatureRequest,
|
|
63
|
+
): Promise<SignatureRequest> => {
|
|
64
|
+
let hash;
|
|
65
|
+
|
|
66
|
+
switch (request.type) {
|
|
67
|
+
case "personal_sign":
|
|
68
|
+
hash = hashMessage(request.data);
|
|
69
|
+
break;
|
|
70
|
+
|
|
71
|
+
case "eth_signTypedData_v4":
|
|
72
|
+
hash = await hashTypedData(request.data);
|
|
73
|
+
break;
|
|
74
|
+
|
|
75
|
+
default:
|
|
76
|
+
assertNeverSignatureRequestType();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
type: "eth_signTypedData_v4",
|
|
81
|
+
data: {
|
|
82
|
+
domain: {
|
|
83
|
+
chainId: Number(chain.id),
|
|
84
|
+
verifyingContract:
|
|
85
|
+
getDefaultSingleSignerValidationModuleAddress(chain),
|
|
86
|
+
salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
|
|
87
|
+
},
|
|
88
|
+
types: {
|
|
89
|
+
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
90
|
+
},
|
|
91
|
+
message: {
|
|
92
|
+
hash,
|
|
93
|
+
},
|
|
94
|
+
primaryType: "ReplaySafeHash",
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
formatSign: async (signature: Hex) => {
|
|
99
|
+
return pack1271Signature({
|
|
100
|
+
validationSignature: signature,
|
|
101
|
+
entityId,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
52
106
|
return {
|
|
107
|
+
...signingMethods,
|
|
53
108
|
getDummySignature: (): Hex => {
|
|
54
109
|
const sig = packUOSignature({
|
|
55
110
|
// orderedHookData: [],
|
|
@@ -80,26 +135,18 @@ export const singleSignerMessageSigner = (
|
|
|
80
135
|
|
|
81
136
|
// we apply the expected 1271 packing here since the account contract will expect it
|
|
82
137
|
async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
validationSignature: await signer.signTypedData({
|
|
87
|
-
domain: {
|
|
88
|
-
chainId: Number(chain.id),
|
|
89
|
-
verifyingContract:
|
|
90
|
-
getDefaultSingleSignerValidationModuleAddress(chain),
|
|
91
|
-
salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
|
|
92
|
-
},
|
|
93
|
-
types: {
|
|
94
|
-
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
95
|
-
},
|
|
96
|
-
message: {
|
|
97
|
-
hash,
|
|
98
|
-
},
|
|
99
|
-
primaryType: "ReplaySafeHash",
|
|
100
|
-
}),
|
|
101
|
-
entityId,
|
|
138
|
+
const { type, data } = await signingMethods.prepareSign({
|
|
139
|
+
type: "personal_sign",
|
|
140
|
+
data: message,
|
|
102
141
|
});
|
|
142
|
+
|
|
143
|
+
if (type !== "eth_signTypedData_v4") {
|
|
144
|
+
throw new Error("Invalid signature request type");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const sig = await signer.signTypedData(data);
|
|
148
|
+
|
|
149
|
+
return signingMethods.formatSign(sig);
|
|
103
150
|
},
|
|
104
151
|
|
|
105
152
|
// TODO: maybe move "sign deferred actions" to a separate function?
|
|
@@ -110,7 +157,17 @@ export const singleSignerMessageSigner = (
|
|
|
110
157
|
>(
|
|
111
158
|
typedDataDefinition: TypedDataDefinition<typedData, primaryType>,
|
|
112
159
|
): Promise<Hex> => {
|
|
113
|
-
|
|
160
|
+
const { type, data } = await signingMethods.prepareSign({
|
|
161
|
+
type: "eth_signTypedData_v4",
|
|
162
|
+
data: typedDataDefinition as TypedDataDefinition,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (type !== "eth_signTypedData_v4") {
|
|
166
|
+
throw new Error("Invalid signature request type");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const sig = await signer.signTypedData(data);
|
|
170
|
+
|
|
114
171
|
const isDeferredAction =
|
|
115
172
|
typedDataDefinition.primaryType === "DeferredAction" &&
|
|
116
173
|
typedDataDefinition.domain != null &&
|
|
@@ -118,29 +175,9 @@ export const singleSignerMessageSigner = (
|
|
|
118
175
|
"verifyingContract" in typedDataDefinition.domain &&
|
|
119
176
|
typedDataDefinition.domain.verifyingContract === accountAddress;
|
|
120
177
|
|
|
121
|
-
const validationSignature = await signer.signTypedData({
|
|
122
|
-
domain: {
|
|
123
|
-
chainId: Number(chain.id),
|
|
124
|
-
verifyingContract:
|
|
125
|
-
getDefaultSingleSignerValidationModuleAddress(chain),
|
|
126
|
-
salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
|
|
127
|
-
},
|
|
128
|
-
types: {
|
|
129
|
-
ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
|
|
130
|
-
},
|
|
131
|
-
message: {
|
|
132
|
-
hash: hashTypedData(typedDataDefinition),
|
|
133
|
-
},
|
|
134
|
-
primaryType: "ReplaySafeHash",
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// TODO: Handle non-EOA signer case
|
|
138
178
|
return isDeferredAction
|
|
139
|
-
? concat([SignatureType.EOA,
|
|
140
|
-
:
|
|
141
|
-
validationSignature,
|
|
142
|
-
entityId,
|
|
143
|
-
});
|
|
179
|
+
? concat([SignatureType.EOA, sig])
|
|
180
|
+
: signingMethods.formatSign(sig);
|
|
144
181
|
},
|
|
145
182
|
};
|
|
146
183
|
};
|
package/src/ma-v2/utils.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Address,
|
|
3
|
+
BundlerClient,
|
|
4
|
+
SmartAccountSigner,
|
|
5
|
+
SignatureRequest,
|
|
6
|
+
} from "@aa-sdk/core";
|
|
2
7
|
import {
|
|
3
8
|
hashMessage,
|
|
4
9
|
hashTypedData,
|
|
@@ -20,7 +25,7 @@ export const multiOwnerMessageSigner = <
|
|
|
20
25
|
signer: () => TSigner,
|
|
21
26
|
pluginAddress: Address = MultiOwnerPlugin.meta.addresses[client.chain.id],
|
|
22
27
|
) => {
|
|
23
|
-
const
|
|
28
|
+
const get712Wrapper = async (msg: Hash): Promise<TypedDataDefinition> => {
|
|
24
29
|
const [, name, version, chainId, verifyingContract, salt] =
|
|
25
30
|
await client.readContract({
|
|
26
31
|
abi: MultiOwnerPluginAbi,
|
|
@@ -29,7 +34,7 @@ export const multiOwnerMessageSigner = <
|
|
|
29
34
|
account: accountAddress,
|
|
30
35
|
});
|
|
31
36
|
|
|
32
|
-
return
|
|
37
|
+
return {
|
|
33
38
|
domain: {
|
|
34
39
|
chainId: Number(chainId),
|
|
35
40
|
name,
|
|
@@ -44,10 +49,32 @@ export const multiOwnerMessageSigner = <
|
|
|
44
49
|
message: msg,
|
|
45
50
|
},
|
|
46
51
|
primaryType: "AlchemyModularAccountMessage",
|
|
47
|
-
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const prepareSign = async (
|
|
56
|
+
params: SignatureRequest,
|
|
57
|
+
): Promise<SignatureRequest> => {
|
|
58
|
+
const data = await get712Wrapper(
|
|
59
|
+
params.type === "personal_sign"
|
|
60
|
+
? hashMessage(params.data)
|
|
61
|
+
: hashTypedData(params.data),
|
|
62
|
+
);
|
|
63
|
+
return {
|
|
64
|
+
type: "eth_signTypedData_v4",
|
|
65
|
+
data,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const formatSign = async (
|
|
70
|
+
signature: `0x${string}`,
|
|
71
|
+
): Promise<`0x${string}`> => {
|
|
72
|
+
return signature;
|
|
48
73
|
};
|
|
49
74
|
|
|
50
75
|
return {
|
|
76
|
+
prepareSign,
|
|
77
|
+
formatSign,
|
|
51
78
|
getDummySignature: (): Hex => {
|
|
52
79
|
return "0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c";
|
|
53
80
|
},
|
|
@@ -56,21 +83,33 @@ export const multiOwnerMessageSigner = <
|
|
|
56
83
|
return signer().signMessage({ raw: uoHash });
|
|
57
84
|
},
|
|
58
85
|
|
|
59
|
-
signMessage({
|
|
86
|
+
async signMessage({
|
|
60
87
|
message,
|
|
61
88
|
}: {
|
|
62
89
|
message: SignableMessage;
|
|
63
90
|
}): Promise<`0x${string}`> {
|
|
64
|
-
|
|
91
|
+
const { type, data } = await prepareSign({
|
|
92
|
+
type: "personal_sign",
|
|
93
|
+
data: message,
|
|
94
|
+
});
|
|
95
|
+
return type === "personal_sign"
|
|
96
|
+
? signer().signMessage(data)
|
|
97
|
+
: signer().signTypedData(data);
|
|
65
98
|
},
|
|
66
99
|
|
|
67
|
-
signTypedData: <
|
|
100
|
+
signTypedData: async <
|
|
68
101
|
const typedData extends TypedData | Record<string, unknown>,
|
|
69
102
|
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
|
|
70
103
|
>(
|
|
71
104
|
typedDataDefinition: TypedDataDefinition<typedData, primaryType>,
|
|
72
105
|
): Promise<Hex> => {
|
|
73
|
-
|
|
106
|
+
const { type, data } = await prepareSign({
|
|
107
|
+
type: "eth_signTypedData_v4",
|
|
108
|
+
data: typedDataDefinition as TypedDataDefinition,
|
|
109
|
+
});
|
|
110
|
+
return type === "personal_sign"
|
|
111
|
+
? signer().signMessage(data)
|
|
112
|
+
: signer().signTypedData(data);
|
|
74
113
|
},
|
|
75
114
|
};
|
|
76
115
|
};
|