-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f78199c
commit 021ddce
Showing
4 changed files
with
127 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,13 @@ See the respective package CHANGELOG for details on updates. | |
|
||
Contributions are welcome. Please submit your pull requests or open issues to propose changes or report bugs. | ||
|
||
## Author | ||
|
||
- [[email protected]](mailto:[email protected]) | ||
- Twitter: [@kristoferlund](https://twitter.com/kristoferlund) | ||
- Discord: kristoferkristofer | ||
- Telegram: [@kristoferkristofer](https://t.me/kristoferkristofer) | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the LICENSE file for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ A SIWE enabled canister is a canister that integrates the [ic_siwe](https://gith | |
- [SiweIdentityProvider props](#siweidentityprovider-props) | ||
- [useSiweIdentity interface](#usesiweidentity-interface) | ||
- [Contributing](#contributing) | ||
- [Author](#author) | ||
- [License](#license) | ||
|
||
## Installation | ||
|
@@ -216,6 +217,13 @@ export type SiweIdentityContextType = { | |
|
||
Contributions are welcome. Please submit your pull requests or open issues to propose changes or report bugs. | ||
|
||
## Author | ||
|
||
- [[email protected]](mailto:[email protected]) | ||
- Twitter: [@kristoferlund](https://twitter.com/kristoferlund) | ||
- Discord: kristoferkristofer | ||
- Telegram: [@kristoferkristofer](https://t.me/kristoferkristofer) | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the LICENSE file for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,12 +22,14 @@ | |
- [React demo application](#react-demo-application) | ||
- [The SIWE Standard](#the-siwe-standard) | ||
- [Login flow](#login-flow) | ||
- [`prepare_login`](#prepare_login) | ||
- [`login`](#login) | ||
- [`get_delegation`](#get_delegation) | ||
- [SIWE canister interface](#siwe-canister-interface) | ||
- [`siwe_prepare_login`](#siwe_prepare_login) | ||
- [`siwe_login`](#siwe_login) | ||
- [`siwe_get_delegation`](#siwe_get_delegation) | ||
- [Crate features](#crate-features) | ||
- [Updates](#updates) | ||
- [Contributing](#contributing) | ||
- [Author](#author) | ||
- [License](#license) | ||
|
||
## Prebuilt `ic_siwe_provider` canister | ||
|
@@ -55,36 +57,89 @@ The SIWE standard defines a protocol for off-chain authentication of Ethereum ac | |
|
||
## Login flow | ||
|
||
Three canister methods need to be exposed to implement the login flow: `prepare_login`, `login`, and `get_delegation`. | ||
Creating a delegate identity using `ic_siwe` is a three-step process that consists of the following steps: | ||
1. Prepare login | ||
2. Login | ||
3. Get delegation | ||
|
||
### `prepare_login` | ||
An implementing canister is free to implement these steps in any way it sees fit. It is recommended though that implementing canisters follow the login flow described below and implement the SIWE canister interface. Doing ensures that the canister is compatible with the [ic-use-siwe-identity](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic-use-siwe-identity) React hook and context provider. | ||
|
||
- The `prepare_login` method is called by the frontend application to initiate the login flow. The method takes the user's Ethereum address as a parameter and returns a SIWE message. The frontend application uses the SIWE message to prompt the user to sign the message with their Ethereum wallet. | ||
- See: [`login::prepare_login`] | ||
### SIWE canister interface | ||
|
||
### `login` | ||
```text | ||
type Address = text; | ||
type CanisterPublicKey = PublicKey; | ||
type PublicKey = blob; | ||
type SessionKey = PublicKey; | ||
type SiweMessage = text; | ||
type SiweSignature = text; | ||
type Timestamp = nat64; | ||
type GetDelegationResponse = variant { | ||
Ok : SignedDelegation; | ||
Err : text; | ||
}; | ||
type SignedDelegation = record { | ||
delegation : Delegation; | ||
signature : blob; | ||
}; | ||
type Delegation = record { | ||
pubkey : PublicKey; | ||
expiration : Timestamp; | ||
targets : opt vec principal; | ||
}; | ||
type LoginResponse = variant { | ||
Ok : LoginDetails; | ||
Err : text; | ||
}; | ||
type LoginDetails = record { | ||
expiration : Timestamp; | ||
user_canister_pubkey : CanisterPublicKey; | ||
}; | ||
type PrepareLoginResponse = variant { | ||
Ok : SiweMessage; | ||
Err : text; | ||
}; | ||
service : (settings_input : SettingsInput) -> { | ||
"siwe_prepare_login" : (Address) -> (PrepareLoginResponse); | ||
"siwe_login" : (SiweSignature, Address, SessionKey) -> (LoginResponse); | ||
"siwe_get_delegation" : (Address, SessionKey, Timestamp) -> (GetDelegationResponse) query; | ||
}; | ||
``` | ||
|
||
### `siwe_prepare_login` | ||
|
||
- The `siwe_prepare_login` method is called by the frontend application to initiate the login flow. The method takes the user's Ethereum address as a parameter and returns a SIWE message. The frontend application uses the SIWE message to prompt the user to sign the message with their Ethereum wallet. | ||
- See: [`login::prepare_login`](src/login.rs) | ||
|
||
- The `login` method is called by the frontend application after the user has signed the SIWE message. The method takes the user's Ethereum address, signature, and session identity as parameters. The method verifies the signature and Ethereum address and returns a delegation. | ||
- See: [`login::login`] | ||
### `siwe_login` | ||
|
||
### `get_delegation` | ||
- The `siwe_login` method is called by the frontend application after the user has signed the SIWE message. The method takes the user's Ethereum address, signature, and session identity as parameters. The method verifies the signature and Ethereum address and returns a delegation. | ||
- See: [`login::login`](src/login.rs) | ||
|
||
- The `get_delegation` method is called by the frontend application after a successful login. The method takes the delegation expiration time as a parameter and returns a delegation. | ||
- The `get_delegation` method is not mirrored by one function in the `ic_siwe` library. The creation of delegate identities requires setting the certified data of the canister. This should not be done by the library, but by the implementing canister. | ||
- Creating a delegate identity involves interacting with the following `ic_siwe` functions: [`delegation::generate_seed`],[`delegation::create_delegation`], [`delegation::create_delegation_hash`], [`delegation::witness`], [`delegation::create_certified_signature`]. | ||
### `siwe_get_delegation` | ||
|
||
- The `siwe_get_delegation` method is called by the frontend application after a successful login. The method takes the delegation expiration time as a parameter and returns a delegation. | ||
- The `siwe_get_delegation` method is not mirrored by one function in the `ic_siwe` library. The creation of delegate identities requires setting the certified data of the canister. This should not be done by the library, but by the implementing canister. | ||
- Creating a delegate identity involves interacting with the following `ic_siwe` functions: [`delegation::generate_seed`](src/delegation.rs),[`delegation::create_delegation`](src/delegation.rs), [`delegation::create_delegation_hash`](src/delegation.rs), [`delegation::witness`](src/delegation.rs), [`delegation::create_certified_signature`](src/delegation.rs). | ||
- For a full implementation example, see the [`ic_siwe_provider`](https://github.com/kristoferlund/ic-siwe/tree/main/packages/ic_siwe_provider) canister. | ||
|
||
The login flow is illustrated in the following diagram: | ||
|
||
```text | ||
┌────────┐ ┌────────┐ ┌─────────┐ | ||
│Frontend│ │Canister│ │EthWallet│ | ||
User └───┬────┘ └───┬────┘ └────┬────┘ | ||
│ Push login button ┌┴┐ │ │ | ||
│ ────────────────────────────>│ │ │ │ | ||
│ │ │ │ │ | ||
│ │ │ prepare_login(eth_address) ┌┴┐ │ | ||
│ │ │ siwe_prepare_login(eth_address) ┌┴┐ │ | ||
│ │ │ ─────────────────────────────────────────────>│ │ │ | ||
│ │ │ └┬┘ │ | ||
│ │ │ OK, siwe_message │ │ | ||
|
@@ -106,7 +161,8 @@ The login flow is illustrated in the following diagram: | |
│ │ │ │ Generate random session_identity │ │ | ||
│ │ │<───┘ │ │ | ||
│ │ │ │ │ | ||
│ │ │login(eth_address, signature, session_identity)┌┴┐ │ | ||
│ │ │ siwe_login(eth_address, │ │ | ||
│ │ │ signature, session_identity) ┌┴┐ │ | ||
│ │ │ ─────────────────────────────────────────────>│ │ │ | ||
│ │ │ │ │ │ | ||
│ │ │ │ │────┐ │ | ||
|
@@ -120,7 +176,7 @@ The login flow is illustrated in the following diagram: | |
│ │ │ OK, canister_pubkey, delegation_expires │ │ | ||
│ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ | ||
│ │ │ │ │ | ||
│ │ │ get_delegation(delegation_expires) ┌┴┐ │ | ||
│ │ │ siwe_get_delegation(delegation_expires) ┌┴┐ │ | ||
│ │ │ ─────────────────────────────────────────────>│ │ │ | ||
│ │ │ └┬┘ │ | ||
│ │ │ OK, delegation │ │ | ||
|
@@ -152,6 +208,13 @@ See the [CHANGELOG](CHANGELOG.md) for details on updates. | |
|
||
Contributions are welcome. Please submit your pull requests or open issues to propose changes or report bugs. | ||
|
||
## Author | ||
|
||
- [[email protected]](mailto:[email protected]) | ||
- Twitter: [@kristoferlund](https://twitter.com/kristoferlund) | ||
- Discord: kristoferkristofer | ||
- Telegram: [@kristoferkristofer](https://t.me/kristoferkristofer) | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the LICENSE file for more details. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
![Sign in with Ethereum for the Internet Computer](/media/header.png) | ||
|
||
Using the pre built `ic_siwe_provider` canister is the easiest way to integrate Ethereum wallet authentication into your [Internet Computer](https://internetcomputer.org) (ICP) application. | ||
Using the pre built `ic_siwe_provider` canister is the easiest way to integrate Ethereum wallet authentication into an [Internet Computer](https://internetcomputer.org) (ICP) application. | ||
|
||
The canister is designed as a plug-and-play solution for developers, enabling easy integration into existing ICP applications with minimal coding requirements. By adding the pre built `ic_siwe_provider` canister to the `dfx.json` of an ICP project, developers can quickly enable Ethereum wallet-based authentication for their applications. The canister simplifies the authentication flow by managing the creation and verification of SIWE messages and handling user session management. | ||
|
||
|
@@ -113,7 +113,7 @@ function App() { | |
|
||
### 4. Use the `useSiweIdentity` hook | ||
|
||
Use the useSiweIdentity hook to initiate the login process: | ||
Use the `useSiweIdentity`` hook to initiate the login process: | ||
|
||
```jsx | ||
// Component.tsx | ||
|
@@ -128,7 +128,7 @@ function MyComponent() { | |
|
||
## Service Interface | ||
|
||
The `ic_siwe_provider` canister exposes the following endpoints: | ||
In addition to the SIWE endpoints, required by the `useSiweIdentity` hook, this canister also exposes endpoints to retrieve the Ethereum address associated with a given ICP principal and vice versa. These endpoints are useful for applications that need to map ICP Principals to Ethereum addresses. | ||
|
||
### [get_address](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/get_address.rs) | ||
|
||
|
@@ -143,14 +143,6 @@ The `ic_siwe_provider` canister exposes the following endpoints: | |
- **Purpose**: Retrieves the Ethereum address associated with the caller. This is a convenience function that internally calls `get_address`. | ||
- **Output**: Same as `get_address`. | ||
|
||
### [get_delegation](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/get_delegation.rs) | ||
|
||
- **Purpose**: Fetches the delegation to be used for authentication once the user is logged in. | ||
- **Input**: Ethereum address (`String`), session key (`ByteBuf`), and expiration timestamp (`u64`). | ||
- **Output**: | ||
- `Ok(SignedDelegation)`: The delegation if the process is successful. | ||
- `Err(String)`: An error message if there is a failure in fetching the delegation. | ||
|
||
### [get_principal](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/get_principal.rs) | ||
|
||
- **Purpose**: Retrieves the principal associated with the given Ethereum address. | ||
|
@@ -159,21 +151,30 @@ The `ic_siwe_provider` canister exposes the following endpoints: | |
- `Ok(ByteBuf)`: The principal if found. | ||
- `Err(String)`: An error message if the address cannot be converted or no principal is found. | ||
|
||
### [login](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/login.rs) | ||
|
||
### [siwe_prepare_login](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/siwe_prepare_login.rs) | ||
|
||
- **Purpose**: Generates a SIWE message challenge and returns it to the caller, initiating the login process. | ||
- **Input**: Ethereum address (`String`). | ||
- **Output**: | ||
- `Ok(String)`: The SIWE message challenge. | ||
- `Err(String)`: An error message if there is an error in preparing the login. | ||
|
||
### [siwe_login](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/siwe_login.rs) | ||
|
||
- **Purpose**: Verifies the signature of the SIWE message and prepares the delegation for authentication. | ||
- **Input**: Signature (`String`), Ethereum address (`String`), and session key (`ByteBuf`). | ||
- **Output**: | ||
- `Ok(LoginOkResponse)`: The public key and other login response data if the login is successful. | ||
- `Ok(LoginDetails)`: The public key and other login response data if the login is successful. | ||
- `Err(String)`: An error message if the login process fails. | ||
|
||
### [prepare_login](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/prepare_login.rs) | ||
### [siwe_get_delegation](https://github.com/kristoferlund/ic-siwe/blob/main/packages/ic_siwe_provider/src/service/siwe_get_delegation.rs) | ||
|
||
- **Purpose**: Generates a SIWE message challenge and returns it to the caller, initiating the login process. | ||
- **Input**: Ethereum address (`String`). | ||
- **Purpose**: Fetches the delegation to be used for authentication once the user is logged in. | ||
- **Input**: Ethereum address (`String`), session key (`ByteBuf`), and expiration timestamp (`u64`). | ||
- **Output**: | ||
- `Ok(String)`: The SIWE message challenge. | ||
- `Err(String)`: An error message if there is an error in preparing the login. | ||
- `Ok(SignedDelegation)`: The delegation if the process is successful. | ||
- `Err(String)`: An error message if there is a failure in fetching the delegation. | ||
|
||
In addition to the key functionalities for Ethereum wallet authentication, the `ic_siwe_provider` canister includes initialization and upgrade endpoints essential for setting up and maintaining the canister. | ||
|
||
|
@@ -191,10 +192,12 @@ In addition to the key functionalities for Ethereum wallet authentication, the ` | |
|
||
## Data Structures | ||
|
||
The `ic_siwe_provider` canister uses several data structures to facilitate the Ethereum wallet authentication process. These data structures are defined in the `ic_siwe` library and are used by the `ic_siwe_provider` canister. | ||
|
||
|
||
### SettingsInput | ||
|
||
Defines the settings that controls the behavior of the `ic_siwe_provider` canister. | ||
|
||
```rust | ||
pub struct SettingsInput { | ||
// The domain from where the frontend that uses SIWE is served. | ||
|
@@ -203,7 +206,8 @@ pub struct SettingsInput { | |
// The full URI, potentially including port number of the frontend that uses SIWE. | ||
pub uri: String, | ||
|
||
// The salt is used when generating the seed that uniquely identifies each user principal. | ||
// The salt is used when generating the seed that uniquely identifies each user principal. The salt can only contain | ||
/// printable ASCII characters. | ||
pub salt: String, | ||
|
||
// Optional. The Ethereum chain ID for ic_siwe, defaults to 1 (Ethereum mainnet). | ||
|
@@ -235,6 +239,13 @@ See the [CHANGELOG](CHANGELOG.md) for details on updates. | |
|
||
Contributions are welcome. Please submit your pull requests or open issues to propose changes or report bugs. | ||
|
||
## Author | ||
|
||
- [[email protected]](mailto:[email protected]) | ||
- Twitter: [@kristoferlund](https://twitter.com/kristoferlund) | ||
- Discord: kristoferkristofer | ||
- Telegram: [@kristoferkristofer](https://t.me/kristoferkristofer) | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the LICENSE file for more details. |