Skip to content

permissioned_delegation - [mainnet]

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

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;

Resources

RegisteredDelegations

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

Functions

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)
}

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));
};
}

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
}

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);
}
};
}

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)
}

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)
}

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(*auth_data::authenticator(&abstraction_auth_data));
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,
*auth_data::digest(&abstraction_auth_data),
),
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)
}

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;