The objective of this TZIP is to propose some features to cover what a decentralized bank account can do, also called "Programmable money".
TZIP-0XX proposes a standard to replicate what bank accounts do today but in a decentralized manner
This document provides an overview and rationale for the global solution as well as an implementation.
Account abstraction has raised concerns to the web3 developers of the importance of UX and the gap we have today. We are focusing here on two major topics which are Account Management and Account Global Rules.
Let's review what we have on Tezos about Account Management and recovery mechanisms:
Let's review what we have on Tezos about Account Global Rules:
This does not cover what we expect from a personal/shared bank account
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”,
“SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be
interpreted as described in RFC 2119.
The use cases we want to cover :
owners
: a set of addresses
.inheritors
: a set of addresses
.quick_recovery_stake
: The minimum stake a claimer should send to be able to call this function. By default it is equal to the balance of the account, otherwise, it is an amount in tez
.quick_recovery_period
: The time in days for the owner of the smart contract wallet to wait until he can retake control of his SC wallet. By default, it is 1 week.status
: An indicator of the status of the SC wallet
ACTIVE
: default statusRECOVERING(address,timestamp)
: when the owner or someone else is trying to recover the accountDEAD
: the owner is considered dead. All entry points are disabled except reboot_inheritancy_countdown
and claim_inheritancy
inheritancy_countdown_date
: The date when an inheritor can claim a part of the assets, and so, the owner is considered deadinheritancy_claims
: a set<address>
of all claims done on XTZ by inheritors addressinheritancy_FA_claims
: a bigMap<[address,address],unit>
of all claims done on FA tokens by inheritors address/FA token addressspending_limit_XTZ
: maximum tez
to be sent on a unique transferspending_limit_FA
: maximum BigMap<[address,nat],nat>
quantity of token n from contract fa to be sent on a unique transferdirect_debit_mandates
: abigMap<[address,Frequency],tez>
of mandates for XTZdirect_debit_mandates_history
: abigMap<[address,Frequency],last_execution_timestamp>
of executed mandates for XTZdirect_debit_mandates
: abigMap<[address,nat,Frequency],nat>
of mandates for FA tokensdirect_debit_mandates_history
: abigMap<[address,nat,Frequency],last_execution_timestamp>
of executed mandates for FA tokensFrequency
: SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, YEARenroll
Enroll an address to the smart contract wallet. Only an owner can do it
function enroll(owner : address)
revoke
Revoke an address to the smart contract wallet. Only an owner can do it
function revoke(owner : address)
transfer_XTZ
Send native money to someone. Only an owner can do it
function transfer_XTZ(target : address,amount : mutez)
transfer_FA
Send FA tokens to someone. Only an owner can do it
function transfer_FA(list<{
from_ : address;
txs : list<{
to_ : address;
amount : Amount.T;
token_id : Token.T;
}>
}>)
proof_of_event
Used to generate proof of ownership of the smart contract wallet and allows login with it. Only an owner can do it
function proof_of_event(payload : bytes)
start_recovery
Initiate a process of recovery due to complete lost or stolen keys. This function requires passing some tez in order to avoid spam. @see quick_recovery_stake
and quick_recovery_period
settings. It is only possible if the contract is ACTIVE
.
function start_recovery(claimer : address)
claim_recovery
This function should enroll the claimer address as an owner after a certain period of time has passed and the recovery has not been canceled (i.e. in status RECOVERING
). If ok, the status passes to ACTIVE
. @see quick_recovery_stake
and quick_recovery_period
settings
function claim_recovery
stop_recovery
Stop the recovery process. This function can be called only by an owner. The status is back to ACTIVE
.
function stop_recovery()
set_inheritors
Add inheritors to the contract. Only an owner can do it.
function set_inheritors(inheritors : set<address>)
remove_inheritors
Remove inheritors from the contract. Only an owner can do it.
function remove_inheritors(inheritors_to_remove : set<address>)
claim_inheritancy
An inheritor can make a claim to get 1/n assets stored on the contract to its address if the countdown date has passed, where n is the number of inheritors. He can call this function only once. The contract is then considered as status DEAD
.
function claim_inheritancy()
claim_inheritancy_FA
An inheritor can make a claim to get 1/n FA assets owned by the contract to its address if the countdown date has passed, where n is the number of inheritors. He can call this function only once. The contract is then considered as status DEAD
.
function claim_inheritancy_FA(fa_address : address)
reboot_inheritancy_countdown
Only owners of the contract can postpone by nbdays
the countdown date. Status passes to ACTIVE
.
function reboot_inheritancy_countdown(nbdays : nat)
set_spending_limit_XTZ
Set the spending limit. Only at minimum 2 owner signatures can do this
function set_spending_limit_XTZ(amount : tez)
set_spending_limit_FA
Set the spending limit on the FA token. Only at minimum 2 owner signatures can do this
function set_spending_limit_XTZ(quantity : nat, token_id : nat )
add_direct_debit_mandate_XTZ
Add a new direct debit mandate in XTZ. Only owners can do it
function add_direct_debit_mandate_XTZ(beneficiary : address,frequency : Frequency,amount : tez)
revoke_direct_debit_mandate_XTZ
Revoke a direct debit mandate in XTZ. Only owners can do it
function revoke_direct_debit_mandate_XTZ(beneficiary : address,frequency : Frequency)
execute_direct_debit_mandate_XTZ
Execute a direct debit mandate in XTZ. Only the beneficiary can call this function at the correct date and not twice
function execute_direct_debit_mandate_XTZ(frequency : Frequency)
add_direct_debit_mandate_FA
Add a new direct debit mandate in FA. Only owners can do it
function add_direct_debit_mandate_FA(beneficiary : address,token_id : nat,frequency : Frequency,amount : tez)
revoke_direct_debit_mandate_FA
Revoke a direct debit mandate in FA. Only owners can do it
function revoke_direct_debit_mandate_FA(beneficiary : address,token_id : nat,frequency : Frequency)
exec_direct_debit_mandate_FA
Execute a direct debit mandate in FA. Only the beneficiary can call this function at the correct date and not twice
function execute_direct_debit_mandate_FA(token_id :nat,frequency : Frequency)
We recommend exploring the possibility of using a mobile phone secure enclave for signing natively Tezos transactions. It does not exist today but it could be implemented on a new tz5 address.
This allows you enrolling several tz addresses and simply sign transactions with a finger touch
Alice configures her bank account with 1 device. She logs in with her bank account to a decentralized application and she makes a payment. Then she loses her phone and tries to make a quick recovery. She succeeds and kickoffs the lost phone from the bank account ownership
Alice is contracting a mobile subscription to be paid 10tez each month. She registers a direct debit mandate on her bank account. Every month, her bill is paid automatically
An implementation is available here
Copyright and related rights waived via
CC0.