#internet-computer #solana #wallet #authentication #siws

ic_siws

将基于 Solana 钱包的认证(SIWS)集成到互联网计算机(ICP)平台上的应用程序中

1 个不稳定版本

0.0.1 2024 年 4 月 1 日

#105 in #internet-computer

MIT 许可证

320KB
1.5K SLoC

Sign in with Solana for the Internet Computer

Crate Docs

ic_siws 是一个 Rust 库,它简化了将基于 Solana 钱包的认证(SIWS)集成到互联网计算机(ICP)平台上的应用程序中的过程。该库提供了从生成 SIWS 消息到创建代表身份所需的所有工具。

ic_siwsic-siws 项目的组成部分。该项目的目标是增强 Solana 与互联网计算机平台之间的互操作性,使开发者能够构建利用两个平台优势的应用程序。

主要功能

  • Solana 钱包登录:为 ICP 应用程序启用 Solana 钱包登录。使用任何 eth 钱包登录以生成 ICP 身份和会话。
  • 会话身份唯一性:确保会话身份特定于每个应用程序的上下文,防止跨应用程序身份误用。
  • 一致的代表生成:保证使用 Solana 钱包登录始终生成相同的代表,无论使用哪个客户端。
  • 直接将 Solana 地址映射到代表:在当前应用程序范围内,在 Solana 地址和代表之间创建一对一的关联。
  • 时间限制的会话:允许开发者为会话设置过期时间,增强安全性和控制。

此外还有

ic-siwe - ic-siws 的姊妹项目,ic-siwe 为基于以太坊的应用程序提供相同的功能。

目录

预构建 ic_siws_provider canister

虽然 ic_siws 库可以与任何基于 Rust 的 ICP 项目集成,但使用预构建的 ic-siws-provider canister 是将 Solana 钱包认证集成到您应用程序中最简单的方法。

该罐体被设计为针对开发者的即插即用解决方案,使得将其轻松集成到现有的 ICP 应用程序中,且代码编写需求最小化。通过将预构建的 ic_siws_provider 罐体添加到 ICP 项目的 dfx.json 文件中,开发者可以快速启用基于 Solana 钱包的认证功能。该罐体通过管理 SIWS 消息的创建和验证以及处理用户会话管理来简化认证流程。

React 示例应用程序

一个使用 ic_siws_provider 罐体来演示完整登录流程的演示应用程序可在 ic-siws-react-demo-rust 找到。该演示使用来自 ic-siws 项目的另一个包,ic-use-siws-identity,这是一个 React 钩子和上下文提供程序,用于简化与启用 SIWS 的互联网计算机罐体的前端集成。

SIWS:使用 Solana 登录

“使用 Solana 登录”(SIWS)是 Solana 钱包的标准,在 Solana 生态系统中得到广泛支持。它允许用户使用他们的 Solana 钱包签署消息,以对 dapp 进行身份验证,通过标准化消息格式来简化认证流程,从而改善用户体验和安全。基于由 ERC-4361: 使用以太坊登录 建立的原则,SIWS 简化了认证流程,消除了传统连接 + 签名消息步骤的需求。

该协议的核心是 SIWS 消息,它是一个包含用户 Solana 地址和一些附加元数据的已签名消息。SIWS 消息由用户的 Solana 钱包签名,然后发送到应用程序的后端。后端验证签名和 Solana 地址,然后为用户创建一个会话。

ic_siws 实现了 Sign In with Solana 标准的大部分内容,但有几个值得注意的例外

  • nonce - SIWS 要求每个登录消息都有一个唯一的 nonce。在此实现中,nonce 并不向登录流程添加任何额外的安全性,并且默认禁用。如果需要随机 nonce,则可以启用 nonce 功能标志。当此功能启用时,nonce 使用加密安全的随机数生成器生成。

  • not-beforerequest-idresources - 未实现。这些字段在 SIWS 标准中标记为“可选”,目前尚未实现。

登录流程

使用 ic_siws 创建代表身份的三步过程包括以下步骤

  1. 准备登录
  2. 登录
  3. 获取委托

实现罐体可以根据自己的意愿实现这些步骤。然而,建议实现罐体遵循以下描述的登录流程并实现 SIWS 罐体接口。这样做确保罐体与 ic-use-siws-identity React 钩子和上下文提供程序兼容。

SIWS 罐体接口

type Address = text;
type CanisterPublicKey = PublicKey;
type PublicKey = blob;
type SessionKey = PublicKey;
type SiwsSignature = 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 SiwsMessage = record {
  domain : text;
  address : Address;
  statement : text;
  uri : text;
  version : nat32;
  chain_id : text;
  nonce : text;
  issued_at : nat64;
  expiration_time : nat64;
};

type PrepareLoginResponse = variant {
  Ok : SiwsMessage;
  Err : text;
};

service : (settings_input : SettingsInput) -> {
  "siws_prepare_login" : (Address) -> (PrepareLoginResponse);
  "siws_login" : (SiwsSignature, Address, SessionKey) -> (LoginResponse);
  "siws_get_delegation" : (Address, SessionKey, Timestamp) -> (GetDelegationResponse) query;
};

siws_prepare_login

  • 前端应用程序通过调用 siws_prepare_login 方法来启动登录流程。该方法接受用户的 Solana 地址作为参数,并返回一个 SIWS 消息。前端应用程序使用 SIWS 消息提示用户使用他们的 Solana 钱包签署消息。
  • 查看:login::prepare_login

登录

  • 前端应用程序在用户签名SIWS消息后调用login方法。该方法接受用户的Solana地址、签名和会话身份作为参数。该方法验证签名和Solana地址,并返回一个代理。
  • 参见:login::login

siws_get_delegation

登录流程如图所示

                                ┌────────┐                                        ┌────────┐                              ┌─────────┐
                                │Frontend│                                        │Canister│                              │SolWallet│
   User                         └───┬────┘                                        └───┬────┘                              └────┬────┘
    │      Push login button       ┌┴┐                                                │                                        │
    │ ────────────────────────────>│ │                                                │                                        │
    │                              │ │                                                │                                        │
    │                              │ │          siws_prepare_login(eth_address)      ┌┴┐                                       │
    │                              │ │ ─────────────────────────────────────────────>│ │                                       │
    │                              │ │                                               └┬┘                                       │
    │                              │ │                OK, siws_message                │                                        │
    │                              │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                        │
    │                              │ │                                                │                                        │
    │                              │ │                                   Sign siws_message                                    ┌┴┐
    │                              │ │ ──────────────────────────────────────────────────────────────────────────────────────>│ │
    │                              │ │                                                │                                       │ │
    │                              │ │                  Ask user to confirm           │                                       │ │
    │ <───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ │
    │                              │ │                                                │                                       │ │
    │                              │ │                          OK                    │                                       │ │
    │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ >│ │
    │                              │ │                                                │                                       └┬┘
    │                              │ │                                      OK, signature                                      │
    │                              │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
    │                              │ │                                                │                                        │
    │                              │ │────┐                                           │                                        │
    │                              │ │    │ Generate random session_identity          │                                        │
    │                              │ │<───┘                                           │                                        │
    │                              │ │                                                │                                        │
    │                              │ │             siws_login(eth_address,            │                                        │
    │                              │ │          signature, session_identity)         ┌┴┐                                       │
    │                              │ │ ─────────────────────────────────────────────>│ │                                       │
    │                              │ │                                               │ │                                       │
    │                              │ │                                               │ │────┐                                  │
    │                              │ │                                               │ │    │ Verify signature and eth_address │
    │                              │ │                                               │ │<───┘                                  │
    │                              │ │                                               │ │                                       │
    │                              │ │                                               │ │────┐                                  │
    │                              │ │                                               │ │    │ Prepare delegation               │
    │                              │ │                                               │ │<───┘                                  │
    │                              │ │                                               └┬┘                                       │
    │                              │ │     OK, canister_pubkey, delegation_expires    │                                        │
    │                              │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                        │
    │                              │ │                                                │                                        │
    │                              │ │     siws_get_delegation(delegation_expires)   ┌┴┐                                       │
    │                              │ │ ─────────────────────────────────────────────>│ │                                       │
    │                              │ │                                               └┬┘                                       │
    │                              │ │                 OK, delegation                 │                                        │
    │                              │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                        │
    │                              │ │                                                │                                        │
    │                              │ │────┐                                           │                                        │
    │                              │ │    │ Create delegation identity                │                                        │
    │                              │ │<───┘                                           │                                        │
    │                              └┬┘                                                │                                        │
    │ OK, logged in with            │                                                 │                                        │
    │ Principal niuiu-iuhbi...-oiu  │                                                 │                                        │
    │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                                  │                                        │
  User                          ┌───┴────┐                                        ┌───┴────┐                              ┌────┴────┐
                                │Frontend│                                        │Canister│                              │SolWallet│
                                └────────┘                                        └────────┘                              └─────────┘

crate 功能

库有一个默认禁用的可选功能。

  • nonce - 启用为SIWS消息生成nonces。此功能使用管理canister的种子初始化随机数生成器。然后使用随机数生成器为每个生成的SIWS消息生成唯一的nonces。nonces不会为SIWS登录流程添加任何额外的安全性,但符合SIWS标准。当此功能禁用时,nonce始终设置为十六进制编码的字符串Not in use

更新

有关更新的详细信息,请参阅CHANGELOG

贡献

欢迎贡献力量。请提交您的pull请求或打开问题以提出更改或报告错误。

作者

许可证

本项目采用MIT许可证。有关更多详细信息,请参阅LICENSE文件。

依赖关系

~8–18MB
~249K SLoC