@agoric/portfolio-api 0.1.1-dev-585d68c.0.585d68c → 0.1.1-dev-f9b3d7d.0.f9b3d7d
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 +5 -4
- package/src/instruments.d.ts +1 -0
- package/src/instruments.js +2 -0
- package/src/observation-messages.d.ts +163 -0
- package/src/observation-messages.d.ts.map +1 -0
- package/src/observation-messages.js +206 -0
- package/src/places.d.ts +8 -0
- package/src/places.d.ts.map +1 -1
- package/src/places.js +4 -0
- package/src/type-guards.d.ts +7 -2
- package/src/type-guards.d.ts.map +1 -1
- package/src/type-guards.js +17 -5
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-f9b3d7d.0.f9b3d7d",
|
|
4
4
|
"description": "API for Portfolio management",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"./src/evm-wallet/message-handler-helpers.js": "./src/evm-wallet/message-handler-helpers.js",
|
|
20
20
|
"./src/network/network-spec.js": "./src/network/network-spec.js",
|
|
21
21
|
"./src/network/prod-network.js": "./src/network/prod-network.js",
|
|
22
|
+
"./src/observation-messages.js": "./src/observation-messages.js",
|
|
22
23
|
"./src/places.js": "./src/places.js",
|
|
23
24
|
"./src/portfolio-permissions.js": "./src/portfolio-permissions.js",
|
|
24
25
|
"./src/portfolio-constants.js": "./src/portfolio-constants.js",
|
|
@@ -46,8 +47,8 @@
|
|
|
46
47
|
"generate:ymax-machine": "npx tsx scripts/gen-ymax-machine.mts"
|
|
47
48
|
},
|
|
48
49
|
"dependencies": {
|
|
49
|
-
"@agoric/internal": "0.3.3-dev-
|
|
50
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
50
|
+
"@agoric/internal": "0.3.3-dev-f9b3d7d.0.f9b3d7d",
|
|
51
|
+
"@agoric/orchestration": "0.1.1-dev-f9b3d7d.0.f9b3d7d",
|
|
51
52
|
"@endo/common": "^1.4.0",
|
|
52
53
|
"@endo/errors": "^1.3.1",
|
|
53
54
|
"@endo/patterns": "^1.9.1"
|
|
@@ -73,5 +74,5 @@
|
|
|
73
74
|
"engines": {
|
|
74
75
|
"node": "^22.11 || ^24.14"
|
|
75
76
|
},
|
|
76
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "f9b3d7de3a57032939d0ad78a50a0dca8ad98f7a"
|
|
77
78
|
}
|
package/src/instruments.d.ts
CHANGED
|
@@ -61,6 +61,7 @@ export namespace InstrumentId {
|
|
|
61
61
|
let ERC4626_morphoReEcosystemVault_Ethereum: "ERC4626_morphoReEcosystemVault_Ethereum";
|
|
62
62
|
let ERC4626_morphoApyxUsdc_Ethereum: "ERC4626_morphoApyxUsdc_Ethereum";
|
|
63
63
|
let ERC4626_morphoRockawayxToriEcosystem_Ethereum: "ERC4626_morphoRockawayxToriEcosystem_Ethereum";
|
|
64
|
+
let ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum: "ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum";
|
|
64
65
|
let USDN: "USDN";
|
|
65
66
|
let USDNVault: "USDNVault";
|
|
66
67
|
}
|
package/src/instruments.js
CHANGED
|
@@ -86,6 +86,8 @@ export const InstrumentId = /** @type {const} */ ({
|
|
|
86
86
|
ERC4626_morphoApyxUsdc_Ethereum: 'ERC4626_morphoApyxUsdc_Ethereum',
|
|
87
87
|
ERC4626_morphoRockawayxToriEcosystem_Ethereum:
|
|
88
88
|
'ERC4626_morphoRockawayxToriEcosystem_Ethereum',
|
|
89
|
+
ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum:
|
|
90
|
+
'ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum',
|
|
89
91
|
USDN: 'USDN',
|
|
90
92
|
USDNVault: 'USDNVault',
|
|
91
93
|
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file EIP-712 messages by which an off-chain observation service (the
|
|
3
|
+
* attestor) vouches for the state of a portfolio, so that a plan submitted by
|
|
4
|
+
* a delegated agent can be checked against it on chain.
|
|
5
|
+
*
|
|
6
|
+
* These messages are only ever signed by the attestor's EOA, never by a
|
|
7
|
+
* portfolio owner, and use their own domain name so that they can never be
|
|
8
|
+
* confused with {@link YmaxPortfolioMessageSchema} operations. They are
|
|
9
|
+
* standalone messages only (no permit2 witness), whose envelope fields are
|
|
10
|
+
* used as the interval during which the observations may be relied upon:
|
|
11
|
+
*
|
|
12
|
+
* - `nonce`: when the observations were issued (`issuedAt`), in seconds since
|
|
13
|
+
* the epoch. It's not used to prevent replay: the observations are bound to
|
|
14
|
+
* an exact portfolio sync state, so replaying them is harmless.
|
|
15
|
+
* - `deadline`: when the observations expire, in seconds since the epoch.
|
|
16
|
+
*
|
|
17
|
+
* The generic machinery lives in `@agoric/orchestration`; this module defines
|
|
18
|
+
* the {@link YmaxObservationMessageSchema} and converts between its messages
|
|
19
|
+
* and the application-level {@link PlanObservations}.
|
|
20
|
+
*/
|
|
21
|
+
import type { TypedDataToStructType } from '@agoric/orchestration/src/utils/abitype.js';
|
|
22
|
+
import { type EIP712MessageKit, type FullDomain, type OperationType, type StandaloneOperationData } from '@agoric/orchestration/src/utils/eip712-messages.js';
|
|
23
|
+
import type { WithSignature } from '@agoric/orchestration/src/utils/viem.js';
|
|
24
|
+
import type { PlanObservations, PortfolioSyncState } from './types.js';
|
|
25
|
+
declare const ObservationOperationTypes: {
|
|
26
|
+
/**
|
|
27
|
+
* The state of a portfolio and of the instruments relevant to it, as
|
|
28
|
+
* observed at the portfolio's `syncState`.
|
|
29
|
+
*
|
|
30
|
+
* - syncState: the portfolio state the observations correspond to
|
|
31
|
+
* - holdings: the balance of every balance-bearing place of the portfolio
|
|
32
|
+
* - instruments: details of the instruments relevant to the portfolio
|
|
33
|
+
*/
|
|
34
|
+
readonly PortfolioObservations: readonly [{
|
|
35
|
+
readonly name: "portfolio";
|
|
36
|
+
readonly type: "uint256";
|
|
37
|
+
}, {
|
|
38
|
+
readonly name: "syncState";
|
|
39
|
+
readonly type: "SyncState";
|
|
40
|
+
}, {
|
|
41
|
+
readonly name: "holdings";
|
|
42
|
+
readonly type: "HoldingDetail[]";
|
|
43
|
+
}, {
|
|
44
|
+
readonly name: "instruments";
|
|
45
|
+
readonly type: "InstrumentDetail[]";
|
|
46
|
+
}];
|
|
47
|
+
};
|
|
48
|
+
declare const ObservationSubTypes: {
|
|
49
|
+
/** @see {@link PortfolioSyncState} */
|
|
50
|
+
readonly SyncState: readonly [{
|
|
51
|
+
readonly name: "policyVersion";
|
|
52
|
+
readonly type: "uint64";
|
|
53
|
+
}, {
|
|
54
|
+
readonly name: "rebalanceCount";
|
|
55
|
+
readonly type: "uint64";
|
|
56
|
+
}];
|
|
57
|
+
readonly HoldingDetail: readonly [{
|
|
58
|
+
readonly name: "place";
|
|
59
|
+
readonly type: "string";
|
|
60
|
+
}, {
|
|
61
|
+
readonly name: "balanceUsdc";
|
|
62
|
+
readonly type: "uint256";
|
|
63
|
+
}];
|
|
64
|
+
readonly InstrumentDetail: readonly [{
|
|
65
|
+
readonly name: "instrumentId";
|
|
66
|
+
readonly type: "string";
|
|
67
|
+
}, {
|
|
68
|
+
readonly name: "tvlUsd";
|
|
69
|
+
readonly type: "uint256";
|
|
70
|
+
}];
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* The schema of Ymax observation messages. The domain name intentionally
|
|
74
|
+
* differs from the `Ymax` portfolio operations domain.
|
|
75
|
+
*/
|
|
76
|
+
export declare const YmaxObservationMessageSchema: {
|
|
77
|
+
readonly domainName: "YmaxObservation";
|
|
78
|
+
readonly domainVersion: "1";
|
|
79
|
+
readonly operationTypes: {
|
|
80
|
+
/**
|
|
81
|
+
* The state of a portfolio and of the instruments relevant to it, as
|
|
82
|
+
* observed at the portfolio's `syncState`.
|
|
83
|
+
*
|
|
84
|
+
* - syncState: the portfolio state the observations correspond to
|
|
85
|
+
* - holdings: the balance of every balance-bearing place of the portfolio
|
|
86
|
+
* - instruments: details of the instruments relevant to the portfolio
|
|
87
|
+
*/
|
|
88
|
+
readonly PortfolioObservations: readonly [{
|
|
89
|
+
readonly name: "portfolio";
|
|
90
|
+
readonly type: "uint256";
|
|
91
|
+
}, {
|
|
92
|
+
readonly name: "syncState";
|
|
93
|
+
readonly type: "SyncState";
|
|
94
|
+
}, {
|
|
95
|
+
readonly name: "holdings";
|
|
96
|
+
readonly type: "HoldingDetail[]";
|
|
97
|
+
}, {
|
|
98
|
+
readonly name: "instruments";
|
|
99
|
+
readonly type: "InstrumentDetail[]";
|
|
100
|
+
}];
|
|
101
|
+
};
|
|
102
|
+
readonly subTypes: {
|
|
103
|
+
/** @see {@link PortfolioSyncState} */
|
|
104
|
+
readonly SyncState: readonly [{
|
|
105
|
+
readonly name: "policyVersion";
|
|
106
|
+
readonly type: "uint64";
|
|
107
|
+
}, {
|
|
108
|
+
readonly name: "rebalanceCount";
|
|
109
|
+
readonly type: "uint64";
|
|
110
|
+
}];
|
|
111
|
+
readonly HoldingDetail: readonly [{
|
|
112
|
+
readonly name: "place";
|
|
113
|
+
readonly type: "string";
|
|
114
|
+
}, {
|
|
115
|
+
readonly name: "balanceUsdc";
|
|
116
|
+
readonly type: "uint256";
|
|
117
|
+
}];
|
|
118
|
+
readonly InstrumentDetail: readonly [{
|
|
119
|
+
readonly name: "instrumentId";
|
|
120
|
+
readonly type: "string";
|
|
121
|
+
}, {
|
|
122
|
+
readonly name: "tvlUsd";
|
|
123
|
+
readonly type: "uint256";
|
|
124
|
+
}];
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
export type YmaxObservationMessageSchema = typeof YmaxObservationMessageSchema;
|
|
128
|
+
export declare const ymaxObservationMessageKit: EIP712MessageKit<YmaxObservationMessageSchema>;
|
|
129
|
+
export type YmaxObservationFullDomain = FullDomain<YmaxObservationMessageSchema>;
|
|
130
|
+
/** The (normalized) data of a `PortfolioObservations` message. */
|
|
131
|
+
export type PortfolioObservationsEIP712 = OperationType<YmaxObservationMessageSchema, 'PortfolioObservations'>;
|
|
132
|
+
/** The data of a `PortfolioObservations` message, as accepted when authoring one. */
|
|
133
|
+
export type PortfolioObservationsEIP712Input = TypedDataToStructType<typeof ObservationOperationTypes & typeof ObservationSubTypes, 'PortfolioObservations', 'input'>;
|
|
134
|
+
/** A standalone `PortfolioObservations` message, as signed by the attestor. */
|
|
135
|
+
export type PortfolioObservationsStandaloneData = StandaloneOperationData<YmaxObservationMessageSchema, 'PortfolioObservations'>;
|
|
136
|
+
export type SignedPortfolioObservations = WithSignature<PortfolioObservationsStandaloneData>;
|
|
137
|
+
/** The application-level content of a `PortfolioObservations` message. */
|
|
138
|
+
export type PortfolioObservationsContent = {
|
|
139
|
+
portfolioId: number;
|
|
140
|
+
syncState: PortfolioSyncState;
|
|
141
|
+
observations: PlanObservations;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Convert the content of a portfolio observation to the data of a
|
|
145
|
+
* `PortfolioObservations` message, e.g. for the attestor to sign.
|
|
146
|
+
*
|
|
147
|
+
* @param observation
|
|
148
|
+
*/
|
|
149
|
+
export declare const portfolioObservationsToEIP712: ({ portfolioId, syncState: { policyVersion, rebalanceCount }, observations: { balances, instrumentTvls }, }: PortfolioObservationsContent) => PortfolioObservationsEIP712Input;
|
|
150
|
+
/**
|
|
151
|
+
* Convert the data of a signed `PortfolioObservations` message to its
|
|
152
|
+
* application-level content.
|
|
153
|
+
*
|
|
154
|
+
* Expects the data as extracted by `makeEIP712MessageHandlerUtils` with
|
|
155
|
+
* `onUnknownSignedField: 'throw'`, i.e. normalized and without fields this
|
|
156
|
+
* version does not understand. Fails closed: rejects places or instruments
|
|
157
|
+
* that are invalid or listed more than once, and values out of range.
|
|
158
|
+
*
|
|
159
|
+
* @param data
|
|
160
|
+
*/
|
|
161
|
+
export declare const portfolioObservationsFromEIP712: ({ portfolio, syncState, holdings, instruments, }: PortfolioObservationsEIP712) => PortfolioObservationsContent;
|
|
162
|
+
export {};
|
|
163
|
+
//# sourceMappingURL=observation-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation-messages.d.ts","sourceRoot":"","sources":["observation-messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,UAAU,EAEf,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC7B,MAAM,oDAAoD,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAK7E,OAAO,KAAK,EACV,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAQpB,QAAA,MAAM,yBAAyB;IAC7B;;;;;;;OAOG;;;;;;;;;;;;;;CAO6D,CAAC;AAEnE,QAAA,MAAM,mBAAmB;IACvB,sCAAsC;;;;;;;;;;;;;;;;;;;;;;CAiB0B,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,4BAA4B;;;;QAxCvC;;;;;;;WAOG;;;;;;;;;;;;;;;;QAUH,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;CA4BA,CAAC;AACzC,MAAM,MAAM,4BAA4B,GAAG,OAAO,4BAA4B,CAAC;AAE/E,eAAO,MAAM,yBAAyB,EAAE,gBAAgB,CAAC,4BAA4B,CACjC,CAAC;AAErD,MAAM,MAAM,yBAAyB,GACnC,UAAU,CAAC,4BAA4B,CAAC,CAAC;AAE3C,kEAAkE;AAClE,MAAM,MAAM,2BAA2B,GAAG,aAAa,CACrD,4BAA4B,EAC5B,uBAAuB,CACxB,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,gCAAgC,GAAG,qBAAqB,CAClE,OAAO,yBAAyB,GAAG,OAAO,mBAAmB,EAC7D,uBAAuB,EACvB,OAAO,CACR,CAAC;AAEF,+EAA+E;AAC/E,MAAM,MAAM,mCAAmC,GAAG,uBAAuB,CACvE,4BAA4B,EAC5B,uBAAuB,CACxB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GACrC,aAAa,CAAC,mCAAmC,CAAC,CAAC;AAErD,0EAA0E;AAC1E,MAAM,MAAM,4BAA4B,GAAG;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,YAAY,EAAE,gBAAgB,CAAC;CAChC,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GAAI,4GAI3C,4BAA4B,KAAG,gCAW9B,CAAC;AAEL;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,GAAI,kDAK7C,2BAA2B,KAAG,4BA0BhC,CAAC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file EIP-712 messages by which an off-chain observation service (the
|
|
3
|
+
* attestor) vouches for the state of a portfolio, so that a plan submitted by
|
|
4
|
+
* a delegated agent can be checked against it on chain.
|
|
5
|
+
*
|
|
6
|
+
* These messages are only ever signed by the attestor's EOA, never by a
|
|
7
|
+
* portfolio owner, and use their own domain name so that they can never be
|
|
8
|
+
* confused with {@link YmaxPortfolioMessageSchema} operations. They are
|
|
9
|
+
* standalone messages only (no permit2 witness), whose envelope fields are
|
|
10
|
+
* used as the interval during which the observations may be relied upon:
|
|
11
|
+
*
|
|
12
|
+
* - `nonce`: when the observations were issued (`issuedAt`), in seconds since
|
|
13
|
+
* the epoch. It's not used to prevent replay: the observations are bound to
|
|
14
|
+
* an exact portfolio sync state, so replaying them is harmless.
|
|
15
|
+
* - `deadline`: when the observations expire, in seconds since the epoch.
|
|
16
|
+
*
|
|
17
|
+
* The generic machinery lives in `@agoric/orchestration`; this module defines
|
|
18
|
+
* the {@link YmaxObservationMessageSchema} and converts between its messages
|
|
19
|
+
* and the application-level {@link PlanObservations}.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import {
|
|
27
|
+
makeEIP712MessageKit,
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
} from '@agoric/orchestration/src/utils/eip712-messages.js';
|
|
34
|
+
;
|
|
35
|
+
import { Fail, q } from '@endo/errors';
|
|
36
|
+
;
|
|
37
|
+
import { isInstrumentId } from './places.js';
|
|
38
|
+
import { isPortfolioBalancePlaceRef } from './type-guards.js';
|
|
39
|
+
;
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// A param to designate the portfolio by its `portfolioId`
|
|
46
|
+
const PortfolioIdParam = {
|
|
47
|
+
name: 'portfolio',
|
|
48
|
+
type: 'uint256',
|
|
49
|
+
} ;
|
|
50
|
+
|
|
51
|
+
const ObservationOperationTypes = {
|
|
52
|
+
/**
|
|
53
|
+
* The state of a portfolio and of the instruments relevant to it, as
|
|
54
|
+
* observed at the portfolio's `syncState`.
|
|
55
|
+
*
|
|
56
|
+
* - syncState: the portfolio state the observations correspond to
|
|
57
|
+
* - holdings: the balance of every balance-bearing place of the portfolio
|
|
58
|
+
* - instruments: details of the instruments relevant to the portfolio
|
|
59
|
+
*/
|
|
60
|
+
PortfolioObservations: [
|
|
61
|
+
PortfolioIdParam,
|
|
62
|
+
{ name: 'syncState', type: 'SyncState' },
|
|
63
|
+
{ name: 'holdings', type: 'HoldingDetail[]' },
|
|
64
|
+
{ name: 'instruments', type: 'InstrumentDetail[]' },
|
|
65
|
+
],
|
|
66
|
+
} ;
|
|
67
|
+
|
|
68
|
+
const ObservationSubTypes = {
|
|
69
|
+
/** @see {@link PortfolioSyncState} */
|
|
70
|
+
SyncState: [
|
|
71
|
+
{ name: 'policyVersion', type: 'uint64' },
|
|
72
|
+
{ name: 'rebalanceCount', type: 'uint64' },
|
|
73
|
+
],
|
|
74
|
+
HoldingDetail: [
|
|
75
|
+
/** a {@link PortfolioBalancePlaceRef} */
|
|
76
|
+
{ name: 'place', type: 'string' },
|
|
77
|
+
/** in micro-USDC (6 decimal places) */
|
|
78
|
+
{ name: 'balanceUsdc', type: 'uint256' },
|
|
79
|
+
],
|
|
80
|
+
InstrumentDetail: [
|
|
81
|
+
/** an {@link InstrumentId} */
|
|
82
|
+
{ name: 'instrumentId', type: 'string' },
|
|
83
|
+
/** in whole USD */
|
|
84
|
+
{ name: 'tvlUsd', type: 'uint256' },
|
|
85
|
+
],
|
|
86
|
+
} ;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The schema of Ymax observation messages. The domain name intentionally
|
|
90
|
+
* differs from the `Ymax` portfolio operations domain.
|
|
91
|
+
*/
|
|
92
|
+
export const YmaxObservationMessageSchema = {
|
|
93
|
+
domainName: 'YmaxObservation',
|
|
94
|
+
domainVersion: '1',
|
|
95
|
+
operationTypes: ObservationOperationTypes,
|
|
96
|
+
subTypes: ObservationSubTypes,
|
|
97
|
+
} ;
|
|
98
|
+
;
|
|
99
|
+
|
|
100
|
+
export const ymaxObservationMessageKit =
|
|
101
|
+
makeEIP712MessageKit(YmaxObservationMessageSchema);
|
|
102
|
+
|
|
103
|
+
;
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
/** The (normalized) data of a `PortfolioObservations` message. */
|
|
107
|
+
;
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
/** The data of a `PortfolioObservations` message, as accepted when authoring one. */
|
|
113
|
+
;
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/** A standalone `PortfolioObservations` message, as signed by the attestor. */
|
|
120
|
+
;
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
;
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/** The application-level content of a `PortfolioObservations` message. */
|
|
129
|
+
;
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
const toSafeNumber = (value , what ) => {
|
|
136
|
+
value <= BigInt(Number.MAX_SAFE_INTEGER) ||
|
|
137
|
+
Fail`${q(what)} out of range: ${value}`;
|
|
138
|
+
return Number(value);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Convert the content of a portfolio observation to the data of a
|
|
143
|
+
* `PortfolioObservations` message, e.g. for the attestor to sign.
|
|
144
|
+
*
|
|
145
|
+
* @param observation
|
|
146
|
+
*/
|
|
147
|
+
export const portfolioObservationsToEIP712 = ({
|
|
148
|
+
portfolioId,
|
|
149
|
+
syncState: { policyVersion, rebalanceCount },
|
|
150
|
+
observations: { balances, instrumentTvls },
|
|
151
|
+
} ) =>
|
|
152
|
+
harden({
|
|
153
|
+
portfolio: portfolioId,
|
|
154
|
+
syncState: { policyVersion, rebalanceCount },
|
|
155
|
+
holdings: Object.entries(balances).flatMap(([place, balanceUsdc]) =>
|
|
156
|
+
balanceUsdc === undefined ? [] : [{ place, balanceUsdc }],
|
|
157
|
+
),
|
|
158
|
+
instruments: Object.entries(instrumentTvls).flatMap(
|
|
159
|
+
([instrumentId, tvl]) =>
|
|
160
|
+
tvl === undefined ? [] : [{ instrumentId, tvlUsd: tvl.tvlUsd }],
|
|
161
|
+
),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Convert the data of a signed `PortfolioObservations` message to its
|
|
166
|
+
* application-level content.
|
|
167
|
+
*
|
|
168
|
+
* Expects the data as extracted by `makeEIP712MessageHandlerUtils` with
|
|
169
|
+
* `onUnknownSignedField: 'throw'`, i.e. normalized and without fields this
|
|
170
|
+
* version does not understand. Fails closed: rejects places or instruments
|
|
171
|
+
* that are invalid or listed more than once, and values out of range.
|
|
172
|
+
*
|
|
173
|
+
* @param data
|
|
174
|
+
*/
|
|
175
|
+
export const portfolioObservationsFromEIP712 = ({
|
|
176
|
+
portfolio,
|
|
177
|
+
syncState,
|
|
178
|
+
holdings,
|
|
179
|
+
instruments,
|
|
180
|
+
} ) => {
|
|
181
|
+
const balances = {};
|
|
182
|
+
for (const { place, balanceUsdc } of holdings) {
|
|
183
|
+
isPortfolioBalancePlaceRef(place) ||
|
|
184
|
+
Fail`invalid holding place ${q(place)}`;
|
|
185
|
+
!Object.hasOwn(balances, place) ||
|
|
186
|
+
Fail`duplicate holding place ${q(place)}`;
|
|
187
|
+
balances[place] = balanceUsdc;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const instrumentTvls = {};
|
|
191
|
+
for (const { instrumentId, tvlUsd } of instruments) {
|
|
192
|
+
isInstrumentId(instrumentId) || Fail`invalid instrument ${q(instrumentId)}`;
|
|
193
|
+
!Object.hasOwn(instrumentTvls, instrumentId) ||
|
|
194
|
+
Fail`duplicate instrument ${q(instrumentId)}`;
|
|
195
|
+
instrumentTvls[instrumentId ] = { tvlUsd };
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return harden({
|
|
199
|
+
portfolioId: toSafeNumber(portfolio, 'portfolio'),
|
|
200
|
+
syncState: {
|
|
201
|
+
policyVersion: toSafeNumber(syncState.policyVersion, 'policyVersion'),
|
|
202
|
+
rebalanceCount: toSafeNumber(syncState.rebalanceCount, 'rebalanceCount'),
|
|
203
|
+
},
|
|
204
|
+
observations: { balances, instrumentTvls },
|
|
205
|
+
});
|
|
206
|
+
};
|
package/src/places.d.ts
CHANGED
|
@@ -190,6 +190,10 @@ export declare const ERC4626PoolPlaces: {
|
|
|
190
190
|
readonly protocol: "ERC4626";
|
|
191
191
|
readonly chainName: "Ethereum";
|
|
192
192
|
};
|
|
193
|
+
readonly ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum: {
|
|
194
|
+
readonly protocol: "ERC4626";
|
|
195
|
+
readonly chainName: "Ethereum";
|
|
196
|
+
};
|
|
193
197
|
};
|
|
194
198
|
export type ERC4626InstrumentId = keyof typeof ERC4626PoolPlaces;
|
|
195
199
|
export declare const PoolPlaces: {
|
|
@@ -329,6 +333,10 @@ export declare const PoolPlaces: {
|
|
|
329
333
|
readonly protocol: "ERC4626";
|
|
330
334
|
readonly chainName: "Ethereum";
|
|
331
335
|
};
|
|
336
|
+
readonly ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum: {
|
|
337
|
+
readonly protocol: "ERC4626";
|
|
338
|
+
readonly chainName: "Ethereum";
|
|
339
|
+
};
|
|
332
340
|
readonly Beefy_re7_Avalanche: {
|
|
333
341
|
readonly protocol: "Beefy";
|
|
334
342
|
readonly chainName: "Avalanche";
|
package/src/places.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["places.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,UAC2B,CAAC;AAG7E;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAcF,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACzD;IACE,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,cAAc,CAAC;CAC3B,CAAC;AAGN,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;CAyBqC,CAAC;AAGlE,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["places.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAEvD,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,UAC2B,CAAC;AAG7E;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAcF,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACzD;IACE,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,cAAc,CAAC;CAC3B,CAAC;AAGN,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;CAyBqC,CAAC;AAGlE,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6ImC,CAAC;AAGlE,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAEjE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAciC,CAAC;AAGzD,MAAM,MAAM,OAAO,GAAG,YAAY,CAAC;AACnC,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAElB,iBAAiB,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;CACtD,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,YAC5B,CAAC;AAIzB,eAAO,MAAM,OAAO,GAAI,IAAI,aAAa,KAAG,cAa3C,CAAC"}
|
package/src/places.js
CHANGED
|
@@ -214,6 +214,10 @@ export const ERC4626PoolPlaces = {
|
|
|
214
214
|
protocol: 'ERC4626',
|
|
215
215
|
chainName: 'Ethereum',
|
|
216
216
|
},
|
|
217
|
+
ERC4626_morphoRockawayxFxProtocolEcosystemUsdc_Ethereum: {
|
|
218
|
+
protocol: 'ERC4626',
|
|
219
|
+
chainName: 'Ethereum',
|
|
220
|
+
},
|
|
217
221
|
} ;
|
|
218
222
|
deepFreeze(ERC4626PoolPlaces);
|
|
219
223
|
|
package/src/type-guards.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TypedPattern } from '@agoric/internal';
|
|
2
|
-
import type
|
|
3
|
-
import type { DepositFromChainRef, LocalChainAccountRef, PortfolioAgentKey, InterChainAccountRef, PortfolioDelegatedClaimRewardsParams, PortfolioDelegatedRebalanceParams, PortfolioSyncState, WithdrawToChainRef } from './types.js';
|
|
2
|
+
import { type BeefyInstrumentId, type ChainTokenMetadata, type ERC4626InstrumentId, type TokenMetadata } from './places.js';
|
|
3
|
+
import type { DepositFromChainRef, LocalChainAccountRef, PortfolioAgentKey, InterChainAccountRef, PortfolioBalancePlaceRef, PortfolioDelegatedClaimRewardsParams, PortfolioDelegatedRebalanceParams, PortfolioSyncState, WithdrawToChainRef } from './types.js';
|
|
4
4
|
export { isInstrumentId, makeTokenIdKey } from './places.js';
|
|
5
5
|
export type { ChainTokenMetadata, ChainTokenMetadataEntry, TokenIdKey, TokenMetadata, } from './places.js';
|
|
6
6
|
export declare const TokenUsageShape: import("@endo/patterns").MatcherOf<"or", ["swapFrom", "swapTo"]>;
|
|
@@ -21,6 +21,11 @@ export declare const isLocalChainAccountRef: (ref: string) => ref is LocalChainA
|
|
|
21
21
|
* InterChainAccountRef (i.e., does it start with `@`)?
|
|
22
22
|
*/
|
|
23
23
|
export declare const isInterChainAccountRef: (ref: string) => ref is InterChainAccountRef;
|
|
24
|
+
/**
|
|
25
|
+
* Without regard to supported chains or instruments, is the input plausibly a
|
|
26
|
+
* PortfolioBalancePlaceRef (i.e., an InterChainAccountRef or InstrumentId)?
|
|
27
|
+
*/
|
|
28
|
+
export declare const isPortfolioBalancePlaceRef: (ref: string) => ref is PortfolioBalancePlaceRef;
|
|
24
29
|
/**
|
|
25
30
|
* Without regard to supported chains, is the input plausibly a
|
|
26
31
|
* WithdrawToChainRef (i.e., does it start with `-`)?
|
package/src/type-guards.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["type-guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["type-guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,wBAAwB,EACxB,oCAAoC,EACpC,iCAAiC,EACjC,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,eAAe,kEAA6B,CAAC;AAG1D,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,aAAa,CAW1D,CAAC;AAGF,eAAO,MAAM,uBAAuB,EAAE,YAAY,CAAC,kBAAkB,CAWlE,CAAC;AAGJ;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,KAAK,MAAM,KACV,GAAG,IAAI,mBAA0C,CAAC;AAGrD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GACjC,KAAK,MAAM,KACV,GAAG,IAAI,oBAA2C,CAAC;AAGtD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GACjC,KAAK,MAAM,KACV,GAAG,IAAI,oBAA2C,CAAC;AAGtD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,KAAK,MAAM,KACV,GAAG,IAAI,wBAC0C,CAAC;AAGrD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,kBACrC,CAAC;AAGtB;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,KAAK,MAAM,KACV,GAAG,IAAI,mBAAiD,CAAC;AAG5D;;;GAGG;AACH,eAAO,MAAM,2BAA2B,GACtC,KAAK,MAAM,KACV,GAAG,IAAI,mBAAuD,CAAC;AAGlE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,iBAC/B,CAAC;AAG3B,eAAO,MAAM,sBAAsB,EAAE,YAAY,CAAC,iBAAiB,CACvD,CAAC;AAEb,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,EAAE,YAAY,CAAC,MAAM,CAE3D,CAAC;AAEH,eAAO,MAAM,uBAAuB,EAAE,YAAY,CAAC,kBAAkB,CAIjE,CAAC;AAEL,eAAO,MAAM,sCAAsC,EAAE,YAAY,CAAC,iCAAiC,CAKhG,CAAC;AAEJ,eAAO,MAAM,yCAAyC,EAAE,YAAY,CAAC,oCAAoC,CAKtG,CAAC"}
|
package/src/type-guards.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
import { M } from '@endo/patterns';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import {
|
|
4
|
+
isInstrumentId,
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
8
|
|
|
9
|
+
} from './places.js';
|
|
9
10
|
;
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
|
|
@@ -83,6 +85,16 @@ export const isInterChainAccountRef = (
|
|
|
83
85
|
) => ref.startsWith('@');
|
|
84
86
|
harden(isInterChainAccountRef);
|
|
85
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Without regard to supported chains or instruments, is the input plausibly a
|
|
90
|
+
* PortfolioBalancePlaceRef (i.e., an InterChainAccountRef or InstrumentId)?
|
|
91
|
+
*/
|
|
92
|
+
export const isPortfolioBalancePlaceRef = (
|
|
93
|
+
ref ,
|
|
94
|
+
) =>
|
|
95
|
+
isInterChainAccountRef(ref) || isInstrumentId(ref);
|
|
96
|
+
harden(isPortfolioBalancePlaceRef);
|
|
97
|
+
|
|
86
98
|
/**
|
|
87
99
|
* Without regard to supported chains, is the input plausibly a
|
|
88
100
|
* WithdrawToChainRef (i.e., does it start with `-`)?
|