cardano/assets

Types

A type-alias for ’AssetName`, which are free-form byte-arrays between 0 and 32 bytes.

Alias

AssetName = ByteArray

Lovelace is a type-alias for Int.

Alias

Lovelace = Int

A type-alias for a PolicyId. A PolicyId is always 28-byte long

Alias

PolicyId = Hash<Blake2b_224, Script>

A multi-asset output Value. Contains tokens indexed by PolicyId and AssetName.

This type maintain some invariants by construction; in particular, a Value will never contain a zero quantity of a particular token.

Constants

ada_asset_name: ByteArray = ""

Ada, the native currency, isn’t associated with any AssetName (it’s not possible to mint Ada!).

By convention, it is an empty ByteArray.

ada_policy_id: ByteArray = ""

Ada, the native currency, isn’t associated with any PolicyId (it’s not possible to mint Ada!).

By convention, it is an empty ByteArray.

zero: Value

Construct an empty Value with nothing in it.

Functions

Constructing

from_asset(policy_id: PolicyId, asset_name: AssetName, quantity: Int) -> Value

Construct a Value from an asset identifier (i.e. PolicyId + AssetName) and a given quantity.

from_ascending_pairs(xs: Pairs<PolicyId, Dict<AssetName, Int>>) -> Value

from_asset_list(xs: Pairs<PolicyId, Pairs<AssetName, Int>>) -> Value

Promote an arbitrary list of assets into a Value. This function fails (i.e. halts the program execution) if:

  • there’s any duplicate amongst PolicyId;
  • there’s any duplicate amongst AssetName;
  • the AssetName aren’t sorted in ascending lexicographic order; or
  • any asset quantity is null.

This function is meant to turn arbitrary user-defined Data into safe Value, while checking for internal invariants.

from_lovelace(quantity: Int) -> Value

Construct a Value from a lovelace quantity.

Friendly reminder: 1 Ada = 1.000.000 Lovelace

Inspecting

contains(self: Dict<AssetName, Int>, subset: Dict<AssetName, Int>) -> Bool

Check whether some tokens list is contained within another. This is a specialised version of dict.{contains}.

has_any_nft(self: Value, policy: PolicyId) -> Bool

Check whether a Value carries any NFT from the given policy. Other assets are tolerated.

let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("bar", "asset#2", 14)

assets.has_any_nft(value, "foo") == True
assets.has_any_nft(value, "bar") == False
assets.has_any_nft(value, "baz") == False

has_any_nft_strict(self: Value, policy: PolicyId) -> Bool

Check whether a Value carries any NFT from the given policy. Other assets (other than Ada) aren’t tolerated. Said differently, the check succeeds if and only if the value contains no assets other than the expected NFT or Ada.

let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("bar", "asset#2", 14)

assets.has_any_nft_strict(value, "foo") == False
assets.has_any_nft_strict(value, "bar") == False
assets.has_any_nft_strict(value, "baz") == False
let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)

assets.has_any_nft_strict(value, "foo") == True
assets.has_any_nft_strict(value, "bar") == False
let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("foo", "asset#2", 1)

assets.has_any_nft_strict(value, "foo") == False
assets.has_any_nft_strict(value, "bar") == False

has_nft(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool

Check whether a Value carries a specific NFT. Other assets are tolerated.

let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("bar", "asset#2", 14)

assets.has_nft(value, "foo", "asset#1") == True
assets.has_nft(value, "foo", "asset#2") == False
assets.has_nft(value, "bar", "asset#2") == False
assets.has_nft(value, "baz", "asset#3") == False
let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("foo", "asset#2", 1)

assets.has_nft(value, "foo", "asset#1") == True
assets.has_nft(value, "foo", "asset#2") == True
assets.has_nft(value, "bar", "asset#2") == False

has_nft_strict(self: Value, policy: PolicyId, asset_name: AssetName) -> Bool

Check whether a Value carries a specific NFT. Other assets (other than Ada) aren’t tolerated. Said differently, the check succeeds if and only if the value contains no assets other than the expected NFT or Ada.

let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("bar", "asset#2", 14)

assets.has_nft_strict(value1, "foo", "asset#1") == False
assets.has_nft_strict(value1, "bar", "asset#2") == False
assets.has_nft_strict(value1, "baz", "asset#3") == False
let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)

assets.has_nft_strict(value, "foo", "asset#1") == True
assets.has_nft_strict(value, "foo", "asset#2") == False
assets.has_nft_strict(value, "bar", "asset#2") == False
let value = assets.from_lovelace(42)
   |> assets.add("foo", "asset#1", 1)
   |> assets.add("foo", "asset#2", 1)

assets.has_nft_strict(value3, "foo", "asset#1") == False
assets.has_nft_strict(value3, "foo", "asset#2") == False

is_zero(self: Value) -> Bool

Check is a Value is zero. That is, it has no assets and holds no Ada/Lovelace.

match(
  left: Value,
  right: Data,
  assert_lovelace: fn(Lovelace, Lovelace) -> Bool,
) -> Bool

Efficiently compare two values together, allowing a custom behaviour for Ada/Lovelace. The second parameter is provided as Data, allowing to conveniently compare serialized datums or similar structurually equivalent types (such as Pairs<PolicyId, Pairs<AssetName, Lovelace>>).

The third argument is a callback function to assert the left and right lovelace quantities. Its first argument refers to the quantity of the first argument of match, and the second argument of the callback to the quantity of the second argument of match. In the absence of lovelace in any value, it defaults to 0.

const value: Value =
  assets.from_lovelace(30)
    |> assets.add("foo", "bar", 1)
    |> assets.add("foo", "baz", 42)

const datum: Data =
  assets.from_lovelace(20)
    |> assets.add("foo", "bar", 1)
    |> assets.add("foo", "baz", 42)

True == assets.match(value, datum, >=)

False == assets.match(value, datum, ==)

True == assets.match(value, datum, fn(value_lovelace, datum_lovelace) {
  2 * datum_lovelace >= value_lovelace
})

False == assets.match(assets.zero, datum, fn(_, _) { True })

match_assets(left: Value, right: Data) -> Bool

A version of match which simply ignores lovelace in either operands.

const value: Value =
  assets.from_lovelace(30)
    |> assets.add("foo", "bar", 1)
    |> assets.add("foo", "baz", 42)

const datum: Data =
  assets.from_lovelace(20)
    |> assets.add("foo", "bar", 1)
    |> assets.add("foo", "baz", 42)

True == assets.match(value, datum)

False == assets.match(assets.zero, datum)

lovelace_of(self: Value) -> Int

A specialized version of quantity_of for the Ada currency.

policies(self: Value) -> List<PolicyId>

A list of all token policies in that Value with non-zero tokens.

quantity_of(self: Value, policy_id: PolicyId, asset_name: AssetName) -> Int

Extract the quantity of a given asset.

tokens(self: Value, policy_id: PolicyId) -> Dict<AssetName, Int>

Get all tokens associated with a given policy.

Inspecting Forcibly

expect_lovelace_of(self: Value) -> Int

More efficient version of lovelace_of, but fails when there’s no lovelace quantity in the Value.

It’s worth noting that:

  • There’s always some lovelace in values from inputs or outputs.
  • There’s never any lovelace in values from mint.

expect_match(
  left: Value,
  right: Data,
  assert_lovelace: fn(Lovelace, Lovelace) -> Bool,
) -> Bool

A slightly more efficient version of match which fails if the provided Data is not akin to a Value.

expect_match_assets(left: Value, right: Data) -> Bool

A slightly more efficient version of match_assets which fails if the provided Data is not akin to a Value.

expect_quantity_of(
  self: Value,
  policy_id: PolicyId,
  asset_name: AssetName,
) -> Int

More efficient version of quantity_of, but fails if the target policy and asset aren’t present in the value.

Modifying

negate(self: Value) -> Value

Negates quantities of all tokens (including Ada) in that Value.

v1
  |> assets.negate
  |> assets.merge(v1)
  |> assets.is_zero
// True

restricted_to(self: Value, mask: List<PolicyId>) -> Value

Get a subset of the assets restricted to the given policies.

without_lovelace(self: Value) -> Value

Get a Value excluding Ada.

Modifying Forcibly

expect_tail(self: Value) -> Value

Removes the first policy id from a Value, but fails if the Value is empty and contains no assets whatsoever.

This is useful to strip Ada forcibly out of values that are known to contain Ada (e.g. inputs or outputs).

Combining

add(
  self: Value,
  policy_id: PolicyId,
  asset_name: AssetName,
  quantity: Int,
) -> Value

Add a (positive or negative) quantity of a single token to a assets. This is more efficient than merge for a single asset.

difference(left: Value, right: Value) -> Value

merge(left: Value, right: Value) -> Value

Combine two Value together.

Transforming

flatten(self: Value) -> List<(PolicyId, AssetName, Int)>

Flatten a Value as list of 3-tuple (PolicyId, AssetName, Quantity).

Handy to manipulate values as uniform lists.

This function is quite expensive and really only viable in testing scenarios. If you need to traverse all elements in a Value, prefer reduce or more bespoke functions for your use case.

flatten_with(self: Value, with: FlattenStrategy<result>) -> List<result>

Flatten a Value as a list of results, possibly discarding some along the way. In particular, we have:

flatten(value) == flatten_with(value, strategy.triple())

reduce(
  self: Value,
  start: result,
  with: fn(PolicyId, AssetName, Int, result) -> result,
) -> result

Reduce a value into a single result

assets.zero
 |> assets.add("a", "1", 10)
 |> assets.add("b", "2", 20)
 |> assets.reduce(v, 0, fn(_, _, quantity, acc) { acc + quantity })
 // 30

to_dict(self: Value) -> Dict<PolicyId, Dict<AssetName, Int>>

Convert the value into a dictionary of dictionaries.

to_pairs(self: Value) -> Pairs<PolicyId, Dict<AssetName, Int>>

Convert the value into an associative list of pairs.

Search Document