Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Module 0x1::permissioned_delegation

use 0x1::auth_data;
use 0x1::bcs_stream;
use 0x1::big_ordered_map;
use 0x1::ed25519;
use 0x1::error;
use 0x1::option;
use 0x1::permissioned_signer;
use 0x1::rate_limiter;
use 0x1::signer;

Enum AccountDelegation

enum AccountDelegation has store
Variants
V1
Fields
handle: permissioned_signer::StorablePermissionedHandle
rate_limiter: option::Option<rate_limiter::RateLimiter>

Enum DelegationKey

enum DelegationKey has copy, drop, store
Variants
Ed25519PublicKey
Fields
0: ed25519::UnvalidatedPublicKey

Resource RegisteredDelegations

struct RegisteredDelegations has key
Fields
delegations: big_ordered_map::BigOrderedMap<permissioned_delegation::DelegationKey, permissioned_delegation::AccountDelegation>

Constants

const ENOT_MASTER_SIGNER: u64 = 1;

const EINVALID_PUBLIC_KEY: u64 = 2;

const EINVALID_SIGNATURE: u64 = 4;

const EDELEGATION_EXISTENCE: u64 = 5;

const EPUBLIC_KEY_NOT_FOUND: u64 = 3;

const ERATE_LIMITED: u64 = 6;

Function gen_ed25519_key

public fun gen_ed25519_key(key: ed25519::UnvalidatedPublicKey): permissioned_delegation::DelegationKey
Implementation
public fun gen_ed25519_key(key: UnvalidatedPublicKey): DelegationKey {
    DelegationKey::Ed25519PublicKey(key)
}

Function check_txn_rate

fun check_txn_rate(bundle: &mut permissioned_delegation::AccountDelegation, check_rate_limit: bool)
Implementation
inline fun check_txn_rate(bundle: &mut AccountDelegation, check_rate_limit: bool) {
    let token_bucket = &mut bundle.rate_limiter;
    if (check_rate_limit && token_bucket.is_some()) {
        assert!(rate_limiter::request(token_bucket.borrow_mut(), 1), std::error::permission_denied(ERATE_LIMITED));
    };
}

Function add_permissioned_handle

public fun add_permissioned_handle(master: &signer, key: permissioned_delegation::DelegationKey, rate_limiter: option::Option<rate_limiter::RateLimiter>, expiration_time: u64): signer
Implementation
public fun add_permissioned_handle(
    master: &signer,
    key: DelegationKey,
    rate_limiter: Option<RateLimiter>,
    expiration_time: u64,
): signer acquires RegisteredDelegations {
    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
    let addr = signer::address_of(master);
    if (!exists<RegisteredDelegations>(addr)) {
        move_to(master, RegisteredDelegations {
            delegations: big_ordered_map::new_with_config(50, 20, false)
        });
    };
    let handles = &mut RegisteredDelegations[addr].delegations;
    assert!(!handles.contains(&key), error::already_exists(EDELEGATION_EXISTENCE));
    let handle = permissioned_signer::create_storable_permissioned_handle(master, expiration_time);
    let permissioned_signer = permissioned_signer::signer_from_storable_permissioned_handle(&handle);
    handles.add(key, AccountDelegation::V1 { handle, rate_limiter });
    permissioned_signer
}

Function remove_permissioned_handle

public fun remove_permissioned_handle(master: &signer, key: permissioned_delegation::DelegationKey)
Implementation
public fun remove_permissioned_handle(
    master: &signer,
    key: DelegationKey,
) acquires RegisteredDelegations {
    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
    let addr = signer::address_of(master);
    let delegations = &mut RegisteredDelegations[addr].delegations;
    assert!(delegations.contains(&key), error::not_found(EDELEGATION_EXISTENCE));
    let delegation = delegations.remove(&key);
    match (delegation) {
        AccountDelegation::V1 { handle, rate_limiter: _ } => {
            permissioned_signer::destroy_storable_permissioned_handle(handle);
        }
    };
}

Function permissioned_signer_by_key

public fun permissioned_signer_by_key(master: &signer, key: permissioned_delegation::DelegationKey): signer
Implementation
public fun permissioned_signer_by_key(
    master: &signer,
    key: DelegationKey,
): signer acquires RegisteredDelegations {
    assert!(!is_permissioned_signer(master), error::permission_denied(ENOT_MASTER_SIGNER));
    let addr = signer::address_of(master);
    let handle = get_storable_permissioned_handle(addr, key, false);
    permissioned_signer::signer_from_storable_permissioned_handle(handle)
}

Function handle_address_by_key

public fun handle_address_by_key(master: address, key: permissioned_delegation::DelegationKey): address
Implementation
public fun handle_address_by_key(master: address, key: DelegationKey): address acquires RegisteredDelegations {
    let handle = get_storable_permissioned_handle(master, key, false);
    permissioned_signer::permissions_storage_address(handle)
}

Function authenticate

Authorization function for account abstraction.

public fun authenticate(account: signer, abstraction_auth_data: auth_data::AbstractionAuthData): signer
Implementation
public fun authenticate(
    account: signer,
    abstraction_auth_data: AbstractionAuthData
): signer acquires RegisteredDelegations {
    let addr = signer::address_of(&account);
    let stream = bcs_stream::new(*abstraction_auth_data.authenticator());
    let public_key = new_unvalidated_public_key_from_bytes(
        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
    );
    let signature = new_signature_from_bytes(
        bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x))
    );
    assert!(
        ed25519::signature_verify_strict(
            &signature,
            &public_key,
            *abstraction_auth_data.digest(),
        ),
        error::permission_denied(EINVALID_SIGNATURE)
    );
    let handle = get_storable_permissioned_handle(addr, DelegationKey::Ed25519PublicKey(public_key), true);
    permissioned_signer::signer_from_storable_permissioned_handle(handle)
}

Function get_storable_permissioned_handle

fun get_storable_permissioned_handle(master: address, key: permissioned_delegation::DelegationKey, count_rate: bool): &permissioned_signer::StorablePermissionedHandle
Implementation
inline fun get_storable_permissioned_handle(
    master: address,
    key: DelegationKey,
    count_rate: bool
): &StorablePermissionedHandle {
    if (exists<RegisteredDelegations>(master)) {
        let delegations = &mut RegisteredDelegations[master].delegations;
        if (delegations.contains(&key)) {
            let delegation = delegations.remove(&key);
            check_txn_rate(&mut delegation, count_rate);
            delegations.add(key, delegation);
            &delegations.borrow(&key).handle
        } else {
            abort error::permission_denied(EINVALID_SIGNATURE)
        }
    } else {
        abort error::permission_denied(EINVALID_SIGNATURE)
    }
}

Specification

pragma verify = false;