Skip to main content

Signing transactions

Advanced
Tutorial

Overview

To use Threshold ECDSA, you will need a public key and a transaction to sign. Public keys can be obtained through the ecdsa_public_key API method, and transactions can be signed using the sign_with_ecdsa API method.

Cost

To send calls to the Threshold ECDSA API, cycles must be attached to the call. Learn more about Threshold ECDSA costs.

Obtaining public keys

To sign transactions, first you need to obtain a public key by making a call to the ecdsa_public_key API method.

  // Declare "ic" to be the management canister, which is evoked by `actor("aaaaa-aa")`.:
let ic : IC = actor("aaaaa-aa");

public shared (msg) func public_key() : async { #Ok : { public_key: Blob }; #Err : Text } {
let caller = Principal.toBlob(msg.caller);

try {

// Make a call to the management canister to request an ECDSA public key:
let { public_key } = await ic.ecdsa_public_key({
canister_id = null;
derivation_path = [ caller ];
key_id = { curve = #secp256k1; name = "test_key_1" };
});

#Ok({ public_key })

} catch (err) {

#Err(Error.message(err))

}

};

Signing transactions

To sign a transaction, make a call to the sign_with_ecdsa API method:

  public shared (msg) func sign(message_hash: Blob) : async { #Ok : { signature: Blob };  #Err : Text } {
assert(message_hash.size() == 32);
let caller = Principal.toBlob(msg.caller);
try {
Cycles.add(10_000_000_000);
let { signature } = await ic.sign_with_ecdsa({
message_hash;
derivation_path = [ caller ];
key_id = { curve = #secp256k1; name = "dfx_test_key" };
});
#Ok({ signature })
} catch (err) {
#Err(Error.message(err))
}
};

Resources