Account

0xe314165EA47eE6B826f21A53A8BdC0Ef37dF154B607d87Bd56f5d974D3b38a480xe314...8a48

Bako Safe
The Bako Safe is a multi-signature wallet that supports Fuel native wallets and passkeys.

Source Code
predicate;

use std::{b512::B512, tx::{GTF_WITNESS_DATA, tx_id, tx_witnesses_count}};

use libraries::{
    constants::{
        BYTE_WITNESS_TYPE_FUEL,
        BYTE_WITNESS_TYPE_WEBAUTHN,
        EMPTY_SIGNERS,
        INVALID_ADDRESS,
        MAX_SIGNERS,
    },
    entities::{
        SignatureType,
        WebAuthnHeader,
    },
    recover_signature::{
        fuel_verify,
        webauthn_verify,
    },
    utilities::{
        b256_to_ascii_bytes,
    },
    validations::{
        check_duplicated_signers,
        check_signer_exists,
        verify_prefix,
    },
    webauthn_digest::{
        get_webauthn_digest,
    },
};

configurable {
    SIGNERS: [b256; 10] = EMPTY_SIGNERS,
    SIGNATURES_COUNT: u64 = 0,
    #[allow(dead_code)]
    HASH_PREDICATE: b256 = b256::zero(),
}

fn main() -> bool {
    let mut i_witnesses = 0;
    let mut verified_signatures: Vec<Address> = Vec::with_capacity(MAX_SIGNERS);

    while i_witnesses < tx_witnesses_count() {
        let mut witness_ptr = __gtf::<raw_ptr>(i_witnesses, GTF_WITNESS_DATA);
        if (verify_prefix(witness_ptr)) {
            let tx_bytes = b256_to_ascii_bytes(tx_id()); // are used 
            witness_ptr = witness_ptr.add_uint_offset(4); // skip bako prefix
            let signature = witness_ptr.read::<SignatureType>();
            witness_ptr = witness_ptr.add_uint_offset(__size_of::<u64>()); // skip enum size
            let pk: Address = match signature {
                SignatureType::WebAuthn(signature_payload) => {
                    let data_ptr = witness_ptr.add_uint_offset(__size_of::<WebAuthnHeader>());

                    webauthn_verify(
                        get_webauthn_digest(signature_payload, data_ptr, tx_bytes),
                        signature_payload,
                    )
                },
                SignatureType::Fuel(_) => {
                    let signature = witness_ptr.read::<B512>();

                    fuel_verify(signature, tx_bytes)
                },
                _ => INVALID_ADDRESS,
            };

            let is_valid_signer = check_signer_exists(pk, SIGNERS);
            check_duplicated_signers(is_valid_signer, verified_signatures);
        }

        i_witnesses += 1;
    }

    return verified_signatures.len() >= SIGNATURES_COUNT;
}
Bytecode
0x1a403000504100301a445000ba49000032400481504100205d490000504100083240048220451300524510044a4400007cf30ca9e83e8b7e0d1e608fb6252d53a08144a65cd73031ff2fbc52614b8a6a00000000000002305dc7d760ec91b932ce83a1d3a562f995966cd44fbf875148e49b7c8f877992c5000000000000000803aab6b3c770e134908ba0cde7bfad7f22b80138e90f2c0d3948ab3ebd0659c8a9580dc10b56419c2dabda0fdd6f4c384ade9d3cbe7687ec17b764889404cc8c6fe7718090e7b18222d3dd3345f0cb67c517346d386d7e4acd9132461a932077335f1258cdd55255d456fe62de516867e337ea2f9bb997984376866132eff3d1b66b649bb1cfdcdffbd8bbfbfccf1853cc7491c97995d021fdf4f32a6c08f0ec9d16d762d06bc148d4931cc3ffdd84f2eb80f26a29de763a11c9eaec74cc0e84ca9009789c6233473a1e2038579025504a197e2964cfa89cb1d5a461639514f06175f16e34e8fcc4931eef97071031e33b03f2d60a8431e9252bc2d85c9ae8530000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042414b4f000000003031323334353637383961626364656600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000cccccccccccc00020000000000001b1000000000000019e000000000000019d8000000000000160000000000000015a8000000000000117800000000000010f80000000000001064000000000000103c0000000000000fa00000000000000c1c00000000000009080000000000000838