# AmountMath Object

Library for manipulating and analyzing Amounts.

# Importing and Using AmountMath

To use AmountMath, import it from ERTP:

  • import { AmountMath } from '@agoric/ertp';

# Brand Parameters

Note that many AmountMath methods have an optional Brand parameter. For these methods, you should pass in a Brand argument you got from when you need to do an "absolute" check on the Brand within an Amount parameter. 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. If they are not equal, an error is thrown and no changes are made.

# AmountMath.make(brand, allegedValue)

Creates an Amount from a given Brand and AmountValue.

// amount837 = { brand: quatloosBrand, value: 837n }
const amount837 = AmountMath.make(quatloosBrand, 837n);

# AmountMath.coerce(brand, allegedAmount)

Makes sure an Amount is for the specified brand and if so, returns it. If the Amount is for an invalid Brand, this method throws an exception.

const quatloos50 = AmountMath.make(quatloosBrand, 50n);
// Returns the same amount as quatloos50
const verifiedAmount = AmountMath.coerce(quatloosBrand, allegedAmount); 

# AmountMath.getValue(brand, amount)

Returns the AmountValue from the given Amount.

const quatloos123 = AmountMath.make(quatloosBrand, 123n);

// Returns 123n
const myValue = AmountMath.getValue(quatloosBrand, quatloos123);

# AmountMath.makeEmpty(brand, assetKind)

Returns the Amount representing an empty Amount for the brand parameter's Brand. This is the identity element for AmountMath.add() and AmountMath.subtract(). The empty AmountValue depends on whether the assetKind is AssetKind.NAT (0n), AssetKind.COPY_SET ([]), or AssetKind.COPY_BAG ([]).

// Returns an empty amount.
// Since this is a fungible assetKind it returns an amount
// with 0n as its value.
const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT);

# AmountMath.makeEmptyFromAmount(amount)

  • amount: Amount
  • Returns: Amount

Returns the Amount representing an empty Amount, using another Amount as the template for the Brand and AmountValue.

// quatloosAmount837 = { brand: quatloos, value: 837n }
const quatloosAmount837 = AmountMath.make(quatloosBrand, 837n);
// Returns an amount = { brand: quatloos, value: 0n }
const quatloosAmount0 = AmountMath.makeEmptyFromAmount(quatloosAmount837);

# AmountMath.isEmpty(amount, brand?)

  • amount: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Boolean

Returns true if the Amount is empty. Otherwise returns false.

If the optional brand argument doesn't match the Amount's Brand, an error is thrown.

const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT);
const quatloos1 = AmountMath.make(quatloosBrand, 1n);

// Returns true
const result = AmountMath.isEmpty(empty);

// Returns false
const result = AmountMath.isEmpty(quatloos1);

# AmountMath.isGTE(leftAmount, rightAmount, brand?)

  • leftAmount: Amount
  • rightAmount: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Boolean

Returns true if the AmountValue of leftAmount is greater than or equal to the AmountValue of rightAmount. Both Amount arguments must have the same Brand.

If the optional brand argument doesn't match the Amounts' Brand, an error is thrown.

For non-fungible AmountValues, what "greater than or equal to" is depends on the kind of AmountMath. For example, { 'seat 1', 'seat 2' } is considered greater than { 'seat 2' } because the former both contains all of the latter's content and has additional elements.

const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT);
const quatloos5 = AmountMath.make(quatloosBrand, 5n);
const quatloos10 = AmountMath.make(quatloosBrand, 10n);

// Returns true
AmountMath.isGTE(quatloos5, empty);
// Returns false
AmountMath.isGTE(empty, quatloos5, quatloosBrand);
// Returns true
AmountMath.isGTE(quatloos10, quatloos5);
// Returns false
AmountMath.isGTE(quatloos5, quatloos10);
// Returns true
AmountMath.isGTE(quatloos5, quatloos5);

# AmountMath.isEqual(leftAmount, rightAmount, brand?)

  • leftAmount: Amount
  • rightAmount: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Boolean

Returns true if the AmountValue of leftAmount is equal to the AmountValue of rightAmount. Both Amount arguments must have the same Brand.

If the optional brand argument doesn't match the Amounts' Brand, an error is thrown.

For non-fungible AmountValues, "equal to" depends on the value of the Brand's AssetKind.

For example, { 'seat 1', 'seat 2' } is considered unequal to { 'seat 2' } because the number of items in the former is different from that of the latter. Similarly { 'seat 1', 'seat 3' } and { 'seat 2' } are considered unequal because the latter has elements that are not contained in the former.

const empty = AmountMath.makeEmpty(quatloosBrand, AssetKind.NAT);
const quatloos5 = AmountMath.make(quatloosBrand, 5n);
const quatloos5b = AmountMath.make(quatloosBrand, 5n);
const quatloos10 = AmountMath.make(quatloosBrand, 10n);

// Returns true
AmountMath.isEqual(quatloos10, quatloos10);
// Returns true
AmountMath.isEqual(quatloos5, quatloos5b);
// Returns false
AmountMath.isEqual(quatloos10, quatloos5);
// Returns false
AmountMath.isEqual(empty, quatloos10);

# AmountMath.add(leftAmount, rightAmount, brand?)

  • leftAmount: Amount
  • rightAmount: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Amount

Returns a new Amount that is the union of leftAmount and rightAmount. Both arguments must be of the same Brand.

If the optional brand argument doesn't match the Amounts' Brand, an error is thrown.

For fungible Amounts this means adding their AmountValues. For non-fungible Amounts, it usually means including all of the elements from leftAmount and rightAmount.

If either leftAmount or rightAmount is empty, this method returns the non-empty Amount argument. If both are empty, this method returns an empty Amount.

import { AssetKind, makeIssuerKit, AmountMath } from '@agoric/ertp';
const { brand: myItemsBrand } = makeIssuerKit('myItems', AssetKind.COPY_SET');
const listAmountA = AmountMath.make(myItemsBrand, ['1','2','4']);
const listAmountB = AmountMath.make(myItemsBrand, ['3']);

// Returns an amount whose value is ['1', '2', '4', '3']
const combinedList = AmountMath.add(listAmountA, listAmountB);

# AmountMath.subtract(leftAmount, rightAmount, brand?)

  • leftAmount: Amount
  • rightAmount: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Amount

Returns a new Amount that is the leftAmount minus the rightAmount (i.e., everything in the leftAmount that is not in the rightAmount). If leftAmount doesn't include rightAmount (i.e., subtraction results in a negative), this method throws an error. Because leftAmount must include rightAmount, this is not equivalent to set subtraction.

leftAmount and rightAmount must be of the same Brand.

If the optional brand argument doesn't match the Amounts' Brand, an error is thrown.

If rightAmount is empty, this method returns leftAmount. If both arguments are empty, this method returns an empty Amount.

import { AssetKind, makeIssuerKit, AmountMath } from '@agoric/ertp';
const { brand: myItemsBrand } = makeIssuerKit('myItems', AssetKind.COPY_SET');
const listAmountA = AmountMath.make(myItemsBrand, ['1','2','4']);
const listAmountB = AmountMath.make(myItemsBrand, ['3']);
const listAmountC = AmountMath.make(myItemsBrand, ['2']);

// Returns ['1', '4']
const subtractedList = AmountMath.subtract(listAmountA, listAmountC)

// Throws error
const badList = AmountMath.subtract(listAmountA, listAmountB)

# AmountMath.min(x, y, brand?)

  • x: Amount
  • y: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Amount

Returns the minimum value between x and y.

x and y must be of the same Brand. If they're not, an error is thrown.

If the optional brand argument doesn't match the Brand of x and y, an error is thrown.

const smallerAmount = AmountMath.make(quatloosBrand, 5n);
const largerAmount = AmountMath.make(quatloosBrand, 10n);

// Returns smallerAmount
const comparisonResult = AmountMath.min(smallerAmount, largerAmount);

# AmountMath.max(x, y, brand?)

  • x: Amount
  • y: Amount
  • brand: Brand - Optional, defaults to undefined.
  • Returns: Amount

Returns the maximum value between x and y.

x and y must be of the same Brand. If they're not, an error is thrown.

If the optional brand argument doesn't match the Brand of x and y, an error is thrown.

const smallerAmount = AmountMath.make(quatloosBrand, 5n);
const largerAmount = AmountMath.make(quatloosBrand, 10n);

// Returns largerAmount
const comparisonResult = AmountMath.max(smallerAmount, largerAmount);

The following methods on other ERTP components and objects also either operate on or return an Amount or AssetKind.