ao-tokens
This library makes it easy to interact with tokens and operate with token quantities.
Installation
The library needs @permaweb/aoconnect
as a peer dependency.
npm i ao-tokens @permaweb/aoconnect
yarn add ao-tokens @permaweb/aoconnect
Usage
Tokens
The Token
class provides basic methods to query token data. It first needs to be loaded:
const aoCredToken = await Token(
"Sa0iBLPNyJQrwpTTG-tWLQU-1QeUAJA73DdxGGiKoJc"
);
You can also provide custom configuration for this:
const aoCredToken = await Token(
"Sa0iBLPNyJQrwpTTG-tWLQU-1QeUAJA73DdxGGiKoJc",
createDataItemSigner(wallet),
connect({ ... })
);
Token info
Information about the token, such as Name
, Ticker
, Denomination
, etc. is preloaded:
const tokenID = aoCredToken.id;
const tokenName = aoCredToken.info.Name;
const symbol = aoCredToken.info.Ticker;
const denomination = aoCredToken.info.Denomination;
const logo = aoCredToken.info.Logo;
Token quantity
You can easily manage quantities as special, bigint
based floating point numbers that keep precision, using the token.Quantity
field. This field provides a Quantity
instance every time it's called, with a pre-configured denomination matching the token's denomination. Read more about quantities here.
const amountToSend = aoCredToken.Quantity.fromString("752.34");
Wallet balance
You can query the token balance for an address. This will return a Quantity
instance.
const balance = await aoCredToken.getBalance(
"HjvCPN31XCLxkBo9FUeB7vAK0VCfSeY52-CS-6Iho8l"
);
console.log("Your balance is:", balance.existingBal.toLocaleString());
All balances
Querying all balances will return the balances object stored in the token's memory. Each holder's address is associated with a Quantity
instance.
const balances = await aoCredToken.getBalances();
for (const addr in balances) {
console.log(`${addr} owns ${balances[addr].toLocaleString()} CRED`);
}
Transfer
The transfer functions allows you to send a message to the token process that initiates the transfer of the provided quantity to a recipient.
const id = await aoCredToken.transfer(
aoCredToken.Quantity.fromString("1000"),
"XjvCPN31XCLPFBo9FUeB7vAK0VC6TwY52MCS-6Iho8h"
);
console.log("The transfer ID is", id);
Quantities
The Quantity
class is an implementation of floating point numbers with extreme precision. It works by storing a bigint
instance as the raw value for token quantities. This is the same value the token process works with, so it makes operations and calculations extremely easy. It helps implementing logic for tokens on the front-end by abstracting calculations with the token denomination away from the developer, executing these within the library.
A quantity first needs to be initialised with the raw quantity provided by the token process (or 0
) and the token denomination:
const quantity = new Quantity(0n, token.info.Denomination);
If you already have a Token
instance in scope, you can also use the shortcut mentioned above to initialise a new quantity that belongs to the token process.
Raw
This is one of the most important fields of the Quantity
class. It is a raw bigint
value that must be used when communicating with a token process, as this is in the same format that token processes use internally for managing balances. For example, if you want to use @permaweb/aoconnect
to transfer tokens, instead of the built in transfer function, you need to provide the raw value to the message:
const quantity = aoCredToken.Quantity.fromString("752.34");
await message({
process: "Sa0iBLPNyJQrwpTTG-tWLQU-1QeUAJA73DdxGGiKoJc",
signer: createDataItemSigner(window.arweaveWallet),
tags: [
{ name: "Action", value: "Transfer" },
{ name: "Recipient", value: "XjvCPN31XCLPFBo9FUeB7vAK0VC6TwY52MCS-6Iho8h" },
{ name: "Quantity", value: quantity.raw.toString() }
]
});
Other getters
These getters are also accessible from a Quantity
instance.
integer
: Get the integer/whole part of the quantity (for e.g. for 115.67
this will return 115n
)fractional
: Get the fractional part of the quantity in integer (for e.g. for 115.67
this will return 67n
)denomination
: The token denomination this instance uses for calculations
isQuantity()
Get if a provided value is a valid Quantity
instance:
Quantity.isQuantity(15);
Quantity.isQuantity(new Quantity(15n, 4n));
isQuantityOf()
Get if a provided value is a valid Quantity
of a Token
instance. This will compare the denomination used in the provided Quantity
instance:
Quantity.isQuantityOf(new Quantity(345n, 12n), aoCredToken);
Quantity.isQuantityOf(new Quantity(9456n, 3n), aoCredToken);
fromString()
Parse a quantity from a string:
aoCredToken.Quantity.fromString("256.8");
fromNumber()
Parse a quantity from a JS number:
aoCredToken.Quantity.fromNumber(256.8);
toString()
Get the stringified quantity:
const qty = aoCredToken.Quantity.fromNumber(74.089);
console.log(qty.toString());
toLocaleString()
Print formatted string according to the provided/default locale:
const qty = aoCredToken.Quantity.fromNumber(1474.089);
console.log(qty.toString());
toNumber()
Get JS native floating point value held in a quantity. This can cause precision loss:
qty.toNumber();
clone()
Clone the Quantity
instance. This will keep the same value and denomination:
const qty = new Quantity(12n, 1n);
const qty2 = qty.clone();
qty2.fromNumber(4);
console.log("qty is", qty.toString());
console.log("qty2 is", qty2.toString());
Math and utilities
These functions have both static and non-static implementations. Static implementations will always start with two "_
" and create new Quantity
instances. Non-static implementations start with one "_
" and modify themselves (the instances they are associated with). Calling static functions with tokens of different denominations will cause the result to have the higher denomination by default. Non-static functions (that are modified in-place) keep their denominations, but might lose precision in doing so.
Math operators
eq()
: Check if two quantities are equallt()
: Check if the first quantity is less than the secondle()
: Check if the first quantity is less or equal than the second_add()
and __add
: Add together two quantities_sub()
and __sub
: Subtract one quantity from another_mul()
and __mul()
: Multiply two quantities_div()
and __div()
: Divide one quantity by another_pow()
and __pow()
: Raise one quantity to the power of an integer_mod()
and __mod()
: Get the remainder of the division of one quantity by another_neg()
and __neg()
: Get the negation of a quantity_abs()
and __abs()
: Get the absolute value of a quantity_trunc()
and __trunc()
: Truncate a quantity_floor()
and __floor()
: Round down a quantity_ceil()
and __ceil()
: Round up a quantity
Utilities
_one()
and __one()
: Shortcut to "1" according to the denomination_convert()
and __convert()
: Convert to a different denominationsameDenomination()
: Ensure that the provided quantities all have the same denomination. Returns an array of quantities converted to the largest denomination from the provided quantities.min()
: Get the minimum of a list of quantitiesmax()
: Get the maximum of a list of quantities