Icon LinkSigning

Once you've instantiated your wallet in an unlocked state using one of the previously discussed methods, you can sign a message with wallet.sign_message. Below is a full example of how to sign and recover a message.

let mut rng = StdRng::seed_from_u64(2322u64);
let mut secret_seed = [0u8; 32];
rng.fill_bytes(&mut secret_seed);
 
let secret = secret_seed
    .as_slice()
    .try_into()
    .expect("The seed size is valid");
 
// Create a wallet using the private key created above.
let wallet = WalletUnlocked::new_from_private_key(secret, None);
 
let message = "my message";
 
let signature = wallet.sign_message(message).await?;
 
// Check if signature is what we expect it to be
assert_eq!(signature, Signature::from_str("0x8eeb238db1adea4152644f1cd827b552dfa9ab3f4939718bb45ca476d167c6512a656f4d4c7356bfb9561b14448c230c6e7e4bd781df5ee9e5999faa6495163d")?);
 
// Recover address that signed the message
let message = Message::new(message);
let recovered_address = signature.recover(&message)?;
 
assert_eq!(wallet.address().hash(), recovered_address.hash());
 
// Verify signature
signature.verify(&recovered_address, &message)?;
Ok(())

You can also sign a transaction by using wallet.sign_transaction. Below is a full example of how to sign and recover a transaction.

let secret = SecretKey::from_str(
    "5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1",
)?;
let mut wallet = WalletUnlocked::new_from_private_key(secret, None);
 
// Set up a dummy transaction.
let coin = Coin {
    amount: 10000000,
    owner: wallet.address().clone(),
    ..Default::default()
};
let input_coin = Input::ResourceSigned {
    resource: CoinType::Coin(coin),
    witness_index: 0,
};
 
let output_coin = Output::coin(
    Address::from_str(
        "0xc7862855b418ba8f58878db434b21053a61a2025209889cc115989e8040ff077",
    )?,
    1,
    Default::default(),
);
 
let mut tx = ScriptTransactionBuilder::prepare_transfer(
    vec![input_coin],
    vec![output_coin],
    Default::default(),
)
.build()?;
 
// Sign the transaction.
let consensus_parameters = ConsensusParameters::default();
let test_provider = Provider::new(FuelClient::new("test")?, consensus_parameters);
wallet.set_provider(test_provider);
let signature = wallet.sign_transaction(&mut tx)?;
let message = Message::from_bytes(*tx.id(consensus_parameters.chain_id.into()));
 
// Check if signature is what we expect it to be
assert_eq!(signature, Signature::from_str("df91e8ae723165f9a28b70910e3da41300da413607065618522f3084c9f051114acb1b51a836bd63c3d84a1ac904bf37b82ef03973c19026b266d04872f170a6")?);
 
// Recover address that signed the transaction
let recovered_address = signature.recover(&message)?;
 
assert_eq!(wallet.address().hash(), recovered_address.hash());
 
// Verify signature
signature.verify(&recovered_address, &message)?;
Ok(())