@agoric/ertp 0.16.3-other-dev-8f8782b.0 → 0.16.3-other-dev-fbe72e7.0.fbe72e7

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.
Files changed (63) hide show
  1. package/exported.d.ts +37 -0
  2. package/exported.js +2 -1
  3. package/package.json +37 -37
  4. package/src/amountMath.d.ts +46 -38
  5. package/src/amountMath.d.ts.map +1 -1
  6. package/src/amountMath.js +136 -128
  7. package/src/amountStore.d.ts +9 -0
  8. package/src/amountStore.d.ts.map +1 -0
  9. package/src/amountStore.js +34 -0
  10. package/src/displayInfo.d.ts +3 -0
  11. package/src/displayInfo.d.ts.map +1 -1
  12. package/src/displayInfo.js +3 -1
  13. package/src/index.d.ts +1 -0
  14. package/src/index.js +4 -0
  15. package/src/issuerKit.d.ts +29 -9
  16. package/src/issuerKit.d.ts.map +1 -1
  17. package/src/issuerKit.js +230 -75
  18. package/src/legacy-payment-helpers.d.ts +9 -2
  19. package/src/legacy-payment-helpers.d.ts.map +1 -1
  20. package/src/legacy-payment-helpers.js +43 -37
  21. package/src/mathHelpers/copyBagMathHelpers.d.ts +3 -4
  22. package/src/mathHelpers/copyBagMathHelpers.d.ts.map +1 -1
  23. package/src/mathHelpers/copyBagMathHelpers.js +4 -5
  24. package/src/mathHelpers/copySetMathHelpers.d.ts +3 -3
  25. package/src/mathHelpers/copySetMathHelpers.d.ts.map +1 -1
  26. package/src/mathHelpers/copySetMathHelpers.js +6 -4
  27. package/src/mathHelpers/natMathHelpers.d.ts +8 -7
  28. package/src/mathHelpers/natMathHelpers.d.ts.map +1 -1
  29. package/src/mathHelpers/natMathHelpers.js +8 -9
  30. package/src/mathHelpers/setMathHelpers.d.ts +2 -0
  31. package/src/mathHelpers/setMathHelpers.d.ts.map +1 -1
  32. package/src/mathHelpers/setMathHelpers.js +2 -1
  33. package/src/payment.d.ts +4 -2
  34. package/src/payment.d.ts.map +1 -1
  35. package/src/payment.js +8 -8
  36. package/src/paymentLedger.d.ts +8 -2
  37. package/src/paymentLedger.d.ts.map +1 -1
  38. package/src/paymentLedger.js +80 -97
  39. package/src/purse.d.ts +19 -9
  40. package/src/purse.d.ts.map +1 -1
  41. package/src/purse.js +86 -26
  42. package/src/ratio.d.ts +48 -0
  43. package/src/ratio.d.ts.map +1 -0
  44. package/src/ratio.js +441 -0
  45. package/src/safeMath.d.ts +11 -0
  46. package/src/safeMath.d.ts.map +1 -0
  47. package/src/safeMath.js +50 -0
  48. package/src/transientNotifier.d.ts +1 -1
  49. package/src/transientNotifier.d.ts.map +1 -1
  50. package/src/transientNotifier.js +5 -0
  51. package/src/typeGuards.d.ts +64 -13
  52. package/src/typeGuards.d.ts.map +1 -1
  53. package/src/typeGuards.js +70 -57
  54. package/src/types-index.d.ts +2 -0
  55. package/src/types-index.js +2 -0
  56. package/src/types.d.ts +254 -220
  57. package/src/types.d.ts.map +1 -1
  58. package/src/types.ts +474 -0
  59. package/CHANGELOG.md +0 -743
  60. package/src/types-ambient.d.ts +0 -376
  61. package/src/types-ambient.d.ts.map +0 -1
  62. package/src/types-ambient.js +0 -440
  63. package/src/types.js +0 -441
package/src/amountMath.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { q, Fail } from '@endo/errors';
1
2
  import { passStyleOf, assertRemotable, assertRecord } from '@endo/marshal';
2
3
 
3
4
  import { M, matches } from '@agoric/store';
@@ -6,67 +7,65 @@ import { setMathHelpers } from './mathHelpers/setMathHelpers.js';
6
7
  import { copySetMathHelpers } from './mathHelpers/copySetMathHelpers.js';
7
8
  import { copyBagMathHelpers } from './mathHelpers/copyBagMathHelpers.js';
8
9
 
9
- const { quote: q, Fail } = assert;
10
+ /**
11
+ * @import {CopyBag, CopySet} from '@endo/patterns';
12
+ * @import {Amount, AmountValue, AssetValueForKind, Brand, CopyBagAmount, CopySetAmount, MathHelpers, NatAmount, NatValue, SetAmount, SetValue} from './types.js';
13
+ */
10
14
 
15
+ // NB: AssetKind is both a constant for enumerated values and a type for those values.
11
16
  /**
12
17
  * Constants for the kinds of assets we support.
13
18
  *
14
- * @type {{ NAT: 'nat', SET: 'set', COPY_SET: 'copySet', COPY_BAG: 'copyBag' }}
19
+ * @enum {(typeof AssetKind)[keyof typeof AssetKind]}
15
20
  */
16
- const AssetKind = harden({
21
+ export const AssetKind = /** @type {const} */ ({
17
22
  NAT: 'nat',
18
23
  SET: 'set',
19
24
  COPY_SET: 'copySet',
20
25
  COPY_BAG: 'copyBag',
21
26
  });
27
+ harden(AssetKind);
22
28
  const assetKindNames = harden(Object.values(AssetKind).sort());
23
29
 
24
- /**
25
- * @param {AssetKind} allegedAK
26
- */
27
- const assertAssetKind = allegedAK => {
30
+ /** @param {AssetKind} allegedAK */
31
+ export const assertAssetKind = allegedAK => {
28
32
  assetKindNames.includes(allegedAK) ||
29
33
  Fail`The assetKind ${allegedAK} must be one of ${q(assetKindNames)}`;
30
34
  };
31
35
  harden(assertAssetKind);
32
36
 
33
37
  /**
34
- * Amounts describe digital assets. From an amount, you can learn the
35
- * brand of digital asset as well as "how much" or "how many". Amounts
36
- * have two parts: a brand (loosely speaking, the type of digital
37
- * asset) and the value (the answer to "how much"). For example, in
38
- * the phrase "5 bucks", "bucks" takes the role of the brand and the
39
- * value is 5. Amounts can describe fungible and non-fungible digital
40
- * assets. Amounts are pass-by-copy and can be made by and sent to
41
- * anyone.
38
+ * Amounts describe digital assets. From an amount, you can learn the brand of
39
+ * digital asset as well as "how much" or "how many". Amounts have two parts: a
40
+ * brand (loosely speaking, the type of digital asset) and the value (the answer
41
+ * to "how much"). For example, in the phrase "5 bucks", "bucks" takes the role
42
+ * of the brand and the value is 5. Amounts can describe fungible and
43
+ * non-fungible digital assets. Amounts are pass-by-copy and can be made by and
44
+ * sent to anyone.
42
45
  *
43
- * The issuer is the authoritative source of the amount in payments
44
- * and purses. The issuer must be able to do things such as add
45
- * digital assets to a purse and withdraw digital assets from a purse.
46
- * To do so, it must know how to add and subtract digital assets.
47
- * Rather than hard-coding a particular solution, we chose to
48
- * parameterize the issuer with a collection of polymorphic functions,
49
- * which we call `AmountMath`. These math functions include concepts
46
+ * The issuer is the authoritative source of the amount in payments and purses.
47
+ * The issuer must be able to do things such as add digital assets to a purse
48
+ * and withdraw digital assets from a purse. To do so, it must know how to add
49
+ * and subtract digital assets. Rather than hard-coding a particular solution,
50
+ * we chose to parameterize the issuer with a collection of polymorphic
51
+ * functions, which we call `AmountMath`. These math functions include concepts
50
52
  * like addition, subtraction, and greater than or equal to.
51
53
  *
52
- * We also want to make sure there is no confusion as to what kind of
53
- * asset we are using. Thus, AmountMath includes checks of the
54
- * `brand`, the unique identifier for the type of digital asset. If
55
- * the wrong brand is used in AmountMath, an error is thrown and the
56
- * operation does not succeed.
54
+ * We also want to make sure there is no confusion as to what kind of asset we
55
+ * are using. Thus, AmountMath includes checks of the `brand`, the unique
56
+ * identifier for the type of digital asset. If the wrong brand is used in
57
+ * AmountMath, an error is thrown and the operation does not succeed.
57
58
  *
58
- * AmountMath uses mathHelpers to do most of the work, but then adds
59
- * the brand to the result. The function `value` gets the value from
60
- * the amount by removing the brand (amount -> value), and the
61
- * function `make` adds the brand to produce an amount (value ->
62
- * amount). The function `coerce` takes an amount and checks it,
63
- * returning an amount (amount -> amount).
59
+ * AmountMath uses mathHelpers to do most of the work, but then adds the brand
60
+ * to the result. The function `value` gets the value from the amount by
61
+ * removing the brand (amount -> value), and the function `make` adds the brand
62
+ * to produce an amount (value -> amount). The function `coerce` takes an amount
63
+ * and checks it, returning an amount (amount -> amount).
64
64
  *
65
- * Each issuer of digital assets has an associated brand in a
66
- * one-to-one mapping. In untrusted contexts, such as in analyzing
67
- * payments and amounts, we can get the brand and find the issuer
68
- * which matches the brand. The issuer and the brand mutually validate
69
- * each other.
65
+ * Each issuer of digital assets has an associated brand in a one-to-one
66
+ * mapping. In untrusted contexts, such as in analyzing payments and amounts, we
67
+ * can get the brand and find the issuer which matches the brand. The issuer and
68
+ * the brand mutually validate each other.
70
69
  */
71
70
 
72
71
  const helpers = {
@@ -76,26 +75,19 @@ const helpers = {
76
75
  copyBag: copyBagMathHelpers,
77
76
  };
78
77
 
79
- /**
80
- * @template {AmountValue} V
81
- * @type {(value: V) => AssetKindForValue<V>}
82
- */
78
+ /** @type {(value: unknown) => 'nat' | 'set' | 'copySet' | 'copyBag'} } */
83
79
  const assertValueGetAssetKind = value => {
84
80
  const passStyle = passStyleOf(value);
85
81
  if (passStyle === 'bigint') {
86
- // @ts-expect-error cast
87
82
  return 'nat';
88
83
  }
89
84
  if (passStyle === 'copyArray') {
90
- // @ts-expect-error cast
91
85
  return 'set';
92
86
  }
93
87
  if (matches(value, M.set())) {
94
- // @ts-expect-error cast
95
88
  return 'copySet';
96
89
  }
97
90
  if (matches(value, M.bag())) {
98
- // @ts-expect-error cast
99
91
  return 'copyBag';
100
92
  }
101
93
  // TODO This isn't quite the right error message, in case valuePassStyle
@@ -121,7 +113,9 @@ export const assertValueGetHelpers = value =>
121
113
  // @ts-expect-error cast
122
114
  helpers[assertValueGetAssetKind(value)];
123
115
 
124
- /** @type {(allegedBrand: Brand, brand?: Brand) => void} */
116
+ /**
117
+ * @type {(allegedBrand: Brand<any>, brand?: Brand<any>) => void}
118
+ */
125
119
  const optionalBrandCheck = (allegedBrand, brand) => {
126
120
  if (brand !== undefined) {
127
121
  assertRemotable(brand, 'brand');
@@ -137,7 +131,7 @@ const optionalBrandCheck = (allegedBrand, brand) => {
137
131
  * @param {Amount<K>} leftAmount
138
132
  * @param {Amount<K>} rightAmount
139
133
  * @param {Brand<K> | undefined} brand
140
- * @returns {MathHelpers<*>}
134
+ * @returns {MathHelpers<any>}
141
135
  */
142
136
  const checkLRAndGetHelpers = (leftAmount, rightAmount, brand = undefined) => {
143
137
  assertRecord(leftAmount, 'leftAmount');
@@ -164,7 +158,7 @@ const checkLRAndGetHelpers = (leftAmount, rightAmount, brand = undefined) => {
164
158
  * @param {MathHelpers<AssetValueForKind<K>>} h
165
159
  * @param {Amount<K>} leftAmount
166
160
  * @param {Amount<K>} rightAmount
167
- * @returns {[K, K]}
161
+ * @returns {[AssetValueForKind<K>, AssetValueForKind<K>]}
168
162
  */
169
163
  const coerceLR = (h, leftAmount, rightAmount) => {
170
164
  // @ts-expect-error could be arbitrary subtype
@@ -172,11 +166,11 @@ const coerceLR = (h, leftAmount, rightAmount) => {
172
166
  };
173
167
 
174
168
  /**
175
- * Returns true if the leftAmount is greater than or equal to the
176
- * rightAmount. The notion of "greater than or equal to" depends
177
- * on the kind of amount, as defined by the MathHelpers. For example,
178
- * whether rectangle A is greater than rectangle B depends on whether rectangle
179
- * A includes rectangle B as defined by the logic in MathHelpers.
169
+ * Returns true if the leftAmount is greater than or equal to the rightAmount.
170
+ * The notion of "greater than or equal to" depends on the kind of amount, as
171
+ * defined by the MathHelpers. For example, whether rectangle A is greater than
172
+ * rectangle B depends on whether rectangle A includes rectangle B as defined by
173
+ * the logic in MathHelpers.
180
174
  *
181
175
  * @template {AssetKind} K
182
176
  * @param {Amount<K>} leftAmount
@@ -194,34 +188,48 @@ const isGTE = (leftAmount, rightAmount, brand = undefined) => {
194
188
  *
195
189
  * Amounts are the canonical description of tradable goods. They are manipulated
196
190
  * by issuers and mints, and represent the goods and currency carried by purses
197
- * and
198
- * payments. They can be used to represent things like currency, stock, and the
199
- * abstract right to participate in a particular exchange.
191
+ * and payments. They can be used to represent things like currency, stock, and
192
+ * the abstract right to participate in a particular exchange.
200
193
  */
201
- const AmountMath = {
194
+ export const AmountMath = {
195
+ // TODO use overloading to handle when Brand has an AssetKind and when it doesn't.
196
+ // a AmountForValue utility could help DRY those cases.
202
197
  /**
203
198
  * Make an amount from a value by adding the brand.
204
199
  *
205
- * @template {AssetKind} K
206
- * @param {Brand<K>} brand
207
- * @param {AssetValueForKind<K>} allegedValue
208
- * @returns {Amount<K>}
200
+ * Does not verify that the Brand's AssetKind matches the value's.
201
+ *
202
+ * @template {Brand<any>} B
203
+ * @template {NatValue | CopySet | CopyBag | SetValue} V
204
+ * @param {B} brand
205
+ * @param {V} allegedValue
206
+ * @returns {B extends Brand<'nat'>
207
+ * ? NatAmount
208
+ * : V extends NatValue
209
+ * ? NatAmount
210
+ * : V extends CopySet
211
+ * ? CopySetAmount<V['payload'][0]>
212
+ * : V extends CopyBag
213
+ * ? CopyBagAmount<V['payload'][0][0]>
214
+ * : V extends SetValue
215
+ * ? SetAmount<V[0]>
216
+ * : never}
209
217
  */
210
- // allegedValue has a conditional expression for type widening, to prevent V being bound to a a literal like 1n
211
218
  make: (brand, allegedValue) => {
212
219
  assertRemotable(brand, 'brand');
213
220
  const h = assertValueGetHelpers(allegedValue);
214
221
  const value = h.doCoerce(allegedValue);
222
+ // @ts-expect-error cast
215
223
  return harden({ brand, value });
216
224
  },
217
225
  /**
218
- * Make sure this amount is valid enough, and return a corresponding
219
- * valid amount if so.
226
+ * Make sure this amount is valid enough, and return a corresponding valid
227
+ * amount if so.
220
228
  *
221
- * @template {AssetKind} K
222
- * @param {Brand<K>} brand
223
- * @param {Amount<K>} allegedAmount
224
- * @returns {Amount<K>}
229
+ * @template {Amount} A
230
+ * @param {Brand} brand
231
+ * @param {A} allegedAmount
232
+ * @returns {A}
225
233
  */
226
234
  coerce: (brand, allegedAmount) => {
227
235
  assertRemotable(brand, 'brand');
@@ -230,46 +238,47 @@ const AmountMath = {
230
238
  brand === allegedBrand ||
231
239
  Fail`The brand in the allegedAmount ${allegedAmount} in 'coerce' didn't match the specified brand ${brand}.`;
232
240
  // Will throw on inappropriate value
241
+ // @ts-expect-error cast
233
242
  return AmountMath.make(brand, allegedValue);
234
243
  },
235
244
  /**
236
245
  * Extract and return the value.
237
246
  *
238
- * @template {AssetKind} K
239
- * @param {Brand<K>} brand
240
- * @param {Amount<K>} amount
241
- * @returns {AssetValueForKind<K>}
247
+ * @template {Amount} A
248
+ * @param {Brand} brand
249
+ * @param {A} amount
250
+ * @returns {A['value']}
242
251
  */
243
252
  getValue: (brand, amount) => AmountMath.coerce(brand, amount).value,
244
253
  /**
245
- * Return the amount representing an empty amount. This is the
246
- * identity element for MathHelpers.add and MatHelpers.subtract.
254
+ * Return the amount representing an empty amount. This is the identity
255
+ * element for MathHelpers.add and MatHelpers.subtract.
247
256
  *
248
257
  * @type {{
249
258
  * (brand: Brand): Amount<'nat'>;
250
- * <K extends AssetKind>(brand: Brand, assetKind: K): Amount<K>;
259
+ * <K extends AssetKind>(brand: Brand<K>, assetKind: K): Amount<K>;
251
260
  * }}
252
261
  */
253
262
  makeEmpty: (brand, assetKind = /** @type {const} */ ('nat')) => {
254
263
  assertRemotable(brand, 'brand');
255
264
  assertAssetKind(assetKind);
256
265
  const value = helpers[assetKind].doMakeEmpty();
266
+ // @ts-expect-error XXX narrowing from function overload
257
267
  return harden({ brand, value });
258
268
  },
259
269
  /**
260
- * Return the amount representing an empty amount, using another
261
- * amount as the template for the brand and assetKind.
270
+ * Return the amount representing an empty amount, using another amount as the
271
+ * template for the brand and assetKind.
262
272
  *
263
- * @template {AssetKind} K
264
- * @param {Amount<K>} amount
265
- * @returns {Amount<K>}
273
+ * @template {Amount} A
274
+ * @param {A} amount
275
+ * @returns {A}
266
276
  */
267
277
  makeEmptyFromAmount: amount => {
268
278
  assertRecord(amount, 'amount');
269
279
  const { brand, value } = amount;
270
- // @ts-expect-error cast
271
280
  const assetKind = assertValueGetAssetKind(value);
272
- // @ts-expect-error cast (ignore b/c erroring in CI but not my IDE)
281
+ // @ts-expect-error different subtype
273
282
  return AmountMath.makeEmpty(brand, assetKind);
274
283
  },
275
284
  /**
@@ -289,13 +298,13 @@ const AmountMath = {
289
298
  },
290
299
  isGTE,
291
300
  /**
292
- * Returns true if the leftAmount equals the rightAmount. We assume
293
- * that if isGTE is true in both directions, isEqual is also true
301
+ * Returns true if the leftAmount equals the rightAmount. We assume that if
302
+ * isGTE is true in both directions, isEqual is also true
294
303
  *
295
- * @template {AssetKind} K
296
- * @param {Amount<K>} leftAmount
297
- * @param {Amount<K>} rightAmount
298
- * @param {Brand<K>} [brand]
304
+ * @template {Amount} A
305
+ * @param {A} leftAmount
306
+ * @param {A} rightAmount
307
+ * @param {Brand} [brand]
299
308
  * @returns {boolean}
300
309
  */
301
310
  isEqual: (leftAmount, rightAmount, brand = undefined) => {
@@ -306,14 +315,17 @@ const AmountMath = {
306
315
  * Returns a new amount that is the union of both leftAmount and rightAmount.
307
316
  *
308
317
  * For fungible amount this means adding the values. For other kinds of
309
- * amount, it usually means including all of the elements from both
310
- * left and right.
318
+ * amount, it usually means including all of the elements from both left and
319
+ * right.
311
320
  *
312
- * @template {AssetKind} K
313
- * @param {Amount<K>} leftAmount
314
- * @param {Amount<K>} rightAmount
315
- * @param {Brand<K>} [brand]
316
- * @returns {Amount<K>}
321
+ * @type {{
322
+ * <A extends CopyBag, B extends CopyBag>(
323
+ * leftAmount: CopyBagAmount<A>,
324
+ * rightAmount: CopyBagAmount<B>,
325
+ * brand?: Brand,
326
+ * ): CopyBagAmount<A | B>;
327
+ * <A extends Amount>(leftAmount: A, rightAmount: A, brand?: Brand): A;
328
+ * }}
317
329
  */
318
330
  add: (leftAmount, rightAmount, brand = undefined) => {
319
331
  const h = checkLRAndGetHelpers(leftAmount, rightAmount, brand);
@@ -321,68 +333,64 @@ const AmountMath = {
321
333
  return harden({ brand: leftAmount.brand, value });
322
334
  },
323
335
  /**
324
- * Returns a new amount that is the leftAmount minus the rightAmount
325
- * (i.e. everything in the leftAmount that is not in the
326
- * rightAmount). If leftAmount doesn't include rightAmount
327
- * (subtraction results in a negative), throw an error. Because the
328
- * left amount must include the right amount, this is NOT equivalent
329
- * to set subtraction.
336
+ * Returns a new amount that is the leftAmount minus the rightAmount (i.e.
337
+ * everything in the leftAmount that is not in the rightAmount). If leftAmount
338
+ * doesn't include rightAmount (subtraction results in a negative), throw an
339
+ * error. Because the left amount must include the right amount, this is NOT
340
+ * equivalent to set subtraction.
330
341
  *
331
- * @template {AssetKind} K
332
- * @param {Amount<K>} leftAmount
333
- * @param {Amount<K>} rightAmount
334
- * @param {Brand<K>} [brand]
335
- * @returns {Amount<K>}
342
+ * @template {Amount} L
343
+ * @template {Amount} R
344
+ * @param {L} leftAmount
345
+ * @param {R} rightAmount
346
+ * @param {Brand} [brand]
347
+ * @returns {L extends R ? L : never}
336
348
  */
337
349
  subtract: (leftAmount, rightAmount, brand = undefined) => {
338
350
  const h = checkLRAndGetHelpers(leftAmount, rightAmount, brand);
339
351
  const value = h.doSubtract(...coerceLR(h, leftAmount, rightAmount));
352
+ // @ts-expect-error different subtype
340
353
  return harden({ brand: leftAmount.brand, value });
341
354
  },
342
355
  /**
343
356
  * Returns the min value between x and y using isGTE
344
357
  *
345
- * @template {AssetKind} K
346
- * @param {Amount<K>} x
347
- * @param {Amount<K>} y
348
- * @param {Brand<K>} [brand]
349
- * @returns {Amount<K>}
358
+ * @template {Amount} A
359
+ * @param {A} x
360
+ * @param {A} y
361
+ * @param {Brand} [brand]
362
+ * @returns {A}
350
363
  */
351
364
  min: (x, y, brand = undefined) =>
352
365
  // eslint-disable-next-line no-nested-ternary
353
366
  isGTE(x, y, brand)
354
367
  ? y
355
368
  : isGTE(y, x, brand)
356
- ? x
357
- : Fail`${x} and ${y} are incomparable`,
369
+ ? x
370
+ : Fail`${x} and ${y} are incomparable`,
358
371
  /**
359
372
  * Returns the max value between x and y using isGTE
360
373
  *
361
- * @template {AssetKind} K
362
- * @param {Amount<K>} x
363
- * @param {Amount<K>} y
364
- * @param {Brand<K>} [brand]
365
- * @returns {Amount<K>}
374
+ * @template {Amount} A
375
+ * @param {A} x
376
+ * @param {A} y
377
+ * @param {Brand} [brand]
378
+ * @returns {A}
366
379
  */
367
380
  max: (x, y, brand = undefined) =>
368
381
  // eslint-disable-next-line no-nested-ternary
369
382
  isGTE(x, y, brand)
370
383
  ? x
371
384
  : isGTE(y, x)
372
- ? y
373
- : Fail`${x} and ${y} are incomparable`,
385
+ ? y
386
+ : Fail`${x} and ${y} are incomparable`,
374
387
  };
375
388
  harden(AmountMath);
376
389
 
377
- /**
378
- * @param {Amount} amount
379
- */
380
- const getAssetKind = amount => {
390
+ /** @param {Amount} amount */
391
+ export const getAssetKind = amount => {
381
392
  assertRecord(amount, 'amount');
382
393
  const { value } = amount;
383
- // @ts-expect-error cast (ignore b/c erroring in CI but not my IDE)
384
394
  return assertValueGetAssetKind(value);
385
395
  };
386
396
  harden(getAssetKind);
387
-
388
- export { AmountMath, AssetKind, getAssetKind, assertAssetKind };
@@ -0,0 +1,9 @@
1
+ export function makeAmountStore<K extends AssetKind = AssetKind>(state: object, key: string): AmountStore<K>;
2
+ export type AmountStore<K extends AssetKind = AssetKind> = {
3
+ getAmount: () => Amount<K>;
4
+ increment: (delta: Amount<K>) => void;
5
+ decrement: (delta: Amount<K>) => boolean;
6
+ };
7
+ import type { AssetKind } from './types.js';
8
+ import type { Amount } from './types.js';
9
+ //# sourceMappingURL=amountStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amountStore.d.ts","sourceRoot":"","sources":["amountStore.js"],"names":[],"mappings":"AAkBO,gCALmB,CAAC,SAAd,SAAW,qBACb,MAAM,OACN,MAAM,GACJ,WAAW,CAAC,CAAC,CAAC,CAgB1B;wBA3ByB,CAAC,SAAd,SAAW;eAEV,MAAM,OAAO,CAAC,CAAC;eACf,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;eAC1B,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,OAAO;;+BAPN,YAAY;4BAAZ,YAAY"}
@@ -0,0 +1,34 @@
1
+ import { AmountMath } from './amountMath.js';
2
+
3
+ /** @import {Amount, AssetKind} from './types.js' */
4
+
5
+ /**
6
+ * @template {AssetKind} [K=AssetKind]
7
+ * @typedef {object} AmountStore
8
+ * @property {() => Amount<K>} getAmount
9
+ * @property {(delta: Amount<K>) => void} increment
10
+ * @property {(delta: Amount<K>) => boolean} decrement
11
+ */
12
+
13
+ /**
14
+ * @template {AssetKind} [K=AssetKind]
15
+ * @param {object} state
16
+ * @param {string} key
17
+ * @returns {AmountStore<K>}
18
+ */
19
+ export const makeAmountStore = (state, key) => {
20
+ return harden({
21
+ getAmount: () => state[key],
22
+ increment: delta => {
23
+ state[key] = AmountMath.add(state[key], delta);
24
+ },
25
+ decrement: delta => {
26
+ if (AmountMath.isGTE(state[key], delta)) {
27
+ state[key] = AmountMath.subtract(state[key], delta);
28
+ return true;
29
+ }
30
+ return false;
31
+ },
32
+ });
33
+ };
34
+ harden(makeAmountStore);
@@ -1,2 +1,5 @@
1
1
  export function coerceDisplayInfo(allegedDisplayInfo: AdditionalDisplayInfo, assetKind: AssetKind): DisplayInfo;
2
+ import type { AdditionalDisplayInfo } from './types.js';
3
+ import type { AssetKind } from './types.js';
4
+ import type { DisplayInfo } from './types.js';
2
5
  //# sourceMappingURL=displayInfo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"displayInfo.d.ts","sourceRoot":"","sources":["displayInfo.js"],"names":[],"mappings":"AAYO,sDAJI,qBAAqB,aACrB,SAAS,GACP,WAAW,CAiBvB"}
1
+ {"version":3,"file":"displayInfo.d.ts","sourceRoot":"","sources":["displayInfo.js"],"names":[],"mappings":"AAcO,sDAJI,qBAAqB,aACrB,SAAS,GACP,WAAW,CAiBvB;2CAtBgE,YAAY;+BAAZ,YAAY;iCAAZ,YAAY"}
@@ -1,10 +1,12 @@
1
1
  // @jessie-check
2
2
 
3
- import { Fail } from '@agoric/assert';
3
+ import { Fail } from '@endo/errors';
4
4
  import { mustMatch } from '@agoric/store';
5
5
 
6
6
  import { DisplayInfoShape } from './typeGuards.js';
7
7
 
8
+ /** @import {AdditionalDisplayInfo, AssetKind, DisplayInfo} from './types.js' */
9
+
8
10
  /**
9
11
  * @param {AdditionalDisplayInfo} allegedDisplayInfo
10
12
  * @param {AssetKind} assetKind
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./amountMath.js";
2
2
  export * from "./issuerKit.js";
3
3
  export * from "./typeGuards.js";
4
+ export * from "./types-index.js";
4
5
  //# sourceMappingURL=index.d.ts.map
package/src/index.js CHANGED
@@ -1,5 +1,9 @@
1
1
  // @jessie-check
2
+ /// <reference types="@agoric/internal/exported" />
2
3
 
3
4
  export * from './amountMath.js';
4
5
  export * from './issuerKit.js';
5
6
  export * from './typeGuards.js';
7
+
8
+ // eslint-disable-next-line import/export
9
+ export * from './types-index.js';
@@ -1,19 +1,39 @@
1
- export function prepareIssuerKit<K extends AssetKind>(issuerBaggage: MapStore<string, unknown>, optShutdownWithFailure?: import("@agoric/swingset-vat").ShutdownWithFailure | undefined): IssuerKit<K>;
2
- export function hasIssuer(baggage: MapStore<string, unknown>): any;
3
- export function makeDurableIssuerKit<K extends AssetKind>(issuerBaggage: MapStore<string, unknown>, name: string, assetKind?: K | undefined, displayInfo?: AdditionalDisplayInfo | undefined, optShutdownWithFailure?: import("@agoric/swingset-vat").ShutdownWithFailure | undefined, { elementShape }?: Partial<{
4
- elementShape: Pattern;
5
- }> | undefined): IssuerKit<K>;
6
- export function makeIssuerKit<K extends AssetKind = "nat">(name: string, assetKind?: K | undefined, displayInfo?: AdditionalDisplayInfo | undefined, optShutdownWithFailure?: import("@agoric/swingset-vat").ShutdownWithFailure | undefined, { elementShape }?: Partial<{
7
- elementShape: Pattern;
8
- }> | undefined): IssuerKit<K>;
9
- export type Baggage = import('@agoric/vat-data').Baggage;
1
+ export function upgradeIssuerKit<K extends AssetKind>(issuerBaggage: Baggage, optShutdownWithFailure?: ShutdownWithFailure, recoverySetsOption?: RecoverySetsOption): IssuerKit<K>;
2
+ export function hasIssuer(baggage: Baggage): boolean;
3
+ export function makeDurableIssuerKit<K extends AssetKind>(issuerBaggage: Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: IssuerOptionsRecord): IssuerKit<K>;
4
+ export function prepareIssuerKit<O extends IssuerOptionsRecord, K extends AssetKind>(issuerBaggage: Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, options?: O): O["elementShape"] extends TypedPattern<infer T extends Key> ? IssuerKit<K, T> : IssuerKit<K>;
5
+ export function makeIssuerKit<K extends AssetKind = "nat", O extends IssuerOptionsRecord = {}>(name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: O): O["elementShape"] extends TypedPattern<infer T extends Key> ? IssuerKit<K, T> : IssuerKit<K>;
10
6
  export type IssuerRecord<K extends AssetKind> = {
11
7
  name: string;
12
8
  assetKind: K;
13
9
  displayInfo: AdditionalDisplayInfo;
14
10
  elementShape: Pattern;
15
11
  };
12
+ /**
13
+ * `elementShape`, may only be present for collection-style amounts. If present,
14
+ * it is a `Pattern` that every element of this issuerKits's amounts must
15
+ * satisfy. For example, the Zoe Invitation issuerKit uses an elementShape
16
+ * describing the invitation details for an individual invitation. An invitation
17
+ * purse or payment has an amount that can only be a set of these. (Though
18
+ * typically, the amount of an invitation payment is a singleton set. Such a
19
+ * payment is often referred to in the singular as "an invitation".)
20
+ *
21
+ * `recoverySetsOption` added in upgrade. Note that `IssuerOptionsRecord` is
22
+ * never stored, so we never need to worry about inheriting one from a
23
+ * predecessor predating the introduction of recovery sets. See
24
+ * `RecoverySetsOption` for defaulting behavior.
25
+ */
16
26
  export type IssuerOptionsRecord = Partial<{
17
27
  elementShape: Pattern;
28
+ recoverySetsOption: RecoverySetsOption;
18
29
  }>;
30
+ import { AssetKind } from './amountMath.js';
31
+ import type { Baggage } from '@agoric/vat-data';
32
+ import type { ShutdownWithFailure } from '@agoric/swingset-vat';
33
+ import type { RecoverySetsOption } from './types.js';
34
+ import type { IssuerKit } from './types.js';
35
+ import type { AdditionalDisplayInfo } from './types.js';
36
+ import type { Key } from '@endo/patterns';
37
+ import type { TypedPattern } from '@agoric/internal';
38
+ import type { Pattern } from '@endo/patterns';
19
39
  //# sourceMappingURL=issuerKit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"issuerKit.d.ts","sourceRoot":"","sources":["issuerKit.js"],"names":[],"mappings":"AA2FO,uMAMN;AASM,mEAAsD;AAmCtD,0GAbI,MAAM;kBAnBmB,OAAO;8BA4C1C;AA+BM,iEAbI,MAAM;kBA9DmB,OAAO;8BA0FxC;sBA3LW,OAAO,kBAAkB,EAAE,OAAO;;UAKlC,MAAM;eACN,CAAC;iBACD,qBAAqB;kBACrB,OAAO;;kCAyFR,QAAQ;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,CAAC"}
1
+ {"version":3,"file":"issuerKit.d.ts","sourceRoot":"","sources":["issuerKit.js"],"names":[],"mappings":"AAkHO,iCAbkB,CAAC,SAAZ,SAAU,iBACb,OAAO,2BACP,mBAAmB,uBAOnB,kBAAkB,GAEhB,UAAU,CAAC,CAAC,CA4BxB;AAQM,mCAFI,OAAO,WAE2C;AAoDtD,qCA1BkB,CAAC,SAAZ,SAAU,iBAYb,OAAO,QACP,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,yCAOnB,mBAAmB,GACjB,UAAU,CAAC,CAAC,CA2BxB;AAoCM,iCA7B4B,CAAC,SAAtB,mBAAoB,EACT,CAAC,SAAZ,SAAU,iBAYb,OAAO,QACP,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,YAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,SAAS,GAAG,CAAC,GAC/D,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAyCpB;AAqCM,8BAzBmB,CAAC,SAAb,SAAU,UACY,CAAC,SAAvB,mBAAoB,aACvB,MAAM,cAMN,CAAC,gBAGD,qBAAqB,2BAErB,mBAAmB,yCAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,SAAS,GAAG,CAAC,GAC/D,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAmBlB;yBA7UsB,CAAC,SAAZ,SAAU;UAEV,MAAM;eACN,CAAC;iBACD,qBAAqB;kBACrB,OAAO;;;;;;;;;;;;;;;;kCA0IR,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC;0BAhKsC,iBAAiB;6BASlC,kBAAkB;yCAFN,sBAAsB;wCAG0B,YAAY;+BAAZ,YAAY;2CAAZ,YAAY;yBALnE,gBAAgB;kCAGhB,kBAAkB;6BAHlB,gBAAgB"}