# 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 (opens new window) type to avoid overflow risks from using the usual JavaScript- Numbertype.
- 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 valueof theamountargument. For fungible assets, this will be aBigInt.
- 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 trueif itsamountargument is empty, otherwisefalse. Throws an error if the optionalbrandargument isn't the same as theamountargument brand.
- 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 trueif theleftAmountargument is greater than or equal to therightAmountargument, otherwisefalse. Throws an error if the optionalbrandargument isn't the same as theamountarguments brands.
- 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 trueif theleftAmountargument equals therightAmountargument. Throws an error if the optionalbrandargument isn't the same as theamountarguments brands.
- 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 amountand returns it if it's a validamount. If invalid, it throws an error.
- 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 amountthat is the union of theleftAmountandrightAmountamountarguments. For a fungibleamount, this means add their values. For a non-fungibleamount, it usually means including all elements from bothleftAmountandrightAmount. Throws an error if the optionalbrandargument isn't the same as theamountarguments brands.
- 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 amountthat is theleftAmountargument minus therightAmountargument (i.e., for strings or objects everything inleftAmountnot inrightAmount). IfleftAmountdoesn't include the contents ofrightAmount, it throws an error. It also throws an error if the optionalbrandargument isn't the same as theamountarguments brands.
- 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 valueargument and returns anamountby making a record with thevalueand thebrandassociated with theAmountMath. Thevalueargument should be represented as aBigInte.g.10nrather than10.
- 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 amountrepresenting an emptyamount, which is the identity element for theAmountMathadd()andsubtract()operations. Note that this value varies depending on thebrandand whether it is of kindAssetKind.NATorAssetKind.SET.
- 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 amountrepresenting an emptyamount, using anotheramountas the template for the new empty amount'sbrandandassetKind.
- 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 AssetKindof theissuer'sbrand. (AssetKind.NATorAssetKind.SET).
- const myAssetKind = quatloosIssuer.getAssetKind();
 
- Returns the 
- zcf.getAssetKind(brand) - Returns the AssetKindof thebrandargument.
- const quatloosAssetKind = zcf.getAssetKind(quatloosBrand);
 
- Returns the