AmountMath
Depositing and withdrawing assets from a purse
and manipulating payment
amounts all require adding and subtracting digital assets. ERTP uses the AmountMath
library for all these operations.
The AmountMath
library functions work for both fungible and nonfungible tokens. There are two AssetKinds
, each of which implements the same methods. Which kind is used for a particular brand
depends on what was specified when the brand
and its issuer
were created. They are:
AssetKind.NAT
("nat"): Used with fungible assets. Values are natural numbers using the JavaScript BigInt type to avoid overflow risks from using the usual JavaScriptNumber
type.AssetKind.SET
("set"): Used with non-fungible assets. Values are copyArrays such as hardened arrays of strings.
AmountMath Methods
The following is a brief description and example of each AmountMath
method. For more detail, click the method's name to go to its entry in the ERTP API Reference.
Note that many methods have a brand
argument, either required or optional. Where optional, use the brand
you got from an issuer (or from Zoe) to add verification that the brand
of "amount" argument(s) corresponds with that brand
.
- Information Getting Methods
- AmountMath.getValue(brand, amount)
- Returns the
value
of theamount
argument. For fungible assets, this will be aBigInt
. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); const quatloos123 = AmountMath.make(quatloosBrand, 123n); // returns 123 const value = AmountMath.getValue(quatloosBrand, quatloos123);
- Returns the
- AmountMath.getValue(brand, amount)
- Comparison Methods
- AmountMath.isEmpty(amount, brand?)
- Returns
true
if itsamount
argument is empty, otherwisefalse
. Throws an error if the optionalbrand
argument isn't the same as theamount
argument brand. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT); const quatloos1 = AmountMath.make(quatloosBrand, 1n); // returns true AmountMath.isEmpty(empty); // returns false AmountMath.isEmpty(quatloos1);
- Returns
- AmountMath.isGTE(leftAmount, rightAmount, brand?)
- Returns
true
if theleftAmount
argument is greater than or equal to therightAmount
argument, otherwisefalse
. Throws an error if the optionalbrand
argument isn't the same as theamount
arguments brands. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT); const quatloos1 = AmountMath.make(quatloosBrand, 1n); // Returns true AmountMath.isGTE(quatloos1, empty); // Returns false AmountMath.isGTE(empty, quatloos1);
- Returns
- AmountMath.isEqual(leftAmount, rightAmount, brand?)
- Returns
true
if theleftAmount
argument equals therightAmount
argument. Throws an error if the optionalbrand
argument isn't the same as theamount
arguments brands. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT); const quatloos1 = AmountMath.make(quatloosBrand, 1n); const anotherQuatloos1 = AmountMath.make(quatloosBrand, 1n); // Returns true AmountMath.isEqual(quatloos1, anotherQuatloos1); // Returns false AmountMath.isEqual(empty, quatloos1);
- Returns
- AmountMath.coerce(brand, allegedAmount)
- Takes an
amount
and returns it if it's a validamount
. If invalid, it throws an error. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); const quatloos50 = AmountMath.make(quatloosBrand, 50n); AmountMath.coerce(quatloosBrand, quatloos50); // equal to quatloos50
- Takes an
- AmountMath.isEmpty(amount, brand?)
- Manipulator Methods
- AmountMath.add(leftAmount, rightAmount, brand?)
- Returns an
amount
that is the union of theleftAmount
andrightAmount
amount
arguments. For a fungibleamount
, this means add their values. For a non-fungibleamount
, it usually means including all elements from bothleftAmount
andrightAmount
. Throws an error if the optionalbrand
argument isn't the same as theamount
arguments brands. - js
const { brand: myItemsBrand } = makeIssuerKit('myItems', 'set'); const listAmountA = AmountMath.make(myItemsBrand, harden(['1', '2', '4'])); const listAmountB = AmountMath.make(myItemsBrand, harden(['3'])); // Returns an amount containing all of ['1', '2', '4', '3'] const combinedList = AmountMath.add(listAmountA, listAmountB);
- Returns an
- AmountMath.subtract(leftAmount, rightAmount, brand?)
- Returns a new
amount
that is theleftAmount
argument minus therightAmount
argument (i.e., for strings or objects everything inleftAmount
not inrightAmount
). IfleftAmount
doesn't include the contents ofrightAmount
, it throws an error. It also throws an error if the optionalbrand
argument isn't the same as theamount
arguments brands. - js
const { brand: myItemsBrand } = makeIssuerKit('myItems', 'set'); const listAmountA = AmountMath.make(myItemsBrand, harden(['1', '2', '4'])); const listAmountB = AmountMath.make(myItemsBrand, harden(['3'])); const listAmountC = AmountMath.make(myItemsBrand, harden(['2'])); // Returns ['1', '4'] const subtractedList = AmountMath.subtract(listAmountA, listAmountC); // Throws error t.throws(() => AmountMath.subtract(listAmountA, listAmountB), { message: /right element .* was not in left/, });
- Returns a new
- AmountMath.add(leftAmount, rightAmount, brand?)
- Amount Creation Methods
- AmountMath.make(brand, allegedValue)
- Takes a
value
argument and returns anamount
by making a record with thevalue
and thebrand
associated with theAmountMath
. Thevalue
argument should be represented as aBigInt
e.g.10n
rather than10
. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); /// An `amount` with `value` = 837 and `brand` = Quatloos const quatloos837 = AmountMath.make(quatloosBrand, 837n); const anotherQuatloos837 = harden({ brand: quatloosBrand, value: 837n }); t.deepEqual(quatloos837, anotherQuatloos837);
- Takes a
- AmountMath.makeEmpty(brand, assetKind)
- Returns an
amount
representing an emptyamount
, which is the identity element for theAmountMath
add()
andsubtract()
operations. Note that this value varies depending on thebrand
and whether it is of kindAssetKind.NAT
orAssetKind.SET
. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); // Returns an empty amount for this issuer. // Since this is a fungible amount it returns 0 const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT);
- Returns an
- AmountMath.makeEmptyFromAmount(amount)
- Returns an
amount
representing an emptyamount
, using anotheramount
as the template for the new empty amount'sbrand
andassetKind
. - js
const { brand: quatloosBrand } = makeIssuerKit('quatloos'); // Returns an empty amount for this issuer. // Since this is a fungible amount it returns 0 const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT); // quatloosAmount837 = { value: 837n, brand: quatloos } const quatloosAmount837 = AmountMath.make(quatloosBrand, 837n); // Returns an amount = { value: 0n, brand: quatloos } const quatloosAmount0 = AmountMath.makeEmptyFromAmount(quatloosAmount837);
- Returns an
- AmountMath.make(brand, allegedValue)
Methods On Other Objects
These methods return an AssetKind:
- anIssuer.getAssetKind()
- Returns the
AssetKind
of theissuer
'sbrand
. (AssetKind.NAT
orAssetKind.SET
). - js
const myAssetKind = quatloosIssuer.getAssetKind();
- Returns the
- zcf.getAssetKind(brand)
- Returns the
AssetKind
of thebrand
argument. - js
const quatloosAssetKind = zcf.getAssetKind(quatloosBrand);
- Returns the