@agoric/smart-wallet 0.5.4-dev-7ffae88.0 → 0.5.4-dev-32c4d68.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/smart-wallet",
3
- "version": "0.5.4-dev-7ffae88.0+7ffae88",
3
+ "version": "0.5.4-dev-32c4d68.0+32c4d68",
4
4
  "description": "Wallet contract",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -16,29 +16,29 @@
16
16
  "lint:eslint": "eslint ."
17
17
  },
18
18
  "devDependencies": {
19
- "@agoric/cosmic-proto": "0.3.1-dev-7ffae88.0+7ffae88",
20
- "@agoric/swingset-vat": "0.32.3-dev-7ffae88.0+7ffae88",
21
- "@endo/bundle-source": "^3.0.2",
22
- "@endo/captp": "^4.0.2",
23
- "@endo/init": "^1.0.2",
19
+ "@agoric/cosmic-proto": "0.4.1-dev-32c4d68.0+32c4d68",
20
+ "@agoric/swingset-vat": "0.32.3-dev-32c4d68.0+32c4d68",
21
+ "@endo/bundle-source": "^3.1.0",
22
+ "@endo/captp": "^4.0.4",
23
+ "@endo/init": "^1.0.4",
24
24
  "ava": "^5.3.0",
25
25
  "import-meta-resolve": "^2.2.1"
26
26
  },
27
27
  "dependencies": {
28
- "@agoric/assert": "0.6.1-dev-7ffae88.0+7ffae88",
29
- "@agoric/casting": "0.4.3-dev-7ffae88.0+7ffae88",
30
- "@agoric/ertp": "0.16.3-dev-7ffae88.0+7ffae88",
31
- "@agoric/internal": "0.3.3-dev-7ffae88.0+7ffae88",
32
- "@agoric/notifier": "0.6.3-dev-7ffae88.0+7ffae88",
33
- "@agoric/store": "0.9.3-dev-7ffae88.0+7ffae88",
34
- "@agoric/vat-data": "0.5.3-dev-7ffae88.0+7ffae88",
35
- "@agoric/vats": "0.15.2-dev-7ffae88.0+7ffae88",
36
- "@agoric/zoe": "0.26.3-dev-7ffae88.0+7ffae88",
37
- "@endo/eventual-send": "^1.1.0",
38
- "@endo/far": "^1.0.2",
39
- "@endo/marshal": "^1.1.0",
40
- "@endo/nat": "^5.0.2",
41
- "@endo/promise-kit": "^1.0.2"
28
+ "@agoric/assert": "0.6.1-dev-32c4d68.0+32c4d68",
29
+ "@agoric/casting": "0.4.3-dev-32c4d68.0+32c4d68",
30
+ "@agoric/ertp": "0.16.3-dev-32c4d68.0+32c4d68",
31
+ "@agoric/internal": "0.3.3-dev-32c4d68.0+32c4d68",
32
+ "@agoric/notifier": "0.6.3-dev-32c4d68.0+32c4d68",
33
+ "@agoric/store": "0.9.3-dev-32c4d68.0+32c4d68",
34
+ "@agoric/vat-data": "0.5.3-dev-32c4d68.0+32c4d68",
35
+ "@agoric/vats": "0.15.2-dev-32c4d68.0+32c4d68",
36
+ "@agoric/zoe": "0.26.3-dev-32c4d68.0+32c4d68",
37
+ "@endo/eventual-send": "^1.1.2",
38
+ "@endo/far": "^1.0.4",
39
+ "@endo/marshal": "^1.3.0",
40
+ "@endo/nat": "^5.0.4",
41
+ "@endo/promise-kit": "^1.0.4"
42
42
  },
43
43
  "files": [
44
44
  "src/"
@@ -67,7 +67,7 @@
67
67
  "access": "public"
68
68
  },
69
69
  "typeCoverage": {
70
- "atLeast": 94.07
70
+ "atLeast": 93.75
71
71
  },
72
- "gitHead": "7ffae88ae37df782d5ffe3cf92261a498b0f636c"
72
+ "gitHead": "32c4d68c5f675f1e8fea1a8bc08621816e7b491e"
73
73
  }
@@ -1,9 +1,20 @@
1
1
  export function watchOfferOutcomes(watchers: OutcomeWatchers, seat: UserSeat): Promise<[unknown, 0 | 1, PaymentPKeywordRecord]>;
2
- export function prepareOfferWatcher(baggage: any): (walletHelper?: any, deposit?: any, offerSpec?: any, address?: any, iAmount?: any, seatRef?: any) => import("@endo/exo/src/exo-makers.js").GuardedKit<{
2
+ export function prepareOfferWatcher(baggage: import('@agoric/vat-data').Baggage): (walletHelper: any, deposit: any, offerSpec: import("./offers.js").OfferSpec, address: string, invitationAmount: Amount<"set">, seatRef: UserSeat<unknown>) => import("@endo/exo/src/exo-makers.js").GuardedKit<{
3
3
  helper: {
4
- updateStatus(offerStatusUpdates: any): void;
4
+ /**
5
+ * @param {Record<string, unknown>} offerStatusUpdates
6
+ */
7
+ updateStatus(offerStatusUpdates: Record<string, unknown>): void;
5
8
  onNewContinuingOffer(offerId: any, invitationAmount: any, invitationMakers: any, publicSubscribers: any): void;
6
- publishResult(result: any): void;
9
+ /** @param {unknown} result */
10
+ publishResult(result: unknown): void;
11
+ /**
12
+ * Called when the offer result promise rejects. The other two watchers
13
+ * are waiting for particular values out of Zoe but they settle at the same time
14
+ * and don't need their own error handling.
15
+ * @param {Error} err
16
+ */
17
+ handleError(err: Error): void;
7
18
  };
8
19
  /** @type {OutcomeWatchers['paymentWatcher']} */
9
20
  paymentWatcher: OutcomeWatchers['paymentWatcher'];
@@ -1 +1 @@
1
- {"version":3,"file":"offerWatcher.d.ts","sourceRoot":"","sources":["offerWatcher.js"],"names":[],"mappings":"AAsEO,6CAHI,eAAe,QACf,QAAQ,oDAQlB;AA8BM;;;;;;IAwED,gDAAgD;oBAArC,eAAe,CAAC,gBAAgB,CAAC;IAyB5C,+CAA+C;mBAApC,eAAe,CAAC,eAAe,CAAC;IAkB3C,iDAAiD;qBAAtC,eAAe,CAAC,iBAAiB,CAAC;GAoBlD;0BAlOY,OAAO,aAAa,EAAE,SAAS,GAAG;IAC9C,KAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAU,CAAC,EAAE,OAAO,GAAG,cAAc,aAAa,EAAE,kBAAkB,CAAC;IACvE,OAAW,CAAC,EAAE,mBAAmB,CAAC;CAC/B;;;;qDAKS,OAAO,4BAA4B,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;8BAIlE;IACZ,aAAe,EAAE,oBAAoB,OAAO,CAAC,CAAC;IAC9C,eAAiB,EAAE,oBAAoB,MAAM,CAAC,CAAC;IAC/C,cAAgB,EAAE,oBAAoB,qBAAqB,CAAC,CAAC;CAC1D;+BAmNU,WAAW,0BAA0B,CAAC"}
1
+ {"version":3,"file":"offerWatcher.d.ts","sourceRoot":"","sources":["offerWatcher.js"],"names":[],"mappings":"AAsEO,6CAHI,eAAe,QACf,QAAQ,oDAQlB;AAkCM,6CAFI,OAAO,kBAAkB,EAAE,OAAO;;QA0BrC;;WAEG;yCADQ,OAAO,MAAM,EAAE,OAAO,CAAC;;QAwBlC,8BAA8B;8BAAlB,OAAO;QAoCnB;;;;;WAKG;yBADQ,KAAK;;IAclB,gDAAgD;oBAArC,eAAe,CAAC,gBAAgB,CAAC;IA6B5C,+CAA+C;mBAApC,eAAe,CAAC,eAAe,CAAC;IAsB3C,iDAAiD;qBAAtC,eAAe,CAAC,iBAAiB,CAAC;GA0BlD;0BAnRY,OAAO,aAAa,EAAE,SAAS,GAAG;IAC9C,KAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,MAAU,CAAC,EAAE,OAAO,GAAG,cAAc,aAAa,EAAE,kBAAkB,CAAC;IACvE,OAAW,CAAC,EAAE,mBAAmB,CAAC;CAC/B;;;;qDAKS,OAAO,4BAA4B,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;8BAIlE;IACZ,aAAe,EAAE,oBAAoB,OAAO,CAAC,CAAC;IAC9C,eAAiB,EAAE,oBAAoB,MAAM,CAAC,CAAC;IAC/C,cAAgB,EAAE,oBAAoB,qBAAqB,CAAC,CAAC;CAC1D;+BAoQU,WAAW,0BAA0B,CAAC"}
@@ -87,6 +87,7 @@ const offerWatcherGuard = harden({
87
87
  .optional(M.record())
88
88
  .returns(),
89
89
  publishResult: M.call(M.any()).returns(),
90
+ handleError: M.call(M.error()).returns(),
90
91
  }),
91
92
  paymentWatcher: M.interface('paymentWatcher', {
92
93
  onFulfilled: M.call(PaymentPKeywordRecordShape, SeatShape).returns(
@@ -104,21 +105,36 @@ const offerWatcherGuard = harden({
104
105
  }),
105
106
  });
106
107
 
108
+ /**
109
+ * @param {import('@agoric/vat-data').Baggage} baggage
110
+ */
107
111
  export const prepareOfferWatcher = baggage => {
108
112
  return prepareExoClassKit(
109
113
  baggage,
110
114
  'OfferWatcher',
111
115
  offerWatcherGuard,
112
- (walletHelper, deposit, offerSpec, address, iAmount, seatRef) => ({
116
+ /**
117
+ *
118
+ * @param {*} walletHelper
119
+ * @param {*} deposit
120
+ * @param {import('./offers.js').OfferSpec} offerSpec
121
+ * @param {string} address
122
+ * @param {Amount<'set'>} invitationAmount
123
+ * @param {UserSeat} seatRef
124
+ */
125
+ (walletHelper, deposit, offerSpec, address, invitationAmount, seatRef) => ({
113
126
  walletHelper,
114
127
  deposit,
115
128
  status: offerSpec,
116
129
  address,
117
- invitationAmount: iAmount,
130
+ invitationAmount,
118
131
  seatRef,
119
132
  }),
120
133
  {
121
134
  helper: {
135
+ /**
136
+ * @param {Record<string, unknown>} offerStatusUpdates
137
+ */
122
138
  updateStatus(offerStatusUpdates) {
123
139
  const { state } = this;
124
140
  state.status = harden({ ...state.status, ...offerStatusUpdates });
@@ -141,6 +157,7 @@ export const prepareOfferWatcher = baggage => {
141
157
  );
142
158
  },
143
159
 
160
+ /** @param {unknown} result */
144
161
  publishResult(result) {
145
162
  const { state, facets } = this;
146
163
 
@@ -157,6 +174,7 @@ export const prepareOfferWatcher = baggage => {
157
174
  facets.helper.updateStatus({ result });
158
175
  break;
159
176
  case 'copyRecord':
177
+ // @ts-expect-error narrowed by passStyle
160
178
  if ('invitationMakers' in result) {
161
179
  // save for continuing invitation offer
162
180
 
@@ -164,6 +182,7 @@ export const prepareOfferWatcher = baggage => {
164
182
  String(state.status.id),
165
183
  state.invitationAmount,
166
184
  result.invitationMakers,
185
+ // @ts-expect-error narrowed by passStyle
167
186
  result.publicSubscribers,
168
187
  );
169
188
  }
@@ -174,6 +193,22 @@ export const prepareOfferWatcher = baggage => {
174
193
  facets.helper.updateStatus({ result: UNPUBLISHED_RESULT });
175
194
  }
176
195
  },
196
+ /**
197
+ * Called when the offer result promise rejects. The other two watchers
198
+ * are waiting for particular values out of Zoe but they settle at the same time
199
+ * and don't need their own error handling.
200
+ * @param {Error} err
201
+ */
202
+ handleError(err) {
203
+ const { facets } = this;
204
+ facets.helper.updateStatus({ error: err.toString() });
205
+ const { seatRef } = this.state;
206
+ void E.when(E(seatRef).hasExited(), hasExited => {
207
+ if (!hasExited) {
208
+ void E(seatRef).tryExit();
209
+ }
210
+ });
211
+ },
177
212
  },
178
213
 
179
214
  /** @type {OutcomeWatchers['paymentWatcher']} */
@@ -190,13 +225,17 @@ export const prepareOfferWatcher = baggage => {
190
225
  facets.helper.updateStatus({ payouts: amounts });
191
226
  },
192
227
  /**
193
- * @param {Error} err
228
+ * If promise disconnected, watch again. Or if there's an Error, handle it.
229
+ *
230
+ * @param {Error | import('@agoric/internal/src/upgrade-api.js').UpgradeDisconnection} reason
194
231
  * @param {UserSeat} seat
195
232
  */
196
- onRejected(err, seat) {
233
+ onRejected(reason, seat) {
197
234
  const { facets } = this;
198
- if (isUpgradeDisconnection(err)) {
235
+ if (isUpgradeDisconnection(reason)) {
199
236
  void watchForPayout(facets, seat);
237
+ } else {
238
+ facets.helper.handleError(reason);
200
239
  }
201
240
  },
202
241
  },
@@ -208,13 +247,17 @@ export const prepareOfferWatcher = baggage => {
208
247
  facets.helper.publishResult(result);
209
248
  },
210
249
  /**
211
- * @param {Error} err
250
+ * If promise disconnected, watch again. Or if there's an Error, handle it.
251
+ *
252
+ * @param {Error | import('@agoric/internal/src/upgrade-api.js').UpgradeDisconnection} reason
212
253
  * @param {UserSeat} seat
213
254
  */
214
- onRejected(err, seat) {
255
+ onRejected(reason, seat) {
215
256
  const { facets } = this;
216
- if (isUpgradeDisconnection(err)) {
257
+ if (isUpgradeDisconnection(reason)) {
217
258
  void watchForOfferResult(facets, seat);
259
+ } else {
260
+ facets.helper.handleError(reason);
218
261
  }
219
262
  },
220
263
  },
@@ -227,12 +270,18 @@ export const prepareOfferWatcher = baggage => {
227
270
  facets.helper.updateStatus({ numWantsSatisfied: numSatisfied });
228
271
  },
229
272
  /**
230
- * @param {Error} err
273
+ * If promise disconnected, watch again.
274
+ *
275
+ * Errors are handled by the paymentWatcher because numWantsSatisfied()
276
+ * and getPayouts() settle the same (they await the same promise and
277
+ * then synchronously return a local value).
278
+ *
279
+ * @param {Error | import('@agoric/internal/src/upgrade-api.js').UpgradeDisconnection} reason
231
280
  * @param {UserSeat} seat
232
281
  */
233
- onRejected(err, seat) {
282
+ onRejected(reason, seat) {
234
283
  const { facets } = this;
235
- if (isUpgradeDisconnection(err)) {
284
+ if (isUpgradeDisconnection(reason)) {
236
285
  void watchForNumWants(facets, seat);
237
286
  }
238
287
  },
@@ -5,11 +5,11 @@ export function prepareSmartWallet(baggage: import('@agoric/vat-data').Baggage,
5
5
  /**
6
6
  * Umarshals the actionCapData and delegates to the appropriate action handler.
7
7
  *
8
- * @param {import('@endo/marshal').CapData<string>} actionCapData of type BridgeAction
8
+ * @param {import('@endo/marshal').CapData<string | null>} actionCapData of type BridgeAction
9
9
  * @param {boolean} [canSpend]
10
10
  * @returns {Promise<void>}
11
11
  */
12
- handleBridgeAction(actionCapData: import('@endo/marshal').CapData<string>, canSpend?: boolean | undefined): Promise<void>;
12
+ handleBridgeAction(actionCapData: import('@endo/marshal').CapData<string | null>, canSpend?: boolean | undefined): Promise<void>;
13
13
  getDepositFacet(): import("@endo/exo/src/exo-makers.js").Guarded<{
14
14
  /**
15
15
  * Put the assets from the payment into the appropriate purse.
@@ -57,8 +57,7 @@ export function prepareSmartWallet(baggage: import('@agoric/vat-data').Baggage,
57
57
  };
58
58
  };
59
59
  /**
60
- * one-time use function. Remove this and repairUnwatchedSeats once the
61
- * repair has taken place.
60
+ * To be called once ever per wallet.
62
61
  *
63
62
  * @param {object} key
64
63
  */
@@ -177,7 +176,7 @@ export type ImmutableState = Readonly<UniqueParams & {
177
176
  paymentQueues: MapStore<Brand, Array<Payment>>;
178
177
  offerToInvitationMakers: MapStore<string, import('./types.js').InvitationMakers>;
179
178
  offerToPublicSubscriberPaths: MapStore<string, Record<string, string>>;
180
- offerToUsedInvitation: MapStore<string, Amount>;
179
+ offerToUsedInvitation: MapStore<string, Amount<'set'>>;
181
180
  purseBalances: MapStore<Purse, Amount>;
182
181
  updateRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<UpdateRecord>;
183
182
  currentRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<CurrentWalletRecord>;
@@ -1 +1 @@
1
- {"version":3,"file":"smartWallet.d.ts","sourceRoot":"","sources":["smartWallet.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smartWallet.d.ts","sourceRoot":"","sources":["smartWallet.js"],"names":[],"mappings":"AAiOA,kDAAmD;AAiB5C,4CAHI,OAAO,kBAAkB,EAAE,OAAO,UAClC,YAAY;uBAk6B2E,KAAK,WAAW,CAAC;;IAvH3G;;;;;;OAMG;sCAHQ,OAAO,eAAe,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,mCAE5C,QAAQ,IAAI,CAAC;;QArP1B;;;;;;;;WAQG;yBAHQ,OAAO,GACL,QAAQ,MAAM,CAAC;;;QAkH5B;;;;;;WAMG;gCAHQ,SAAS,GACP,QAAQ,IAAI,CAAC;QAuG1B;;;;;;WAMG;8BAHQ,OAAO,GACL,QAAQ,IAAI,CAAC;;IAmE1B,sCAAsC;;IAKtC,sCAAsC;;;;;;;;;;;;;;IAuBtC;;;;OAIG;qCADQ,MAAM;IA+CxB;sBA7mCa,MAAM,GAAG,MAAM;wBAGhB;IACZ,EAAM,EAAE,OAAO,CAAC;IAChB,cAAkB,EAAE,OAAO,eAAe,EAAE,cAAc,CAAC;IAC3D,QAAY,EAAE,QAAQ,CAAC;IACvB,SAAa,CAAC,EAAE,OAAO,CAAA;CACpB;;;wBAK2B,GAAG,EAAE,KAAK,IAAI;yBAAmB,GAAG,EAAE,KAAK,IAAI;;sBACvD,OAAO,mBAAmB,EAAE,gBAAgB;wBAC1C,KAAK,UAAU,CAAC;;iCAK5B;IACZ,MAAU,EAAE,cAAc,CAAA;IAC1B,KAAS,EAAE,SAAS,CAAC;CAClB;iCAIS;IACZ,MAAU,EAAE,cAAc,CAAA;IAC1B,OAAW,EAAE,OAAO,CAAC;CAClB;2BAOU,kBAAkB,GAAG,kBAAkB;;;;;;;;;;;;;;;;;;YAoBxC,MAAM;QAAC,KAAK,EAAE,KAAK,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;2BACvB,MAAM,CAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,CAAE,CAAC;;;;gBAE7D,MAAM,CAAC,OAAO,EAAE,OAAO,aAAa,EAAE,WAAW,CAAC,CAAC;;;;;;;;;;;;;;2BAKvD;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,QAAQ,OAAO,aAAa,EAAE,WAAW,CAAA;CAAE,GAC3E;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;;;;8BAchD;IACZ,KAAS,EAAE,KAAK,CAAC;IACjB,WAAe,EAAE,WAAW,CAAC;IAC7B,MAAU,EAAE,MAAM,CAAC;IACnB,OAAW,EAAE,OAAO,YAAY,EAAE,OAAO,CAAA;CACtC;2BAKS;IACZ,OAAW,EAAE,MAAM,CAAC;IACpB,IAAQ,EAAE,KAAK,OAAO,8BAA8B,EAAE,IAAI,CAAC,CAAC;IAC5D,kBAAsB,EAAE,WAAW,CAAC;IACpC,eAAmB,EAAE,MAAM,KAAK,CAAC,CAAC;IAClC,iBAAqB,EAAE,WAAW,CAAC;CAChC;sCAES,KAAK,SAAS,KAAK,EAAE,eAAe,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;2BAChE;IACZ,WAAe,EAAE,KAAK,OAAO,cAAc,EAAE,OAAO,CAAC,CAAC;IACtD,QAAY,EAAE,uBAAuB,CAAC;IACtC,gBAAoB,EAAE,OAAO,KAAK,CAAC,CAAC;IACpC,eAAmB,EAAE,MAAM,KAAK,CAAC,CAAC;IAClC,qBAAyB,EAAE,WAAW,CAAC;IACvC,gBAAoB,EAAE,UAAU,CAAC;IACjC,GAAO,EAAE,KAAK,UAAU,CAAC,CAAC;IAC1B,sBAA0B,EAAE,GAAG,CAAC;CAC7B;;;;;;;oBAES,cAAc,GAAG,YAAY;6BAM7B,SAAS,YAAY,GAAG;IACpC,aAAiB,EAAE,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IACnD,uBAA2B,EAAE,SAAS,MAAM,EAAE,OAAO,YAAY,EAAE,gBAAgB,CAAC,CAAC;IACrF,4BAAgC,EAAE,SAAS,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3E,qBAAyB,EAAE,SAAS,MAAM,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC;IAC3D,aAAiB,EAAE,SAAS,KAAK,EAAE,MAAM,CAAC,CAAC;IAC3C,iBAAqB,EAAE,OAAO,6CAA6C,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACvG,kBAAsB,EAAE,OAAO,6CAA6C,EAAE,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAC/G,UAAc,EAAE,SAAS,OAAO,EAAE,OAAO,aAAa,EAAE,WAAW,CAAC,CAAC;IACrE,cAAkB,EAAE,SAAS,OAAO,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC;IACzD,iBAAqB,EAAE,SAAS,OAAO,EAAE,SAAS,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;CAChE,CAAC;0BAEQ,eAAe,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE;2BAClC,EACT;0BA4+BU,QAAQ,WAAW,WAAW,yBAAyB,CAAC,CAAC,CAAC"}
@@ -173,7 +173,7 @@ const trace = makeTracer('SmrtWlt');
173
173
  * paymentQueues: MapStore<Brand, Array<Payment>>,
174
174
  * offerToInvitationMakers: MapStore<string, import('./types.js').InvitationMakers>,
175
175
  * offerToPublicSubscriberPaths: MapStore<string, Record<string, string>>,
176
- * offerToUsedInvitation: MapStore<string, Amount>,
176
+ * offerToUsedInvitation: MapStore<string, Amount<'set'>>,
177
177
  * purseBalances: MapStore<Purse, Amount>,
178
178
  * updateRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<UpdateRecord>,
179
179
  * currentRecorderKit: import('@agoric/zoe/src/contractSupport/recorder.js').RecorderKit<CurrentWalletRecord>,
@@ -456,6 +456,7 @@ export const prepareSmartWallet = (baggage, shared) => {
456
456
  }),
457
457
  };
458
458
 
459
+ // TODO move to top level so its type can be exported
459
460
  /**
460
461
  * Make the durable object to return, but taking some parameters that are awaited by a wrapping function.
461
462
  * This is necessary because the class kit construction helpers, `initState` and `finish` run synchronously
@@ -643,24 +644,47 @@ export const prepareSmartWallet = (baggage, shared) => {
643
644
  const offerSpec = liveOffers.get(seatId);
644
645
  const seat = liveOfferSeats.get(seatId);
645
646
 
646
- const invitation = invitationFromSpec(offerSpec.invitationSpec);
647
- watcherPromises.push(
648
- E.when(
649
- E(invitationIssuer).getAmountOf(invitation),
650
- invitationAmount => {
651
- const watcher = makeOfferWatcher(
652
- facets.helper,
653
- facets.deposit,
654
- offerSpec,
655
- address,
656
- invitationAmount,
657
- seat,
658
- );
659
- return watchOfferOutcomes(watcher, seat);
660
- },
661
- ),
662
- );
647
+ const watchOutcome = (async () => {
648
+ await null;
649
+ let invitationAmount = state.offerToUsedInvitation.has(
650
+ // @ts-expect-error older type allowed number
651
+ offerSpec.id,
652
+ )
653
+ ? state.offerToUsedInvitation.get(
654
+ // @ts-expect-error older type allowed number
655
+ offerSpec.id,
656
+ )
657
+ : undefined;
658
+ if (invitationAmount) {
659
+ facets.helper.logWalletInfo(
660
+ 'recovered invitation amount for offer',
661
+ offerSpec.id,
662
+ );
663
+ } else {
664
+ facets.helper.logWalletInfo(
665
+ 'inferring invitation amount for offer',
666
+ offerSpec.id,
667
+ );
668
+ const tempInvitation = invitationFromSpec(
669
+ offerSpec.invitationSpec,
670
+ );
671
+ invitationAmount =
672
+ await E(invitationIssuer).getAmountOf(tempInvitation);
673
+ void E(invitationIssuer).burn(tempInvitation);
674
+ }
675
+
676
+ const watcher = makeOfferWatcher(
677
+ facets.helper,
678
+ facets.deposit,
679
+ offerSpec,
680
+ address,
681
+ invitationAmount,
682
+ seat,
683
+ );
684
+ return watchOfferOutcomes(watcher, seat);
685
+ })();
663
686
  trace(`Repaired seat ${seatId} for wallet ${address}`);
687
+ watcherPromises.push(watchOutcome);
664
688
  }
665
689
 
666
690
  await Promise.all(watcherPromises);
@@ -830,6 +854,10 @@ export const prepareSmartWallet = (baggage, shared) => {
830
854
 
831
855
  payments: {
832
856
  /**
857
+ * Withdraw the offered amount from the appropriate purse of this wallet.
858
+ *
859
+ * Save its amount in liveOfferPayments in case we need to reclaim the payment.
860
+ *
833
861
  * @param {AmountKeywordRecord} give
834
862
  * @param {OfferId} offerId
835
863
  * @returns {PaymentPKeywordRecord}
@@ -845,8 +873,8 @@ export const prepareSmartWallet = (baggage, shared) => {
845
873
  .getLiveOfferPayments()
846
874
  .init(offerId, brandPaymentRecord);
847
875
 
848
- // Add each payment to liveOfferPayments as it is withdrawn. If
849
- // there's an error partway through, we can recover the withdrawals.
876
+ // Add each payment amount to brandPaymentRecord as it is withdrawn. If
877
+ // there's an error later, we can use it to redeposit the correct amount.
850
878
  return objectMap(give, amount => {
851
879
  /** @type {Promise<Purse>} */
852
880
  const purseP = facets.helper.purseForBrand(amount.brand);
@@ -867,19 +895,27 @@ export const prepareSmartWallet = (baggage, shared) => {
867
895
  });
868
896
  },
869
897
 
898
+ /**
899
+ * Find the live payments for the offer and deposit them back in the appropriate purses.
900
+ *
901
+ * @param {OfferId} offerId
902
+ * @returns {Promise<void>}
903
+ */
870
904
  async tryReclaimingWithdrawnPayments(offerId) {
871
905
  const { facets } = this;
872
906
 
907
+ await null;
908
+
873
909
  const liveOfferPayments = facets.helper.getLiveOfferPayments();
874
910
  if (liveOfferPayments.has(offerId)) {
875
911
  const brandPaymentRecord = liveOfferPayments.get(offerId);
876
912
  if (!brandPaymentRecord) {
877
- return Promise.resolve(undefined);
913
+ return;
878
914
  }
879
915
  // Use allSettled to ensure we attempt all the deposits, regardless of
880
916
  // individual rejections.
881
- return Promise.allSettled(
882
- Array.from(brandPaymentRecord.entries()).map(async ([b, p]) => {
917
+ await Promise.allSettled(
918
+ Array.from(brandPaymentRecord.entries()).map(([b, p]) => {
883
919
  // Wait for the withdrawal to complete. This protects against a
884
920
  // race when updating paymentToPurse.
885
921
  const purseP = facets.helper.purseForBrand(b);
@@ -966,22 +1002,24 @@ export const prepareSmartWallet = (baggage, shared) => {
966
1002
 
967
1003
  // await so that any errors are caught and handled below
968
1004
  await watchOfferOutcomes(watcher, seatRef);
969
- } catch (err) {
970
- facets.helper.logWalletError('OFFER ERROR:', err);
1005
+ } catch (reason) {
1006
+ // This block only runs if the block above fails during one vat incarnation.
1007
+ facets.helper.logWalletError('IMMEDIATE OFFER ERROR:', reason);
971
1008
 
972
- // Notify the user
973
- if (err.upgradeMessage === 'vat upgraded') {
1009
+ // Update status to observers
1010
+ if (isUpgradeDisconnection(reason)) {
974
1011
  // The offer watchers will reconnect. Don't reclaim or exit
975
1012
  return;
976
1013
  } else if (watcher) {
977
- watcher.helper.updateStatus({ error: err.toString() });
1014
+ // The watcher's onRejected will updateStatus()
978
1015
  } else {
979
1016
  facets.helper.updateStatus({
980
- error: err.toString(),
1017
+ error: reason.toString(),
981
1018
  ...offerSpec,
982
1019
  });
983
1020
  }
984
1021
 
1022
+ // Backstop recovery, in case something very basic fails.
985
1023
  if (offerSpec?.proposal?.give) {
986
1024
  facets.payments
987
1025
  .tryReclaimingWithdrawnPayments(offerSpec.id)
@@ -993,15 +1031,9 @@ export const prepareSmartWallet = (baggage, shared) => {
993
1031
  );
994
1032
  }
995
1033
 
996
- if (seatRef) {
997
- void E.when(E(seatRef).hasExited(), hasExited => {
998
- if (!hasExited) {
999
- void E(seatRef).tryExit();
1000
- }
1001
- });
1002
- }
1003
-
1004
- throw err;
1034
+ // XXX tests rely on throwing immediate errors, not covering the
1035
+ // error handling in the event the failure is after an upgrade
1036
+ throw reason;
1005
1037
  }
1006
1038
  },
1007
1039
  /**
@@ -1020,7 +1052,7 @@ export const prepareSmartWallet = (baggage, shared) => {
1020
1052
  /**
1021
1053
  * Umarshals the actionCapData and delegates to the appropriate action handler.
1022
1054
  *
1023
- * @param {import('@endo/marshal').CapData<string>} actionCapData of type BridgeAction
1055
+ * @param {import('@endo/marshal').CapData<string | null>} actionCapData of type BridgeAction
1024
1056
  * @param {boolean} [canSpend]
1025
1057
  * @returns {Promise<void>}
1026
1058
  */
@@ -1102,9 +1134,9 @@ export const prepareSmartWallet = (baggage, shared) => {
1102
1134
  },
1103
1135
  });
1104
1136
  },
1137
+ // TODO remove this and repairUnwatchedSeats once the repair has taken place.
1105
1138
  /**
1106
- * one-time use function. Remove this and repairUnwatchedSeats once the
1107
- * repair has taken place.
1139
+ * To be called once ever per wallet.
1108
1140
  *
1109
1141
  * @param {object} key
1110
1142
  */
@@ -1115,8 +1147,12 @@ export const prepareSmartWallet = (baggage, shared) => {
1115
1147
  return;
1116
1148
  }
1117
1149
 
1118
- void facets.helper.repairUnwatchedSeats();
1119
- void facets.helper.repairUnwatchedPurses();
1150
+ facets.helper.repairUnwatchedSeats().catch(e => {
1151
+ console.error('repairUnwatchedSeats rejection', e);
1152
+ });
1153
+ facets.helper.repairUnwatchedPurses().catch(e => {
1154
+ console.error('repairUnwatchedPurses rejection', e);
1155
+ });
1120
1156
  trace(`repaired wallet ${state.address}`);
1121
1157
  },
1122
1158
  },
package/src/types.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { ERef } from '@endo/far';
9
9
  import type { CapData } from '@endo/marshal';
10
- import type { MsgWalletSpendAction } from '@agoric/cosmic-proto/swingset/msgs';
10
+ import type { agoric } from '@agoric/cosmic-proto';
11
11
  import type { AgoricNamesRemotes } from '@agoric/vats/tools/board-utils.js';
12
12
  import type { OfferSpec } from './offers.js';
13
13
 
@@ -40,7 +40,7 @@ export type BridgeActionCapData = WalletCapData<
40
40
  /**
41
41
  * Defined by walletAction struct in msg_server.go
42
42
  *
43
- * @see {MsgWalletSpendAction} and walletSpendAction in msg_server.go
43
+ * @see {agoric.swingset.MsgWalletAction} and walletSpendAction in msg_server.go
44
44
  */
45
45
  export type WalletActionMsg = {
46
46
  type: 'WALLET_ACTION';
@@ -55,7 +55,7 @@ export type WalletActionMsg = {
55
55
  /**
56
56
  * Defined by walletSpendAction struct in msg_server.go
57
57
  *
58
- * @see {MsgWalletSpendAction} and walletSpendAction in msg_server.go
58
+ * @see {agoric.swingset.MsgWalletSpendAction} and walletSpendAction in msg_server.go
59
59
  */
60
60
  export type WalletSpendActionMsg = {
61
61
  type: 'WALLET_SPEND_ACTION';
@@ -37,7 +37,7 @@ export function prepare(zcf: ZCF<SmartWalletContractTerms>, privateArgs: {
37
37
  * and creating a new one.
38
38
  */
39
39
  provideSmartWallet(address: string, bank: ERef<import('@agoric/vats/src/vat-bank.js').Bank>, namesByAddressAdmin: ERef<import('@agoric/vats/src/types.js').NameAdmin>): Promise<[wallet: {
40
- handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
40
+ handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string | null>, canSpend?: boolean | undefined): Promise<void>;
41
41
  getDepositFacet(): import("@endo/exo/src/exo-makers.js").Guarded<{
42
42
  receive(payment: Payment<AssetKind>): Promise<Amount<AssetKind>>;
43
43
  }>;
@@ -61,7 +61,7 @@ export function prepare(zcf: ZCF<SmartWalletContractTerms>, privateArgs: {
61
61
  };
62
62
  repairWalletForIncarnation2(key: any): void;
63
63
  } & import("@endo/exo/src/get-interface.js").GetInterfaceGuard<{
64
- handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
64
+ handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string | null>, canSpend?: boolean | undefined): Promise<void>;
65
65
  getDepositFacet(): import("@endo/exo/src/exo-makers.js").Guarded<{
66
66
  receive(payment: Payment<AssetKind>): Promise<Amount<AssetKind>>;
67
67
  }>;
@@ -85,7 +85,7 @@ export function prepare(zcf: ZCF<SmartWalletContractTerms>, privateArgs: {
85
85
  };
86
86
  repairWalletForIncarnation2(key: any): void;
87
87
  }> & import("@endo/eventual-send").RemotableBrand<{}, {
88
- handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
88
+ handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string | null>, canSpend?: boolean | undefined): Promise<void>;
89
89
  getDepositFacet(): import("@endo/exo/src/exo-makers.js").Guarded<{
90
90
  receive(payment: Payment<AssetKind>): Promise<Amount<AssetKind>>;
91
91
  }>;
@@ -109,7 +109,7 @@ export function prepare(zcf: ZCF<SmartWalletContractTerms>, privateArgs: {
109
109
  };
110
110
  repairWalletForIncarnation2(key: any): void;
111
111
  } & import("@endo/exo/src/get-interface.js").GetInterfaceGuard<{
112
- handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string>, canSpend?: boolean | undefined): Promise<void>;
112
+ handleBridgeAction(actionCapData: import("@endo/marshal").CapData<string | null>, canSpend?: boolean | undefined): Promise<void>;
113
113
  getDepositFacet(): import("@endo/exo/src/exo-makers.js").Guarded<{
114
114
  receive(payment: Payment<AssetKind>): Promise<Amount<AssetKind>>;
115
115
  }>;