Skip to main content

soroban_sdk/
auth.rs

1//! Auth contains types for building custom account contracts.
2
3use crate::{
4    contractimpl_trait_macro, contracttype, crypto::Hash, Address, BytesN, Env, Error, Symbol, Val,
5    Vec,
6};
7
8/// Context of a single authorized call performed by an address.
9///
10/// Custom account contracts that implement `__check_auth` special function
11/// receive a list of `Context` values corresponding to all the calls that
12/// need to be authorized.
13#[derive(Clone)]
14#[contracttype(crate_path = "crate", export = false)]
15pub enum Context {
16    /// Contract invocation.
17    Contract(ContractContext),
18    /// Contract that has a constructor with no arguments is created.
19    CreateContractHostFn(CreateContractHostFnContext),
20    /// Contract that has a constructor with 1 or more arguments is created.
21    CreateContractWithCtorHostFn(CreateContractWithConstructorHostFnContext),
22}
23
24/// Authorization context of a single contract call.
25///
26/// This struct corresponds to a `require_auth_for_args` call for an address
27/// from `contract` function with `fn_name` name and `args` arguments.
28#[derive(Clone)]
29#[contracttype(crate_path = "crate", export = false)]
30pub struct ContractContext {
31    pub contract: Address,
32    pub fn_name: Symbol,
33    pub args: Vec<Val>,
34}
35
36/// Authorization context for `create_contract` host function that creates a
37/// new contract on behalf of authorizer address.
38#[derive(Clone)]
39#[contracttype(crate_path = "crate", export = false)]
40pub struct CreateContractHostFnContext {
41    pub executable: ContractExecutable,
42    pub salt: BytesN<32>,
43}
44
45/// Authorization context for `create_contract` host function that creates a
46/// new contract on behalf of authorizer address.
47/// This is the same as `CreateContractHostFnContext`, but also has
48/// contract constructor arguments.
49#[derive(Clone)]
50#[contracttype(crate_path = "crate", export = false)]
51pub struct CreateContractWithConstructorHostFnContext {
52    pub executable: ContractExecutable,
53    pub salt: BytesN<32>,
54    pub constructor_args: Vec<Val>,
55}
56
57/// Contract executable used for creating a new contract and used in
58/// `CreateContractHostFnContext`.
59#[derive(Clone)]
60#[contracttype(crate_path = "crate", export = false)]
61pub enum ContractExecutable {
62    Wasm(BytesN<32>),
63}
64
65/// A node in the tree of authorizations performed on behalf of the current
66/// contract as invoker of the contracts deeper in the call stack.
67///
68/// This is used as an argument of `authorize_as_current_contract` host function.
69///
70/// This tree corresponds `require_auth[_for_args]` calls on behalf of the
71/// current contract.
72#[derive(Clone)]
73#[contracttype(crate_path = "crate", export = false)]
74pub enum InvokerContractAuthEntry {
75    /// Invoke a contract.
76    Contract(SubContractInvocation),
77    /// Create a contract passing 0 arguments to constructor.
78    CreateContractHostFn(CreateContractHostFnContext),
79    /// Create a contract passing 0 or more arguments to constructor.
80    CreateContractWithCtorHostFn(CreateContractWithConstructorHostFnContext),
81}
82
83/// Value of contract node in InvokerContractAuthEntry tree.
84#[derive(Clone)]
85#[contracttype(crate_path = "crate", export = false)]
86pub struct SubContractInvocation {
87    pub context: ContractContext,
88    pub sub_invocations: Vec<InvokerContractAuthEntry>,
89}
90
91/// Custom account interface that a contract implements to support being used
92/// as a custom account for auth.
93///
94/// Once a contract implements the interface, call to [`Address::require_auth`]
95/// for the contract's address will call its `__check_auth` implementation.
96#[contractimpl_trait_macro(crate_path = "crate")]
97pub trait CustomAccountInterface {
98    type Signature;
99    type Error: Into<Error>;
100
101    /// Check that the signatures and auth contexts are valid.
102    fn __check_auth(
103        env: Env,
104        signature_payload: Hash<32>,
105        signatures: Self::Signature,
106        auth_contexts: Vec<Context>,
107    ) -> Result<(), Self::Error>;
108}