@agoric/inter-protocol 0.13.2-dev-3080ea7.0 → 0.13.2-dev-2529e82.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/inter-protocol",
3
- "version": "0.13.2-dev-3080ea7.0+3080ea7",
3
+ "version": "0.13.2-dev-2529e82.0+2529e82",
4
4
  "description": "Core cryptoeconomy contracts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -29,16 +29,16 @@
29
29
  },
30
30
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
31
31
  "dependencies": {
32
- "@agoric/assert": "0.5.2-dev-3080ea7.0+3080ea7",
33
- "@agoric/ertp": "0.15.4-dev-3080ea7.0+3080ea7",
34
- "@agoric/governance": "0.9.2-dev-3080ea7.0+3080ea7",
35
- "@agoric/internal": "0.2.2-dev-3080ea7.0+3080ea7",
36
- "@agoric/notifier": "0.5.2-dev-3080ea7.0+3080ea7",
37
- "@agoric/store": "0.8.4-dev-3080ea7.0+3080ea7",
38
- "@agoric/time": "0.2.2-dev-3080ea7.0+3080ea7",
39
- "@agoric/vat-data": "0.4.4-dev-3080ea7.0+3080ea7",
40
- "@agoric/vats": "0.13.1-dev-3080ea7.0+3080ea7",
41
- "@agoric/zoe": "0.25.4-dev-3080ea7.0+3080ea7",
32
+ "@agoric/assert": "0.5.2-dev-2529e82.0+2529e82",
33
+ "@agoric/ertp": "0.15.4-dev-2529e82.0+2529e82",
34
+ "@agoric/governance": "0.9.2-dev-2529e82.0+2529e82",
35
+ "@agoric/internal": "0.2.2-dev-2529e82.0+2529e82",
36
+ "@agoric/notifier": "0.5.2-dev-2529e82.0+2529e82",
37
+ "@agoric/store": "0.8.4-dev-2529e82.0+2529e82",
38
+ "@agoric/time": "0.2.2-dev-2529e82.0+2529e82",
39
+ "@agoric/vat-data": "0.4.4-dev-2529e82.0+2529e82",
40
+ "@agoric/vats": "0.13.1-dev-2529e82.0+2529e82",
41
+ "@agoric/zoe": "0.25.4-dev-2529e82.0+2529e82",
42
42
  "@endo/captp": "^2.0.18",
43
43
  "@endo/eventual-send": "^0.16.8",
44
44
  "@endo/far": "^0.2.14",
@@ -46,10 +46,10 @@
46
46
  "@endo/nat": "^4.1.23"
47
47
  },
48
48
  "devDependencies": {
49
- "@agoric/deploy-script-support": "0.9.5-dev-3080ea7.0+3080ea7",
50
- "@agoric/smart-wallet": "0.4.3-dev-3080ea7.0+3080ea7",
51
- "@agoric/swingset-liveslots": "0.9.1-dev-3080ea7.0+3080ea7",
52
- "@agoric/swingset-vat": "0.30.3-dev-3080ea7.0+3080ea7",
49
+ "@agoric/deploy-script-support": "0.9.5-dev-2529e82.0+2529e82",
50
+ "@agoric/smart-wallet": "0.4.3-dev-2529e82.0+2529e82",
51
+ "@agoric/swingset-liveslots": "0.9.1-dev-2529e82.0+2529e82",
52
+ "@agoric/swingset-vat": "0.30.3-dev-2529e82.0+2529e82",
53
53
  "@endo/bundle-source": "^2.4.2",
54
54
  "@endo/init": "^0.5.52",
55
55
  "@endo/promise-kit": "^0.2.52",
@@ -78,5 +78,5 @@
78
78
  "publishConfig": {
79
79
  "access": "public"
80
80
  },
81
- "gitHead": "3080ea77dc39bc84db176017173c9dd5cebd4011"
81
+ "gitHead": "2529e82427277d98ea777c5a35e6bd753e65e6f7"
82
82
  }
@@ -0,0 +1,228 @@
1
+ // @ts-check
2
+
3
+ import { Fail } from '@agoric/assert';
4
+
5
+ // XXX support other decimal places
6
+ const COSMOS_UNIT = 1_000_000n;
7
+
8
+ // NB: not really a Proposal because the brands are not remotes
9
+ // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
10
+ // mustMatch(harden(proposal), ProposalShape);
11
+ /**
12
+ * Give/want
13
+ *
14
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
15
+ * @param {{ giveMinted?: number, wantMinted?: number } | { collateralBrandKey: string, giveCollateral?: number, wantCollateral?: number }} opts
16
+ * @returns {Proposal}
17
+ */
18
+ const makeVaultProposal = (brands, opts) => {
19
+ const proposal = { give: {}, want: {} };
20
+
21
+ if ('giveCollateral' in opts && opts.giveCollateral) {
22
+ const { collateralBrandKey } = opts;
23
+ proposal.give.Collateral = {
24
+ brand: brands[collateralBrandKey],
25
+ value: BigInt(opts.giveCollateral * Number(COSMOS_UNIT)),
26
+ };
27
+ }
28
+ if ('giveMinted' in opts && opts.giveMinted) {
29
+ proposal.give.Minted = {
30
+ brand: brands.IST,
31
+ value: BigInt(opts.giveMinted * Number(COSMOS_UNIT)),
32
+ };
33
+ }
34
+
35
+ if ('wantCollateral' in opts && opts.wantCollateral) {
36
+ const { collateralBrandKey } = opts;
37
+ proposal.want.Collateral = {
38
+ brand: brands[collateralBrandKey],
39
+ value: BigInt(opts.wantCollateral * Number(COSMOS_UNIT)),
40
+ };
41
+ }
42
+ if ('wantMinted' in opts && opts.wantMinted) {
43
+ proposal.want.Minted = {
44
+ brand: brands.IST,
45
+ value: BigInt(opts.wantMinted * Number(COSMOS_UNIT)),
46
+ };
47
+ }
48
+
49
+ return harden(proposal);
50
+ };
51
+
52
+ // TODO factor out BridgeAction so that these functions just return OfferSpec
53
+ // That they are composed into a BridgeAction is the concern of the caller.
54
+ // Then these can be used in tests as arguments to `executeOffer()` without a bridge.
55
+
56
+ /**
57
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
58
+ * @param {{ offerId: string, wantMinted: number, giveCollateral: number, collateralBrandKey: string }} opts
59
+ * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
60
+ */
61
+ const makeOpenOffer = (brands, opts) => {
62
+ const proposal = makeVaultProposal(brands, opts);
63
+
64
+ console.warn('vaults open give', proposal.give);
65
+ console.warn('vaults open want', proposal.want);
66
+
67
+ // NB: not really a Proposal because the brands are not remotes
68
+ // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
69
+ // mustMatch(harden(proposal), ProposalShape);
70
+
71
+ const collateralBrand = brands[opts.collateralBrandKey];
72
+
73
+ return {
74
+ id: opts.offerId,
75
+ invitationSpec: {
76
+ source: 'agoricContract',
77
+ instancePath: ['VaultFactory'],
78
+ callPipe: [
79
+ ['getCollateralManager', [collateralBrand]],
80
+ ['makeVaultInvitation'],
81
+ ],
82
+ },
83
+ proposal,
84
+ };
85
+ };
86
+
87
+ /**
88
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
89
+ * @param {{ offerId: string, collateralBrandKey?: string, giveCollateral?: number, wantCollateral?: number, giveMinted?: number, wantMinted?: number }} opts
90
+ * @param {string} previousOffer
91
+ * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
92
+ */
93
+ const makeAdjustOffer = (brands, opts, previousOffer) => {
94
+ // NB: not really a Proposal because the brands are not remotes
95
+ // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
96
+ // mustMatch(harden(proposal), ProposalShape);
97
+ const proposal = makeVaultProposal(brands, opts);
98
+
99
+ return {
100
+ id: opts.offerId,
101
+ invitationSpec: {
102
+ source: 'continuing',
103
+ previousOffer,
104
+ invitationMakerName: 'AdjustBalances',
105
+ },
106
+ proposal,
107
+ };
108
+ };
109
+
110
+ /**
111
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
112
+ * @param {{ offerId: string, collateralBrandKey?: string, giveMinted: number }} opts
113
+ * @param {string} previousOffer
114
+ * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
115
+ */
116
+ const makeCloseOffer = (brands, opts, previousOffer) => {
117
+ const proposal = makeVaultProposal(brands, opts);
118
+ console.warn('vaults close give', proposal.give);
119
+
120
+ return {
121
+ id: opts.offerId,
122
+ invitationSpec: {
123
+ source: 'continuing',
124
+ previousOffer,
125
+ invitationMakerName: 'CloseVault',
126
+ },
127
+ proposal,
128
+ };
129
+ };
130
+
131
+ /**
132
+ * @param {string} vaultId
133
+ * @param {Promise<import('@agoric/smart-wallet/src/smartWallet').CurrentWalletRecord>} currentP
134
+ * @returns {Promise<string>} offer id in which the vault was made
135
+ */
136
+ export const lookupOfferIdForVault = async (vaultId, currentP) => {
137
+ const { offerToPublicSubscriberPaths } = await currentP;
138
+
139
+ for (const [offerId, publicSubscribers] of Object.entries(
140
+ offerToPublicSubscriberPaths,
141
+ )) {
142
+ if (publicSubscribers.vault?.endsWith(vaultId)) {
143
+ return offerId;
144
+ }
145
+ }
146
+ throw Fail`vault ${vaultId} not found`;
147
+ };
148
+
149
+ /**
150
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
151
+ * @param {({ wantMinted: number | undefined, giveMinted: number | undefined })} opts
152
+ * @param {number} [fee=0]
153
+ * @param {string} [anchor]
154
+ * @returns {Proposal} XXX not a real proposal, uses BoardRemote
155
+ */
156
+ const makePsmProposal = (brands, opts, fee = 0, anchor = 'AUSD') => {
157
+ const giving = opts.giveMinted ? 'minted' : 'anchor';
158
+ const brand =
159
+ giving === 'anchor'
160
+ ? { in: brands[anchor], out: brands.IST }
161
+ : { in: brands.IST, out: brands[anchor] };
162
+ const value =
163
+ Number(giving === 'anchor' ? opts.wantMinted : opts.giveMinted) *
164
+ Number(COSMOS_UNIT);
165
+ const adjusted = {
166
+ in: BigInt(Math.ceil(giving === 'anchor' ? value / (1 - fee) : value)),
167
+ out: BigInt(Math.ceil(giving === 'minted' ? value * (1 - fee) : value)),
168
+ };
169
+ return {
170
+ give: {
171
+ // @ts-expect-error XXX BoardRemote not real remote
172
+ In: { brand: brand.in, value: adjusted.in },
173
+ },
174
+ want: {
175
+ // @ts-expect-error XXX BoardRemote not real remote
176
+ Out: { brand: brand.out, value: adjusted.out },
177
+ },
178
+ };
179
+ };
180
+
181
+ /**
182
+ * @param {Instance} instance
183
+ * @param {Record<string, import('@agoric/vats/tools/board-utils').BoardRemote>} brands
184
+ * @param {{ offerId: number, feePct?: number } &
185
+ * ({ wantMinted: number | undefined, giveMinted: number | undefined })} opts
186
+ * @returns {import('@agoric/smart-wallet/src/offers.js').OfferSpec}
187
+ */
188
+ const makePsmSwapOffer = (instance, brands, opts) => {
189
+ const method = opts.wantMinted
190
+ ? 'makeWantMintedInvitation'
191
+ : 'makeGiveMintedInvitation'; // ref psm.js
192
+ const proposal = makePsmProposal(
193
+ brands,
194
+ opts,
195
+ opts.feePct ? opts.feePct / 100 : undefined,
196
+ // @ts-expect-error please update types. Not sure where pair goees.
197
+ opts.pair[1],
198
+ );
199
+
200
+ console.warn('psm spend give', proposal.give);
201
+ console.warn('psm spend want', proposal.want);
202
+
203
+ // NB: not really a Proposal because the brands are not remotes
204
+ // Instead they're copyRecord like "{"boardId":"board0257","iface":"Alleged: IST brand"}" to pass through the boardId
205
+ // mustMatch(harden(proposal), ProposalShape);
206
+
207
+ return {
208
+ id: opts.offerId,
209
+ invitationSpec: {
210
+ source: 'contract',
211
+ instance,
212
+ publicInvitationMaker: method,
213
+ },
214
+ proposal,
215
+ };
216
+ };
217
+
218
+ export const Offers = {
219
+ psm: {
220
+ // lowercase because it's not an invitation name. Instead it's an abstraction over two invitation makers.
221
+ swap: makePsmSwapOffer,
222
+ },
223
+ vaults: {
224
+ OpenVault: makeOpenOffer,
225
+ AdjustBalances: makeAdjustOffer,
226
+ CloseVault: makeCloseOffer,
227
+ },
228
+ };
@@ -33,7 +33,7 @@ const BASIS_POINTS = 10_000n;
33
33
  * @property {Instance} psm
34
34
  * @property {Instance} psmGovernor
35
35
  * @property {Awaited<ReturnType<import('../psm/psm.js').start>>['creatorFacet']} psmCreatorFacet
36
- * @property {GovernedContractFacetAccess<{},{}>} psmGovernorCreatorFacet
36
+ * @property {GovernedContractFacetAccess<import('../../src/psm/psm.js').PsmPublicFacet,{}>} psmGovernorCreatorFacet
37
37
  * @property {AdminFacet} psmAdminFacet
38
38
  */
39
39