# 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 JavaScriptNumbertype.AssetKind.SET(set): Used with non-fungible assets. Values are copyArrays such as hardened arrays of strings.
makeIssuerKit(allegedName, assetKind, displayInfo=) creates a new issuer,
mint, and brand.
The second, optional, assetKind argument specifies which type
of AmountMath is used for the brand in a one-to-one
association with the new issuer. It defaults to AssetKind.NAT.
The third, optional, displayInfo argument tells the UI how to display
values associated with the created brand. It defaults to undefined.
For example:
makeIssuerKit('Quatloos'); // Defaults to AssetKind.NAT
makeIssuerKit('Quatloos', AssetKind.SET);Note that many AmountMath methods have a brand argument, either required or
optional. For the ones with an optional brand argument, you should use it if
you need to do an "absolute" check on the brand in the amount argument(s).
In this case, you want to use the brand you got from the issuer (or from Zoe)
as the optional parameter to compare the amount brand(s) to.
# 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.
- 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 a AssetKind:
- issuer.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