Skip to content

jennifertrin/suionicp

Repository files navigation

Sui on ICP

This demo provides an example of how to generate a Sui address controlled by an ICP canister smart contract.

ICP canister smart contracts can create and manage wallet addresses on any blockchain that uses the ECDSA signature scheme including Ethereum, EVM, and Sui. This feature named threshold ECDSA enables various cross-chain use cases.

Use cases

An ECDSA-based public key generated by an ICP canister smart contract can be derived into an unlimited amount of addresses on multiple chains. Therefore, this enables developers to create one ICP canister smart contract to interact with any blockchain that uses the ECDSA signature scheme including Ethereum, EVM, and Sui.

Developers can now easily create the following without needing to deploy multiple smart contracts on multiple chains:

Technical Implementation

This demo example implements an ICP canister smart contract on Typecript using the Azle CDK.

src/backend/index.ts stores the canister logic.

Generating a Sui address

In src/backend/index.ts, the suiAddress function calls ICP to generate the ECDSA public key and uses the Sui SDK to convert the ECDSA public key to a Sui address.

suiAddress: update([], text, async () => {
        const caller = ic.caller().toUint8Array();

        const publicKeyResult = await ic.call(
            managementCanister.ecdsa_public_key,
            {
                args: [
                    {
                        canister_id: None,
                        derivation_path: [caller],
                        key_id: {
                            curve: { secp256k1: null },
                            name: 'dfx_test_key'
                        }
                    }
                ]
            }
        );

        const suiPublicKey = new Secp256k1PublicKey(publicKeyResult.public_key);
        const suiAddress = suiPublicKey.toSuiAddress();
        return suiAddress;
    })

This code snippet calls the ICP management canister which exposes ICP system features including the creation of an ECDSA public key.

const caller = ic.caller().toUint8Array();

        const publicKeyResult = await ic.call(
            managementCanister.ecdsa_public_key,
            {
                args: [
                    {
                        canister_id: None,
                        derivation_path: [caller],
                        key_id: {
                            curve: { secp256k1: null },
                            name: 'dfx_test_key'
                        }
                    }
                ]
            }
        );

This code snippet converts the bytes of the public key returned from the ICP management canister into a secp256k1 public key as a base-64 encoded string. It then converts the secp256k1 public key into a Sui address.

const suiPublicKey = new Secp256k1PublicKey(publicKeyResult.public_key);
const suiAddress = suiPublicKey.toSuiAddress();

Signing for a Sui address

In src/backend/index.ts, the sign function is able to sign transactions for the ECDSA public key created above.

sign: update([blob], Signature, async (messageHash) => {
        if (messageHash.length !== 32) {
            ic.trap('messageHash must be 32 bytes');
        }
        const caller = ic.caller().toUint8Array();
        const signatureResult = await ic.call(
            managementCanister.sign_with_ecdsa,
            {
                args: [
                    {
                        message_hash: messageHash,
                        derivation_path: [caller],
                        key_id: {
                            curve: { secp256k1: null },
                            name: 'dfx_test_key'
                        }
                    }
                ],
                cycles: 10_000_000_000n
            }
        );
        return {
            signature: signatureResult.signature
        };
    })

About

An example of using Sui on ICP

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages