Module-level declarations

Types

Link copied to clipboard
entity account

Represents a user profile on a dapp. Multiple users could access this profile, if specifically setup to do so by making use of auth descriptors.

Link copied to clipboard

An entity that allows fine-tuned access control over accounts. It's used to specify what keypairs can access an account, and it can limit the conditions for access in some ways.

Link copied to clipboard

Used to represent account_auth_descriptor entities before creation.

Link copied to clipboard

Represents the auth descriptor configuration found on the chromia.yml file. It can be modified under moduleArgs -> lib.ft4.core.accounts -> auth_descriptor.

Link copied to clipboard

Represents a keypair that has access to an auth descriptor.

Link copied to clipboard

Represents the auth flag configuration found on the chromia.yml file. It can be modified under moduleArgs -> lib.ft4.core.accounts -> auth_flags

Link copied to clipboard

Types of authentication supported for auth descriptors.

  • S - Single signature

  • M - Multiple signatures (multisig)

Link copied to clipboard

The auth descriptor that manages an account.

It can only be substituted, not deleted. Every user account must have a main auth descriptor.

Link copied to clipboard

The configuration defined in the chromia.yml file.

Link copied to clipboard

What the args property of an account_auth descriptor entity or auth_descriptor struct must contain if it represents a multi-sig auth descriptor

Link copied to clipboard

Represents the rate limit configuration found on the chromia.yml file. It can be modified under moduleArgs -> lib.ft4.core.accounts -> rate_limit

Link copied to clipboard
entity rl_state

Rate limiter state, keeping track of whether an account can do more operations.

Link copied to clipboard

The expression of a single rule.

Three statuses of the expression are of interest. We want to know whether a rule is:

  • violated or valid;

  • active or inactive;

  • expired or not.

A rule can be violated, which means that the given rule condition is currently false.

A rule can also be inactive, which means that the given rule condition has never been true, but will be in the future.

The status of every possible rule expression can either:

  • always be "active";

  • trigger once, going from "inactive" to "active".

This gives us the definition of expired: A rule is expired if it is both violated and active, meaning that it doesn't allow the auth descriptor to be used and will never change state.

Examples:

Ruleactiveviolatedexpired
"time < 1000"truetruetrue
"time < 1e10"truefalsefalse
"time 1000"truefalsefalse
"time 1e10"falsetruefalse
Link copied to clipboard

The comparison operator that the auth descriptor rule will use.

Link copied to clipboard

Used to simplify rule creation, it describes a rule without the operator.

This struct shouldn't generally be handled by developers, the intended workflow is less_than(block_height(10));, which should give a rule_expression without ever handling rule_parameters

Link copied to clipboard

The variables that an auth descriptor rule can check against.

Link copied to clipboard

What the args property of an account_auth descriptor entity or auth_descriptor struct must contain if it represents a single-sig auth descriptor

Properties

Link copied to clipboard
val ACCOUNT_TYPE_USER: text = "FT4_USER"

Constant that represents account type for regular user accounts created with create_account_with_auth.

Link copied to clipboard

Used instead of module_args -> auth_descriptor.max_number_per_account to limit the value to 200.

Link copied to clipboard
val GTV_NULL: gtv = null

The GTV representation of null

Link copied to clipboard

The byte_array representation of null

Functions

Link copied to clipboard
function Account(id: byte_array): account

Retrieve an account given the id

Throws '"MISSING ACCOUNT"' if there's no account with the given id

Link copied to clipboard

Finds an account based on its ID.

Throws "MISSING ACCOUNT" if none is found.

Link copied to clipboard
@extendable function account_rate_limit_config(account: account): rate_limit_config?

Extend this function to have different rate limiting for different accounts.

Link copied to clipboard

Adds an auth descriptor to an account.

Can only be called from an operation.

Throws "TOO MANY AUTH DESCRIPTORS" if the account already has AUTH_DESCRIPTORS_PER_ACCOUNT_UPPER_BOUND number of auth descriptors registered to it.

Throws if auth_descriptor's args field is invalid. Common cases include:

  • if a multi-sig auth descriptor's required_signatures is 0 or less

  • if a multi-sig auth descriptor's required_signature parameter is greater than the number of signers

Throws if auth_descriptor's rules field is invalid. Common cases include:

  • rules is a complex rule with too many rule components

  • rules has already expired

  • rules is not the valid GTV representation of a rule

Link copied to clipboard
function add_rate_limit_points(account: account, amount: integer)

Adds rate limit points to an account to allow calling more operations in a short amount of time. Rate limit points never exceed the config value for max_points.

Can only be called from an operation.

Throws "MISSING RATE LIMITER STATE" if the account does not have an rl_state. This should generally never happen for user accounts, unless the rl_state entity has manually been deleted.

Link copied to clipboard
function add_signers(account: account, auth_descriptor: auth_descriptor, account_auth_descriptor: account_auth_descriptor)

Associates new signers with an account.

Can only be called from an operation.

Link copied to clipboard
function are_and_rules_violated(rules: list<rule_expression>, variables: map<text, gtv>): boolean

Detects whether any of a list of rule expressions is violated.

Link copied to clipboard
function are_rules_active(rules: gtv): boolean

Checks whether all the rules in the gtv are active.

Can only be called in an operation.

Throws when rules is not the valid GTV representation of a rule.

Link copied to clipboard
function are_rules_violating(rules: gtv, variables: map<text, gtv>): boolean

Checks whether any of the rules in the gtv are violated currently.

Throws "INVALID RULE" if the gtv does not start with "and", implying it's a simple rule, but the length is not 3 (operator, variable and value).

Link copied to clipboard

Finds an auth descriptor based on its ID and the account it belongs to.

Throws "MISSING AUTH DESCRIPTOR" if none is found.

Link copied to clipboard

Retrieve an account_auth_descriptor given the id

Throws '"MISSING AUTH DESCRIPTOR"' if there's no auth descriptor with the given id

Link copied to clipboard

First step in creating a rule_expression based on block_height. Should be passed to an operator function, e.g. less_than(block_height(100))

Link copied to clipboard
function block_time(integer: integer): rule_parameters

First step in creating a rule_expression based on block_time. Should be passed to an operator function, e.g. less_than(block_time(1000))

Link copied to clipboard
function check_auth_args(a_t: auth_type, args: byte_array, signers: list<byte_array>, required_flags: list<text>): validation_result

Checks that the multi-sig auth descriptor has all the requirements to authorize an operation.

Can only be called from an operation.

Gives invalid results when the signatures cannot be validated, i.e.:

  • signers is 0 or more than one, but the auth type is auth_type.S

  • the single sig signer did not sign

  • not enough multisig signers signed

  • the flags of the auth descriptors do not contain all required_flags

Link copied to clipboard
function check_multi_sig_auth(args: byte_array, signers: list<byte_array>, required_flags: list<text>): validation_result

Checks that the multi-sig auth descriptor has all the requirements to authorize an operation.

Can only be called from an operation.

Gives invalid result "NOT ENOUGH SIGNATURES" if not enough signers signed the operation that called this function.

Gives invalid result "MISSING FLAGS" if the multi_sig_args does not contain all required flags.

Link copied to clipboard
function check_required_flags(flags: set<text>, required_flags: list<text>): boolean

Checks that the set of flags contains all the required flags, which means the auth descriptor has the authorization necessary to call the operation.

Link copied to clipboard
function check_single_sig_auth(args: byte_array, signers: list<byte_array>, required_flags: list<text>): validation_result

Checks that the single signature auth descriptor has all the requirements to authorize an operation.

Can only be called from an operation.

Gives invalid result "SIGNERS ERROR" if signers has zero or more than one elements.

Gives invalid result "MISSING SIGNATURE" if the signer did not sign the operation that called this function.

Gives invalid result "MISSING FLAGS" if the single_sig_args does not contain all required flags.

Link copied to clipboard
function create_account_with_auth(auth_descriptor: auth_descriptor, account_id: byte_array?): account

Standard way of creating a user account. Account registration strategies call this function.

Can only be called from an operation.

Throws "RESTRICTED MAIN AUTH" if the auth descriptor has expiration rules, i.e. if the rules field is not equivalent to the value of GTV_NULL.

Throws if the auth descriptor is invalid. Common cases include:

  • errors with the args field:

    • some required flags are missing

    • in multi-sig auth descriptors, the required_signatures field:

      • is 0 or less

      • is greater than the number of signers

Link copied to clipboard
function create_account_without_auth(account_id: byte_array, type: text): account

Creates an account without auth descriptor. Used to create different "system" account types that cannot be directly accessed, e.g. POOL, FEE, BLOCKCHAIN, ... accounts.

Can only be called from an operation.

Link copied to clipboard

Creates a rate limiter state entity (rl_state) for the specified account

Can only be called from an operation.

Link copied to clipboard
function current_rate_limit_points(rate_limit_config: rate_limit_config, rl_state: rl_state, current_timestamp: integer): integer

Returns how many rate limit points are available to a certain rl_state given the current time.

Link copied to clipboard

Deletes all auth descriptors of an account that are not the main auth descriptor. This can be useful if you have many disposable auth descriptors you lost the keys to, like the ones created by logging in, and need to delete them to get back under the limit.

Can only be called from an operation.

Link copied to clipboard

Deletes an auth descriptor that is not a main auth descriptor.

Can only be called from an operation.

Throws "DELETE MAIN UNAUTHORIZED" if a main auth descriptor is passed.

Link copied to clipboard

Deletes all expired auth descriptors associated with an account.

Can only be called from an operation.

Throws if the rules to any of the auth descriptors associated with the account have invalid rules.

Throws if the main auth descriptor for the account has expired. This should never happen, as main auth descriptors with rules cannot be added via FT4.

Link copied to clipboard

Deletes the main auth descriptor for the account. It does not add a new one, so it leaves the account prone to being inaccessible.

Using this function directly on a user account might end up leaving it misconfigured. It's strongly advised to use update_main_auth_descriptor if the main auth descriptor should be changed.

Can only be called from an operation.

Throws "MISSING AUTH DESCRIPTOR" if the account has no main_auth_descriptor associated.

Link copied to clipboard
function ensure_account_without_auth(account_id: byte_array, type: text): account

Finds or creates an account of specific type.

Can only be called from an operation.

Throws "MISMATCHING TYPE" if an account with given ID exists, but the type is not the one passed.

Link copied to clipboard
function equals(rule_parameters: rule_parameters): rule_expression

Composes a rule from the rule_parameters and the eq operator

Link copied to clipboard

Checks whether the rule is valid.

Link copied to clipboard

Default calculation for new account IDs.

Throws "NO SIGNERS" if the list has no elements.

Link copied to clipboard

Retrieves the auth descriptor config

Link copied to clipboard
function get_auth_descriptor_data(ad: immutable_mirror_struct<account_auth_descriptor>): (id: byte_array, account_id: byte_array, auth_type: auth_type, args: gtv, rules: gtv, created: integer)

Extract info from an account_auth_descriptor in a more accessible format. Useful for queries that return auth descriptors.

Link copied to clipboard
function get_auth_descriptors(id: byte_array): list<(id: byte_array, account_id: byte_array, auth_type: auth_type, args: gtv, rules: gtv, created: integer)>

Returns all auth descriptors registered to an account.

Link copied to clipboard
function get_auth_descriptors_by_signer(account_id: byte_array, signer: byte_array): list<(id: byte_array, account_id: byte_array, auth_type: auth_type, args: gtv, rules: gtv, created: integer)>

Returns all auth descriptors of which the signer takes part that are registered to a specific account.

Link copied to clipboard
function get_auth_flags_config(): (mandatory: list<text>, default: list<text>)

retrieve the settings for auth flags written in the chromia.yml file

Link copied to clipboard
function get_flags(auth_descriptor: auth_descriptor): set<text>

Extracts the flags from an auth descriptor.

Link copied to clipboard

Extracts the set of flags found in the "args" parameter.

Link copied to clipboard

Returns the maximum number of rules that can be composed to limit the duration of an auth descriptor

Link copied to clipboard
function get_paginated_accounts_by_ad_id(id: byte_array, page_size: integer?, page_cursor: text?): list<pagination_result>

Retrieves all accounts the given auth descriptor can interact with, paginated.

Link copied to clipboard

Retrieves all accounts the given signer can interact with, paginated.

Link copied to clipboard
function get_paginated_accounts_by_type(type: text, page_size: integer?, page_cursor: text?): list<pagination_result>

Retrieves all accounts of the given type, paginated.

Link copied to clipboard

Returns the rate limit config extracted from the chromia.yml.

Link copied to clipboard

Retrieves the rate limit config to apply to a specific account. Defaults to the value in the chromia.yml if:

  • rate limit is inactive on the chain

  • no special configuration has been added for this account.

Link copied to clipboard

retrieve the settings for auth flags written in the chromia.yml file, unparsed

Link copied to clipboard
function get_signers(auth_descriptor: auth_descriptor): list<byte_array>

Extracts the signer list from an auth descriptor

Link copied to clipboard

Extracts the signer list from an auth descriptor's args

Link copied to clipboard

Composes a rule from the rule_parameters and the ge operator

Link copied to clipboard
function greater_than(rule_parameters: rule_parameters): rule_expression

Composes a rule from the rule_parameters and the gt operator

Link copied to clipboard
function has_flags(account_auth_descriptor: account_auth_descriptor, required_flags: list<text>): boolean

Checks if an account_auth_descriptor has all the specified flags

Link copied to clipboard

Checks if any rules of the given auth descriptor are violated.

Throws when the rules cannot be parsed, that is, when the rules field does not contain any of the acceptable values.

Can only be called from an operation.

Link copied to clipboard
function is_active(account_auth_descriptor: account_auth_descriptor): boolean

Checks whether all the rules of the auth descriptor are active.

Can only be called in an operation.

An inactive rule cannot be valid, and it cannot have expired yet. This allows skipping some checks.

Throws when rules is not the valid GTV representation of a rule.

Link copied to clipboard

Whether the rule, which is expected to have a block_height variable, is active. It does not check whether the rule variable is block_height.

Can only be called from an operation.

Link copied to clipboard

Whether the rule, which is expected to have a block_time variable, is active. It does not check whether the rule variable is block_time.

Can only be called from an operation.

Link copied to clipboard

Checks whether the rule expression is active.

Can only be called in an operation.

Link copied to clipboard
function is_rule_violated(rule: rule_expression, variables: map<text, gtv>): boolean

Detects whether a rule expression is violated.

Link copied to clipboard
function less_or_equal(rule_parameters: rule_parameters): rule_expression

Composes a rule from the rule_parameters and the le operator

Link copied to clipboard
function less_than(rule_parameters: rule_parameters): rule_expression

Composes a rule from the rule_parameters and the lt operator

Link copied to clipboard
function load_variables(op_count: integer): map<text, gtv>

Loads the current value of all possible variables that can appear in an auth descriptor rule. This function thus loads:

  • the number of operations the auth descriptor has performed, including the one we're currently validating for (op_count);

  • the block height of the block being built (block_height);

  • the timestamp of the last block (block_time).

Can only be called from an operation.

Link copied to clipboard

Takes a gtv representation of rules, and converts them into a list of rule_expressions

Throws if gtv_rules contains any entry that is not the GTV representation of a rule. Common scenarios are if any element of the list<gtv>:

  • is not a list itself

  • has components which are not, in this exact order:

    • an element of rule_operator

    • an element of rule_variable

    • an integer value

Link copied to clipboard
function multi_sig_auth_descriptor(signers: list<byte_array>, signatures_required: integer, flags: set<text>): auth_descriptor

Creates a multi-signature auth descriptor given the arguments with no expiration rules.

Link copied to clipboard
function op_count(integer: integer): rule_parameters

First step in creating a rule_expression based on op_count. Should be passed to an operator function, e.g. less_than(op_count(10))

Link copied to clipboard
function parse_auth_flags(gtv: gtv): list<text>

Parse the values in the gtv as auth flags. Used to retrieve the configuration found in the chromia.yml file for the auth flag config.

Throws "INVALID FLAGS" if the value is:

  • a list of anything else than just text values

  • neither a list nor a comma separated text

Throws if the flags are not valid.

Link copied to clipboard
function rate_limit(account: account)

Rate limit an account, i.e. verify that the account is only sending up to as many operations as are allowed in its rl_state. By default, the rl_state corresponds to the configuration found in the chromia.yml file.

Can only be called from an operation.

Throws "RATE LIMITED" if the account has exceeded the rate limit.

Throws "MISSING RATE LIMITER STATE" if the account does not have an rl_state. This should generally never happen for user accounts, unless the rl_state entity has manually been deleted.

Link copied to clipboard
function require_mandatory_flags(auth_descriptor: auth_descriptor)

Checks that the auth descriptor contains all the flags deemed necessary for this dapp.

Throws "MISSING MANDATORY FLAGS" if some are missing.

Link copied to clipboard

Checks that all flags values passed are composed of letters and/or underscores.

Throws "INVALID FLAGS" if any flag does not match /[a-z_A-Z]+/

Link copied to clipboard

Takes a GTV representation of one rule, and converts it into a single rule_expression

Throws "INVALID RULE" if the first component of the gtv can't be mapped into a rule_operator value or the second one can't be mapped into a rule_variable value.

Throws if gtv is not the GTV representation of a rule, for example:

  • it is not a list

  • the first two components are not texts

  • the last component is not an integer

Link copied to clipboard
function rule_expression_to_gtv(rule_expression: rule_expression): gtv

Takes a single rule_expression and returns the gtv representation that can be used inside of auth descriptors.

Link copied to clipboard

Takes a list of rule_expressions and returns the gtv representation that can be used inside of auth descriptors.

Link copied to clipboard
function set_main_auth_descriptor(account: account, account_auth_descriptor: account_auth_descriptor)

Sets an auth descriptor as main_auth_descriptor of the account

Using this function directly on a user account might end up leaving it misconfigured. It's strongly advised to use update_main_auth_descriptor if the main auth descriptor should be changed.

Can only be called from an operation.

Throws "MAIN AUTH DESCRIPTOR EXISTS" if the account has a main auth descriptor already.

Link copied to clipboard

Creates a single signature auth descriptor given the arguments with no expiration rules.

Link copied to clipboard

Updates the counter of the auth descriptor, which should always be increased by one when the auth descriptor is used to sign an operation

Can only be called from an operation.

Link copied to clipboard
function update_main_auth_descriptor(account: account, auth_descriptor: auth_descriptor)

Sets provided auth descriptor as main auth descriptor, deleting the previous one.

Can only be called from an operation.

Throws "RESTRICTED MAIN AUTH" if the auth descriptor's rules are not GTV_NULL

Throws if any mandatory flags are missing on the auth descriptor.

Throws if the account has no main auth descriptor associated. This should normally not happen for user accounts.

Throws if the auth descriptor's args field is invalid. Common cases are:

  • the auth descriptor is a misconfigured multisig. required_signatures is:

    • 0 or less

    • greater than the number of signers

Link copied to clipboard

Checks if the auth descriptor args correspond to single_sig_args or multi_sig_args, based on the descriptor's auth_type

Throws "MULTISIG NEGATIVE REQUIREMENT" if a multi-sig auth descriptor's required_signatures is 0 or less

Throws "MULTISIG REQUIREMENT TOO HIGH" if a multi-sig auth descriptor's required_signature parameter is greater than the number of signers

Link copied to clipboard

Analyze the rules before assigning them to an auth descriptor, to check that they haven't already expired and that the values are sensible.

Can only be called from an operation.

Throws "INVALID RULES" when there are more than the max_rules configured in the chromia.yml file.

Throws "EXPIRED" when the rule set has expired.

Throws when rules is not the valid GTV representation of a rule.

Link copied to clipboard

Checks that the rule is sensible. This means that the rule does not expect:

  • block height or timestamp to be negative

  • op_count to be zero or negative

It also rejects op_count rules with operators that are not lt or le.

Throws "INVALID RULE" if:

  • the rule variable is block_height and the value is less than 0

  • the rule variable is block_time and the value is less than 0

  • the rule variable is block_height and the operator is neither of lt and le

  • the rule variable is op_count but the requirement would never be satisfied, i.e.:

    • op_count, lt, any value below two

    • op_count, le, any value below one

The first authentication attempt will be checked against an op_count value of 1, not 0.

Link copied to clipboard
function variable_value(variable: rule_variable, variables: map<text, gtv>): integer

Extracts the required variable value from the state