Search
Duplicate
Try Notion
🚧🚧

Custody Module

Concept

Managing private keys can be difficult and exposes users to various risks, such as sending assets to the wrong recipient or having their private keys compromised by malicious fishing campaigns. One solution to this problem is to provide users with tools for protecting their digital assets. This is the role of the Custody Module, which adds an extra layer of protection by providing users with three additional safeguards. This helps to ensure that users are better able to secure their funds and reduce the risks associated with managing private keys.

Parameters

NAME
TYPE
EXAMPLE
DESCRIPTION
custody_enabled
bool
true
Enables or disables the Custody Module. If set to true, all token transfers must be performed via the module’s own custody send CLI.
custody_mode
uint64
2/3
Specifies the n/m scheme of the Custody Module, i.e. the minimum number of registered custodians required to approve transactions.
use_password
bool
true
Specifies whether to use a password in the Custody Module.
use_white_list
bool
false
Specifies whether to restrict transfers to a whitelist of addresses
use_limits
bool
true
Specifies whether to use transfer rate limits
key
string
e2d8ce14e...
Specifies the secret key used in the Custody Module. The key can only be used once and each subsequent transaction requires a new key.

Collaborative custody

The first layer is collaborative custody, which allows users to set up specific transaction signature schemes. This means that transactions can only be sent if one or more configurable other addresses (third parties) give their approval. The collaborative custody differs from traditional m-of-n multi-signatures in that it maintains the concept of ownership. This means that third parties cannot sign transactions without the original address owning the assets also signing the transaction. Simply put, collaborative custody can be thought of as a 2-factor authentication that can be set up to N-factor authentication, where N is the number of extra KIRA addresses needed to sign transactions.

Secret protected transfers

The second layer of protection offered by the Custody Module is a mechanism that allows token transfers to occur only when the recipient of funds submits a secret provided off-chain by the sender. If the funds are not claimed within a predefined period of time, they are returned to the sender's account. This mechanism, when combined with collaborative custody, ensures that both the sender and the recipient can be verified in more than one way effectively adding an extra layer of security to the process of transferring digital assets.

Withdrawal address whitelist & transfer limit

The third layer of account protection enable users to manage a withdraw whitelist & set up custom time period transfer limits for every tokens (day, week, month…), i.e. the user’s account cannot transfer tokens unless the recipient address figures in the user’s whitelist and the withdraw amount for the given token doesn’t exceeds the current current withdrawal capacity. The whitelisting & limits setup processes can be protected by secrets, effectively preventing malicious actors getting around this protection in the case where the user’s private key is compromised. Additionally withdrawal limits have a 24-hour waiting period to prevent an attacker to immediately change limits and withdraw all funds at once in the event user’s secrets have also been compromised.

Custodian transaction propagation

When a user’s custody_enabled is enabled, all token transfers must be performed using the custody send CLI. Attempts to use the bank send CLI will be automatically rejected. Transactions are placed in an on-chain buffer awaiting approval by the quorum of custodian addresses defined by the user via the custody_mode property. The buffer has limited size defined by the max_custody_buffer_size network property (default 10) and the transaction/stored data size by max_custody_tx_size (default 8192 characters). It is important that each transaction includes adequate fees to motivate custodians to cast their approval. The fees should be at least double the cost of approving or denying the transaction, which will effectively cover the refund of transaction fees. If a custodian does not cast a judgement, they do not receive any rewards and any remaining rewards will be returned to the user. Transactions without sufficient fees included will be automatically rejected.

Custody module’s security

All transactions of the custody module can only be propagated by providing a key defined by the user or the frontend. However a key becomes exposed and thereby obsolete as soon as it used to submit a transaction. Therefore, to circumvent this security weakness, keys can only be used once and each transaction (except the first one) require providing the previously defined key hashed once SHA256(secret) as well as setting up the new key SHA256(SHA256(secret)) for the subsequent transaction.
All transactions of the custody module can only be propagated by providing a key. This key is a secret password defined by the user that is hashed twice before being stored on the blockchain to ensure its security. For each subsequent transaction the user must provide the previously set password hashed once for the system to check, but also set a new key for the next transaction. The reason for this design is due to the very public nature of transaction data in blockchains, making the secret obsolete as soon as it is used to submit a transaction. By hashing the key twice before storing it on the blockchain, and requiring the user to provide the same secret password, hashed once, for subsequent transactions, the module provides an added layer of security for the user's digital assets.

CLI syntax & examples

Governance

Each user is responsible of its own custody account parameters and does not depend on specific governance permissions. However, the module has two network properties, max_custody_tx_size and max_custody_buffer_size, which require a specific governance process to be modified (cf. Network Properties).

Transactions

sekaid tx custody
create - Create new custody settings
send - When custody_enabled is set to true, allows to send funds from one account to another.
approve - Approve custody transaction by receiver address and transaction hash
confirm - Confirm password-protected transaction
decline - Decline custody transaction by receiver address and transaction hash
add - Add one or multiple addresses to the custodians list
drop - Drop the entire custodians list
remove - Remove address from custodians list
add - Add new address to the custody limits
drop - Drop the custody limits
remove - Remove address from the custody limits
add - Add new address to the custody whitelist
drop - Drop the custody whitelist
remove - Remove address from the custody whitelist

Queries

sekaid query customgov
get - Query the current custody settings assigned to an address
custodians- Query commands for the custody custodians
get - Query custody custodians assigned to an address
pool - Query all pending transactions
limits get - Query transfer limits assigned to an address
whitelist get - Query whitelisted addressed assigned to an address
custody-registrar-query - list all details regarding custody of a specific account, including all incoming/outgoing transactions to/from specific account and their status. We should allow verifier to easily check if they have any pending tx’es to sign as well as the beneficiary so that UI can easily find & display incoming transactions.
bank-tx-query-protected - query all pending transactions that you are sending or receiving
custody-accounts-list - list all accounts which use custody module
custody-registrar-clean-txs - remove one or many/all transactions from the registrar
custody-registrar-propagate-txs (optional) - propagate one, many or all approved transactions - this should be optional if transactions can be automatically propagated

Syntax & examples

Callout icon
Each CLI command and proposal process in KIRA requires specific permissions. These permissions must be added to the account's whitelist or obtained as sudo permissions for direct changes. Refer to the Roles & Permissions documentation for more details. $SIGNER represents the transaction signer's account name or address. For instructions on setting common flags as environment variables, such as $FLAGS_TX and $FLAGS_QR, see the CLI flags configuration section

Custody settings management

Custody settings are set using the create CLI. Settings are stored in a dedicated registry and can then be retrieved using the custodians get CLI.
$MODE
int
Quorum as percentage [1, 100] of custodians’ approval to complete transaction.
$PASSWORD
bool
Enable/disable transaction password protection
$LIMITS
bool
Enable/disable period withdrawal limits protection
$WHITELIST
bool
Enable/disable withdrawal addresses whitelist protection
$OKEY
string
Digest of previous defined key, SHA256( old key )
$NKEY
string
Digest of digest of new defined key, SHA256(SHA256( new key ))
Bash
Copy
sekaid tx custody create --fees=100ukex \ --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $MODE $PASSWORD $LIMITS $WHITELIST
​
Bash
Copy
# Example sekaid tx custody create --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from="kira1rxu5ltg5z63rl6du80xe45vghhy4cxlna5mzfm" --chain-id="localnet-1" --home="/root/.sekaid-localnet-1" \ --okey="0" --nkey="e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" \ 33 false false false
​

Custodians list management

Adding custodians can be done one by one or by providing a comma-separated list of addresses using custodians add.
$CUSTODIANS
string, string, …
Comma separated list of Kira addresses
$OKEY
string
Digest of previous defined key, SHA256( old key )
$NKEY
string
Digest of digest of new defined key, SHA256(SHA256( new key ))
Bash
Copy
sekaid tx custody custodians add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $CUSTODIANS
​
Bash
Copy
# Example LIST="kira1kjx6g2sd5rev3dnuzqh8q9fznkq22qaz52kpt4,kira1j8d78jzk460a6tn8e22jm0ynmnvc79mg8h7t77,kira1lxeslhhus8qw63fxm4l0gphmf2flxajxg5l5tz" sekaid tx custody custodians add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from="kira1rxu5ltg5z63rl6du80xe45vghhy4cxlna5mzfm" --chain-id="localnet-1" --home="/root/.sekaid-localnet-1" \ --okey="e2d8ce14e4zf189zffze18f88619853b075143deea596c477b8dc077e309c0cece2d58" --nkey="e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" \ $LIST
​
Removing a single custodian address with custodians remove. Removing a custodian address will not erase it from the list but simply set it to false. It can be switched back to true using custodians add.
$CUSTODIAN
string
Custodian address
Bash
Copy
sekaid tx custody custodians remove \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $CUSTODIAN
​
The list of custodians addresses can be dropped all at once using custodians drop. Dropping the list will erase all addresses completely.
Bash
Copy
sekaid tx custody custodians drop \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY
​

Transfer limits management

Adding transfer limit for a specific token can be done using limits add. Note that there is a 24h waiting period before any subsequent modification takes effect.
$DENOM
string
Denomination of the token to the transfer limits will be set for (e.g ukex)
$AMOUNT
int
Amount of token available to transfer for the given period
$PERIOD
string
Period value and unit (e.g 2d , 23h or 15m)
$OKEY
string
Digest of previous defined key, SHA256( old key )
$NKEY
string
Digest of digest of new defined key, SHA256(SHA256( new key ))
Bash
Copy
sekaid tx custody limits add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $DENOM $AMOUNT $PERIOD
​
Bash
Copy
# Example sekaid tx custody limits add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from="kira1rxu5ltg5z63rl6du80xe45vghhy4cxlna5mzfm" --chain-id="localnet-1" --home="/root/.sekaid-localnet-1" \ --okey="e2d8ce14e4zf189zffze18f88619853b075143deea596c477b8dc077e309c0cece2d58" --nkey="e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" \ ukex 100000 24h
​
Removing a limit is done using limits remove.
$DENOM
string
Denomination of the token to the transfer limits will be set for (e.g ukex)
Bash
Copy
sekaid tx custody limits remove \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $DENOM
​
All limits can be dropped at once using limits drop.
Bash
Copy
sekaid tx custody limits drop \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY
​

Withdrawal address whitelist management

Adding addresses to the withdrawal whitelist can be done one by one or by providing a comma-separated list of addresses using whitelist add. Note that there is a 24h waiting period before any subsequent modification takes effect.
$ADDRESS
string
Kira address to be whitelisted for transfer
$OKEY
string
Digest of previous defined key, SHA256( old key )
$NKEY
string
Digest of digest of new defined key, SHA256(SHA256( new key ))
Bash
Copy
sekaid tx custody whitelist add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $ADDRESS
​
Bash
Copy
# Example LIST="kira1kjx6g2sd5rev3dnuzqh8q9fznkq22qaz52kpt4,kira1j8d78jzk460a6tn8e22jm0ynmnvc79mg8h7t77,kira1lxeslhhus8qw63fxm4l0gphmf2flxajxg5l5tz" sekaid tx custody whitelist add \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from="kira1rxu5ltg5z63rl6du80xe45vghhy4cxlna5mzfm" --chain-id="localnet-1" --home="/root/.sekaid-localnet-1" \ --okey="e2d8ce14e4zf189zffze18f88619853b075143deea596c477b8dc077e309c0cece2d58" --nkey="e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" \ $LIST
​
Removing an address from the whitelist is done using whitelist remove. Removed addresses are not erased but simply set to false and can be switched back to true using whitelist add.
$ADDRESS
string
Whitelisted address
Bash
Copy
sekaid tx custody whitelist remove \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY \ $ADDRESS
​
All whitelisted addresses can be dropped at once using whitelist drop. Dropping the whitelist will erase all addresses completely.
Bash
Copy
sekaid tx custody whitelist drop \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --from=$SIGNER --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ --okey=$OKEY --nkey=$NKEY
​

Send custody transaction

When custody_enabled is set to true, token transfers have to be performed with the custody send CLI and will be propagated once the quorum of custodians approval is reached. Additionally, if use_password is set totrue, the beneficiary will have to provide the digest of the password used for $PASSWORD. Note that the $PASSWORD argument always has to be provided (can be random value if not needed). Note: A sufficient amount of —fees must be provided for the transaction to be valid which is at least N+1 times the standard transaction cost with N being the numbers of custodians required to reach quorum. Note, the'--from' flag is ignored as it is implied from [from_key_or_address].
$TO
string
Kira address of the beneficiary
$COINS
string
Coin denomination and amount to send in the format <amount><denom> (e.g. 20000ukex)
$PASSWORD
string
Digest of digest of the sender’s password, SHA256(SHA256( password ))
$REWARD
string
Coin denomination and amount used as reward in the format <amount><denom> (e.g. 200ukex)
$FROM
string
Kira address of the sender
Bash
Copy
sekaid tx custody send \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ $FROM $TO $COINS $PASSWORD
​
Bash
Copy
# Example (5 custodians to reach quorum = 600ukex fees) sekaid tx custody send \ --fees=600ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --chain-id="localnet-1" --home="/root/.sekaid-localnet-1" \ --okey="e2d8ce14e4zf189zffze18f88619853b075143deea596c477b8dc077e309c0cece2d58" --nkey="e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" \ kira1rxu5ltg5z63rl6du80xe45vghhy4cxlna5mzfm kira1lxeslhhus8qw63fxm4l0gphmf2flxajxg5l5tz 5000ukex "test"
​

Approve & decline transaction (Custodians)

Custodians can approve or decline incoming transactions using custody approve/ decline.
$SENDER
string
Kira address of the sender
$HASH
string
Hash of transaction to be approved (can be get by query 5)
Bash
Copy
sekaid tx custody approve \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ $SENDER $HASH
​

Confirm transaction (Beneficiary)

When use_password is set totrue, the transfer beneficiary can confirm the transaction by providing the $PASSWORD using custody confirm.
$SENDER
string
Kira address of the transfer sender
$HASH
string
Hash of transaction to be confirmed (can be get by query 5)
$PASSWORD
string
Digest of the sender’s password, SHA256( password )
Approve
Bash
Copy
sekaid tx custody confirm \ --fees=100ukex --keyring-backend=test --broadcast-mode=block --log_format=json --output=json \ --chain-id=$NETWORK_NAME --home=$SEKAID_HOME \ $SENDER $HASH $PASSWORD
​

Queries syntax & examples

Custody settings

The custody settings of a specific Kira address can be obtain using the get query.
$FROM
string
Kira address
Bash
Copy
sekaid query custody get $FROM --home=$SEKAID_HOME --chain-id=$NETWORK_NAME --output=json | jq
​
Which should return the following response:
JSON
Copy
{ "custody_settings": { "custody_enabled": true, "custody_mode": "33", "use_password": false, "use_white_list": false, "use_limits": false, "key": "e0bc614e4fd035a488619799853b075143deea596c477b8dc077e309c0fe42e9" } }
​

Custodians list & custody send pending transactions

The list of custodians addresses assigned to a Kira address can be obtained using the custodians get query CLI.
$FROM
string
Kira address
Bash
Copy
sekaid query custody custodians get $FROM --home=$SEKAID_HOME --chain-id=$NETWORK_NAME --output=json | jq
​
It will return the following response:
JSON
Copy
{ "custody_custodians": { "addresses": { "kira1j8d78jzk460a6tn8e22jm0ynmnvc79mg8h7t77": true, "kira1kjx6g2sd5rev3dnuzqh8q9fznkq22qaz52kpt4": true, "kira1lxeslhhus8qw63fxm4l0gphmf2flxajxg5l5tz": true } } }
​
The list of transactions sent via custody send by a specific Kira address which are pending for custodians’ quorum approval can be obtained by using the custodians pool query.
$FROM
string
Kira address
Bash
Copy
sekaid query custody custodians pool $FROM --home=$SEKAID_HOME --chain-id=$NETWORK_NAME --output=json | jq
​
It will return the following response:
JSON
Copy
TODO
​

Transfer limits

The list of different transfer limits for specific token assigned to a Kira address can be obtained using the whitelist get query CLI.
$FROM
string
Kira address
Bash
Copy
sekaid query custody limits get $FROM --home=$SEKAID_HOME --chain-id=$NETWORK_NAME --output=json | jq
​
It will return the following response:
JSON
Copy
TODO
​

Withdrawal address whitelist

The list of whitelisted addresses assigned to a Kira address can be obtained using the whitelist get query CLI.
$FROM
string
Kira address
Bash
Copy
sekaid query custody whitelist get $FROM --home=$SEKAID_HOME --chain-id=$NETWORK_NAME --output=json | jq
​
It will return the following response:
JSON
Copy
{ "custody_white_list": { "addresses": { "kira1kjx6g2sd5rev3dnuzqh8q9fznkq22qaz52kpt4": true, "kira1lxeslhhus8qw63fxm4l0gphmf2flxajxg5l5tz": true } } }
​