Skip to content

Commit

Permalink
Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
kristoferlund committed Jan 31, 2024
1 parent f78199c commit 021ddce
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 38 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
8 changes: 8 additions & 0 deletions packages/ic-use-siwe-identity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
99 changes: 81 additions & 18 deletions packages/ic_siwe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 │ │
Expand All @@ -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) ┌┴┐ │
│ │ │ ─────────────────────────────────────────────>│ │ │
│ │ │ │ │ │
│ │ │ │ │────┐ │
Expand All @@ -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 │ │
Expand Down Expand Up @@ -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.
Expand Down
51 changes: 31 additions & 20 deletions packages/ic_siwe_provider/README.md
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.

Expand Down Expand Up @@ -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
Expand All @@ -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)

Expand All @@ -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.
Expand All @@ -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.

Expand All @@ -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.
Expand All @@ -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).
Expand Down Expand Up @@ -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.

0 comments on commit 021ddce

Please sign in to comment.