Recovering Signer Addresses in Sway: EOA vs. Smart Wallet (Bako Safe) Signatures

How can I recover a signer address in Sway for smart wallets? I’ve implemented signer recovery for EOAs using ec_recover_address, but I’m not sure if this approach works for smart wallets—such as Bako Safe—or if a different implementation is required. Are there any examples or recommended methods for handling smart wallet signatures in Sway?

3 Likes

Hey Nerses, i will get back to you on this in a couple of mins.

1 Like

The ec_recover_address function is usually used to recover an address from a signature, which is useful for determining whether a message was signed by the holder of the address’s private key. though, when dealing with smart wallets, like Bako, the logic may differ due to additional layers of logic or multiple signers.
i believe to verify signatures from smart wallets, you must ensure that the logic within the smart wallet contract is consistent with your verification process. If the smart wallet uses a different signing mechanism or has multiple signers, you may need to modify your verification logic accordingly. I will get someone in from the bako team, to comment on this.

So there isnt one universal standard that can be used for every smart wallet.And for every smart wallet should be used its own verification mechnaism.Did I get right ?

Hey @nerses, i just confirmed with our team. there are a couple of things here:

  • firstly, this method is deprecated and you should be using std::crypto instead
  • as far as EIP-1271 is concerned, it doesn’t specify what kind of cryptographic scheme to use to implement it, so I guess it depends what your scheme looks like exactly, sway just provides some building blocks
  • lastly, It’s just a cryptographic curve, so any signatures using that curve will work
2 Likes

heyy @nerses

Bako wallets are built using predicates, which — despite working similarly to traditional EOAs — have one important limitation: predicates cannot sign messages.

In transactions sent by predicates, the signature is actually provided by a standard EOA, which is part of the predicate’s internal rules.

  • Predicates → cannot sign messages.
  • EOAs → can sign messages.

If your goal is to recognize and validate a signature made by a predicate, it might be possible, but it’s a complex process — especially if you want to obtain this directly within Sway.

:books: To better understand how Bako wallets work, I recommend reading the BakoSafe proposal:
Revolutionizing Multisig: A Fully Non-Custodial Solution Powered by Fuel Network

An Alternative Approach

One possible approach to work around this limitation could be:

  1. Deploy a contract that mints an intention token, serving as proof that the vault (predicate) agrees with a given message.
  2. The token ID could be derived as:
    sha256(contract_id, sha256(message+vault_address))
  3. This token would act as evidence that the message was validated according to the vault’s rules.
  4. To verify this intention in a future transaction, you would simply include this token as one of the transaction’s inputs.
    Within Sway, you could validate that:
  • The token was indeed minted by a specific contract.
  • The hash of the message matches the hash stored within the token.
  1. This way, you’d have an indirect mechanism for predicates to “sign” messages, ensuring the message was approved by the vault’s logic.

If you have any questions, I’ll be happy to help :slightly_smiling_face:

2 Likes

let me rephrase the problem, as it seems there is misunderstood.I have a flow where a user with an account abstraction wallet (e.g., Bako Safe) sends funds to a contract while writing some data. Later, they provide a signature to a third party, allowing that party to modify the data on their behalf.

How can I verify in a Sway smart contract that the provided signature belongs to the original user who sent the funds?

the problem is that in my dapp the user should sign on some data,and that signature is a way to do tx on behalf of user.So this approach will solve the previous issue but will create new one.

Could you share your code base?
Let me take a look to understand better and try to help

here is the minimal code so you the flow will be more easier to understand.

1)    #[payable]
    #[storage(read, write)]
    fn commit(
        timelock: u64
    ) {
            sender: msg_sender().unwrap().as_address().unwrap(),
            timelock: timelock,

      }


2)  user provides signature on data timelock

3)      #[storage(read, write)]
	fn add_lock_sig(signature: B512, timelock: u64) -> u256 {
		verify(signature,timelock) == sender

	}

user with Bako safe wallet calls function commit later in step 2 he signs on timelock data and provides that signature and timelock to 3rd party. in 3rd step someone calls add_lock_sig with provided signature and data. My main question is how should verify be implemnted in case of Bako wallet ? As in ordinary EOA I will just use ec_recover_address which cant be used for Bako safe

above is simplified version of code