Account

0xec8Ff99af54e7f4c9dd81F32dFfade6B41f3B980436eE2EabF47A069F998CD730xec8F...CD73

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
0x1a403000504100301a445000ba49000032400481504100205d490000504100083240048220451300524510044a4400007cf30ca9e83e8b7e0d1e608fb6252d53a08144a65cd73031ff2fbc52614b8a6a0000000000000230a03eba9fbd2017ff1ecc2d1108a59a611c355ef482bd1eeb0e047c844a147e4400000000000000021a58ce845d44f0eef80344528c590c720f63cc402b6a339f822b78f2cdfb1f3d03aab6b3c770e134908ba0cde7bfad7f22b80138e90f2c0d3948ab3ebd0659c8d6a82e105a9e9a8137241f42d4fc3df27f978b4094dc3461f68da31ce89a691244d4e649de059432c9a658839a2ac12706bf0b66b07f300d83ceb0ca02c32ace8de45294d81ae41964019661f9705becb6e63bd3f4987ec61b50ce23609b893e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042414b4f000000003031323334353637383961626364656600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000cccccccccccc00020000000000001b1000000000000019e000000000000019d8000000000000160000000000000015a8000000000000117800000000000010f80000000000001064000000000000103c0000000000000fa00000000000000c1c00000000000009080000000000000838