@agoric/inter-protocol 0.16.2-dev-9b9282d.0 → 0.16.2-dev-47d00ff.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.16.2-dev-9b9282d.0+9b9282d",
3
+ "version": "0.16.2-dev-47d00ff.0+47d00ff",
4
4
  "description": "Core cryptoeconomy contracts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -84,5 +84,5 @@
84
84
  "typeCoverage": {
85
85
  "atLeast": 95.72
86
86
  },
87
- "gitHead": "9b9282da6084800264431cb198a5230f8e2606c9"
87
+ "gitHead": "47d00ffad8c595b0a9be215efc6665204ff90525"
88
88
  }
@@ -48,8 +48,8 @@ export function start(zcf: ZCF<ProvisionTerms>, privateArgs: {
48
48
  getUnknown: (name: string) => any;
49
49
  getSubscription: () => globalThis.StoredSubscription<globalThis.GovernanceSubscriptionState>;
50
50
  getGovernedParams: () => globalThis.ERef<globalThis.ParamStateRecord>;
51
- getMetrics(): any;
52
- getPublicTopics(): any;
51
+ getMetrics(): Promise<any>;
52
+ getPublicTopics(): Promise<any>;
53
53
  }>;
54
54
  }>;
55
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"provisionPool.d.ts","sourceRoot":"","sources":["provisionPool.js"],"names":[],"mappings":"AAmBA;;;;;GAKG;AAEH,2BAA2B;AAC3B,mBADW,YAAY,CAerB;AAsBK,2BAbI,IAAI,cAAc,CAAC,eACnB;IACN,QAAQ,EAAE,OAAO,WAAW,EAAE,IAAI,CACtC,OAAa,8BAA8B,EAAE,IAAI,CAC5C,CAAC;IACF,sBAAsB,EAAE,UAAU,CAAC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,uBAAuB,EAAE,mBAAmB,CAAC;IACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC7D,WACO,OAAO,kBAAkB,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwE5C;;;;6BAxFY,aAAa,GACzB,gBAAoB;IACd,uBAAuB,EAAE,QAAQ,CAAC;CACnC,CAAC;kCA1BwD,aAAa;yBAAb,aAAa;gCAAb,aAAa;6BAFlD,eAAe;4BACO,cAAc;2BAAd,cAAc;mCACC,aAAa;qCAC1C,iCAAiC"}
1
+ {"version":3,"file":"provisionPool.d.ts","sourceRoot":"","sources":["provisionPool.js"],"names":[],"mappings":"AAmBA;;;;;GAKG;AAEH,2BAA2B;AAC3B,mBADW,YAAY,CAerB;AAsBK,2BAbI,IAAI,cAAc,CAAC,eACnB;IACN,QAAQ,EAAE,OAAO,WAAW,EAAE,IAAI,CACtC,OAAa,8BAA8B,EAAE,IAAI,CAC5C,CAAC;IACF,sBAAsB,EAAE,UAAU,CAAC;IACnC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,uBAAuB,EAAE,mBAAmB,CAAC;IACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC7D,WACO,OAAO,kBAAkB,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0E5C;;;;6BA1FY,aAAa,GACzB,gBAAoB;IACd,uBAAuB,EAAE,QAAQ,CAAC;CACnC,CAAC;kCA1BwD,aAAa;yBAAb,aAAa;gCAAb,aAAa;6BAFlD,eAAe;4BACO,cAAc;2BAAd,cAAc;mCACC,aAAa;qCAC1C,iCAAiC"}
@@ -93,33 +93,35 @@ export const start = async (zcf, privateArgs, baggage) => {
93
93
  makeBridgeProvisionTool,
94
94
  });
95
95
 
96
+ const poolBrand = /** @type {Brand<'nat'>} */ (
97
+ params.getPerAccountInitialAmount().brand
98
+ );
96
99
  const provisionPoolKit = await provideSingleton(
97
100
  baggage,
98
101
  'provisionPoolKit',
99
102
  () =>
100
103
  makeProvisionPoolKit({
101
- // XXX governance can change the brand of the amount but should only be able to change the value
102
- // NB: changing the brand will break this pool
103
- // @ts-expect-error XXX Brand AssetKind
104
- poolBrand: params.getPerAccountInitialAmount().brand,
104
+ poolBrand,
105
105
  storageNode: privateArgs.storageNode,
106
106
  }),
107
- kit => kit.helper.start({ metrics: metricsOverride }),
108
107
  );
108
+ provisionPoolKit.helper.start(poolBrand, { metrics: metricsOverride });
109
109
 
110
110
  const publicFacet = prepareExo(
111
111
  baggage,
112
112
  'Provisioning Pool public',
113
113
  M.interface('ProvisionPool', {
114
- getMetrics: M.call().returns(M.remotable('MetricsSubscriber')),
115
- getPublicTopics: M.call().returns(TopicsRecordShape),
114
+ getMetrics: M.callWhen().returns(M.remotable('MetricsSubscriber')),
115
+ getPublicTopics: M.callWhen().returns(TopicsRecordShape),
116
116
  ...publicMixinAPI,
117
117
  }),
118
118
  {
119
- getMetrics() {
119
+ async getMetrics() {
120
+ await null;
120
121
  return provisionPoolKit.public.getPublicTopics().metrics.subscriber;
121
122
  },
122
- getPublicTopics() {
123
+ async getPublicTopics() {
124
+ await null;
123
125
  return provisionPoolKit.public.getPublicTopics();
124
126
  },
125
127
  ...publicMixin,
@@ -1 +1 @@
1
- {"version":3,"file":"provisionPoolKit.d.ts","sourceRoot":"","sources":["provisionPoolKit.js"],"names":[],"mappings":"AAkFO,iDAFI,OAAO,cAAc,EAAE,IAAI;;;;;eA+ds7E,CAAC;;;;;;IAtcv9E,iCAAiC;oBAArB,aAAa;GA6B5B;AAYI,8CATI,OAAO,cAAc,EAAE,IAAI,uEAC3B;IACN,eAAe,EAAE,OAAO,6CAA6C,EAAE,eAAe,CAAC;IACvF,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,OAAO,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,GAAG,EAAE,GAAG,CAAC;IACT,uBAAuB,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;CACxE,gCA8YC;IAA2B,SAAS,EAA5B,MAAM,KAAK,CAAC;IACY,WAAW,EAAnC,KAAK,WAAW,CAAC;CACzB,KAAU,OAAO,CAAC,gBAAgB,CAAC,CAcvC;+BAngBY;IACR,OAAO,EAAE,GAAG,CAAC;IACb,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,GAAG,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC;CACb;0BAIS,OAAO,qCAAqC,EAAE,QAAQ,CAClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAyD,CACtD;;iBAKU,KAAK,WAAW,CAAC;yBACjB,KAAK,OAAO,cAAc,EAAE,SAAS,CAAC;mBACtC,KACb,OAAW,6CAA6C,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAC/F;;;;;;;;;;wBAMU,MAAM;;;;;yBACN,OAAO,KAAK,CAAC;;;;;0BAEb,OAAO,KAAK,CAAC;;0BAzCJ,WAAW;6BAHc,cAAc;0BAI1B,8BAA8B;mCALlC,sCAAsC;yBAGhD,aAAa;2BAFa,cAAc;iCAChC,0CAA0C;4BADxB,cAAc;iCAI1B,8BAA8B"}
1
+ {"version":3,"file":"provisionPoolKit.d.ts","sourceRoot":"","sources":["provisionPoolKit.js"],"names":[],"mappings":"AAmFO,iDAFI,OAAO,cAAc,EAAE,IAAI;;;;;eA8gBoqB,CAAC;;;;;;IArfrsB,iCAAiC;oBAArB,aAAa;GA6B5B;AAYI,8CATI,OAAO,cAAc,EAAE,IAAI,uEAC3B;IACN,eAAe,EAAE,OAAO,6CAA6C,EAAE,eAAe,CAAC;IACvF,MAAM,EAAE,GAAG,CAAC;IACZ,QAAQ,EAAE,OAAO,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,GAAG,EAAE,GAAG,CAAC;IACT,uBAAuB,EAAE,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;CACxE,gCA6bC;IAA2B,SAAS,EAA5B,MAAM,KAAK,CAAC;IACY,WAAW,EAAnC,KAAK,WAAW,CAAC;CACzB,KAAU,OAAO,CAAC,gBAAgB,CAAC,CAcvC;+BAljBY;IACR,OAAO,EAAE,GAAG,CAAC;IACb,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,GAAG,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC;CACb;0BAIS,OAAO,qCAAqC,EAAE,QAAQ,CAClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAyD,CACtD;;iBAKU,KAAK,WAAW,CAAC;yBACjB,KAAK,OAAO,cAAc,EAAE,SAAS,CAAC;mBACtC,KACb,OAAW,6CAA6C,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAC/F;;;;;;;;;;wBAMU,MAAM;;;;;yBACN,OAAO,KAAK,CAAC;;;;;0BAEb,OAAO,KAAK,CAAC;;0BAzCJ,WAAW;6BAHc,cAAc;0BAI1B,8BAA8B;mCALlC,sCAAsC;yBAGhD,aAAa;2BAFa,cAAc;iCAChC,0CAA0C;4BADxB,cAAc;iCAI1B,8BAA8B"}
@@ -15,6 +15,7 @@ import {
15
15
  makeScalarBigMapStore,
16
16
  makeScalarBigSetStore,
17
17
  } from '@agoric/vat-data';
18
+ import { makeAtomicProvider, makeScalarMapStore } from '@agoric/store';
18
19
  import { PowerFlags } from '@agoric/vats/src/walletFlags.js';
19
20
  import {
20
21
  PublicTopicShape,
@@ -149,6 +150,20 @@ export const prepareProvisionPoolKit = (
149
150
  { makeRecorderKit, params, poolBank, zcf, makeBridgeProvisionTool },
150
151
  ) => {
151
152
  const zoe = zcf.getZoeService();
153
+ const ephemeralPurses = makeScalarMapStore('fundingPurseForBrand');
154
+ const purseProvider = makeAtomicProvider(ephemeralPurses);
155
+ const getFundingPurseForBrand = async poolBrand => {
156
+ await null;
157
+ try {
158
+ const purse = await purseProvider.provideAsync(poolBrand, brand =>
159
+ E(poolBank).getPurse(brand),
160
+ );
161
+ return purse;
162
+ } catch (err) {
163
+ trace(`🚨 could not get purse for brand ${poolBrand}`, err);
164
+ throw err;
165
+ }
166
+ };
152
167
 
153
168
  const makeProvisionPoolKitInternal = zone.exoClassKit(
154
169
  'ProvisionPoolKit',
@@ -180,7 +195,7 @@ export const prepareProvisionPoolKit = (
180
195
  },
181
196
  /**
182
197
  * @param {object} opts
183
- * @param {Purse<'nat'>} opts.fundPurse
198
+ * @param {Purse<'nat'>} [opts.fundPurse]
184
199
  * @param {Brand<'nat'>} opts.poolBrand
185
200
  * @param {StorageNode} opts.metricsNode
186
201
  */
@@ -335,35 +350,43 @@ export const prepareProvisionPoolKit = (
335
350
  );
336
351
  facets.helper.publishMetrics();
337
352
  },
353
+ /**
354
+ * @param {Amount} amount
355
+ * @param {ERef<Purse>} srcPurse
356
+ */
357
+ async onPoolDeposit(amount, srcPurse) {
358
+ const { helper } = this.facets;
359
+ const { brandToPSM, poolBrand } = this.state;
360
+
361
+ const { brand } = amount;
362
+ if (AmountMath.isEmpty(amount) || brand === poolBrand) {
363
+ return;
364
+ }
365
+
366
+ // `amount` doesn't match the current `poolBrand`, so we need to swap
367
+ // it.
368
+ if (!brandToPSM.has(brand)) {
369
+ console.error('funds arrived but no PSM instance', brand);
370
+ return;
371
+ }
372
+ const instance = brandToPSM.get(brand);
373
+ const payment = E(srcPurse).withdraw(amount);
374
+ await helper.swap(payment, amount, instance).catch(async reason => {
375
+ console.error(X`swap failed: ${reason}`);
376
+ const resolvedPayment = await payment;
377
+ return E(srcPurse).deposit(resolvedPayment);
378
+ });
379
+ },
338
380
  /**
339
381
  * @param {ERef<Purse>} exchangePurse
340
382
  * @param {ERef<Brand>} brand
341
383
  */
342
384
  watchCurrentAmount(exchangePurse, brand) {
343
- const {
344
- state: { brandToPSM, poolBrand },
345
- facets: { helper },
346
- } = this;
347
-
385
+ const { helper } = this.facets;
348
386
  void observeNotifier(E(exchangePurse).getCurrentAmountNotifier(), {
349
387
  updateState: async amount => {
350
388
  trace('provisionPool balance update', amount);
351
- if (AmountMath.isEmpty(amount) || amount.brand === poolBrand) {
352
- return;
353
- }
354
- if (!brandToPSM.has(brand)) {
355
- console.error('funds arrived but no PSM instance', brand);
356
- return;
357
- }
358
- const instance = brandToPSM.get(brand);
359
- const payment = E(exchangePurse).withdraw(amount);
360
- await helper
361
- .swap(payment, amount, instance)
362
- .catch(async reason => {
363
- console.error(X`swap failed: ${reason}`);
364
- const resolvedPayment = await payment;
365
- return E(exchangePurse).deposit(resolvedPayment);
366
- });
389
+ await helper.onPoolDeposit(amount, exchangePurse);
367
390
  },
368
391
  fail: reason => {
369
392
  if (isUpgradeDisconnection(reason)) {
@@ -429,40 +452,50 @@ export const prepareProvisionPoolKit = (
429
452
  );
430
453
  },
431
454
  /**
455
+ * @param {Brand<'nat'>} poolBrand
432
456
  * @param {object} [options]
433
457
  * @param {MetricsNotification} [options.metrics]
434
458
  */
435
- start({ metrics } = {}) {
436
- const {
437
- state: { poolBrand },
438
- facets: { helper },
439
- } = this;
459
+ start(poolBrand, { metrics } = {}) {
460
+ const { facets, state } = this;
461
+ const { helper } = facets;
462
+ const lastPoolBrand = state.poolBrand;
440
463
 
441
- // Must match. poolBrand is from durable state and the param is from
442
- // the contract, so it technically can change between incarnations.
443
- // That would be a severe bug.
464
+ // The PerAccountInitialAmount param must use the correct brand for
465
+ // this incarnation.
444
466
  AmountMath.coerce(poolBrand, params.getPerAccountInitialAmount());
445
467
 
446
- void helper.watchAssetSubscription();
447
-
468
+ // Restore old metrics.
448
469
  if (metrics) {
449
- // Restore state.
450
- // we publishMetrics() below
451
470
  const {
452
471
  walletsProvisioned,
453
472
  totalMintedProvided,
454
473
  totalMintedConverted,
455
474
  } = metrics;
456
475
  assert.typeof(walletsProvisioned, 'bigint');
457
- AmountMath.coerce(poolBrand, totalMintedProvided);
458
- AmountMath.coerce(poolBrand, totalMintedConverted);
459
- Object.assign(this.state, {
476
+ AmountMath.coerce(lastPoolBrand, totalMintedProvided);
477
+ AmountMath.coerce(lastPoolBrand, totalMintedConverted);
478
+ Object.assign(state, {
460
479
  walletsProvisioned,
461
480
  totalMintedProvided,
462
481
  totalMintedConverted,
463
482
  });
464
483
  helper.publishMetrics();
465
484
  }
485
+
486
+ // Update as needed when `poolBrand` changes.
487
+ if (poolBrand !== lastPoolBrand) {
488
+ state.poolBrand = poolBrand;
489
+ state.fundPurse = undefined;
490
+ void getFundingPurseForBrand(poolBrand).then(purse =>
491
+ helper.updateFundPurse(purse, poolBrand),
492
+ );
493
+ state.totalMintedProvided = AmountMath.makeEmpty(poolBrand);
494
+ state.totalMintedConverted = AmountMath.makeEmpty(poolBrand);
495
+ helper.publishMetrics();
496
+ }
497
+
498
+ void helper.watchAssetSubscription();
466
499
  },
467
500
  /**
468
501
  * @param {ERef<Payment>} payIn
@@ -470,10 +503,13 @@ export const prepareProvisionPoolKit = (
470
503
  * @param {PsmInstance} instance
471
504
  */
472
505
  async swap(payIn, amount, instance) {
506
+ await null;
507
+ const { facets, state } = this;
508
+ const { helper } = facets;
473
509
  const {
474
- facets: { helper },
475
- state: { fundPurse },
476
- } = this;
510
+ poolBrand,
511
+ fundPurse = await getFundingPurseForBrand(poolBrand),
512
+ } = state;
477
513
  const psmPub = E(zoe).getPublicFacet(instance);
478
514
  const proposal = harden({ give: { In: amount } });
479
515
  const invitation = E(psmPub).makeWantMintedInvitation();
@@ -483,19 +519,31 @@ export const prepareProvisionPoolKit = (
483
519
  helper.onTrade(rxd);
484
520
  return rxd;
485
521
  },
522
+ /**
523
+ * @param {Purse<'nat'>} purse
524
+ * @param {Brand<'nat'>} brand
525
+ */
526
+ updateFundPurse(purse, brand) {
527
+ const { state } = this;
528
+ if (brand !== state.poolBrand || state.fundPurse) return;
529
+ state.fundPurse = purse;
530
+ },
486
531
  },
487
532
  forHandler: {
488
533
  onProvisioned() {
489
- const { state, facets } = this;
534
+ const { facets, state } = this;
490
535
  state.walletsProvisioned += 1n;
491
536
  facets.helper.publishMetrics();
492
537
  },
493
538
  /** @param {ERef<Bank>} destBank */
494
539
  async sendInitialPayment(destBank) {
540
+ await null;
541
+ const { facets, state } = this;
542
+ const { helper } = facets;
495
543
  const {
496
- facets: { helper },
497
- state: { fundPurse, poolBrand },
498
- } = this;
544
+ poolBrand,
545
+ fundPurse = await getFundingPurseForBrand(poolBrand),
546
+ } = state;
499
547
  const perAccountInitialAmount = /** @type {Amount<'nat'>} */ (
500
548
  params.getPerAccountInitialAmount()
501
549
  );
@@ -545,7 +593,7 @@ export const prepareProvisionPoolKit = (
545
593
  * @returns {Promise<ProvisionPoolKit>}
546
594
  */
547
595
  const makeProvisionPoolKit = async ({ poolBrand, storageNode }) => {
548
- const fundPurse = await E(poolBank).getPurse(poolBrand);
596
+ const fundPurse = await getFundingPurseForBrand(poolBrand);
549
597
  const metricsNode = await E(storageNode).makeChildNode('metrics');
550
598
 
551
599
  return makeProvisionPoolKitInternal({