@agoric/smart-wallet 0.5.4-other-dev-3eb1a1d.0 → 0.5.4-other-dev-d15096d.0.d15096d

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.
@@ -1,5 +1,5 @@
1
1
  import { Fail, q } from '@endo/errors';
2
- import { E } from '@endo/far';
2
+ import { E, passStyleOf } from '@endo/far';
3
3
  import {
4
4
  AmountShape,
5
5
  BrandShape,
@@ -15,7 +15,7 @@ import {
15
15
  StorageNodeShape,
16
16
  } from '@agoric/internal';
17
17
  import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
18
- import { M, mustMatch } from '@agoric/store';
18
+ import { M, matches, mustMatch } from '@agoric/store';
19
19
  import {
20
20
  appendToStoredArray,
21
21
  provideLazy,
@@ -36,6 +36,7 @@ import {
36
36
  import {
37
37
  AmountKeywordRecordShape,
38
38
  PaymentPKeywordRecordShape,
39
+ InvitationElementShape,
39
40
  } from '@agoric/zoe/src/typeGuards.js';
40
41
  import { prepareVowTools } from '@agoric/vow';
41
42
  import { makeDurableZone } from '@agoric/zone/durable.js';
@@ -45,7 +46,25 @@ import { shape } from './typeGuards.js';
45
46
  import { objectMapStoragePath } from './utils.js';
46
47
  import { prepareOfferWatcher, makeWatchOfferOutcomes } from './offerWatcher.js';
47
48
 
48
- /** @import {OfferId, OfferStatus} from './offers.js'; */
49
+ /**
50
+ * @import {ERemote, Remote} from '@agoric/internal';
51
+ * @import {EMarshaller} from '@agoric/internal/src/marshal/wrap-marshaller.js';
52
+ * @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
53
+ * @import {WeakMapStore, MapStore} from '@agoric/store'
54
+ * @import {InvitationAmount, InvitationDetails, PaymentPKeywordRecord, Proposal, UserSeat} from '@agoric/zoe';
55
+ * @import {CopyRecord} from '@endo/pass-style';
56
+ * @import {EReturn} from '@endo/far';
57
+ * @import {OfferId, OfferStatus, OfferSpec, InvokeEntryMessage, ResultPlan} from './offers.js';
58
+ * @import {MakeOfferWatcher} from './offerWatcher.js';
59
+ * @import {Petname} from './types.js';
60
+ * @import {Bank} from '@agoric/vats/src/vat-bank.js';
61
+ * @import {NameHub} from '@agoric/vats';
62
+ * @import {InvitationMakers} from './types.js';
63
+ * @import {RecorderKit} from '@agoric/zoe/src/contractSupport/recorder.js';
64
+ * @import {Baggage} from '@agoric/vat-data';
65
+ * @import {PublicSubscribers} from './types.js';
66
+ * @import {CapData} from '@endo/marshal';
67
+ */
49
68
 
50
69
  const trace = makeTracer('SmrtWlt');
51
70
 
@@ -54,24 +73,13 @@ const trace = makeTracer('SmrtWlt');
54
73
  * @see {@link ../README.md} }
55
74
  */
56
75
 
57
- /** @typedef {number | string} OfferId */
58
-
59
- /**
60
- * @typedef {{
61
- * id: OfferId;
62
- * invitationSpec: import('./invitations').InvitationSpec;
63
- * proposal: Proposal;
64
- * offerArgs?: any;
65
- * }} OfferSpec
66
- */
67
-
68
76
  /**
69
77
  * @typedef {{
70
78
  * logger: {
71
79
  * info: (...args: any[]) => void;
72
80
  * error: (...args: any[]) => void;
73
81
  * };
74
- * makeOfferWatcher: import('./offerWatcher.js').MakeOfferWatcher;
82
+ * makeOfferWatcher: MakeOfferWatcher;
75
83
  * invitationFromSpec: ERef<Invitation>;
76
84
  * }} ExecutorPowers
77
85
  */
@@ -90,10 +98,16 @@ const trace = makeTracer('SmrtWlt');
90
98
  * }} TryExitOfferAction
91
99
  */
92
100
 
101
+ /**
102
+ * @typedef {object} InvokeStoreEntryAction
103
+ * @property {'invokeEntry'} method BridgeAction discriminator
104
+ * @property {InvokeEntryMessage} message object method call to make
105
+ */
106
+
93
107
  // Discriminated union. Possible future messages types:
94
108
  // maybe suggestIssuer for https://github.com/Agoric/agoric-sdk/issues/6132
95
109
  // setting petnames and adding brands for https://github.com/Agoric/agoric-sdk/issues/6126
96
- /** @typedef {ExecuteOfferAction | TryExitOfferAction} BridgeAction */
110
+ /** @typedef {ExecuteOfferAction | TryExitOfferAction | InvokeStoreEntryAction} BridgeAction */
97
111
 
98
112
  /**
99
113
  * Purses is an array to support a future requirement of multiple purses per
@@ -132,7 +146,13 @@ const trace = makeTracer('SmrtWlt');
132
146
  /**
133
147
  * @typedef {{ updated: 'offerStatus'; status: OfferStatus }
134
148
  * | { updated: 'balance'; currentAmount: Amount }
135
- * | { updated: 'walletAction'; status: { error: string } }} UpdateRecord
149
+ * | { updated: 'walletAction'; status: { error: string } }
150
+ * | {
151
+ * updated: 'invocation';
152
+ * id: string | number;
153
+ * error?: string;
154
+ * result?: { name?: string; passStyle: string };
155
+ * }} UpdateRecord
136
156
  * Record of an update to the state of this wallet.
137
157
  *
138
158
  * Client is responsible for coalescing updates into a current state. See
@@ -151,7 +171,7 @@ const trace = makeTracer('SmrtWlt');
151
171
  * brand: Brand;
152
172
  * displayInfo: DisplayInfo;
153
173
  * issuer: Issuer;
154
- * petname: import('./types.js').Petname;
174
+ * petname: Petname;
155
175
  * }} BrandDescriptor
156
176
  * For use by clients to describe brands to users. Includes `displayInfo` to
157
177
  * save a remote call.
@@ -160,10 +180,10 @@ const trace = makeTracer('SmrtWlt');
160
180
  /**
161
181
  * @typedef {{
162
182
  * address: string;
163
- * bank: ERef<import('@agoric/vats/src/vat-bank.js').Bank>;
164
- * currentStorageNode: StorageNode;
183
+ * bank: ERef<Bank>;
184
+ * currentStorageNode: Remote<StorageNode>;
165
185
  * invitationPurse: Purse<'set', InvitationDetails>;
166
- * walletStorageNode: StorageNode;
186
+ * walletStorageNode: Remote<StorageNode>;
167
187
  * }} UniqueParams
168
188
  *
169
189
  *
@@ -171,12 +191,12 @@ const trace = makeTracer('SmrtWlt');
171
191
  *
172
192
  *
173
193
  * @typedef {{
174
- * agoricNames: ERef<import('@agoric/vats').NameHub>;
194
+ * agoricNames: ERef<NameHub>;
175
195
  * registry: BrandDescriptorRegistry;
176
196
  * invitationIssuer: Issuer<'set'>;
177
197
  * invitationBrand: Brand<'set'>;
178
198
  * invitationDisplayInfo: DisplayInfo;
179
- * publicMarshaller: Marshaller;
199
+ * publicMarshaller: ERemote<EMarshaller>;
180
200
  * zoe: ERef<ZoeService>;
181
201
  * }} SharedParams
182
202
  *
@@ -193,18 +213,16 @@ const trace = makeTracer('SmrtWlt');
193
213
  * @typedef {Readonly<
194
214
  * UniqueParams & {
195
215
  * paymentQueues: MapStore<Brand, Payment[]>;
196
- * offerToInvitationMakers: MapStore<
197
- * string,
198
- * import('./types.js').InvitationMakers
199
- * >;
216
+ * offerToInvitationMakers: MapStore<string, InvitationMakers>;
200
217
  * offerToPublicSubscriberPaths: MapStore<string, Record<string, string>>;
201
218
  * offerToUsedInvitation: MapStore<string, Amount<'set'>>;
202
219
  * purseBalances: MapStore<Purse, Amount>;
203
- * updateRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<UpdateRecord>;
204
- * currentRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<CurrentWalletRecord>;
220
+ * updateRecorderKit: RecorderKit<UpdateRecord>;
221
+ * currentRecorderKit: RecorderKit<CurrentWalletRecord>;
205
222
  * liveOffers: MapStore<OfferId, OfferStatus>;
206
223
  * liveOfferSeats: MapStore<OfferId, UserSeat<unknown>>;
207
224
  * liveOfferPayments: MapStore<OfferId, MapStore<Brand, Payment>>;
225
+ * myStore: MapStore;
208
226
  * }
209
227
  * >} ImmutableState
210
228
  *
@@ -220,17 +238,17 @@ const trace = makeTracer('SmrtWlt');
220
238
  * TODO: consider moving to nameHub.js?
221
239
  *
222
240
  * @param {unknown} target - passable Key
223
- * @param {ERef<import('@agoric/vats').NameHub>} nameHub
241
+ * @param {ERef<NameHub>} nameHub
224
242
  */
225
243
  const namesOf = async (target, nameHub) => {
226
244
  const entries = await E(nameHub).entries();
227
- const matches = [];
245
+ const results = [];
228
246
  for (const [name, candidate] of entries) {
229
247
  if (candidate === target) {
230
- matches.push(name);
248
+ results.push(name);
231
249
  }
232
250
  }
233
- return harden(matches);
251
+ return harden(results);
234
252
  };
235
253
 
236
254
  /**
@@ -264,7 +282,7 @@ const getBrandToPurses = (walletPurses, key) => {
264
282
  };
265
283
 
266
284
  /**
267
- * @param {import('@agoric/vat-data').Baggage} baggage
285
+ * @param {Baggage} baggage
268
286
  * @param {SharedParams} shared
269
287
  */
270
288
  export const prepareSmartWallet = (baggage, shared) => {
@@ -315,7 +333,9 @@ export const prepareSmartWallet = (baggage, shared) => {
315
333
  amountWatcherGuard,
316
334
  /**
317
335
  * @param {Purse} purse
318
- * @param {ReturnType<makeWalletWithResolvedStorageNodes>['helper']} helper
336
+ * @param {ReturnType<
337
+ * typeof makeWalletWithResolvedStorageNodes
338
+ * >['helper']} helper
319
339
  */
320
340
  (purse, helper) => ({ purse, helper }),
321
341
  {
@@ -350,6 +370,31 @@ export const prepareSmartWallet = (baggage, shared) => {
350
370
 
351
371
  const makeAmountWatcher = prepareAmountWatcher();
352
372
 
373
+ /**
374
+ * @param {Amount} amount
375
+ * @returns {Amount}
376
+ */
377
+ const cleanAmountForPublish = amount => {
378
+ mustMatch(amount, AmountShape);
379
+ if (
380
+ !matches(amount.brand, shared.invitationBrand) ||
381
+ !matches(amount.value, M.arrayOf(InvitationElementShape))
382
+ ) {
383
+ return amount;
384
+ }
385
+
386
+ const invitationAmount = /** @type {InvitationAmount} */ (amount);
387
+ const filteredInvitationValue = invitationAmount.value.map(
388
+ ({ handle: _, ...filteredInvitationDetails }) =>
389
+ filteredInvitationDetails,
390
+ );
391
+
392
+ return harden({
393
+ brand: shared.invitationBrand,
394
+ value: filteredInvitationValue,
395
+ });
396
+ };
397
+
353
398
  /**
354
399
  * @param {UniqueParams} unique
355
400
  * @returns {State}
@@ -362,6 +407,7 @@ export const prepareSmartWallet = (baggage, shared) => {
362
407
  address: M.string(),
363
408
  bank: M.eref(M.remotable()),
364
409
  invitationPurse: PurseShape,
410
+ // Should not be M.eref, makeRecordedKit assumes resolved
365
411
  currentStorageNode: M.eref(StorageNodeShape),
366
412
  walletStorageNode: M.eref(StorageNodeShape),
367
413
  }),
@@ -394,14 +440,17 @@ export const prepareSmartWallet = (baggage, shared) => {
394
440
  durable: true,
395
441
  },
396
442
  ),
443
+ // NB: Wallets before this state property was added do not support
444
+ // saving results or invoking the saved items.
445
+ myStore: zone.detached().mapStore('my items'),
397
446
  };
398
447
 
399
- /** @type {import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<UpdateRecord>} */
448
+ /** @type {RecorderKit<UpdateRecord>} */
400
449
  const updateRecorderKit = makeRecorderKit(unique.walletStorageNode);
401
450
  // NB: state size must not grow monotonically
402
451
  // This is the node that UIs subscribe to for everything they need.
403
452
  // e.g. agoric follow :published.wallet.agoric1nqxg4pye30n3trct0hf7dclcwfxz8au84hr3ht
404
- /** @type {import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<CurrentWalletRecord>} */
453
+ /** @type {RecorderKit<CurrentWalletRecord>} */
405
454
  const currentRecorderKit = makeRecorderKit(unique.currentStorageNode);
406
455
 
407
456
  const nonpreciousState = {
@@ -426,6 +475,11 @@ export const prepareSmartWallet = (baggage, shared) => {
426
475
  };
427
476
  };
428
477
 
478
+ const invocationResultShape = M.splitRecord(
479
+ {},
480
+ { id: M.or(M.string(), M.number()), saveResult: shape.ResultPlan },
481
+ );
482
+
429
483
  const behaviorGuards = {
430
484
  helper: M.interface('helperFacetI', {
431
485
  assertUniqueOfferId: M.call(M.string()).returns(),
@@ -447,6 +501,8 @@ export const prepareSmartWallet = (baggage, shared) => {
447
501
  logWalletInfo: M.call().rest(M.arrayOf(M.any())).returns(),
448
502
  logWalletError: M.call().rest(M.arrayOf(M.any())).returns(),
449
503
  getLiveOfferPayments: M.call().returns(M.remotable('mapStore')),
504
+ saveEntry: M.call(shape.ResultPlan, M.any()).returns(M.string()),
505
+ findUnusedName: M.call(M.string()).returns(M.string()),
450
506
  }),
451
507
 
452
508
  deposit: M.interface('depositFacetI', {
@@ -465,11 +521,19 @@ export const prepareSmartWallet = (baggage, shared) => {
465
521
  executeOffer: M.call(shape.OfferSpec).returns(M.promise()),
466
522
  tryExitOffer: M.call(M.scalar()).returns(M.promise()),
467
523
  }),
524
+ invoke: M.interface('invoke', {
525
+ invokeEntry: M.callWhen(shape.InvokeEntryMessage).returns(),
526
+ }),
527
+ resultStepWatcher: M.interface('resultStepWatcher', {
528
+ onFulfilled: M.call(M.any(), invocationResultShape).returns(),
529
+ onRejected: M.call(M.any(), invocationResultShape).returns(),
530
+ }),
468
531
  self: M.interface('selfFacetI', {
469
532
  handleBridgeAction: M.call(shape.StringCapData, M.boolean()).returns(
470
533
  M.promise(),
471
534
  ),
472
535
  getDepositFacet: M.call().returns(M.remotable()),
536
+ getInvokeFacet: M.call().returns(M.remotable()),
473
537
  getOffersFacet: M.call().returns(M.remotable()),
474
538
  getCurrentSubscriber: M.call().returns(SubscriberShape),
475
539
  getUpdatesSubscriber: M.call().returns(SubscriberShape),
@@ -529,7 +593,7 @@ export const prepareSmartWallet = (baggage, shared) => {
529
593
  }
530
594
  void updateRecorderKit.recorder.write({
531
595
  updated: 'balance',
532
- currentAmount: balance,
596
+ currentAmount: cleanAmountForPublish(balance),
533
597
  });
534
598
  const { helper } = this.facets;
535
599
  helper.publishCurrentState();
@@ -546,9 +610,11 @@ export const prepareSmartWallet = (baggage, shared) => {
546
610
  void currentRecorderKit.recorder.write({
547
611
  purses: [...purseBalances.values()].map(a => ({
548
612
  brand: a.brand,
549
- balance: a,
613
+ balance: cleanAmountForPublish(a),
550
614
  })),
551
- offerToUsedInvitation: [...offerToUsedInvitation.entries()],
615
+ offerToUsedInvitation: [...offerToUsedInvitation.entries()].map(
616
+ ([offerId, a]) => [offerId, cleanAmountForPublish(a)],
617
+ ),
552
618
  offerToPublicSubscriberPaths: [
553
619
  ...offerToPublicSubscriberPaths.entries(),
554
620
  ],
@@ -586,8 +652,7 @@ export const prepareSmartWallet = (baggage, shared) => {
586
652
  * transition to decentralized introductions.
587
653
  *
588
654
  * @param {Brand} brand
589
- * @param {ERef<import('@agoric/vats').NameHub>} known - namehub with
590
- * brand, issuer branches
655
+ * @param {ERef<NameHub>} known - namehub with brand, issuer branches
591
656
  * @returns {Promise<Purse | undefined>} undefined if brand is not known
592
657
  */
593
658
  async getPurseIfKnownBrand(brand, known) {
@@ -666,8 +731,8 @@ export const prepareSmartWallet = (baggage, shared) => {
666
731
  /**
667
732
  * @param {string} offerId
668
733
  * @param {Amount<'set'>} invitationAmount
669
- * @param {import('./types.js').InvitationMakers} invitationMakers
670
- * @param {import('./types.js').PublicSubscribers} publicSubscribers
734
+ * @param {InvitationMakers} invitationMakers
735
+ * @param {PublicSubscribers} publicSubscribers
671
736
  */
672
737
  async addContinuingOffer(
673
738
  offerId,
@@ -739,6 +804,35 @@ export const prepareSmartWallet = (baggage, shared) => {
739
804
  }
740
805
  return baggage.get(state.address);
741
806
  },
807
+ /** @param {string} suggestion */
808
+ findUnusedName(suggestion) {
809
+ const { myStore } = this.state;
810
+ let nonce = 0;
811
+ let name = suggestion;
812
+ while (myStore.has(name)) {
813
+ nonce += myStore.getSize(); // avoid linear work
814
+ name = `${suggestion}.${nonce}`;
815
+ }
816
+ return name;
817
+ },
818
+ /**
819
+ * @param {ResultPlan} plan
820
+ * @param {unknown} value
821
+ */
822
+ saveEntry(plan, value) {
823
+ const { myStore } = this.state;
824
+ const name = plan.overwrite
825
+ ? plan.name
826
+ : this.facets.helper.findUnusedName(plan.name);
827
+
828
+ if (myStore.has(name)) {
829
+ myStore.set(name, value);
830
+ } else {
831
+ myStore.init(name, value);
832
+ }
833
+ trace('set', name, '=', value);
834
+ return name;
835
+ },
742
836
  },
743
837
  /**
744
838
  * Similar to {DepositFacet} but async because it has to look up the
@@ -1013,19 +1107,90 @@ export const prepareSmartWallet = (baggage, shared) => {
1013
1107
  await E(seatRef).tryExit();
1014
1108
  },
1015
1109
  },
1110
+
1111
+ invoke: {
1112
+ /**
1113
+ * @param {InvokeEntryMessage} message
1114
+ */
1115
+ async invokeEntry(message) {
1116
+ trace('invokeEntry', message);
1117
+ const { myStore } = this.state;
1118
+ const { resultStepWatcher } = this.facets;
1119
+
1120
+ const { targetName: name, method, args, saveResult, id } = message;
1121
+ myStore.has(name) || Fail`cannot invoke ${q(name)}: no such item`;
1122
+ const value = myStore.get(name);
1123
+ trace('entry', name, value);
1124
+ trace('invoke', value, '.', method, '(', args, ')');
1125
+ if (id) {
1126
+ const { updateRecorderKit } = this.state;
1127
+ void updateRecorderKit.recorder.write({
1128
+ updated: 'invocation',
1129
+ id,
1130
+ });
1131
+ }
1132
+ const callP = E(value)[method](...args);
1133
+ if (id || saveResult) {
1134
+ vowTools.watch(callP, resultStepWatcher, { id, saveResult });
1135
+ } else {
1136
+ void callP;
1137
+ }
1138
+ },
1139
+ },
1140
+
1141
+ resultStepWatcher: {
1142
+ /**
1143
+ * @param {unknown} result
1144
+ * @param {{ id?: string | number; saveResult?: ResultPlan }} opts
1145
+ */
1146
+ onFulfilled(result, opts) {
1147
+ trace('resultStepWatcher opts', opts);
1148
+ const { id, saveResult } = opts;
1149
+ if (saveResult) {
1150
+ this.facets.helper.saveEntry(saveResult, result);
1151
+ }
1152
+ const passStyle = passStyleOf(result);
1153
+ const { updateRecorderKit } = this.state;
1154
+ if (id) {
1155
+ void updateRecorderKit.recorder.write({
1156
+ updated: 'invocation',
1157
+ id,
1158
+ result: {
1159
+ ...(saveResult?.name ? { name: saveResult.name } : {}),
1160
+ passStyle,
1161
+ },
1162
+ });
1163
+ }
1164
+ },
1165
+ /**
1166
+ * @param {unknown} reason
1167
+ * @param {{ id: string | number; saveResult?: ResultPlan }} opts
1168
+ */
1169
+ onRejected(reason, opts) {
1170
+ trace('rejected', reason, opts);
1171
+ if (opts.id) {
1172
+ const { updateRecorderKit } = this.state;
1173
+ void updateRecorderKit.recorder.write({
1174
+ updated: 'invocation',
1175
+ id: opts.id,
1176
+ error: String(reason),
1177
+ });
1178
+ }
1179
+ },
1180
+ },
1181
+
1016
1182
  self: {
1017
1183
  /**
1018
1184
  * Umarshals the actionCapData and delegates to the appropriate action
1019
1185
  * handler.
1020
1186
  *
1021
- * @param {import('@endo/marshal').CapData<string | null>} actionCapData
1022
- * of type BridgeAction
1187
+ * @param {CapData<string | null>} actionCapData of type BridgeAction
1023
1188
  * @param {boolean} [canSpend]
1024
1189
  * @returns {Promise<void>}
1025
1190
  */
1026
1191
  handleBridgeAction(actionCapData, canSpend = false) {
1027
- const { facets } = this;
1028
- const { offers } = facets;
1192
+ const { facets, state } = this;
1193
+ const { offers, invoke } = facets;
1029
1194
  const { publicMarshaller } = shared;
1030
1195
 
1031
1196
  /** @param {Error} err */
@@ -1038,6 +1203,8 @@ export const prepareSmartWallet = (baggage, shared) => {
1038
1203
  });
1039
1204
  };
1040
1205
 
1206
+ const walletHasNameHub = 'myStore' in state && state.myStore != null;
1207
+
1041
1208
  // use E.when to retain distributed stack trace
1042
1209
  return E.when(
1043
1210
  E(publicMarshaller).fromCapData(actionCapData),
@@ -1047,12 +1214,21 @@ export const prepareSmartWallet = (baggage, shared) => {
1047
1214
  switch (action.method) {
1048
1215
  case 'executeOffer': {
1049
1216
  canSpend || Fail`executeOffer requires spend authority`;
1217
+ if (action.offer.saveResult != null && !walletHasNameHub) {
1218
+ Fail`executeOffer saveResult requires a new smart wallet with myStore`;
1219
+ }
1220
+
1050
1221
  return offers.executeOffer(action.offer);
1051
1222
  }
1052
1223
  case 'tryExitOffer': {
1053
1224
  assert(canSpend, 'tryExitOffer requires spend authority');
1054
1225
  return offers.tryExitOffer(action.offerId);
1055
1226
  }
1227
+ case 'invokeEntry': {
1228
+ walletHasNameHub ||
1229
+ Fail`invokeEntry requires a new smart wallet with myStore`;
1230
+ return invoke.invokeEntry(action.message);
1231
+ }
1056
1232
  default: {
1057
1233
  throw Fail`invalid handle bridge action ${q(action)}`;
1058
1234
  }
@@ -1071,6 +1247,9 @@ export const prepareSmartWallet = (baggage, shared) => {
1071
1247
  getDepositFacet() {
1072
1248
  return this.facets.deposit;
1073
1249
  },
1250
+ getInvokeFacet() {
1251
+ return this.facets.invoke;
1252
+ },
1074
1253
  getOffersFacet() {
1075
1254
  return this.facets.offers;
1076
1255
  },
@@ -1118,7 +1297,7 @@ export const prepareSmartWallet = (baggage, shared) => {
1118
1297
  * UniqueParams,
1119
1298
  * 'currentStorageNode' | 'walletStorageNode'
1120
1299
  * > & {
1121
- * walletStorageNode: ERef<StorageNode>;
1300
+ * walletStorageNode: ERemote<StorageNode>;
1122
1301
  * }} uniqueWithoutChildNodes
1123
1302
  */
1124
1303
  const makeSmartWallet = async uniqueWithoutChildNodes => {
@@ -1138,5 +1317,4 @@ export const prepareSmartWallet = (baggage, shared) => {
1138
1317
  return makeSmartWallet;
1139
1318
  };
1140
1319
  harden(prepareSmartWallet);
1141
-
1142
- /** @typedef {Awaited<ReturnType<ReturnType<typeof prepareSmartWallet>>>} SmartWallet */
1320
+ /** @typedef {EReturn<EReturn<typeof prepareSmartWallet>>} SmartWallet */
package/src/typeGuards.js CHANGED
@@ -4,6 +4,28 @@ import {
4
4
  ProposalShape,
5
5
  } from '@agoric/zoe/src/typeGuards.js';
6
6
 
7
+ /**
8
+ * @import {TypedPattern} from '@agoric/internal';
9
+ * @import {InvokeEntryMessage, ResultPlan} from './offers.js';
10
+ */
11
+
12
+ /** @type {TypedPattern<ResultPlan>} */
13
+ const ResultPlanShape = M.splitRecord(
14
+ { name: M.string() },
15
+ { overwrite: M.boolean() },
16
+ {},
17
+ );
18
+ /** @type {TypedPattern<InvokeEntryMessage>} */
19
+ const InvokeEntryMessageShape = M.splitRecord(
20
+ {
21
+ targetName: M.string(),
22
+ method: M.string(),
23
+ args: M.array(),
24
+ },
25
+ { saveResult: ResultPlanShape, id: M.or(M.number(), M.string()) },
26
+ {},
27
+ );
28
+
7
29
  export const shape = {
8
30
  // smartWallet
9
31
  StringCapData: {
@@ -51,8 +73,14 @@ export const shape = {
51
73
  invitationSpec: M.any(),
52
74
  proposal: ProposalShape,
53
75
  },
54
- { offerArgs: M.any() },
76
+ {
77
+ offerArgs: M.any(),
78
+ saveResult: ResultPlanShape,
79
+ },
80
+ {},
55
81
  ),
82
+ ResultPlan: ResultPlanShape,
83
+ InvokeEntryMessage: InvokeEntryMessageShape,
56
84
 
57
85
  // walletFactory
58
86
  /**
package/src/types.d.ts CHANGED
@@ -4,11 +4,12 @@
4
4
  * Similar to types.js but in TypeScript syntax because some types here need it.
5
5
  * Downside is it can't reference any ambient types, which most of agoric-sdk type are presently.
6
6
  */
7
+ import type { Payment } from '@agoric/ertp';
7
8
  import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js';
9
+ import type { InvitationDetails } from '@agoric/zoe';
8
10
  import type { PublicTopic } from '@agoric/zoe/src/contractSupport/topics.js';
9
- import type { Payment } from '@agoric/ertp';
10
11
  import type { OfferSpec } from './offers.js';
11
- type Invitation = Payment<'set'>;
12
+ type Invitation = Payment<'set', InvitationDetails>;
12
13
  /**
13
14
  * A petname can either be a plain string or a path for which the first element
14
15
  * is a petname for the origin, and the rest of the elements are a snapshot of
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM7C,KAAK,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAExC,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,MAAM,EACN,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CACxC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;IACpB,GAAG,EAAE,MAAM,CAAC,CAAC;IACb,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,eAAe,CAAC;IACtB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,WAAW,EAAE,kBAAkB,EAC/B,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,SAAS,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,KAAK,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAExC,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,MAAM,EACN,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CACxC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,iBAAiB,EAAE,iBAAiB,CAAC;CACtC;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI;IACpB,GAAG,EAAE,MAAM,CAAC,CAAC;IACb,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,eAAe,CAAC;IACtB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CACvB,WAAW,EAAE,kBAAkB,EAC/B,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,SAAS,CAAC"}
package/src/types.ts CHANGED
@@ -5,17 +5,17 @@
5
5
  * Downside is it can't reference any ambient types, which most of agoric-sdk type are presently.
6
6
  */
7
7
 
8
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- fails to notice the @see uses
8
9
  import type { agoric } from '@agoric/cosmic-proto/agoric/bundle.js';
10
+ import type { Payment } from '@agoric/ertp';
9
11
  import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js';
12
+ import type { InvitationDetails } from '@agoric/zoe';
10
13
  import type { PublicTopic } from '@agoric/zoe/src/contractSupport/topics.js';
11
- import type { Payment } from '@agoric/ertp';
12
14
  import type { OfferSpec } from './offers.js';
13
15
 
14
- declare const CapDataShape: unique symbol;
15
-
16
16
  // Match the type in Zoe, which can't be imported because it's ambient.
17
17
  // This omits the parameters that aren't used in this module.
18
- type Invitation = Payment<'set'>;
18
+ type Invitation = Payment<'set', InvitationDetails>;
19
19
 
20
20
  /**
21
21
  * A petname can either be a plain string or a path for which the first element
package/src/utils.d.ts CHANGED
@@ -1,8 +1,14 @@
1
- /** @import {OfferId, OfferStatus} from './offers.js'; */
1
+ /**
2
+ * @import {OfferId, OfferStatus} from './offers.js';
3
+ * @import {UpdateRecord} from './smartWallet.js';
4
+ * @import {Follower} from '@agoric/casting';
5
+ * @import {PublicSubscribers} from './types.js';
6
+ * @import {TopicsRecord} from '@agoric/zoe/src/contractSupport/index.js';
7
+ */
2
8
  export const NO_SMART_WALLET_ERROR: "no smart wallet";
3
- export function makeWalletStateCoalescer(invitationBrand?: globalThis.Brand<"set"> | undefined): {
9
+ export function makeWalletStateCoalescer(invitationBrand?: Brand<"set">): {
4
10
  state: {
5
- invitationsReceived: Map<OfferId, {
11
+ invitationsReceived: Map<string, {
6
12
  acceptedIn: OfferId;
7
13
  description: string;
8
14
  instance: Instance;
@@ -10,10 +16,10 @@ export function makeWalletStateCoalescer(invitationBrand?: globalThis.Brand<"set
10
16
  offerStatuses: Map<OfferId, OfferStatus>;
11
17
  balances: Map<globalThis.Brand, globalThis.Amount>;
12
18
  };
13
- update: (updateRecord: import("./smartWallet.js").UpdateRecord | {}) => void;
19
+ update: (updateRecord: UpdateRecord | {}) => void;
14
20
  };
15
- export function coalesceUpdates(updates: ERef<Subscriber<import("./smartWallet.js").UpdateRecord>>, invitationBrand?: globalThis.Brand<"set"> | undefined): {
16
- invitationsReceived: Map<OfferId, {
21
+ export function coalesceUpdates(updates: ERef<Subscriber<UpdateRecord>>, invitationBrand?: Brand<"set">): {
22
+ invitationsReceived: Map<string, {
17
23
  acceptedIn: OfferId;
18
24
  description: string;
19
25
  instance: Instance;
@@ -21,9 +27,13 @@ export function coalesceUpdates(updates: ERef<Subscriber<import("./smartWallet.j
21
27
  offerStatuses: Map<OfferId, OfferStatus>;
22
28
  balances: Map<globalThis.Brand, globalThis.Amount>;
23
29
  };
24
- export function assertHasData(follower: import("@agoric/casting").Follower<any>): Promise<void>;
25
- export function objectMapStoragePath(subscribers?: import("@agoric/zoe/src/contractSupport/topics.js").TopicsRecord | import("./types.js").PublicSubscribers | undefined): ERef<Record<string, string>> | null;
30
+ export function assertHasData(follower: Follower<any>): Promise<void>;
31
+ export function objectMapStoragePath(subscribers?: PublicSubscribers | TopicsRecord): ERef<Record<string, string>> | null;
26
32
  export type CoalescedWalletState = ReturnType<typeof makeWalletStateCoalescer>["state"];
27
33
  import type { OfferId } from './offers.js';
28
34
  import type { OfferStatus } from './offers.js';
35
+ import type { UpdateRecord } from './smartWallet.js';
36
+ import type { Follower } from '@agoric/casting';
37
+ import type { PublicSubscribers } from './types.js';
38
+ import type { TopicsRecord } from '@agoric/zoe/src/contractSupport/index.js';
29
39
  //# sourceMappingURL=utils.d.ts.map