Skip to main content

Sign in with Bitcoin

Advanced
Bitcoin

Overview

Sign in with Bitcoin (SIWB) is a fork of the sign in with Ethereum package that enables dapps to provide users with the option to authenticate with their Bitcoin wallet address.

SIWB supports the popular BTC wallets Wizz and Unisat.

Key features

  • Consistent principal generation: Ensures that logging in with a BTC wallet will produce the same principal consistently.

  • Session identity uniqueness: Each session identity is specific to the application's context, avoiding cross-app identity exploits.

  • Direct BTC-to-principal mapping: Each BTC address has a 1:1 correlation with a principal.

  • Timebound sessions: Developers can set session expiration times for control and security enhancement.

  • Prebuilt identity provider: A prebuilt canister to integrate into any existing ICP dapp.

Usage

The SIWB package can be downloaded from its GitHub repo which includes an example integration.

To use the example integration, clone the repo, then deploy the included pre-built canisters:

git clone https://github.com/AstroxNetwork/ic-siwb.git
cd ic-siwb
dfx start --clean --background
npm install
dfx deploy

This example deploys the prebuild ic_siwb_provider canister alongside an example ic_siwb_test_canister.

If you are deploying on a Mac OS X machine and receive an error such as:

secp256k1-sys@0.8.1: error: unable to create target: 'No available targets are compatible with triple "wasm32-unknown-unknown"'
error: failed to run custom build command for `secp256k1-sys v0.8.1`

This is due to the default Mac OS X clang compiler not supporting compiling to target wasm32-unknown-unknown.

You can remedy this error by installing another compiler using brew that does support wasm32-unknown-unknown:

brew install llvm
export PATH="/opt/homebrew/opt/llvm/bin:$PATH" &&  export LDFLAGS="-L/opt/homebrew/opt/llvm/lib" && export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
cargo build --target wasm32-unknown-unknown --release

As part of the canisters' deployment, both will require initialization arguments. The first is the ic_siwb_provider canister. Before initialization, this canister's ID will be printed on the terminal in a line such as:

Installing canisters...
Installing code for canister ic_siwb_provider, with canister ID bkyz2-fmaaa-aaaaa-qaaaq-cai
This canister requires an initialization argument.

Copy the canister's ID. Then, configure the initialization arguments as prompted:

  • URI: The full URL, such as http://localhost:3000.
  • Salt: A string used to generate seed that uniquely identifies each user principal.
  • Domain: The domain name, such as localhost.
  • Optional runtime feature enabled: Select yes to enable and no to disable.
  • Optional statement: A message presented to the user by the Bitcoin wallet.
  • Optional scheme: The scheme used to serve the frontend that uses SIWB. Defaults to "https".
  • Optional network: Defaults to the Bitcoin mainnet. 
  • Optional session expiration time: Time to live for a session in nanoseconds.
  • Optional target: All canisters for which the identity delegation is allowed. Defaults to None.
  • Optional sign in expiration time: Time to live for a sign in message in nanoseconds.

An example of the canister's initialization configuration can be found below:

(
  record {
    uri = "http://localhost:3000";
    runtime_features = null;
    domain = "localhost";
    statement = null;
    scheme = null;
    salt = "test";
    network = null;
    session_expires_in = null;
    targets = null;
    sign_in_expires_in = null;
  },
)

Next, you will need to pass the canister ID for ic_siwb_provider to the ic_siwb_test_canister as its initialization argument when prompted:

Installing code for canister ic_siwb_test_canister, with canister ID bd3sg-teaaa-aaaaa-qaaba-cai
This canister requires an initialization argument.
✔ Enter a text (type :e to use editor) · bkyz2-fmaaa-aaaaa-qaaaq-cai
Sending the following argument:
("bkyz2-fmaaa-aaaaa-qaaaq-cai")

Once both canisters have been installed, initialized, and deployed, you will receive the local URLs for both canisters:

URLs:
  Backend canister via Candid interface:
    ic_siwb_provider: http://127.0.0.1:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai
    ic_siwb_test_canister: http://127.0.0.1:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai&id=bd3sg-teaaa-aaaaa-qaaba-cai

You can view the full frontend example in the project's repo.

Resources