Module-level declarations

Functions

Link copied to clipboard
@extend(auth_handler) function (): map<text, _auth_handler>
Link copied to clipboard
function get_apply_transfer_details(tx: gtx_transaction, apply_op_index: integer): (tx_rid: byte_array, args: immutable_mirror_struct<apply_transfer>, (tx_rid: byte_array, args: immutable_mirror_struct<init_transfer>, sender_account_id: byte_array))

Given a transaction that contains the apply_transfer operation and the index it's at, this function retrieves the transaction RID, the arguments to the init_transfer operation and the details of the init_transfer as returned by get_init_transfer_details.

Throws "APPLY TRANSFER NOT FOUND" if the op_index does not point to apply_transfer

Throws if the init_tx_op_index of the apply_transfer operation does not point to init_transfer on its init_transfer_tx

Throws if the operation preceding the init_transfer is not an auth operation

Link copied to clipboard
function get_init_transfer_details(tx: gtx_transaction, op_index: integer): (tx_rid: byte_array, args: immutable_mirror_struct<init_transfer>, sender_account_id: byte_array)

Given a transaction that contains the init_transfer operation and the index it's at, this function retrieves the transaction RID, the arguments to the init_transfer operation and the ID of the sender account.

Throws "INIT TRANSFER NOT FOUND" if the op_index does not point to init_transfer on tx

Throws if the operation preceding the init_transfer is not an auth operation

Link copied to clipboard
Link copied to clipboard
function validate_apply_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer, previous_hop_tx: gtx_transaction, op_index: integer, hop_index: integer): ((tx_rid: byte_array, args: immutable_mirror_struct<init_transfer>, sender_account_id: byte_array), byte_array)

Validates that the parameters are correct for an apply_transfer operation. Also used in other operations that require the same validation to occur (e.g. cancel_transfer) It does not verify whether the transfer expired.

Among other things, this function validates that:

  • Transfer was not already applied on this chain

  • Transfer was not already canceled on this chain

  • Transfer was not already unapplied on this chain

  • That the init_transfer details are correct

  • The iccf_proof that states that this transfer was applied on the previous hop

Throws "INVALID TRANSACTION" if the transfer has already been applied, canceled or unapplied on this chain.

Throws "INPUT ERROR" if the input is malformed. Common scenarios include:

  • arguments found in init_transfer_tx and previous_hop_tx do not match

  • hop_index is out of bounds

  • previous_hop_tx has not been sent to the chain that comes before this one on the transfer hops

Throws "WRONG BLOCKCHAIN" if the chain at hop_index on the init transaction is not this chain

Throws if the op_index does not point to apply_transfer

Throws if the init_tx_op_index does not point to init_transfer on its init_transfer_tx

Throws if the operation preceding init_transfer is not an auth operation

Throws if the transaction is missing the iccf_proof operation, which demonstrates that the block containing the previous_hop_tx has been anchored from the previous chain.

Queries

Link copied to clipboard
@mount("ft4.crosschain.get_apply_transfer_tx") query get_apply_transfer_tx(init_tx_rid: byte_array, init_op_index: integer): (tx: gtv, op_index: integer)

Retrieves a transaction and op_index that can be passed as parameters to functions like apply_transfer, cancel_transfer and so on.

Link copied to clipboard
@mount("ft4.crosschain.get_asset_origin_by_id") query get_asset_origin_by_id(asset_id: byte_array): byte_array?

Retrieves the origin chain RID for the specified asset. If this asset does not have an origin, which is the case if this asset is not a crosschain asset, this query will return null.

Link copied to clipboard
@mount("ft4.crosschain.get_last_pending_transfer_for_account") query get_last_pending_transfer_for_account(account_id: byte_array, target_blockchain_rid: byte_array, recipient_id: byte_array, asset_id: byte_array, amount: big_integer): (tx_data: byte_array, op_index: integer, account_id: byte_array)?

Same as core.crosschain.get_last_pending_transfer_for_account. Retrieves the pending transfer which was last created for this account that matches the provided parameters.

Link copied to clipboard
@mount("ft4.crosschain.get_pending_transfers_for_account") query get_pending_transfers_for_account(account_id: byte_array, page_size: integer?, page_cursor: text?): paged_result

Retrieves all pending transfers for an account, that is: all crosschain transfers which was sent from this account but was not yet delivered to the final recipient. Once a transfer has been marked as completed on this chain, it will no longer show up in this query. Paginated.

Link copied to clipboard
@mount("ft4.crosschain.is_transfer_applied") query is_transfer_applied(init_tx_rid: byte_array, init_op_index: integer): boolean

Checks if the transfer which was pointed out by the provided arguments was applied on this chain or not.

Operations

Link copied to clipboard
@mount("ft4.crosschain.apply_transfer") operation apply_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer, previous_hop_tx: gtx_transaction, op_index: integer, hop_index: integer)

This operation must be called on every chain listed in the hops array provided to the init_transfer function which corresponds to this transfer.

When this is done, one of two things will happen:

  • If this is an intermediary hop, this chain will update its internal record of which chain that owns how much of what asset

  • If this is the final hop, the transferred amount will be credited to the recipient account

In the case where this is the last hop and the recipient account does not exist, one of two things can happen:

  • If the create on transfer account creation strategy is enabled, the assets will be received and the recipient will be able create the account and claim them.

  • If the feature is not enabled, the transfer will be rejected, in which case, the sender can get their assets back by calling the cancel_transfer in the reverse hops order.

Anyone can call this operation on behalf of any transfer, but it needs to include an iccf_proof operation which prove that the transaction was applied in the previous hop.

The functionality provided by apply_transfer can be modified by extending before_apply_transfer and after_apply_transfer

Throws "TRANSFER EXPIRED"` if deadline is a past timestamp

Throws "MISSING ACCOUNT" if all these conditions apply:

  • this chain is the last chain in the crosschain transaction

  • the account corresponding to recipient_id does not exist

  • creating account on crosschain transfer is not enabled on this chain

Throws if additional conditions provided through extensions of before_apply_transfer and after_apply_transfer are not satisfied

Throws if the current transfer is misconfigured. Common cases are:

  • the next hop or the previous one are:

    • equal to one another

    • this blockchain's RID

    • the ID of an account on this chain which is not a blockchain account

  • amount is:

    • not in the accepted range (0, 2^256) (exclusive)

    • higher than the blockchain account balance they're coming from

  • the asset is not registered on this chain

  • input is malformed:

    • arguments found in init_transfer_tx and previous_hop_tx do not match

    • hop_index is out of bounds

    • previous_hop_tx has not been sent to the chain that comes before this one on the transfer hops

  • the transfer has already been applied, canceled or unapplied on this chain.

  • the chain at hop_index on the init transaction is not this chain

  • the op_index on previous_hop_tx does not point to:

    • init_transfer when hop_index is 0

    • apply_transfer otherwise

  • the init_tx_op_index does not point to init_transfer on its init_transfer_tx

  • the operation preceding init_transfer is not an auth operation

Throws if all these conditions apply:

  • this chain is the last chain in the crosschain transaction

  • the account corresponding to recipient_id does not exist

  • creating account on crosschain transfer is enabled on this chain

  • the function implementing the account creation strategy being used (extension of create_on_crosschain_transfer) has conditions which are not satisfied

Throws if the transaction is missing the iccf_proof operation, which demonstrates that the block containing the previous_hop_tx has been anchored from the previous chain.

Requires no flags - no authorization is performed to apply a transfer.

Link copied to clipboard
@mount("ft4.crosschain.cancel_transfer") operation cancel_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer, previous_hop_tx: gtx_transaction, op_index: integer, hop_index: integer)

Cancels a crosschain transfer that has expired. This operation must be called in place of apply_transfer to start the transfer canceling process. unapply_transfer must then be called on all previous chains to bring the funds back to the sender account.

Throws "TRANSFER NOT EXPIRED" if the transfer has not yet expired.

Throws in various cases of misconfiguration. Some examples:

  • the transfer has already been applied, canceled or unapplied on this chain.

  • the chain at hop_index on the init transaction is not this chain

  • the op_index on previous_hop_tx does not point to:

    • init_transfer when hop_index is 0

    • apply_transfer otherwise

  • the init_tx_op_index does not point to init_transfer on its init_transfer_tx

  • the operation preceding init_transfer is not an auth operation

  • arguments found in init_transfer_tx and previous_hop_tx do not match

  • hop_index is out of bounds

  • previous_hop_tx has not been sent to the chain that comes before this one on the transfer hops

Throws if the transaction is missing the iccf_proof operation, which demonstrates that the block containing the previous_hop_tx has been anchored from the previous chain.

Anyone can call this operation, but it needs to include an iccf_proof operation that apply_transfer was performed on the previous chain.

Link copied to clipboard
@mount("ft4.crosschain.complete_transfer") operation complete_transfer(final_apply_transfer_tx: gtx_transaction, op_index: integer)

This operation is to be called on the initial chain (the chain for which a crosschain transfer originated) once all hops are completed and the transfer has been successfully delivered to the recipient. Even if this operation is not called, the recipient will still receive their assets, but calling this operation will allow clients to stop displaying it as ongoing to the user that sent it.

Anyone can call this operation, but it needs to include an iccf_proof operation that the final apply_transfer was performed.

Throws "INPUT ERROR"if op_indexdoes not point to an apply_transfer` operation

Throws "INCOMPLETE TRANSFER" if the given apply_transfer was not called on the last chain; that is, if the hop_index parameter does not correspond to the last hop index.

Throws "WRONG DESTINATION" if the given apply_transfer was called on a chain that does not correspond to the init_transfer's last chain in the hops parameter

Throws if the transaction is missing the iccf_proof operation, which demonstrates that the block containing the final_apply_transfer_tx has been anchored from the target chain.

Requires no flags - no authorization is performed to complete a transfer.

Link copied to clipboard
@mount("ft4.crosschain.init_transfer") operation init_transfer(recipient_id: byte_array, asset_id: byte_array, amount: big_integer, hops: list<byte_array>, deadline: integer)

Initializes a crosschain transfer, which is a transfer that goes to a different blockchain on the Chromia network.

Since this chain cannot communicate with any other chain, it is up to the client to perform the necessary steps to complete this transfer. Furthermore, this chain will not validate if the sender is allowed to send assets to the target chain or if the recipient account exists, meaning that when the client tries to apply the transfer on the target chain, it might not be accepted. Should that happen, the sender can recall their transfer after the deadline has expired.

Must be signed by an auth descriptor with accounts.auth_flags.TRANSFER

The functionality provided by init_transfer can be modified by extending before_init_transfer and after_init_transfer

Throws "TRANSFER EXPIRED"` if deadline is a past timestamp

Throws "MISSING ASSET" if the asset does not exist on this chain

Throws if additional conditions provided through extensions of before_init_transfer and after_init_transfer are not satisfied

Throws if the first transfer is misconfigured. Common cases are:

  • hops[0] is:

    • equal to the sender account ID

    • this blockchain's RID

    • the ID of an account on this chain which is not a blockchain account

  • amount is:

    • not in the accepted range (0, 2^256) (exclusive)

    • higher than the account's balance

  • sender account ID is equal to this chain's ID

Requires the Transfer flag to be present on the auth descriptor that authorizes this operation.

Link copied to clipboard
@mount("ft4.crosschain.recall_unclaimed_transfer") operation recall_unclaimed_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer)

Recalls an unclaimed transfer. A transfer does not generally need to be claimed, unless account registration on crosschain transfers is configured on the target chain.

If it is, when a crosschain transfer is sent to that chain and the recipient account does not exist, the transfer is considered the start of an account registration process. The account is not automatically created, and account registration strategies must be used to claim the transfer and create an account.

If this is not done within the transfer deadline, the transfer can be recalled on the target chain, unapplied on all intermediate chains if any, and reverted on the init chain to move the funds back to the original sender.

Throws "ACCOUNT REGISTRATION DISABLED" if this chain is not configured to allow account registration on crosschain transfers. This means that a transfer can never end up unclaimed.

Throws "WRONG BLOCKCHAIN" if the transfer has a target chain different from this one.

Throws "INVALID TRANSACTION" if the transaction has either:

  • never been applied here

  • already been recalled

Throws if any conditions on the recall of crosschain account registration (defined as extensions to recall_on_crosschain_transfer) are not met

Throws if init_tx_op_index does not point to init_transfer on init_transfer_tx

Throws if the operation preceding the init_transfer on init_transfer_tx is not an auth operation

This operation can be called by anyone after the timeout has expired.

Link copied to clipboard
@mount("ft4.crosschain.revert_transfer") operation revert_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer, last_tx: gtx_transaction, last_op_index: integer)

Reverts a transfer that was initialized on this chain, after it has expired. If a crosschain transfer is to be rolled back after expiring and the assets are to be returned to the original sender, after the process of walking the path backwards until the source chain, then this operation should be called as the final step on the source chain to complete the rollback. When this operation is called, the assets are returned back to the original sender.

Throws "INVALID TRANSFER" if the transfer that is being unapplied was:

  • never initialized on this chain

  • already reverted on this chain

Throws "INPUT ERROR" if the input is malformed. This could be one of many different things:

  • arguments found in init_transfer_tx and last_tx do not match

  • last_tx has not been sent to the chain that comes after this one on the transfer hops

Throws"UNSUPPORTED LAST OP" if the operation found in last_tx at the given index is neither of the three supported operations:

  • unapply_transfer if the transfer was canceled or recalled, but it had more than one hop (i.e. it went from starting chain to target chain while going through at least another chain)

  • cancel_transfer if the transfer was canceled before being applied on the chain that came after the init chain

  • recall_unclaimed_transfer if the transfer was applied on the target chain, it was sent to a non-existing account, and it has expired

Throws "TRANSFER NOT EXPIRED" if the transfer being reverted did not expire

Throws if the init_tx_op_index does not point to init_transfer on init_transfer_tx

Throws if the required assets cannot be transferred. While this could throw in all cases of misconfiguration considered possible for init_transfer, to revert a transfer it must first have been applied. This means that the most probable scenario for the transfer of funds to fail is if the sender blockchain account balance is lower than amount.

Other cases considered possible for init_transfer are still possible, although unlikely. For example, the asset entity could have been deleted, which means that the asset is no longer registered on this chain.

Anyone can call this operation, but it needs to include an iccf_proof operation that unapply_transfer was performed on the previous chain.

Link copied to clipboard
@mount("ft4.crosschain.unapply_transfer") operation unapply_transfer(init_transfer_tx: gtx_transaction, init_tx_op_index: integer, last_tx: gtx_transaction, last_op_index: integer, hop_index: integer)

Unapplies a crosschain transfer that has expired. This operation must be called if apply_transfer was already executed on this chain. To successfully unapply a transfer, it must have been:

  • canceled or any later hop (including the target chain), or

  • recalled on the target chain. This operation should not be called on the init chain - revert_transfer should be used instead.

Throws "INVALID TRANSFER" if the transfer that is being unapplied was:

  • never applied on this chain

  • already canceled or unapplied

Throws "INPUT ERROR" if the input is malformed. This could be one of many different things:

  • arguments found in init_transfer_tx and last_tx do not match

  • hop_index is out of bounds or points to a different chain than this one

  • hop_index points to the target chain, where canceling or recall should happen (not unapplying)

  • last_tx has not been sent to the chain that comes after this one on the transfer hops

Throws"UNSUPPORTED LAST OP" if the operation found in last_tx at the given index is neither of the three supported operations:

  • cancel_transfer if the transfer was canceled before being applied on the chain that came after this one on the transfer hops

  • recall_unclaimed_transfer if the transfer was applied on the target chain, it was sent to a non-existing account, and it has expired

  • unapply_transfer if the transfer was canceled or recalled, and then unapplied on another chain before reaching this one

Throws "TRANSFER NOT EXPIRED" if the transfer being reverted did not expire

Throws if the init_tx_op_index does not point to init_transfer on init_transfer_tx

Throws if the required assets cannot be transferred. While this could throw in all cases of misconfiguration considered possible for apply_transfer, to unapply a transfer it must first have been applied. This means that the most probable scenario for the transfer of funds to fail is if the sender blockchain account balance is lower than amount.

Other cases considered possible for apply_transfer are still possible, although unlikely. For example, the asset entity could have been deleted, which means that the asset is no longer registered on this chain.

Requires no flags - no authorization is performed to unapply a transfer.