@agoric/wallet-backend 0.13.4-dev-bc4e1aa.0 → 0.13.4-dev-8b50322.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/wallet-backend",
3
- "version": "0.13.4-dev-bc4e1aa.0+bc4e1aa",
3
+ "version": "0.13.4-dev-8b50322.0+8b50322",
4
4
  "description": "Wallet backend",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -14,23 +14,23 @@
14
14
  "lint:eslint": "eslint ."
15
15
  },
16
16
  "devDependencies": {
17
- "@agoric/deploy-script-support": "0.9.5-dev-bc4e1aa.0+bc4e1aa",
18
- "@agoric/vats": "0.13.1-dev-bc4e1aa.0+bc4e1aa",
17
+ "@agoric/vats": "0.13.1-dev-8b50322.0+8b50322",
19
18
  "@endo/bundle-source": "^2.4.2",
20
19
  "@endo/init": "^0.5.52",
21
20
  "ava": "^5.1.0"
22
21
  },
23
22
  "dependencies": {
24
- "@agoric/assert": "0.5.2-dev-bc4e1aa.0+bc4e1aa",
25
- "@agoric/cache": "0.2.4-dev-bc4e1aa.0+bc4e1aa",
26
- "@agoric/ertp": "0.15.4-dev-bc4e1aa.0+bc4e1aa",
27
- "@agoric/inter-protocol": "0.13.2-dev-bc4e1aa.0+bc4e1aa",
28
- "@agoric/internal": "0.2.2-dev-bc4e1aa.0+bc4e1aa",
23
+ "@agoric/assert": "0.5.2-dev-8b50322.0+8b50322",
24
+ "@agoric/cache": "0.2.4-dev-8b50322.0+8b50322",
25
+ "@agoric/ertp": "0.15.4-dev-8b50322.0+8b50322",
26
+ "@agoric/inter-protocol": "0.13.2-dev-8b50322.0+8b50322",
27
+ "@agoric/internal": "0.2.2-dev-8b50322.0+8b50322",
29
28
  "@agoric/nat": "^4.1.0",
30
- "@agoric/notifier": "0.5.2-dev-bc4e1aa.0+bc4e1aa",
31
- "@agoric/store": "0.8.4-dev-bc4e1aa.0+bc4e1aa",
32
- "@agoric/vat-data": "0.4.4-dev-bc4e1aa.0+bc4e1aa",
33
- "@agoric/zoe": "0.25.4-dev-bc4e1aa.0+bc4e1aa",
29
+ "@agoric/notifier": "0.5.2-dev-8b50322.0+8b50322",
30
+ "@agoric/smart-wallet": "0.4.3-dev-8b50322.0+8b50322",
31
+ "@agoric/store": "0.8.4-dev-8b50322.0+8b50322",
32
+ "@agoric/vat-data": "0.4.4-dev-8b50322.0+8b50322",
33
+ "@agoric/zoe": "0.25.4-dev-8b50322.0+8b50322",
34
34
  "@endo/eventual-send": "^0.16.8",
35
35
  "@endo/marshal": "^0.8.1",
36
36
  "@endo/promise-kit": "^0.2.52",
@@ -57,5 +57,5 @@
57
57
  "publishConfig": {
58
58
  "access": "public"
59
59
  },
60
- "gitHead": "bc4e1aa1f2e80bd58ca6d9fdf7b2216f09754da2"
60
+ "gitHead": "8b50322bfb6ed332518045e0514741796ca01fe1"
61
61
  }
@@ -1,6 +1,6 @@
1
1
  #! /usr/bin/env node
2
2
  import '@endo/init';
3
- import { createBundles } from '@agoric/deploy-script-support';
3
+ import { createBundles } from '@agoric/internal/src/createBundles.js';
4
4
  import url from 'url';
5
5
 
6
6
  const dirname = url.fileURLToPath(new URL('.', import.meta.url));
@@ -7,6 +7,8 @@
7
7
  * @property {PurseActions} actions
8
8
  */
9
9
 
10
+ /** @typedef {import('@agoric/deploy-script-support/src/externalTypes').Petname} Petname */
11
+
10
12
  /**
11
13
  * @typedef {PursesJSONState & PursesAddedState} PursesFullState
12
14
  */
package/src/lib-wallet.js CHANGED
@@ -33,12 +33,12 @@ import {
33
33
  } from '@agoric/notifier';
34
34
  import { makePromiseKit } from '@endo/promise-kit';
35
35
 
36
+ import { makeExportContext } from '@agoric/smart-wallet/src/marshal-contexts.js';
36
37
  import { makeIssuerTable } from './issuerTable.js';
37
38
  import { makeDehydrator } from './lib-dehydrate.js';
38
39
  import { makeId, findOrMakeInvitation } from './findOrMakeInvitation.js';
39
40
  import { bigintStringify } from './bigintStringify.js';
40
41
  import { makePaymentActions } from './actions.js';
41
- import { makeExportContext } from './marshal-contexts.js';
42
42
 
43
43
  import '@agoric/store/exported.js';
44
44
  import '@agoric/zoe/exported.js';
@@ -6,7 +6,7 @@ import {
6
6
  makeExportContext,
7
7
  makeImportContext,
8
8
  makeLoggingPresence,
9
- } from '../src/marshal-contexts.js';
9
+ } from '@agoric/smart-wallet/src/marshal-contexts.js';
10
10
 
11
11
  const capData1 = {
12
12
  body: JSON.stringify([
@@ -7,7 +7,7 @@ import { makeHandle } from '@agoric/zoe/src/makeHandle.js';
7
7
  import {
8
8
  makeExportContext,
9
9
  makeImportContext,
10
- } from '../src/marshal-contexts.js';
10
+ } from '@agoric/smart-wallet/src/marshal-contexts.js';
11
11
 
12
12
  /** @param {ReturnType<typeof makeBoard>} board */
13
13
  const makeAMM = board => {
@@ -1,389 +0,0 @@
1
- // @ts-check
2
- import { makeScalarMapStore } from '@agoric/store';
3
- import { Far, makeMarshal, Remotable } from '@endo/marshal';
4
- import { HandledPromise } from '@endo/eventual-send'; // TODO: convince tsc this isn't needed
5
-
6
- const { Fail, quote: q } = assert;
7
-
8
- /**
9
- * For a value with a known id in the board, we can use
10
- * that board id as a slot to preserve identity when marshaling.
11
- *
12
- * @typedef {`board${Digits}`} BoardId
13
- */
14
-
15
- /**
16
- * @param {unknown} specimen
17
- * @returns {specimen is BoardId}
18
- */
19
- const isBoardId = specimen => {
20
- return typeof specimen === 'string' && !!specimen.match(/^board[^:]/);
21
- };
22
-
23
- /**
24
- * When marshaling a purse, payment, etc. we partition the slots
25
- * using prefixes.
26
- *
27
- * @template {Record<string, IdTable<*,*>>} T
28
- * @typedef {`${string & keyof T}:${Digits}`} WalletSlot<T>
29
- */
30
- /**
31
- * @template {string} K
32
- * @typedef {`${K}:${Digits}`} KindSlot<K>
33
- */
34
-
35
- /**
36
- * @template {Record<string, IdTable<*,*>>} T
37
- * @param {T} _tables
38
- * @param {string & keyof T} kind
39
- * @param {number} id
40
- * @returns {WalletSlot<T>}
41
- */
42
- const makeWalletSlot = (_tables, kind, id) => {
43
- const digits = /** @type {Digits} */ (`${id}`);
44
- return `${kind}:${digits}`;
45
- };
46
-
47
- /**
48
- * @template {Record<string, IdTable<*,*>>} T
49
- * @param {T} record
50
- * @param {(value: string, index: number, obj: string[]) => boolean} predicate
51
- * @returns {string & keyof T | undefined}
52
- */
53
- const findKey = (record, predicate) => {
54
- const key = Object.keys(record).find(predicate);
55
- return key;
56
- };
57
-
58
- /**
59
- * @template {Record<string, IdTable<*,*>>} T
60
- * @param {T} tables
61
- * @param {string} slot
62
- * @returns {{ kind: undefined | string & keyof T, id: number }}
63
- */
64
- const parseWalletSlot = (tables, slot) => {
65
- const kind = findKey(tables, k => slot.startsWith(`${k}:`));
66
- const id = kind ? Number(slot.slice(kind.length + 1)) : NaN;
67
- return { kind, id };
68
- };
69
-
70
- /**
71
- * Since KindSlots always include a colon and BoardIds never do,
72
- * we an mix them without confusion.
73
- *
74
- * @template {Record<string, IdTable<*,*>>} T
75
- * @typedef {WalletSlot<T> | BoardId} MixedSlot<T>
76
- */
77
- /**
78
- * @typedef {`1` | `12` | `123`} Digits - 1 or more digits.
79
- * NOTE: the typescript definition here is more restrictive than
80
- * actual usage.
81
- */
82
-
83
- /**
84
- * @template Slot
85
- * @template Val
86
- *
87
- * @typedef {{
88
- * bySlot: MapStore<Slot, Val>,
89
- * byVal: MapStore<Val, Slot>,
90
- * }} IdTable<Value>
91
- */
92
-
93
- /**
94
- * @template Slot
95
- * @template Val
96
- * @param {IdTable<Slot, Val>} table
97
- * @param {Slot} slot
98
- * @param {Val} val
99
- */
100
- const initSlotVal = (table, slot, val) => {
101
- table.bySlot.init(slot, val);
102
- table.byVal.init(val, slot);
103
- };
104
-
105
- /**
106
- * Make context for exporting wallet data where brands etc. can be recognized by boardId.
107
- * Export for use outside the smart wallet.
108
- *
109
- * When serializing wallet state for, there's a tension between
110
- *
111
- * - keeping purses etc. closely held
112
- * - recognizing identity of brands also referenced in the state of contracts such as the AMM
113
- *
114
- * `makeMarshal()` is parameterized by the type of slots. Here we use a disjoint union of
115
- * - board ids for widely shared objects
116
- * - kind:seq ids for closely held objects; for example purse:123
117
- */
118
- export const makeExportContext = () => {
119
- const walletObjects = {
120
- /** @type {IdTable<number, Purse>} */
121
- purse: {
122
- bySlot: makeScalarMapStore(),
123
- byVal: makeScalarMapStore(),
124
- },
125
- /** @type {IdTable<number, Payment>} */
126
- payment: {
127
- bySlot: makeScalarMapStore(),
128
- byVal: makeScalarMapStore(),
129
- },
130
- // TODO: offer, contact, dapp
131
- /** @type {IdTable<number, unknown>} */
132
- unknown: {
133
- bySlot: makeScalarMapStore(),
134
- byVal: makeScalarMapStore(),
135
- },
136
- };
137
- /** @type {IdTable<BoardId, unknown>} */
138
- const boardObjects = {
139
- bySlot: makeScalarMapStore(),
140
- byVal: makeScalarMapStore(),
141
- };
142
-
143
- /**
144
- * Look up the slot in mappings from published data
145
- * else try walletObjects that we have seen.
146
- *
147
- * @throws if not found (a slotToVal function typically
148
- * conjures a new identity)
149
- *
150
- * @param {MixedSlot<typeof walletObjects>} slot
151
- * @param {string} _iface
152
- */
153
- const slotToVal = (slot, _iface) => {
154
- if (isBoardId(slot) && boardObjects.bySlot.has(slot)) {
155
- return boardObjects.bySlot.get(slot);
156
- }
157
- const { kind, id } = parseWalletSlot(walletObjects, slot);
158
- kind || Fail`bad slot kind: ${slot}`;
159
- const val = walletObjects[kind].bySlot.get(id); // or throw
160
- return val;
161
- };
162
-
163
- let unknownNonce = 0;
164
-
165
- /**
166
- * @param {unknown} val
167
- * @returns {MixedSlot<typeof walletObjects>}
168
- */
169
- const valToSlot = val => {
170
- if (boardObjects.byVal.has(val)) {
171
- return boardObjects.byVal.get(val);
172
- }
173
- const kind = findKey(walletObjects, k => walletObjects[k].byVal.has(val));
174
- if (kind) {
175
- // @ts-expect-error has(val) above ensures val has the right type
176
- const id = walletObjects[kind].byVal.get(val);
177
- return makeWalletSlot(walletObjects, kind, id);
178
- }
179
- unknownNonce += 1;
180
- const slot = makeWalletSlot(walletObjects, 'unknown', unknownNonce);
181
- initSlotVal(walletObjects.unknown, unknownNonce, val);
182
- return slot;
183
- };
184
-
185
- /**
186
- * @template V
187
- * @param {string & keyof typeof walletObjects} kind
188
- * @param {IdTable<number, V>} table
189
- */
190
- const makeSaver = (kind, table) => {
191
- let nonce = 0;
192
- /** @param {V} val */
193
- const saver = val => {
194
- nonce += 1;
195
- initSlotVal(table, nonce, val);
196
- };
197
- return saver;
198
- };
199
-
200
- return harden({
201
- savePurseActions: makeSaver('purse', walletObjects.purse),
202
- savePaymentActions: makeSaver('payment', walletObjects.payment),
203
- /**
204
- * @param {number} id
205
- * @param {Purse} purse
206
- */
207
- initPurseId: (id, purse) => {
208
- initSlotVal(walletObjects.purse, id, purse);
209
- },
210
- purseEntries: walletObjects.purse.bySlot.entries,
211
- /**
212
- * @param {BoardId} id
213
- * @param {unknown} val
214
- */
215
- initBoardId: (id, val) => {
216
- initSlotVal(boardObjects, id, val);
217
- },
218
- /**
219
- * @param {BoardId} id
220
- * @param {unknown} val
221
- */
222
- ensureBoardId: (id, val) => {
223
- if (boardObjects.byVal.has(val)) {
224
- assert.equal(boardObjects.byVal.get(val), id);
225
- return;
226
- }
227
- initSlotVal(boardObjects, id, val);
228
- },
229
- ...makeMarshal(valToSlot, slotToVal),
230
- });
231
- };
232
-
233
- const defaultMakePresence = iface => {
234
- const severed = `SEVERED: ${iface.replace(/^Alleged: /, '')}`;
235
- return Far(severed, {});
236
- };
237
-
238
- /**
239
- * Make context for marshalling wallet or board data.
240
- * To be imported into the client, which never exports objects.
241
- *
242
- * @param {(iface: string) => unknown} [makePresence]
243
- */
244
- export const makeImportContext = (makePresence = defaultMakePresence) => {
245
- const walletObjects = {
246
- /** @type {IdTable<number, unknown>} */
247
- purse: {
248
- bySlot: makeScalarMapStore(),
249
- byVal: makeScalarMapStore(),
250
- },
251
- /** @type {IdTable<number, unknown>} */
252
- payment: {
253
- bySlot: makeScalarMapStore(),
254
- byVal: makeScalarMapStore(),
255
- },
256
- /** @type {IdTable<number, unknown>} */
257
- unknown: {
258
- bySlot: makeScalarMapStore(),
259
- byVal: makeScalarMapStore(),
260
- },
261
- };
262
- /** @type {IdTable<BoardId, unknown>} */
263
- const boardObjects = {
264
- bySlot: makeScalarMapStore(),
265
- byVal: makeScalarMapStore(),
266
- };
267
-
268
- /**
269
- * @template Slot
270
- * @template Val
271
- * @param {IdTable<Slot, Val>} table
272
- * @param {Slot} slot
273
- * @param {string} iface
274
- */
275
- const provideVal = (table, slot, iface) => {
276
- if (table.bySlot.has(slot)) {
277
- return table.bySlot.get(slot);
278
- }
279
- const val = makePresence(iface);
280
- initSlotVal(table, slot, val);
281
- return val;
282
- };
283
-
284
- const slotToVal = {
285
- /**
286
- * @param {string} slot
287
- * @param {string} iface
288
- */
289
- fromBoard: (slot, iface) => {
290
- isBoardId(slot) || Fail`bad board slot ${q(slot)}`;
291
- return provideVal(boardObjects, slot, iface);
292
- },
293
-
294
- /**
295
- * @param {string} slot
296
- * @param {string} iface
297
- */
298
- fromMyWallet: (slot, iface) => {
299
- if (!slot) {
300
- // Empty or null slots are neither in the wallet nor the board.
301
- return makePresence(`${slot}`);
302
- }
303
- const { kind, id } = parseWalletSlot(walletObjects, slot);
304
- return kind
305
- ? provideVal(walletObjects[kind], id, iface)
306
- : slotToVal.fromBoard(slot, iface);
307
- },
308
- };
309
-
310
- const valToSlot = {
311
- fromBoard: val => boardObjects.byVal.get(val),
312
- /** @param {unknown} val */
313
- fromMyWallet: val => {
314
- const kind = findKey(walletObjects, k => walletObjects[k].byVal.has(val));
315
- if (kind === undefined) {
316
- throw Fail`cannot serialize unregistered ${val}`;
317
- }
318
-
319
- const id = walletObjects[kind].byVal.get(val);
320
- return makeWalletSlot(walletObjects, kind, id);
321
- },
322
- };
323
-
324
- const marshal = {
325
- fromBoard: makeMarshal(valToSlot.fromBoard, slotToVal.fromBoard, {
326
- marshalName: 'fromBoard',
327
- }),
328
- fromMyWallet: makeMarshal(valToSlot.fromMyWallet, slotToVal.fromMyWallet, {
329
- marshalName: 'fromMyWallet',
330
- }),
331
- };
332
-
333
- return harden({
334
- /**
335
- * @param {BoardId} id
336
- * @param {unknown} val
337
- */
338
- initBoardId: (id, val) => {
339
- initSlotVal(boardObjects, id, val);
340
- },
341
- /**
342
- * @param {BoardId} id
343
- * @param {unknown} val
344
- */
345
- ensureBoardId: (id, val) => {
346
- if (boardObjects.byVal.has(val)) {
347
- assert.equal(boardObjects.byVal.get(val), id);
348
- return;
349
- }
350
- initSlotVal(boardObjects, id, val);
351
- },
352
- fromMyWallet: Far('wallet marshaller', { ...marshal.fromMyWallet }),
353
- fromBoard: Far('board marshaller', { ...marshal.fromBoard }),
354
- });
355
- };
356
-
357
- /**
358
- * @param {string} iface
359
- * @param {{
360
- * applyMethod: (target: unknown, method: string | symbol, args: unknown[]) => void,
361
- * applyFunction: (target: unknown, args: unknown[]) => void,
362
- * }} handler
363
- */
364
- const makePresence = (iface, handler) => {
365
- let obj;
366
- // eslint-disable-next-line no-new
367
- new HandledPromise((resolve, reject, resolveWithPresence) => {
368
- obj = resolveWithPresence(handler);
369
- });
370
- assert(obj);
371
- return Remotable(iface, undefined, obj);
372
- };
373
-
374
- /**
375
- * @param {string} iface
376
- * @param {(parts: unknown[]) => void} log
377
- */
378
- export const makeLoggingPresence = (iface, log) => {
379
- /** @type {any} */ // TODO: solve types puzzle
380
- const it = makePresence(iface, {
381
- applyMethod: (target, method, args) => {
382
- log(harden(['applyMethod', target, method, args]));
383
- },
384
- applyFunction: (target, args) => {
385
- log(harden(['applyFunction', target, args]));
386
- },
387
- });
388
- return it;
389
- };