@agoric/portfolio-api 0.2.0 → 0.2.1-upgrade-23-dev-bd79330.0.bd79330
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 +26 -28
- package/src/constants.d.ts +115 -0
- package/src/constants.d.ts.map +1 -0
- package/src/constants.js +170 -13
- package/src/evm/types.d.ts +19 -0
- package/src/evm/types.d.ts.map +1 -0
- package/src/evm/types.js +27 -0
- package/src/evm-wallet/eip712-messages.d.ts +213 -0
- package/src/evm-wallet/eip712-messages.d.ts.map +1 -0
- package/src/evm-wallet/eip712-messages.js +355 -0
- package/src/evm-wallet/message-handler-helpers.d.ts +54 -0
- package/src/evm-wallet/message-handler-helpers.d.ts.map +1 -0
- package/src/evm-wallet/message-handler-helpers.js +289 -0
- package/src/instruments.d.ts +54 -0
- package/src/instruments.d.ts.map +1 -0
- package/src/instruments.js +69 -0
- package/src/main.d.ts +6 -0
- package/src/main.d.ts.map +1 -0
- package/src/main.js +6 -1
- package/src/model/generated/ymax-machine.d.ts +71 -0
- package/src/model/generated/ymax-machine.d.ts.map +1 -0
- package/src/model/generated/ymax-machine.js +1292 -0
- package/src/model/ymax-machine.mmd +56 -0
- package/src/model/ymax-machine.schema.json +180 -0
- package/src/model/ymax-machine.yaml +942 -0
- package/src/portfolio-constants.d.ts +44 -0
- package/src/portfolio-constants.d.ts.map +1 -0
- package/src/portfolio-constants.js +80 -0
- package/src/resolver.d.ts +159 -0
- package/src/resolver.d.ts.map +1 -0
- package/src/resolver.js +115 -0
- package/src/type-guards.d.ts +39 -0
- package/src/type-guards.d.ts.map +1 -0
- package/src/type-guards.js +71 -0
- package/src/types.d.ts +296 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.js +337 -0
- package/src/types.ts +0 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Portfolio operations are either in a permit2 witness or standalone,
|
|
3
|
+
* in either case, following EIP-712
|
|
4
|
+
*
|
|
5
|
+
* The fields included in the operation differ based on which way they're submitted.
|
|
6
|
+
* In the wrapped case, we don't want to repeat stuff from the permit envelope.
|
|
7
|
+
* {@link OperationTypes}
|
|
8
|
+
*
|
|
9
|
+
* Currently all types and helpers are built around a hard-coded Ymax product
|
|
10
|
+
* name but with some effort this could be parametrizable
|
|
11
|
+
*/
|
|
12
|
+
import type { Address, TypedDataDomain, TypedDataToPrimitiveTypes } from 'abitype';
|
|
13
|
+
import type { TypedDataDefinition } from 'viem';
|
|
14
|
+
import type { TypedDataParameter } from '@agoric/orchestration/src/utils/abitype.js';
|
|
15
|
+
import { type Witness, type getPermitWitnessTransferFromData, type getPermitBatchWitnessTransferFromData } from '@agoric/orchestration/src/utils/permit2.js';
|
|
16
|
+
declare const YMAX_DOMAIN_NAME = "Ymax";
|
|
17
|
+
declare const YMAX_DOMAIN_VERSION = "1";
|
|
18
|
+
declare const StandaloneDomainTypeParams: [{
|
|
19
|
+
readonly name: "name";
|
|
20
|
+
readonly type: "string";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "version";
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "chainId";
|
|
26
|
+
readonly type: "uint256";
|
|
27
|
+
}, {
|
|
28
|
+
readonly name: "verifyingContract";
|
|
29
|
+
readonly type: "address";
|
|
30
|
+
}];
|
|
31
|
+
declare const YmaxStandaloneDomainBase: {
|
|
32
|
+
readonly name: "Ymax";
|
|
33
|
+
readonly version: "1";
|
|
34
|
+
};
|
|
35
|
+
export type YmaxFullDomain = typeof YmaxStandaloneDomainBase & {
|
|
36
|
+
chainId: bigint;
|
|
37
|
+
verifyingContract: Address;
|
|
38
|
+
};
|
|
39
|
+
declare const SharedPortfolioTypeParams: [];
|
|
40
|
+
/**
|
|
41
|
+
* Fields included in Permit data that we don't want duplicated in witness data,
|
|
42
|
+
* so only included in standalone typed data.
|
|
43
|
+
*/
|
|
44
|
+
declare const PortfolioStandaloneTypeParams: [{
|
|
45
|
+
readonly name: "nonce";
|
|
46
|
+
readonly type: "uint256";
|
|
47
|
+
}, {
|
|
48
|
+
readonly name: "deadline";
|
|
49
|
+
readonly type: "uint256";
|
|
50
|
+
}];
|
|
51
|
+
/**
|
|
52
|
+
* The set of portfolio operations supported by EVM Wallets, and their associated params
|
|
53
|
+
*/
|
|
54
|
+
declare const OperationTypes: {
|
|
55
|
+
readonly OpenPortfolio: readonly [{
|
|
56
|
+
readonly name: "allocations";
|
|
57
|
+
readonly type: "Allocation[]";
|
|
58
|
+
}];
|
|
59
|
+
readonly Rebalance: readonly [{
|
|
60
|
+
readonly name: "portfolio";
|
|
61
|
+
readonly type: "uint256";
|
|
62
|
+
}];
|
|
63
|
+
readonly SetTargetAllocation: readonly [{
|
|
64
|
+
readonly name: "allocations";
|
|
65
|
+
readonly type: "Allocation[]";
|
|
66
|
+
}, {
|
|
67
|
+
readonly name: "portfolio";
|
|
68
|
+
readonly type: "uint256";
|
|
69
|
+
}];
|
|
70
|
+
readonly Deposit: readonly [{
|
|
71
|
+
readonly name: "portfolio";
|
|
72
|
+
readonly type: "uint256";
|
|
73
|
+
}];
|
|
74
|
+
/**
|
|
75
|
+
* Withdraw funds from a portfolio to the source EVM account.
|
|
76
|
+
* The signer of the message must match the portfolio's source EVM account
|
|
77
|
+
* The destination chain is determined from the domain info (chainId).
|
|
78
|
+
* - token: ERC-20 token contract address (must be USDC contract on the destination chain)
|
|
79
|
+
*/
|
|
80
|
+
readonly Withdraw: readonly [{
|
|
81
|
+
readonly name: "withdraw";
|
|
82
|
+
readonly type: "Asset";
|
|
83
|
+
}, {
|
|
84
|
+
readonly name: "portfolio";
|
|
85
|
+
readonly type: "uint256";
|
|
86
|
+
}];
|
|
87
|
+
};
|
|
88
|
+
type OperationTypes = typeof OperationTypes;
|
|
89
|
+
export type OperationTypeNames = keyof OperationTypes;
|
|
90
|
+
declare const OperationSubTypes: {
|
|
91
|
+
readonly Allocation: readonly [{
|
|
92
|
+
readonly name: "instrument";
|
|
93
|
+
readonly type: "string";
|
|
94
|
+
}, {
|
|
95
|
+
readonly name: "portion";
|
|
96
|
+
readonly type: "uint256";
|
|
97
|
+
}];
|
|
98
|
+
readonly Asset: [{
|
|
99
|
+
readonly name: "token";
|
|
100
|
+
readonly type: "address";
|
|
101
|
+
}, {
|
|
102
|
+
readonly name: "amount";
|
|
103
|
+
readonly type: "uint256";
|
|
104
|
+
}];
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Target allocation for portfolio positions.
|
|
108
|
+
* Uses 'portion' (not 'basisPoints') to allow flexible ratios.
|
|
109
|
+
* The denominator is implicitly the sum of all portions.
|
|
110
|
+
*
|
|
111
|
+
* Examples:
|
|
112
|
+
* - [{instrument: 'A', portion: 60}, {instrument: 'B', portion: 40}] => 60:40 ratio
|
|
113
|
+
* - [{instrument: 'A', portion: 6}, {instrument: 'B', portion: 4}] => 6:4 ratio (same as 60:40)
|
|
114
|
+
*/
|
|
115
|
+
export type TargetAllocation = TypedDataToPrimitiveTypes<typeof OperationSubTypes>['Allocation'];
|
|
116
|
+
/**
|
|
117
|
+
* In the wrapped case, the domain is fixed by permit2, so we can't choose name/version there.
|
|
118
|
+
* so we put the ymax-specifc domain name and version in the type name.
|
|
119
|
+
*/
|
|
120
|
+
declare const getYmaxWitnessTypeName: <T extends OperationTypeNames>(operation: T) => `YmaxV1${T}`;
|
|
121
|
+
type YmaxWitnessTypeName<T extends OperationTypeNames> = ReturnType<typeof getYmaxWitnessTypeName<T>>;
|
|
122
|
+
declare const getYmaxWitnessFieldName: <T extends OperationTypeNames>(operation: T) => `ymax${T}`;
|
|
123
|
+
type YmaxWitnessFieldName<T extends OperationTypeNames> = ReturnType<typeof getYmaxWitnessFieldName<T>>;
|
|
124
|
+
export type YmaxWitnessTypeParam<T extends OperationTypeNames = OperationTypeNames> = TypedDataParameter<YmaxWitnessFieldName<T>, Extract<keyof YmaxWitnessOperationTypes<T>, string>>;
|
|
125
|
+
type YmaxWitnessOperationTypes<T extends OperationTypeNames = OperationTypeNames> = {
|
|
126
|
+
[K in T as YmaxWitnessTypeName<K>]: [
|
|
127
|
+
...OperationTypes[K],
|
|
128
|
+
...typeof SharedPortfolioTypeParams
|
|
129
|
+
];
|
|
130
|
+
};
|
|
131
|
+
type YmaxWitnessTypes<T extends OperationTypeNames = OperationTypeNames> = YmaxWitnessOperationTypes<T> & typeof OperationSubTypes;
|
|
132
|
+
type YmaxStandaloneOperationTypes<T extends OperationTypeNames = OperationTypeNames> = {
|
|
133
|
+
[K in T]: [
|
|
134
|
+
...OperationTypes[K],
|
|
135
|
+
...typeof SharedPortfolioTypeParams,
|
|
136
|
+
...typeof PortfolioStandaloneTypeParams
|
|
137
|
+
];
|
|
138
|
+
};
|
|
139
|
+
type YmaxStandaloneTypes<T extends OperationTypeNames = OperationTypeNames> = YmaxStandaloneOperationTypes<T> & typeof OperationSubTypes & {
|
|
140
|
+
EIP712Domain: typeof StandaloneDomainTypeParams;
|
|
141
|
+
};
|
|
142
|
+
export type YmaxOperationType<T extends OperationTypeNames> = TypedDataToPrimitiveTypes<OperationTypes & typeof OperationSubTypes>[T];
|
|
143
|
+
type YmaxWitnessData<T extends OperationTypeNames> = TypedDataToPrimitiveTypes<YmaxWitnessTypes<T>>[YmaxWitnessTypeParam<T>['type']];
|
|
144
|
+
type YmaxStandaloneData<T extends OperationTypeNames> = TypedDataToPrimitiveTypes<YmaxStandaloneTypes<T>>[T];
|
|
145
|
+
export declare const getYmaxOperationTypes: <T extends OperationTypeNames>(operation: T) => { [K in T]: {
|
|
146
|
+
readonly OpenPortfolio: readonly [{
|
|
147
|
+
readonly name: "allocations";
|
|
148
|
+
readonly type: "Allocation[]";
|
|
149
|
+
}];
|
|
150
|
+
readonly Rebalance: readonly [{
|
|
151
|
+
readonly name: "portfolio";
|
|
152
|
+
readonly type: "uint256";
|
|
153
|
+
}];
|
|
154
|
+
readonly SetTargetAllocation: readonly [{
|
|
155
|
+
readonly name: "allocations";
|
|
156
|
+
readonly type: "Allocation[]";
|
|
157
|
+
}, {
|
|
158
|
+
readonly name: "portfolio";
|
|
159
|
+
readonly type: "uint256";
|
|
160
|
+
}];
|
|
161
|
+
readonly Deposit: readonly [{
|
|
162
|
+
readonly name: "portfolio";
|
|
163
|
+
readonly type: "uint256";
|
|
164
|
+
}];
|
|
165
|
+
/**
|
|
166
|
+
* Withdraw funds from a portfolio to the source EVM account.
|
|
167
|
+
* The signer of the message must match the portfolio's source EVM account
|
|
168
|
+
* The destination chain is determined from the domain info (chainId).
|
|
169
|
+
* - token: ERC-20 token contract address (must be USDC contract on the destination chain)
|
|
170
|
+
*/
|
|
171
|
+
readonly Withdraw: readonly [{
|
|
172
|
+
readonly name: "withdraw";
|
|
173
|
+
readonly type: "Asset";
|
|
174
|
+
}, {
|
|
175
|
+
readonly name: "portfolio";
|
|
176
|
+
readonly type: "uint256";
|
|
177
|
+
}];
|
|
178
|
+
}[K]; } & {
|
|
179
|
+
readonly Allocation: readonly [{
|
|
180
|
+
readonly name: "instrument";
|
|
181
|
+
readonly type: "string";
|
|
182
|
+
}, {
|
|
183
|
+
readonly name: "portion";
|
|
184
|
+
readonly type: "uint256";
|
|
185
|
+
}];
|
|
186
|
+
readonly Asset: [{
|
|
187
|
+
readonly name: "token";
|
|
188
|
+
readonly type: "address";
|
|
189
|
+
}, {
|
|
190
|
+
readonly name: "amount";
|
|
191
|
+
readonly type: "uint256";
|
|
192
|
+
}];
|
|
193
|
+
};
|
|
194
|
+
export declare const getYmaxWitness: <T extends OperationTypeNames>(operation: T, data: NoInfer<YmaxWitnessData<T>>) => Witness<YmaxWitnessTypes<T>, YmaxWitnessTypeParam<T>>;
|
|
195
|
+
export declare const getYmaxStandaloneDomain: (chainId: bigint | number, verifyingContract: Address) => YmaxFullDomain;
|
|
196
|
+
export declare const getYmaxStandaloneOperationData: <T extends OperationTypeNames>(data: NoInfer<YmaxStandaloneData<T>>, operation: T, chainId: bigint | number, verifyingContract: Address) => TypedDataDefinition<YmaxStandaloneTypes<T>, T, T> & {
|
|
197
|
+
domain: YmaxFullDomain;
|
|
198
|
+
};
|
|
199
|
+
export type YmaxStandaloneOperationData<T extends OperationTypeNames = OperationTypeNames> = ReturnType<typeof getYmaxStandaloneOperationData<T>>;
|
|
200
|
+
export type YmaxPermitWitnessTransferFromData<T extends OperationTypeNames = OperationTypeNames> = ReturnType<typeof getPermitWitnessTransferFromData<YmaxWitnessTypes<T>, YmaxWitnessTypeParam<T>>>;
|
|
201
|
+
export type YmaxPermitBatchWitnessTransferFromData<T extends OperationTypeNames = OperationTypeNames> = ReturnType<typeof getPermitBatchWitnessTransferFromData<YmaxWitnessTypes<T>, YmaxWitnessTypeParam<T>>>;
|
|
202
|
+
export declare function validateYmaxDomainBase(domain: TypedDataDomain): asserts domain is typeof YmaxStandaloneDomainBase;
|
|
203
|
+
export declare function validateYmaxDomain(domain: TypedDataDomain, validContractAddresses?: Record<number | string, Address> | undefined): asserts domain is YmaxFullDomain;
|
|
204
|
+
export declare function validateYmaxOperationTypeName<T extends OperationTypeNames>(typeName: string): asserts typeName is T;
|
|
205
|
+
export declare const splitWitnessFieldType: <T extends OperationTypeNames>(fieldName: `${typeof YMAX_DOMAIN_NAME}V${typeof YMAX_DOMAIN_VERSION}${T}`) => {
|
|
206
|
+
domain: {
|
|
207
|
+
readonly name: "Ymax";
|
|
208
|
+
readonly version: "1";
|
|
209
|
+
};
|
|
210
|
+
primaryType: T;
|
|
211
|
+
};
|
|
212
|
+
export {};
|
|
213
|
+
//# sourceMappingURL=eip712-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eip712-messages.d.ts","sourceRoot":"","sources":["eip712-messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Portfolio operations are either in a permit2 witness or standalone,
|
|
3
|
+
* in either case, following EIP-712
|
|
4
|
+
*
|
|
5
|
+
* The fields included in the operation differ based on which way they're submitted.
|
|
6
|
+
* In the wrapped case, we don't want to repeat stuff from the permit envelope.
|
|
7
|
+
* {@link OperationTypes}
|
|
8
|
+
*
|
|
9
|
+
* Currently all types and helpers are built around a hard-coded Ymax product
|
|
10
|
+
* name but with some effort this could be parametrizable
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
import { Fail, q } from '@endo/errors';
|
|
21
|
+
;
|
|
22
|
+
import {
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
makeWitness,
|
|
27
|
+
TokenPermissionsComponents,
|
|
28
|
+
} from '@agoric/orchestration/src/utils/permit2.js';
|
|
29
|
+
|
|
30
|
+
const YMAX_DOMAIN_NAME = 'Ymax';
|
|
31
|
+
const YMAX_DOMAIN_VERSION = '1';
|
|
32
|
+
|
|
33
|
+
const YMAX_WITNESS_FIELD_NAME_PREFIX = 'ymax';
|
|
34
|
+
|
|
35
|
+
const StandaloneDomainTypeParams = [
|
|
36
|
+
{ name: 'name', type: 'string' },
|
|
37
|
+
{ name: 'version', type: 'string' },
|
|
38
|
+
{ name: 'chainId', type: 'uint256' },
|
|
39
|
+
{ name: 'verifyingContract', type: 'address' },
|
|
40
|
+
] ;
|
|
41
|
+
|
|
42
|
+
const YmaxStandaloneDomainBase = {
|
|
43
|
+
name: YMAX_DOMAIN_NAME,
|
|
44
|
+
version: YMAX_DOMAIN_VERSION,
|
|
45
|
+
} ;
|
|
46
|
+
;
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// A param to designate the portfolio in operations by its `portfolioId`
|
|
52
|
+
const PortfolioIdParam = {
|
|
53
|
+
name: 'portfolio',
|
|
54
|
+
type: 'uint256',
|
|
55
|
+
} ;
|
|
56
|
+
|
|
57
|
+
// XXX: Remove
|
|
58
|
+
const SharedPortfolioTypeParams = [] ;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fields included in Permit data that we don't want duplicated in witness data,
|
|
62
|
+
* so only included in standalone typed data.
|
|
63
|
+
*/
|
|
64
|
+
const PortfolioStandaloneTypeParams = [
|
|
65
|
+
{ name: 'nonce', type: 'uint256' },
|
|
66
|
+
{ name: 'deadline', type: 'uint256' },
|
|
67
|
+
] ;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The set of portfolio operations supported by EVM Wallets, and their associated params
|
|
71
|
+
*/
|
|
72
|
+
const OperationTypes = {
|
|
73
|
+
OpenPortfolio: [{ name: 'allocations', type: 'Allocation[]' }],
|
|
74
|
+
Rebalance: [PortfolioIdParam],
|
|
75
|
+
SetTargetAllocation: [
|
|
76
|
+
{ name: 'allocations', type: 'Allocation[]' },
|
|
77
|
+
PortfolioIdParam,
|
|
78
|
+
],
|
|
79
|
+
Deposit: [PortfolioIdParam],
|
|
80
|
+
/**
|
|
81
|
+
* Withdraw funds from a portfolio to the source EVM account.
|
|
82
|
+
* The signer of the message must match the portfolio's source EVM account
|
|
83
|
+
* The destination chain is determined from the domain info (chainId).
|
|
84
|
+
* - token: ERC-20 token contract address (must be USDC contract on the destination chain)
|
|
85
|
+
*/
|
|
86
|
+
Withdraw: [{ name: 'withdraw', type: 'Asset' }, PortfolioIdParam],
|
|
87
|
+
} ;
|
|
88
|
+
;
|
|
89
|
+
;
|
|
90
|
+
|
|
91
|
+
const OperationSubTypes = {
|
|
92
|
+
Allocation: [
|
|
93
|
+
{ name: 'instrument', type: 'string' },
|
|
94
|
+
{ name: 'portion', type: 'uint256' },
|
|
95
|
+
],
|
|
96
|
+
Asset: TokenPermissionsComponents,
|
|
97
|
+
} ;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Target allocation for portfolio positions.
|
|
101
|
+
* Uses 'portion' (not 'basisPoints') to allow flexible ratios.
|
|
102
|
+
* The denominator is implicitly the sum of all portions.
|
|
103
|
+
*
|
|
104
|
+
* Examples:
|
|
105
|
+
* - [{instrument: 'A', portion: 60}, {instrument: 'B', portion: 40}] => 60:40 ratio
|
|
106
|
+
* - [{instrument: 'A', portion: 6}, {instrument: 'B', portion: 4}] => 6:4 ratio (same as 60:40)
|
|
107
|
+
*/
|
|
108
|
+
;
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
;
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* In the wrapped case, the domain is fixed by permit2, so we can't choose name/version there.
|
|
120
|
+
* so we put the ymax-specifc domain name and version in the type name.
|
|
121
|
+
*/
|
|
122
|
+
const getYmaxWitnessTypeName = (operation ) =>
|
|
123
|
+
`${YMAX_DOMAIN_NAME}V${YMAX_DOMAIN_VERSION}${operation}` ;
|
|
124
|
+
;
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
const getYmaxWitnessFieldName = (operation ) =>
|
|
128
|
+
`${YMAX_WITNESS_FIELD_NAME_PREFIX}${operation}` ;
|
|
129
|
+
;
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
;
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* showing a field named "witness" in the wallet signing UI is... boring
|
|
141
|
+
* so let's put something more relevant like the @{link OperationTypes}: Deposit etc.
|
|
142
|
+
*/
|
|
143
|
+
const getYmaxWitnessTypeParam = (
|
|
144
|
+
operation ,
|
|
145
|
+
) => ({
|
|
146
|
+
name: getYmaxWitnessFieldName(operation),
|
|
147
|
+
type: getYmaxWitnessTypeName(operation) ,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// TODO: Filter operation types to only those needed for witness/standalone
|
|
151
|
+
;
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
;
|
|
160
|
+
|
|
161
|
+
;
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
;
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
;
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
;
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
;
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
const getYmaxOperationAndSubTypes = (
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
operation ,
|
|
190
|
+
params ,
|
|
191
|
+
) =>
|
|
192
|
+
({
|
|
193
|
+
[operation]: params,
|
|
194
|
+
...OperationSubTypes,
|
|
195
|
+
}) ;
|
|
196
|
+
|
|
197
|
+
const getYmaxWitnessTypes = (operation ) =>
|
|
198
|
+
getYmaxOperationAndSubTypes(getYmaxWitnessTypeName(operation), [
|
|
199
|
+
...OperationTypes[operation],
|
|
200
|
+
...SharedPortfolioTypeParams,
|
|
201
|
+
]) ;
|
|
202
|
+
|
|
203
|
+
const getYmaxStandaloneTypes = (operation ) =>
|
|
204
|
+
({
|
|
205
|
+
EIP712Domain: StandaloneDomainTypeParams,
|
|
206
|
+
...getYmaxOperationAndSubTypes(operation, [
|
|
207
|
+
...OperationTypes[operation],
|
|
208
|
+
...SharedPortfolioTypeParams,
|
|
209
|
+
...PortfolioStandaloneTypeParams,
|
|
210
|
+
]),
|
|
211
|
+
}) ;
|
|
212
|
+
|
|
213
|
+
export const getYmaxOperationTypes = (
|
|
214
|
+
operation ,
|
|
215
|
+
) =>
|
|
216
|
+
getYmaxOperationAndSubTypes(operation, OperationTypes[operation])
|
|
217
|
+
|
|
218
|
+
;
|
|
219
|
+
|
|
220
|
+
export const getYmaxWitness = (
|
|
221
|
+
operation ,
|
|
222
|
+
data ,
|
|
223
|
+
) =>
|
|
224
|
+
makeWitness (
|
|
225
|
+
data,
|
|
226
|
+
getYmaxWitnessTypes(operation),
|
|
227
|
+
getYmaxWitnessTypeParam(operation),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
export const getYmaxStandaloneDomain = (
|
|
231
|
+
chainId ,
|
|
232
|
+
verifyingContract ,
|
|
233
|
+
) => ({
|
|
234
|
+
...YmaxStandaloneDomainBase,
|
|
235
|
+
chainId: BigInt(chainId),
|
|
236
|
+
verifyingContract,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
export const getYmaxStandaloneOperationData = (
|
|
240
|
+
data ,
|
|
241
|
+
operation ,
|
|
242
|
+
chainId ,
|
|
243
|
+
verifyingContract ,
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
) => {
|
|
247
|
+
const types = getYmaxStandaloneTypes(operation);
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
domain: getYmaxStandaloneDomain(chainId, verifyingContract),
|
|
251
|
+
types,
|
|
252
|
+
primaryType: operation,
|
|
253
|
+
message: data ,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
;
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
;
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
;
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
export function validateYmaxDomainBase(
|
|
282
|
+
domain ,
|
|
283
|
+
) {
|
|
284
|
+
if (domain.name !== YMAX_DOMAIN_NAME) {
|
|
285
|
+
throw new Error(
|
|
286
|
+
`Invalid Ymax domain name: ${domain.name} (expected ${YMAX_DOMAIN_NAME})`,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
if (domain.version !== YMAX_DOMAIN_VERSION) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
`Invalid Ymax domain version: ${domain.version} (expected ${YMAX_DOMAIN_VERSION})`,
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function validateYmaxDomain(
|
|
297
|
+
domain ,
|
|
298
|
+
validContractAddresses ,
|
|
299
|
+
) {
|
|
300
|
+
const baseDomain = domain;
|
|
301
|
+
validateYmaxDomainBase(baseDomain);
|
|
302
|
+
|
|
303
|
+
typeof domain.chainId === 'bigint' || Fail`Chain ID expected to be a BigInt`;
|
|
304
|
+
|
|
305
|
+
if (validContractAddresses) {
|
|
306
|
+
const chainIdStr = String(domain.chainId);
|
|
307
|
+
|
|
308
|
+
chainIdStr in validContractAddresses ||
|
|
309
|
+
Fail`Unknown chain ID in Ymax domain: ${q(domain.chainId)}`;
|
|
310
|
+
|
|
311
|
+
domain.verifyingContract === validContractAddresses[chainIdStr] ||
|
|
312
|
+
Fail`Invalid verifying contract for chain ID ${q(domain.chainId)}: ${q(
|
|
313
|
+
domain.verifyingContract,
|
|
314
|
+
)} (expected ${q(validContractAddresses[chainIdStr])})`;
|
|
315
|
+
} else {
|
|
316
|
+
(domain.chainId !== undefined && domain.verifyingContract !== undefined) ||
|
|
317
|
+
Fail`Ymax domain must include chainId and verifyingContract`;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// XXX: check no extra fields?
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export function validateYmaxOperationTypeName (
|
|
324
|
+
typeName ,
|
|
325
|
+
) {
|
|
326
|
+
if (!(typeName in OperationTypes)) {
|
|
327
|
+
throw new Error(
|
|
328
|
+
`Unknown Ymax operation type: ${typeName} (expected one of ${Object.keys(OperationTypes).join(', ')})`,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export const splitWitnessFieldType = (
|
|
334
|
+
fieldName ,
|
|
335
|
+
) => {
|
|
336
|
+
const match =
|
|
337
|
+
fieldName.startsWith(YMAX_DOMAIN_NAME) &&
|
|
338
|
+
fieldName.substring(YMAX_DOMAIN_NAME.length).match(/^V(\d+)(\w+)$/u);
|
|
339
|
+
if (!match) {
|
|
340
|
+
throw new Error(`Invalid witness field type name: ${fieldName}`);
|
|
341
|
+
}
|
|
342
|
+
const [, version, operation] = match;
|
|
343
|
+
const domain = {
|
|
344
|
+
name: YMAX_DOMAIN_NAME,
|
|
345
|
+
version,
|
|
346
|
+
} ;
|
|
347
|
+
|
|
348
|
+
validateYmaxDomainBase(domain);
|
|
349
|
+
validateYmaxOperationTypeName (operation);
|
|
350
|
+
|
|
351
|
+
return {
|
|
352
|
+
domain,
|
|
353
|
+
primaryType: operation,
|
|
354
|
+
};
|
|
355
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Helpers to handle portfolio EIP-712 messages, extracting operation and
|
|
3
|
+
* deposit permit details, as well as verifying the signature.
|
|
4
|
+
*
|
|
5
|
+
* The viem runtime dependency is expected as a power to make this usable both
|
|
6
|
+
* on chain and in off-chain services.
|
|
7
|
+
*/
|
|
8
|
+
import type { AbiParameterToPrimitiveType, Address, TypedDataDomain } from 'abitype';
|
|
9
|
+
import type { hashStruct, isHex, recoverTypedDataAddress, validateTypedData } from 'viem/utils';
|
|
10
|
+
import { encodeType, type WithSignature } from '@agoric/orchestration/src/utils/viem.js';
|
|
11
|
+
import { type PermitWitnessTransferFromInputComponents } from '@agoric/orchestration/src/utils/permit2.js';
|
|
12
|
+
import { type OperationTypeNames, type YmaxStandaloneOperationData, type YmaxPermitWitnessTransferFromData, type YmaxOperationType, type YmaxFullDomain } from './eip712-messages.js';
|
|
13
|
+
export type YmaxOperationDetails<T extends OperationTypeNames = OperationTypeNames> = {
|
|
14
|
+
[P in T]: {
|
|
15
|
+
operation: P;
|
|
16
|
+
domain: YmaxFullDomain;
|
|
17
|
+
data: YmaxOperationType<P>;
|
|
18
|
+
};
|
|
19
|
+
}[T];
|
|
20
|
+
export type PermitWitnessTransferFromPayload = AbiParameterToPrimitiveType<{
|
|
21
|
+
type: 'tuple';
|
|
22
|
+
components: typeof PermitWitnessTransferFromInputComponents;
|
|
23
|
+
}>;
|
|
24
|
+
export type PermitDetails = {
|
|
25
|
+
chainId: NonNullable<TypedDataDomain['chainId']>;
|
|
26
|
+
token: Address;
|
|
27
|
+
amount: bigint;
|
|
28
|
+
spender: Address;
|
|
29
|
+
permit2Payload: Omit<PermitWitnessTransferFromPayload, 'transferDetails'>;
|
|
30
|
+
};
|
|
31
|
+
export type FullMessageDetails<T extends OperationTypeNames = OperationTypeNames> = YmaxOperationDetails<T> & {
|
|
32
|
+
permitDetails?: PermitDetails;
|
|
33
|
+
evmWalletAddress: Address;
|
|
34
|
+
nonce: bigint;
|
|
35
|
+
deadline: bigint;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* EVM Message handler utils that depend on 'viem' utils for their
|
|
39
|
+
* implementation. Since on-chain we cannot directly import from 'viem',
|
|
40
|
+
* use a maker pattern to create these utils.
|
|
41
|
+
*/
|
|
42
|
+
export declare const makeEVMHandlerUtils: (viemUtils: {
|
|
43
|
+
isHex: typeof isHex;
|
|
44
|
+
hashStruct: typeof hashStruct;
|
|
45
|
+
recoverTypedDataAddress: typeof recoverTypedDataAddress;
|
|
46
|
+
validateTypedData: typeof validateTypedData;
|
|
47
|
+
encodeType: typeof encodeType;
|
|
48
|
+
}) => {
|
|
49
|
+
extractOperationDetailsFromStandaloneData: <T extends OperationTypeNames>(data: YmaxStandaloneOperationData<T>, validContractAddresses?: Record<number | string, Address>) => YmaxOperationDetails<T>;
|
|
50
|
+
extractOperationDetailsFromPermit2WitnessData: <T extends OperationTypeNames>(data: YmaxPermitWitnessTransferFromData<T>) => YmaxOperationDetails<T>;
|
|
51
|
+
extractPermitDetails: <T extends OperationTypeNames>(data: YmaxPermitWitnessTransferFromData<T>, owner: Address, signature: WithSignature<object>["signature"]) => PermitDetails;
|
|
52
|
+
extractOperationDetailsFromSignedData: <T extends OperationTypeNames = "Withdraw" | "Deposit" | "Rebalance" | "OpenPortfolio" | "SetTargetAllocation">(signedData: WithSignature<YmaxPermitWitnessTransferFromData<T> | YmaxStandaloneOperationData<T>>, validStandaloneContractAddresses?: Record<number | string, Address>) => Promise<FullMessageDetails<T>>;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=message-handler-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-handler-helpers.d.ts","sourceRoot":"","sources":["message-handler-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,2BAA2B,EAC3B,OAAO,EACP,eAAe,EAChB,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,uBAAuB,EAEvB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,UAAU,EACV,KAAK,aAAa,EACnB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAIL,KAAK,wCAAwC,EAC9C,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,iCAAiC,EACtC,KAAK,iBAAiB,EAKtB,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,oBAAoB,CAC9B,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAC/C;KACD,CAAC,IAAI,CAAC,GAAG;QACR,SAAS,EAAE,CAAC,CAAC;QACb,MAAM,EAAE,cAAc,CAAC;QACvB,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;KAC5B;CACF,CAAC,CAAC,CAAC,CAAC;AAEL,MAAM,MAAM,gCAAgC,GAAG,2BAA2B,CAAC;IACzE,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,wCAAwC,CAAC;CAC7D,CAAC,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;IACjD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,IAAI,CAAC,gCAAgC,EAAE,iBAAiB,CAAC,CAAC;CAC3E,CAAC;AAEF,MAAM,MAAM,kBAAkB,CAC5B,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAC/C,oBAAoB,CAAC,CAAC,CAAC,GAAG;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW;IAC7C,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,UAAU,EAAE,OAAO,UAAU,CAAC;CAC/B;gDAqBG,CAAC,SAAS,kBAAkB,QAEtB,2BAA2B,CAAC,CAAC,CAAC,2BACX,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,KACxD,oBAAoB,CAAC,CAAC,CAAC;oDA6BxB,CAAC,SAAS,kBAAkB,QAEtB,iCAAiC,CAAC,CAAC,CAAC,KACzC,oBAAoB,CAAC,CAAC,CAAC;2BAmCI,CAAC,SAAS,kBAAkB,QAClD,iCAAiC,CAAC,CAAC,CAAC,SACnC,OAAO,aACH,aAAa,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,KAC5C,aAAa;4CAiDd,CAAC,SAAS,kBAAkB,+FAEhB,aAAa,CACvB,iCAAiC,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC,CAAC,CAAC,CACtE,qCACkC,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,KAClE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAoDlC,CAAC"}
|