@agoric/portfolio-api 0.1.1-dev-d1bb9cd.0.d1bb9cd → 0.1.1-dev-304c8cb.0.304c8cb
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/package.json +4 -4
- package/src/evm-wallet/eip712-messages.d.ts +1 -1
- package/src/evm-wallet/eip712-messages.d.ts.map +1 -1
- package/src/evm-wallet/eip712-messages.js +23 -12
- package/src/evm-wallet/message-handler-helpers.d.ts +31 -8
- package/src/evm-wallet/message-handler-helpers.d.ts.map +1 -1
- package/src/evm-wallet/message-handler-helpers.js +224 -57
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/portfolio-api",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-304c8cb.0.304c8cb",
|
|
4
4
|
"description": "API for Portfolio management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"generate:ymax-machine": "npx tsx scripts/gen-ymax-machine.mts"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@agoric/internal": "0.3.3-dev-
|
|
31
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
30
|
+
"@agoric/internal": "0.3.3-dev-304c8cb.0.304c8cb",
|
|
31
|
+
"@agoric/orchestration": "0.1.1-dev-304c8cb.0.304c8cb",
|
|
32
32
|
"@endo/common": "^1.2.13",
|
|
33
33
|
"@endo/errors": "^1.2.13",
|
|
34
34
|
"@endo/patterns": "^1.7.0"
|
|
@@ -69,5 +69,5 @@
|
|
|
69
69
|
"engines": {
|
|
70
70
|
"node": "^20.9 || ^22.11"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "304c8cbe29fa2aa182050d213d7e489b91d126e2"
|
|
73
73
|
}
|
|
@@ -200,7 +200,7 @@ export type YmaxStandaloneOperationData<T extends OperationTypeNames = Operation
|
|
|
200
200
|
export type YmaxPermitWitnessTransferFromData<T extends OperationTypeNames = OperationTypeNames> = ReturnType<typeof getPermitWitnessTransferFromData<YmaxWitnessTypes<T>, YmaxWitnessTypeParam<T>>>;
|
|
201
201
|
export type YmaxPermitBatchWitnessTransferFromData<T extends OperationTypeNames = OperationTypeNames> = ReturnType<typeof getPermitBatchWitnessTransferFromData<YmaxWitnessTypes<T>, YmaxWitnessTypeParam<T>>>;
|
|
202
202
|
export declare function validateYmaxDomainBase(domain: TypedDataDomain): asserts domain is typeof YmaxStandaloneDomainBase;
|
|
203
|
-
export declare function validateYmaxDomain(domain: TypedDataDomain, validContractAddresses?: Record<number | string, Address
|
|
203
|
+
export declare function validateYmaxDomain(domain: TypedDataDomain, validContractAddresses?: Partial<Record<number | string, Address>> | undefined): asserts domain is YmaxFullDomain;
|
|
204
204
|
export declare function validateYmaxOperationTypeName<T extends OperationTypeNames>(typeName: string): asserts typeName is T;
|
|
205
205
|
export declare const splitWitnessFieldType: <T extends OperationTypeNames>(fieldName: `${typeof YMAX_DOMAIN_NAME}V${typeof YMAX_DOMAIN_VERSION}${T}`) => {
|
|
206
206
|
domain: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eip712-messages.d.ts","sourceRoot":"","sources":["eip712-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,OAAO,EAEP,eAAe,EACf,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"eip712-messages.d.ts","sourceRoot":"","sources":["eip712-messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
;
|
|
20
|
+
|
|
22
21
|
import {
|
|
23
22
|
|
|
24
23
|
|
|
@@ -26,6 +25,7 @@ import {
|
|
|
26
25
|
makeWitness,
|
|
27
26
|
TokenPermissionsComponents,
|
|
28
27
|
} from '@agoric/orchestration/src/utils/permit2.js';
|
|
28
|
+
import { sameEvmAddress } from '@agoric/orchestration/src/utils/address.js';
|
|
29
29
|
|
|
30
30
|
const YMAX_DOMAIN_NAME = 'Ymax';
|
|
31
31
|
const YMAX_DOMAIN_VERSION = '1';
|
|
@@ -295,26 +295,37 @@ export function validateYmaxDomainBase(
|
|
|
295
295
|
|
|
296
296
|
export function validateYmaxDomain(
|
|
297
297
|
domain ,
|
|
298
|
-
validContractAddresses
|
|
298
|
+
validContractAddresses
|
|
299
|
+
|
|
300
|
+
,
|
|
299
301
|
) {
|
|
300
302
|
const baseDomain = domain;
|
|
301
303
|
validateYmaxDomainBase(baseDomain);
|
|
302
304
|
|
|
303
|
-
|
|
305
|
+
if (
|
|
306
|
+
typeof domain.chainId !== 'bigint' ||
|
|
307
|
+
domain.verifyingContract === undefined
|
|
308
|
+
) {
|
|
309
|
+
throw new Error(`Ymax domain must include chain ID and verifying contract`);
|
|
310
|
+
}
|
|
304
311
|
|
|
305
312
|
if (validContractAddresses) {
|
|
306
313
|
const chainIdStr = String(domain.chainId);
|
|
307
314
|
|
|
308
|
-
chainIdStr in validContractAddresses
|
|
309
|
-
|
|
315
|
+
if (!(chainIdStr in validContractAddresses)) {
|
|
316
|
+
throw new Error(`Unknown chain ID in Ymax domain: ${domain.chainId}`);
|
|
317
|
+
}
|
|
310
318
|
|
|
311
|
-
|
|
312
|
-
|
|
319
|
+
if (
|
|
320
|
+
!sameEvmAddress(
|
|
313
321
|
domain.verifyingContract,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
322
|
+
validContractAddresses[chainIdStr],
|
|
323
|
+
)
|
|
324
|
+
) {
|
|
325
|
+
throw new Error(
|
|
326
|
+
`Invalid verifying contract for chain ID ${domain.chainId}: ${domain.verifyingContract} (expected ${validContractAddresses[chainIdStr]})`,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
318
329
|
}
|
|
319
330
|
|
|
320
331
|
// XXX: check no extra fields?
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* The viem runtime dependency is expected as a power to make this usable both
|
|
6
6
|
* on chain and in off-chain services.
|
|
7
7
|
*/
|
|
8
|
-
import type { AbiParameterToPrimitiveType, Address
|
|
8
|
+
import type { AbiParameterToPrimitiveType, Address } from 'abitype';
|
|
9
|
+
import type { getTypesForEIP712Domain } from 'viem';
|
|
9
10
|
import type { hashStruct, isHex, recoverTypedDataAddress, validateTypedData } from 'viem/utils';
|
|
10
|
-
import { encodeType,
|
|
11
|
-
import { type PermitWitnessTransferFromInputComponents } from '@agoric/orchestration/src/utils/permit2.js';
|
|
11
|
+
import type { encodeType, WithSignature } from '@agoric/orchestration/src/utils/viem.js';
|
|
12
|
+
import { type Permit2Domain, type PermitWitnessTransferFromInputComponents } from '@agoric/orchestration/src/utils/permit2.js';
|
|
12
13
|
import { type OperationTypeNames, type YmaxStandaloneOperationData, type YmaxPermitWitnessTransferFromData, type YmaxOperationType, type YmaxFullDomain } from './eip712-messages.js';
|
|
13
14
|
export type YmaxOperationDetails<T extends OperationTypeNames = OperationTypeNames> = {
|
|
14
15
|
[P in T]: {
|
|
@@ -22,7 +23,7 @@ export type PermitWitnessTransferFromPayload = AbiParameterToPrimitiveType<{
|
|
|
22
23
|
components: typeof PermitWitnessTransferFromInputComponents;
|
|
23
24
|
}>;
|
|
24
25
|
export type PermitDetails = {
|
|
25
|
-
chainId:
|
|
26
|
+
chainId: bigint;
|
|
26
27
|
token: Address;
|
|
27
28
|
amount: bigint;
|
|
28
29
|
spender: Address;
|
|
@@ -45,10 +46,32 @@ export declare const makeEVMHandlerUtils: (viemUtils: {
|
|
|
45
46
|
recoverTypedDataAddress: typeof recoverTypedDataAddress;
|
|
46
47
|
validateTypedData: typeof validateTypedData;
|
|
47
48
|
encodeType: typeof encodeType;
|
|
49
|
+
getTypesForEIP712Domain: typeof getTypesForEIP712Domain;
|
|
48
50
|
}) => {
|
|
49
|
-
extractOperationDetailsFromStandaloneData: <T extends OperationTypeNames>(data: YmaxStandaloneOperationData<T>,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
extractOperationDetailsFromStandaloneData: <T extends OperationTypeNames>(data: Omit<YmaxStandaloneOperationData<T>, "domain"> & {
|
|
52
|
+
domain: YmaxFullDomain;
|
|
53
|
+
}, validContractAddresses?: undefined) => YmaxOperationDetails<T>;
|
|
54
|
+
extractOperationDetailsFromPermit2WitnessData: <T extends OperationTypeNames>(data: Omit<YmaxPermitWitnessTransferFromData<T>, "domain"> & {
|
|
55
|
+
domain: Permit2Domain;
|
|
56
|
+
}) => YmaxOperationDetails<T>;
|
|
57
|
+
extractPermitDetails: {
|
|
58
|
+
<T extends OperationTypeNames>(data: Omit<YmaxPermitWitnessTransferFromData<T>, "domain"> & {
|
|
59
|
+
domain: Permit2Domain;
|
|
60
|
+
address: Address;
|
|
61
|
+
signature: WithSignature<object>["signature"];
|
|
62
|
+
}): PermitDetails;
|
|
63
|
+
<T extends OperationTypeNames>(data: Omit<YmaxPermitWitnessTransferFromData<T>, "domain"> & {
|
|
64
|
+
domain: Permit2Domain;
|
|
65
|
+
}, owner: Address, signature: WithSignature<object>["signature"]): PermitDetails;
|
|
66
|
+
};
|
|
67
|
+
extractOperationDetailsFromDataWithAddress: <T extends OperationTypeNames = "Withdraw" | "Deposit" | "Rebalance" | "OpenPortfolio" | "SetTargetAllocation">(data: (WithSignature<YmaxPermitWitnessTransferFromData<T>> | YmaxStandaloneOperationData<T>) & {
|
|
68
|
+
address: Address;
|
|
69
|
+
}, contractAddresses?: {
|
|
70
|
+
permit2?: Partial<Record<number | string, Address>>;
|
|
71
|
+
ymaxRepresentative?: Partial<Record<number | string, Address>>;
|
|
72
|
+
}) => FullMessageDetails<T>;
|
|
73
|
+
extractOperationDetailsFromSignedData: <T extends OperationTypeNames = "Withdraw" | "Deposit" | "Rebalance" | "OpenPortfolio" | "SetTargetAllocation">(signedData: WithSignature<YmaxPermitWitnessTransferFromData<T> | YmaxStandaloneOperationData<T>> & {
|
|
74
|
+
address?: Address;
|
|
75
|
+
}, validYmaxRepresentativeContractAddresses?: Partial<Record<number | string, Address>>) => Promise<FullMessageDetails<T>>;
|
|
53
76
|
};
|
|
54
77
|
//# sourceMappingURL=message-handler-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-handler-helpers.d.ts","sourceRoot":"","sources":["message-handler-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"message-handler-helpers.d.ts","sourceRoot":"","sources":["message-handler-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,11 +6,8 @@
|
|
|
6
6
|
* on chain and in off-chain services.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
|
|
10
|
+
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
|
|
@@ -18,14 +15,18 @@
|
|
|
18
15
|
|
|
19
16
|
|
|
20
17
|
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
import { sameEvmAddress } from '@agoric/orchestration/src/utils/address.js';
|
|
19
|
+
;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
25
23
|
import {
|
|
26
24
|
extractWitnessFieldFromTypes,
|
|
27
25
|
isPermit2MessageType,
|
|
28
26
|
makeWitnessTypeStringExtractor,
|
|
27
|
+
validatePermit2Domain,
|
|
28
|
+
validateTokenPermissionsType,
|
|
29
|
+
|
|
29
30
|
|
|
30
31
|
} from '@agoric/orchestration/src/utils/permit2.js';
|
|
31
32
|
import {
|
|
@@ -56,7 +57,7 @@ import {
|
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
;
|
|
59
|
-
|
|
60
|
+
|
|
60
61
|
|
|
61
62
|
|
|
62
63
|
|
|
@@ -83,6 +84,7 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
83
84
|
|
|
84
85
|
|
|
85
86
|
|
|
87
|
+
|
|
86
88
|
) => {
|
|
87
89
|
const {
|
|
88
90
|
isHex,
|
|
@@ -90,35 +92,59 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
90
92
|
recoverTypedDataAddress,
|
|
91
93
|
validateTypedData,
|
|
92
94
|
encodeType,
|
|
95
|
+
getTypesForEIP712Domain,
|
|
93
96
|
} = viemUtils;
|
|
94
97
|
|
|
98
|
+
for (const util of [
|
|
99
|
+
isHex,
|
|
100
|
+
hashStruct,
|
|
101
|
+
recoverTypedDataAddress,
|
|
102
|
+
validateTypedData,
|
|
103
|
+
encodeType,
|
|
104
|
+
getTypesForEIP712Domain,
|
|
105
|
+
]) {
|
|
106
|
+
if (typeof util !== 'function') {
|
|
107
|
+
throw new Error(`Expected viemUtils.${util} to be a function`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
95
111
|
const getPermit2WitnessTypeString = makeWitnessTypeStringExtractor({
|
|
96
112
|
encodeType,
|
|
97
113
|
});
|
|
98
114
|
|
|
99
115
|
/**
|
|
100
|
-
* Extract operation type name and data from an EIP-712 standalone Ymax typed data
|
|
116
|
+
* Extract operation type name and data from an EIP-712 standalone Ymax typed data.
|
|
117
|
+
* Validates that the message data satisfies the expected types for the operation,
|
|
118
|
+
* but does not validate that the supplied data types exactly match the expected
|
|
119
|
+
* types. In particular the message data may be a superset of the expected types,
|
|
120
|
+
* and extra fields are included in the returned extracted details.
|
|
121
|
+
*
|
|
122
|
+
* Assumes the domain has the expected shape of a Ymax domain.
|
|
101
123
|
*
|
|
102
124
|
* @param data - The EIP-712 typed data of a standalone message
|
|
103
|
-
* @param validContractAddresses - *Deprecated*
|
|
104
125
|
* @returns The operation type name and associated data
|
|
105
126
|
*/
|
|
106
127
|
const extractOperationDetailsFromStandaloneData = (
|
|
107
128
|
|
|
108
129
|
|
|
109
|
-
data
|
|
110
|
-
|
|
130
|
+
data
|
|
131
|
+
|
|
132
|
+
,
|
|
133
|
+
validContractAddresses ,
|
|
111
134
|
) => {
|
|
112
|
-
|
|
113
|
-
const standaloneData = data;
|
|
135
|
+
const { domain, ...standaloneData } = data;
|
|
114
136
|
|
|
115
|
-
|
|
137
|
+
if (validContractAddresses) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
'Contract address validation expected to be validated separately',
|
|
140
|
+
);
|
|
141
|
+
}
|
|
116
142
|
|
|
117
|
-
validateYmaxDomain(domain, validContractAddresses);
|
|
118
143
|
validateYmaxOperationTypeName (standaloneData.primaryType);
|
|
119
144
|
|
|
120
145
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
121
|
-
const { nonce, deadline, ..._operationData } =
|
|
146
|
+
const { nonce, deadline, ..._operationData } =
|
|
147
|
+
standaloneData.message ;
|
|
122
148
|
const operationData = _operationData ;
|
|
123
149
|
const operation = standaloneData.primaryType;
|
|
124
150
|
// @ts-expect-error inference issue
|
|
@@ -132,6 +158,14 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
132
158
|
|
|
133
159
|
/**
|
|
134
160
|
* Extract operation type name and data from an EIP-712 Permit2 witness typed data.
|
|
161
|
+
* Validates that the supplied types exactly match types of a permit2 message.
|
|
162
|
+
* Validates that the witness data satisfies the expected types for the operation,
|
|
163
|
+
* but does not validate that the supplied data types exactly match the expected
|
|
164
|
+
* types. In particular the witness data may be a superset of the expected types,
|
|
165
|
+
* and extra fields are included in the returned witness data.
|
|
166
|
+
*
|
|
167
|
+
* Assumes the message has already been validated against the types from the data.
|
|
168
|
+
* Assumes the domain has the expected shape of a permit2 domain.
|
|
135
169
|
*
|
|
136
170
|
* @param data - The EIP-712 typed data of a Permit2 witness message
|
|
137
171
|
* @returns The operation type name and associated data
|
|
@@ -139,7 +173,9 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
139
173
|
const extractOperationDetailsFromPermit2WitnessData = (
|
|
140
174
|
|
|
141
175
|
|
|
142
|
-
data
|
|
176
|
+
data
|
|
177
|
+
|
|
178
|
+
,
|
|
143
179
|
) => {
|
|
144
180
|
// @ts-expect-error generic/union type compatibility
|
|
145
181
|
const permitData = data;
|
|
@@ -149,8 +185,10 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
149
185
|
witnessField.name
|
|
150
186
|
] ;
|
|
151
187
|
const { primaryType, domain } = splitWitnessFieldType(witnessField.type);
|
|
152
|
-
const chainId = BigInt(
|
|
188
|
+
const chainId = BigInt(data.domain.chainId);
|
|
153
189
|
const operation = primaryType ;
|
|
190
|
+
|
|
191
|
+
// Validates the witness data satisfies the expected types for the operation
|
|
154
192
|
// @ts-expect-error inference issue
|
|
155
193
|
validateTypedData({
|
|
156
194
|
types: getYmaxOperationTypes(operation),
|
|
@@ -165,9 +203,32 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
165
203
|
};
|
|
166
204
|
};
|
|
167
205
|
|
|
206
|
+
;
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
168
223
|
/**
|
|
169
224
|
* Extract the data that can be used as partial arguments to permit2's
|
|
170
|
-
* permitWitnessTransferFrom
|
|
225
|
+
* `permitWitnessTransferFrom`.
|
|
226
|
+
* Validates that the supplied types exactly match types of a permit2 message.
|
|
227
|
+
* Does not validate any part of the witness data, uses the supplied types to
|
|
228
|
+
* compute the witness data hash.
|
|
229
|
+
*
|
|
230
|
+
* Assumes the message has already been validated against the types from the data.
|
|
231
|
+
* Assumes the domain has the expected shape of a permit2 domain.
|
|
171
232
|
*
|
|
172
233
|
* This does not verify the signature; that is expected to be done by the caller.
|
|
173
234
|
*
|
|
@@ -175,11 +236,17 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
175
236
|
* @param owner address of the permit2 message signer
|
|
176
237
|
* @param signature signature of the permit2 message
|
|
177
238
|
*/
|
|
178
|
-
const extractPermitDetails
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
239
|
+
const extractPermitDetails = (
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
data
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
,
|
|
247
|
+
owner = data.address,
|
|
248
|
+
signature = data.signature,
|
|
249
|
+
) => {
|
|
183
250
|
// @ts-expect-error generic/union type compatibility
|
|
184
251
|
const permitData = data;
|
|
185
252
|
|
|
@@ -187,7 +254,14 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
187
254
|
throw new Error(`Invalid signature format: ${signature}`);
|
|
188
255
|
}
|
|
189
256
|
|
|
257
|
+
if (!owner) {
|
|
258
|
+
throw new Error(`Missing owner address`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Validates the permit2 related types are correct
|
|
190
262
|
const witnessField = extractWitnessFieldFromTypes(permitData.types);
|
|
263
|
+
validateTokenPermissionsType(permitData.types);
|
|
264
|
+
|
|
191
265
|
const { [witnessField.name]: witnessData, ...permit } = permitData.message;
|
|
192
266
|
const witness = hashStruct({
|
|
193
267
|
primaryType: witnessField.type,
|
|
@@ -209,8 +283,10 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
209
283
|
signature,
|
|
210
284
|
};
|
|
211
285
|
|
|
286
|
+
const chainId = BigInt(data.domain.chainId);
|
|
287
|
+
|
|
212
288
|
const details = {
|
|
213
|
-
chainId
|
|
289
|
+
chainId,
|
|
214
290
|
token: permit.permitted.token,
|
|
215
291
|
amount: permit.permitted.amount,
|
|
216
292
|
permit2Payload,
|
|
@@ -224,37 +300,80 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
224
300
|
* Extract all details sufficient to handle any EIP-712 portfolio message,
|
|
225
301
|
* optionally with permit data.
|
|
226
302
|
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
303
|
+
* This does not verify the signature of permit2 based messages; that is
|
|
304
|
+
* expected to be done by the caller.
|
|
305
|
+
*
|
|
306
|
+
* Validates the domain of the typed data, and optionally the verifying
|
|
307
|
+
* contract and spender against the provided contract addresses.
|
|
308
|
+
*
|
|
309
|
+
* @param data The operation data with an `address` field of the signing owner.
|
|
310
|
+
* @param contractAddresses Optionally, a set of valid contract addresses to validate against
|
|
311
|
+
* @param contractAddresses.permit2 If provided, validates a permit2 based message's verifying contract
|
|
312
|
+
* @param contractAddresses.standalone If provided, validates a standalone message's verifying contract or permit2 spender
|
|
229
313
|
*/
|
|
230
|
-
const
|
|
314
|
+
const extractOperationDetailsFromDataWithAddress = (
|
|
231
315
|
|
|
232
316
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
317
|
+
data
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
,
|
|
321
|
+
contractAddresses
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
= {},
|
|
325
|
+
) => {
|
|
326
|
+
const {
|
|
327
|
+
address: tokenOwner,
|
|
328
|
+
domain,
|
|
329
|
+
...otherData
|
|
330
|
+
} = data
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
;
|
|
334
|
+
const { nonce, deadline } = otherData.message;
|
|
246
335
|
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
336
|
+
if (!domain) {
|
|
337
|
+
throw new Error(`Missing domain in typed data`);
|
|
338
|
+
}
|
|
339
|
+
validateTypedData({
|
|
340
|
+
...otherData,
|
|
341
|
+
// @ts-expect-error inference issue
|
|
342
|
+
domain,
|
|
343
|
+
types: {
|
|
344
|
+
...otherData.types,
|
|
345
|
+
// Do not trust the type definitions coming from the message for the domain
|
|
346
|
+
EIP712Domain: getTypesForEIP712Domain({ domain }),
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
if (isPermit2MessageType(data.primaryType)) {
|
|
351
|
+
const { signature, ...permit2Data } = otherData
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
;
|
|
355
|
+
|
|
356
|
+
validatePermit2Domain(domain, contractAddresses.permit2);
|
|
357
|
+
const permit2DataWithDomain = { ...permit2Data, domain };
|
|
250
358
|
|
|
359
|
+
// Validates the permit2 related types are correct
|
|
251
360
|
const permitDetails = extractPermitDetails(
|
|
252
|
-
|
|
361
|
+
permit2DataWithDomain,
|
|
253
362
|
tokenOwner,
|
|
254
|
-
|
|
363
|
+
signature,
|
|
255
364
|
);
|
|
256
|
-
|
|
257
|
-
|
|
365
|
+
// Validates the witness data satisfies the expected types for the operation
|
|
366
|
+
const operationDetails = extractOperationDetailsFromPermit2WitnessData(
|
|
367
|
+
permit2DataWithDomain,
|
|
368
|
+
);
|
|
369
|
+
// If we have standalone representative addresses, validate the extracted
|
|
370
|
+
// spender against them.
|
|
371
|
+
if (contractAddresses.ymaxRepresentative) {
|
|
372
|
+
validateYmaxDomain(
|
|
373
|
+
operationDetails.domain,
|
|
374
|
+
contractAddresses.ymaxRepresentative,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
258
377
|
|
|
259
378
|
return {
|
|
260
379
|
...operationDetails,
|
|
@@ -264,12 +383,17 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
264
383
|
deadline,
|
|
265
384
|
};
|
|
266
385
|
} else {
|
|
267
|
-
const standaloneData =
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
);
|
|
386
|
+
const standaloneData = otherData
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
;
|
|
390
|
+
|
|
391
|
+
validateYmaxDomain(domain, contractAddresses.ymaxRepresentative);
|
|
392
|
+
|
|
393
|
+
const operationDetails = extractOperationDetailsFromStandaloneData({
|
|
394
|
+
...standaloneData,
|
|
395
|
+
domain,
|
|
396
|
+
});
|
|
273
397
|
|
|
274
398
|
return {
|
|
275
399
|
...operationDetails,
|
|
@@ -280,10 +404,53 @@ export const makeEVMHandlerUtils = (viemUtils
|
|
|
280
404
|
}
|
|
281
405
|
};
|
|
282
406
|
|
|
407
|
+
/**
|
|
408
|
+
* Extract all details sufficient to handle any EIP-712 portfolio message,
|
|
409
|
+
* optionally with permit data.
|
|
410
|
+
*
|
|
411
|
+
* This expects an ECDSA signature and recovers the signer address from it.
|
|
412
|
+
* If an address field is present, the recovered address must match the
|
|
413
|
+
* provided address.
|
|
414
|
+
*
|
|
415
|
+
* @deprecated Use `extractOperationDetailsFromDataWithAddress` instead,
|
|
416
|
+
* performing signature verification separately.
|
|
417
|
+
*
|
|
418
|
+
* @param signedData
|
|
419
|
+
* @param validYmaxRepresentativeContractAddresses
|
|
420
|
+
*/
|
|
421
|
+
const extractOperationDetailsFromSignedData = async (
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
signedData
|
|
425
|
+
|
|
426
|
+
,
|
|
427
|
+
validYmaxRepresentativeContractAddresses
|
|
428
|
+
|
|
429
|
+
,
|
|
430
|
+
) => {
|
|
431
|
+
const tokenOwner = await recoverTypedDataAddress(
|
|
432
|
+
signedData ,
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
if (signedData.address && !sameEvmAddress(tokenOwner, signedData.address)) {
|
|
436
|
+
throw new Error(
|
|
437
|
+
`Recovered address does not match provided address ${signedData.address}`,
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return extractOperationDetailsFromDataWithAddress(
|
|
442
|
+
{ ...signedData, address: tokenOwner },
|
|
443
|
+
{
|
|
444
|
+
ymaxRepresentative: validYmaxRepresentativeContractAddresses,
|
|
445
|
+
},
|
|
446
|
+
);
|
|
447
|
+
};
|
|
448
|
+
|
|
283
449
|
return {
|
|
284
450
|
extractOperationDetailsFromStandaloneData,
|
|
285
451
|
extractOperationDetailsFromPermit2WitnessData,
|
|
286
452
|
extractPermitDetails,
|
|
453
|
+
extractOperationDetailsFromDataWithAddress,
|
|
287
454
|
extractOperationDetailsFromSignedData,
|
|
288
455
|
};
|
|
289
456
|
};
|