Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/rust-vetkeys-basic-bls-signing-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: rust-vetkeys-basic-bls-signing
on:
push:
branches:
- master
pull_request:
paths:
- rust/vetkeys/basic_bls_signing/**
- .github/workflows/provision-darwin.sh
- .github/workflows/provision-linux.sh
- .github/workflows/rust-vetkeys-basic-bls-signing-example.yml
- .ic-commit
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
rust-basic-bls-signing-darwin:
runs-on: macos-15
steps:
- uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Provision Darwin
run: bash .github/workflows/provision-darwin.sh
- name: Pre-download network launcher
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/workflows/pre-download-launcher.sh
- name: Deploy Basic BLS Signing Rust Darwin
env:
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eExuo pipefail
pushd rust/vetkeys/basic_bls_signing/rust
icp network start -d && icp deploy
popd
rust-basic-bls-signing-linux:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Provision Linux
run: bash .github/workflows/provision-linux.sh
- name: Pre-download network launcher
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/workflows/pre-download-launcher.sh
- name: Deploy Basic BLS Signing Rust Linux
env:
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eExuo pipefail
pushd rust/vetkeys/basic_bls_signing/rust
icp network start -d && icp deploy
popd
motoko-basic-bls-signing-darwin:
runs-on: macos-15
steps:
- uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Provision Darwin
run: bash .github/workflows/provision-darwin.sh
- name: Pre-download network launcher
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/workflows/pre-download-launcher.sh
- name: Deploy Basic BLS Signing Motoko Darwin
env:
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eExuo pipefail
pushd rust/vetkeys/basic_bls_signing/motoko
icp network start -d && icp deploy
popd
motoko-basic-bls-signing-linux:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
- name: Provision Linux
run: bash .github/workflows/provision-linux.sh
- name: Pre-download network launcher
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash .github/workflows/pre-download-launcher.sh
- name: Deploy Basic BLS Signing Motoko Linux
env:
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eExuo pipefail
pushd rust/vetkeys/basic_bls_signing/motoko
icp network start -d && icp deploy
popd
47 changes: 36 additions & 11 deletions rust/vetkeys/basic_bls_signing/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Threshold BLS Signatures

<!-- TODO: re-enable once icp.ninja supports icp-cli -->
<!--
| Motoko backend | [![](https://icp.ninja/assets/open.svg)](http://icp.ninja/editor?g=https://github.com/dfinity/examples/tree/master/rust/vetkeys/basic_bls_signing/motoko)|
| --- | --- |
| Rust backend | [![](https://icp.ninja/assets/open.svg)](http://icp.ninja/editor?g=https://github.com/dfinity/examples/tree/master/rust/vetkeys/basic_bls_signing/rust) |
-->

The **Basic BLS signing** example demonstrates how to use **[vetKeys](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/introduction)** to implement a threshold BLS signing service on the **Internet Computer (IC)**, where every authenticated user can ask the canister (IC smart contract) to produce signatures, where the **Internet Identity Principal** identifies the signer. This canister ensures that users can only produce signature for their own principal and not for someone else's principal. Furthermore, the vetKeys in this dapp can only be produced upon a user request, as specified in the canister code, meaning that the canister cannot produce signatures for arbitrary users or messages.
The **Basic BLS signing** example demonstrates how to use **[vetKeys](https://docs.internetcomputer.org/concepts/vetkeys)** to implement a threshold BLS signing service on the **Internet Computer (IC)**, where every authenticated user can ask the canister (IC smart contract) to produce signatures, where the **Internet Identity Principal** identifies the signer. This canister ensures that users can only produce signature for their own principal and not for someone else's principal. Furthermore, the vetKeys in this dapp can only be produced upon a user request, as specified in the canister code, meaning that the canister cannot produce signatures for arbitrary users or messages.

For confirming that the canister can only produce signatures in the intended way, users need to inspect the code installed in the canister. For this, it is crucial that canisters using VetKeys have their code public.

Expand All @@ -19,22 +22,42 @@ For confirming that the canister can only produce signatures in the intended way

### Prerequisites

- [Internet Computer software development kit](https://internetcomputer.org/docs/building-apps/getting-started/install)
- [ICP CLI](https://cli.internetcomputer.org)
- [npm](https://www.npmjs.com/package/npm)

### (Optionally) Choose a Different Master Key

This example uses `test_key_1` by default. To use a different [available master key](https://internetcomputer.org/docs/building-apps/network-features/vetkeys/api#available-master-keys), change the `"init_arg": "(\"test_key_1\")"` line in `dfx.json` to the desired key before running `dfx deploy` in the next step.
This example uses `test_key_1` by default. To use a different [available master key](https://docs.internetcomputer.org/concepts/vetkeys/#api-overview), change the `value: "(\"test_key_1\")"` line in `icp.yaml` to the desired key before running `icp deploy` in the next step.

### Folder Structure

This example provides both a **Rust** and a **Motoko** backend, sharing a common `frontend/`:

```
basic_bls_signing/
├── frontend/ ← shared frontend (symlinked into rust/ and motoko/)
├── motoko/ ← Motoko backend + icp.yaml
└── rust/ ← Rust backend + icp.yaml
```

### Deploy the Canisters Locally

If you want to deploy this project locally with a Motoko backend, then run:
Deploy with the **Motoko** backend:
```bash
dfx start --background && dfx deploy
cd motoko
icp network start -d && icp deploy
```
from the `motoko` folder.

To use the Rust backend instead of Motoko, run the same command in the `rust` folder.
Or deploy with the **Rust** backend:
```bash
cd rust
icp network start -d && icp deploy
```

When finished, stop the local network:
```bash
icp network stop
```

## Example Components

Expand All @@ -49,12 +72,14 @@ The backend consists of a canister that:

The frontend is a vanilla typescript application providing a simple interface for signing, showing the signatures stored in the canister, and publishing a signature.

To run the frontend in development mode with hot reloading (after running `dfx deploy`):

To run the frontend in development mode with hot reloading (after running `icp deploy`):
```bash
npm run dev
cd frontend
npm run dev:rust # if you deployed the Rust backend
# or
npm run dev:motoko # if you deployed the Motoko backend
```

## Additional Resources

- **[What are VetKeys](https://internetcomputer.org/docs/building-apps/network-features/encryption/vetkeys)** - For more information about VetKeys and VetKD.
- **[What are VetKeys](https://docs.internetcomputer.org/concepts/vetkeys)** - For more information about VetKeys and VetKD.
13 changes: 7 additions & 6 deletions rust/vetkeys/basic_bls_signing/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "npm run build:bindings && vite",
"dev": "printf '\\nNo backend specified. Use one of:\\n\\n npm run dev:motoko\\n npm run dev:rust\\n\\n' && exit 1",
"dev:motoko": "npm run build:bindings && BACKEND=motoko vite",
"dev:rust": "npm run build:bindings && BACKEND=rust vite",
"build": "npm run build:bindings && tsc && vite build",
"build:bindings": "cd scripts && ./gen_bindings.sh",
"preview": "vite preview",
Expand All @@ -20,12 +22,11 @@
"tslib": "^2.8.1",
"typescript": "~5.7.2",
"typescript-eslint": "^8.35.1",
"vite": "^6.4.1",
"vite-plugin-environment": "^1.1.3"
"vite": "^6.4.1"
},
"dependencies": {
"@dfinity/auth-client": "^2.4.1",
"@dfinity/principal": "^2.4.1",
"@dfinity/vetkeys": "^0.3.0"
"@icp-sdk/auth": "^7.1.0",
"@icp-sdk/core": "^5.4.0",
"@icp-sdk/vetkeys": "^0.5.0-beta.0"
}
}
28 changes: 17 additions & 11 deletions rust/vetkeys/basic_bls_signing/frontend/scripts/gen_bindings.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
#!/bin/bash
set -eu

cd ../../backend && make extract-candid
# Resolve the script's physical location so we work correctly even when the
# icp CLI has symlinked `frontend/` into a backend subdirectory for the build.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
FRONTEND_DIR="$(dirname "$SCRIPT_DIR")"
EXAMPLE_ROOT="$(dirname "$FRONTEND_DIR")"

cd .. && dfx generate basic_bls_signing || exit 1
# Bindings are always generated from the Rust backend since both backends
# expose the same Candid interface.
if command -v candid-extractor >/dev/null 2>&1; then
(cd "$EXAMPLE_ROOT/rust/backend" && make extract-candid)
fi

rm -r frontend/src/declarations/basic_bls_signing > /dev/null 2>&1 || true

mkdir -p frontend/src/declarations/basic_bls_signing
mv src/declarations/basic_bls_signing frontend/src/declarations
rmdir -p src/declarations > /dev/null 2>&1 || true

# dfx 0.31+ generates @icp-sdk/core imports; rewrite to @dfinity/* to match deps
find frontend/src/declarations -type f \( -name '*.ts' -o -name '*.js' \) -exec \
perl -i -pe 's|\@icp-sdk/core/agent|\@dfinity/agent|g; s|\@icp-sdk/core/principal|\@dfinity/principal|g; s|\@icp-sdk/core/candid|\@dfinity/candid|g' {} +
rm -rf "$FRONTEND_DIR/src/declarations/basic_bls_signing"
mkdir -p "$FRONTEND_DIR/src/declarations/basic_bls_signing"
npx --yes @icp-sdk/bindgen \
--did-file "$EXAMPLE_ROOT/rust/backend/backend.did" \
--out-dir "$FRONTEND_DIR/src/declarations/basic_bls_signing" \
--declarations-flat --force
Loading
Loading