@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.
- package/exported.d.ts +37 -0
- package/exported.js +2 -1
- package/package.json +37 -37
- package/src/amountMath.d.ts +46 -38
- package/src/amountMath.d.ts.map +1 -1
- package/src/amountMath.js +136 -128
- package/src/amountStore.d.ts +9 -0
- package/src/amountStore.d.ts.map +1 -0
- package/src/amountStore.js +34 -0
- package/src/displayInfo.d.ts +3 -0
- package/src/displayInfo.d.ts.map +1 -1
- package/src/displayInfo.js +3 -1
- package/src/index.d.ts +1 -0
- package/src/index.js +4 -0
- package/src/issuerKit.d.ts +29 -9
- package/src/issuerKit.d.ts.map +1 -1
- package/src/issuerKit.js +230 -75
- package/src/legacy-payment-helpers.d.ts +9 -2
- package/src/legacy-payment-helpers.d.ts.map +1 -1
- package/src/legacy-payment-helpers.js +43 -37
- package/src/mathHelpers/copyBagMathHelpers.d.ts +3 -4
- package/src/mathHelpers/copyBagMathHelpers.d.ts.map +1 -1
- package/src/mathHelpers/copyBagMathHelpers.js +4 -5
- package/src/mathHelpers/copySetMathHelpers.d.ts +3 -3
- package/src/mathHelpers/copySetMathHelpers.d.ts.map +1 -1
- package/src/mathHelpers/copySetMathHelpers.js +6 -4
- package/src/mathHelpers/natMathHelpers.d.ts +8 -7
- package/src/mathHelpers/natMathHelpers.d.ts.map +1 -1
- package/src/mathHelpers/natMathHelpers.js +8 -9
- package/src/mathHelpers/setMathHelpers.d.ts +2 -0
- package/src/mathHelpers/setMathHelpers.d.ts.map +1 -1
- package/src/mathHelpers/setMathHelpers.js +2 -1
- package/src/payment.d.ts +4 -2
- package/src/payment.d.ts.map +1 -1
- package/src/payment.js +8 -8
- package/src/paymentLedger.d.ts +8 -2
- package/src/paymentLedger.d.ts.map +1 -1
- package/src/paymentLedger.js +80 -97
- package/src/purse.d.ts +19 -9
- package/src/purse.d.ts.map +1 -1
- package/src/purse.js +86 -26
- package/src/ratio.d.ts +48 -0
- package/src/ratio.d.ts.map +1 -0
- package/src/ratio.js +441 -0
- package/src/safeMath.d.ts +11 -0
- package/src/safeMath.d.ts.map +1 -0
- package/src/safeMath.js +50 -0
- package/src/transientNotifier.d.ts +1 -1
- package/src/transientNotifier.d.ts.map +1 -1
- package/src/transientNotifier.js +5 -0
- package/src/typeGuards.d.ts +64 -13
- package/src/typeGuards.d.ts.map +1 -1
- package/src/typeGuards.js +70 -57
- package/src/types-index.d.ts +2 -0
- package/src/types-index.js +2 -0
- package/src/types.d.ts +254 -220
- package/src/types.d.ts.map +1 -1
- package/src/types.ts +474 -0
- package/CHANGELOG.md +0 -743
- package/src/types-ambient.d.ts +0 -376
- package/src/types-ambient.d.ts.map +0 -1
- package/src/types-ambient.js +0 -440
- 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
|
-
|
|
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
|
-
* @
|
|
19
|
+
* @enum {(typeof AssetKind)[keyof typeof AssetKind]}
|
|
15
20
|
*/
|
|
16
|
-
const AssetKind =
|
|
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
|
-
|
|
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
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* the
|
|
39
|
-
*
|
|
40
|
-
*
|
|
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
|
-
*
|
|
45
|
-
* digital assets
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
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
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
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
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
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
|
-
/**
|
|
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
|
|
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
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* whether rectangle A
|
|
179
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* @
|
|
208
|
-
* @
|
|
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
|
-
*
|
|
226
|
+
* Make sure this amount is valid enough, and return a corresponding valid
|
|
227
|
+
* amount if so.
|
|
220
228
|
*
|
|
221
|
-
* @template {
|
|
222
|
-
* @param {Brand
|
|
223
|
-
* @param {
|
|
224
|
-
* @returns {
|
|
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 {
|
|
239
|
-
* @param {Brand
|
|
240
|
-
* @param {
|
|
241
|
-
* @returns {
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
270
|
+
* Return the amount representing an empty amount, using another amount as the
|
|
271
|
+
* template for the brand and assetKind.
|
|
262
272
|
*
|
|
263
|
-
* @template {
|
|
264
|
-
* @param {
|
|
265
|
-
* @returns {
|
|
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
|
|
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
|
-
*
|
|
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 {
|
|
296
|
-
* @param {
|
|
297
|
-
* @param {
|
|
298
|
-
* @param {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
|
-
*
|
|
318
|
+
* amount, it usually means including all of the elements from both left and
|
|
319
|
+
* right.
|
|
311
320
|
*
|
|
312
|
-
* @
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
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
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
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 {
|
|
332
|
-
* @
|
|
333
|
-
* @param {
|
|
334
|
-
* @param {
|
|
335
|
-
* @
|
|
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 {
|
|
346
|
-
* @param {
|
|
347
|
-
* @param {
|
|
348
|
-
* @param {Brand
|
|
349
|
-
* @returns {
|
|
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
|
-
|
|
357
|
-
|
|
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 {
|
|
362
|
-
* @param {
|
|
363
|
-
* @param {
|
|
364
|
-
* @param {Brand
|
|
365
|
-
* @returns {
|
|
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
|
-
|
|
373
|
-
|
|
385
|
+
? y
|
|
386
|
+
: Fail`${x} and ${y} are incomparable`,
|
|
374
387
|
};
|
|
375
388
|
harden(AmountMath);
|
|
376
389
|
|
|
377
|
-
/**
|
|
378
|
-
|
|
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);
|
package/src/displayInfo.d.ts
CHANGED
|
@@ -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
|
package/src/displayInfo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displayInfo.d.ts","sourceRoot":"","sources":["displayInfo.js"],"names":[],"mappings":"
|
|
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"}
|
package/src/displayInfo.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// @jessie-check
|
|
2
2
|
|
|
3
|
-
import { Fail } from '@
|
|
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
package/src/index.js
CHANGED
package/src/issuerKit.d.ts
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
export function
|
|
2
|
-
export function hasIssuer(baggage:
|
|
3
|
-
export function makeDurableIssuerKit<K extends AssetKind>(issuerBaggage:
|
|
4
|
-
|
|
5
|
-
}>
|
|
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
|
package/src/issuerKit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"issuerKit.d.ts","sourceRoot":"","sources":["issuerKit.js"],"names":[],"mappings":"
|
|
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"}
|