| Crates.io | ic_sis |
| lib.rs | ic_sis |
| version | 0.2.1 |
| created_at | 2025-05-06 08:22:44.49531+00 |
| updated_at | 2025-06-19 23:54:21.246799+00 |
| description | Integrate Sui wallet-based authentication (SIS) with applications on the Internet Computer (ICP) platform. Supports BCS serialization, intent signing, and multiple signature schemes. |
| homepage | https://github.com/Talentum-id/ic_sis |
| repository | https://github.com/Talentum-id/ic_sis |
| max_upload_size | |
| id | 1661986 |
| size | 451,227 |
ic_sis is a Rust library that facilitates the integration of Sui wallet-based authentication with applications on the Internet Computer (ICP) platform. The library provides all necessary tools for integrating Sign-In with Sui (SIS) into ICP canisters, from generating SIS messages to creating delegate identities.
ic_sis enhances the interoperability between Sui and the Internet Computer platform, enabling developers to build applications that leverage the strengths of both platforms.
ic_sis_provider canisterWhile the ic_sis library can be integrated with any Rust-based ICP project, using the pre-built ic_sis_provider canister is the easiest way to integrate Sui wallet authentication into your 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_sis_provider canister to the dfx.json of an ICP project, developers can quickly enable Sui wallet-based authentication for their applications. The canister simplifies the authentication flow by managing the creation and verification of SIS messages and handling user session management.
Sign-In with Sui (SIS) is a protocol for off-chain authentication of Sui accounts. The protocol is designed to enable Sui wallet-based authentication for applications on other platforms, such as the Internet Computer. At the core of the protocol is the SIS message, which is a signed message that contains the Sui address of the user and additional metadata. The SIS message is signed by the user's Sui wallet using one of the supported signature schemes and then sent to the application's backend. The backend verifies the signature and Sui address and then creates a session for the user.
The SIS protocol leverages Sui's multiple signature schemes, including:
Each signature includes a scheme flag, the signature bytes, and the public key bytes, all properly formatted according to Sui's standards.
Creating a delegate identity using ic_sis is a three-step process:
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 SIS canister interface.
The login flow is illustrated in the following diagram:
┌────────┐ ┌────────┐ ┌────────┐
│Frontend│ │Canister│ │SuiWallet│
User └───┬────┘ └───┬────┘ └────┬────┘
│ Push login button ┌┴┐ │ │
│ ────────────────────────────>│ │ │ │
│ │ │ │ │
│ │ │ sis_prepare_login(sui_address) ┌┴┐ │
│ │ │ ─────────────────────────────────────────────>│ │ │
│ │ │ └┬┘ │
│ │ │ OK, sis_message │ │
│ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │ │ │ │
│ │ │ Sign sis_message ┌┴┐
│ │ │ ──────────────────────────────────────────────────────────────────────────────────────>│ │
│ │ │ │ │ │
│ │ │ Ask user to confirm │ │ │
│ <───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ │
│ │ │ │ │ │
│ │ │ OK │ │ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ >│ │
│ │ │ │ └┬┘
│ │ │ OK, signature │
│ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
│ │ │ │ │
│ │ │────┐ │ │
│ │ │ │ Generate random session_identity │ │
│ │ │<───┘ │ │
│ │ │ │ │
│ │ │ sis_login(sui_address, │ │
│ │ │ signature, session_identity) ┌┴┐ │
│ │ │ ─────────────────────────────────────────────>│ │ │
│ │ │ │ │ │
│ │ │ │ │────┐ │
│ │ │ │ │ │ Verify signature with intent │
│ │ │ │ │<───┘ │
│ │ │ │ │ │
│ │ │ │ │────┐ │
│ │ │ │ │ │ Prepare delegation │
│ │ │ │ │<───┘ │
│ │ │ └┬┘ │
│ │ │ OK, canister_pubkey, delegation_expires │ │
│ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │ │ │ │
│ │ │ sis_get_delegation(delegation_expires) ┌┴┐ │
│ │ │ ─────────────────────────────────────────────>│ │ │
│ │ │ └┬┘ │
│ │ │ OK, delegation │ │
│ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │ │ │ │
│ │ │────┐ │ │
│ │ │ │ Create delegation identity │ │
│ │ │<───┘ │ │
│ └┬┘ │ │
│ OK, logged in with │ │ │
│ Principal niuiu-iuhbi...-oiu │ │ │
│ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
User ┌───┴────┐ ┌───┴────┐ ┌────┴────┐
│Frontend│ │Canister│ │SuiWallet│
└────────┘ └────────┘ └─────────┘
sis_prepare_loginInitiates the login flow by creating a SIS message:
pub fn prepare_login(address: &SuiAddress) -> Result
sis_loginVerifies the signed message and creates a session:
pub fn login(
signature: &SuiSignature,
address: &SuiAddress,
session_key: ByteBuf,
signature_map: &mut SignatureMap,
canister_id: &Principal,
nonce: &str,
) -> Result
sis_get_delegationRetrieves the delegation for authenticated access:
generate_seed, create_delegation, witness, etc.// Signature verification with BCS and intent signing
pub fn verify_sui_signature(
blake2b_hash: &[u8],
signature: &SuiSignature,
) -> Result;
// Intent hash creation for authentication
pub fn create_auth_intent_hash(message: &[u8]) -> Result<Vec, SuiError>;
// Address derivation from public key
pub fn derive_sui_address_from_public_key(
scheme: u8,
public_key: &[u8]
) -> Result;
// Create SIS message with BCS serialization
let message = SisMessage::new(&address, &nonce);
// Get BCS bytes for signing
let bcs_bytes = message.to_sign_bytes();
// Create intent hash for verification
let intent_hash = message.create_intent_message();
use ic_sis::{
settings::SettingsBuilder,
sui::{SuiAddress, SuiSignature},
login::{prepare_login, login},
init,
};
// Initialize library
let settings = SettingsBuilder::new(
"myapp.com",
"https://myapp.com",
"unique_salt"
).network("mainnet").build()?;
init(settings)?;
// 1. Prepare login
let address = SuiAddress::new("0x1234...")?;
let (sis_message, nonce) = prepare_login(&address)?;
// 2. User signs message with wallet (frontend)
// let signature = wallet.sign(sis_message.to_human_readable());
// 3. Verify and login
let signature = SuiSignature::from_hex("0x00...")?;
let login_details = login(
&signature,
&address,
session_key,
&mut signature_map,
&canister_id,
&nonce,
)?;
// Create message and serialize with BCS
let message = SisMessage::new(&address, &nonce);
// BCS serialization (recommended)
let bcs_bytes = message.to_sign_bytes();
// Validate BCS compatibility
message.validate_bcs_serialization()?;
// Compare with JSON (debugging)
let (bcs, json) = message.compare_serializations();
println!("BCS: {} bytes, JSON: {} bytes", bcs.len(), json.len());
See the CHANGELOG for details on updates.
Contributions are welcome! Please feel free to submit pull requests or open issues to propose changes or report bugs.
cargo test
cargo test -- --nocapture
cargo fmt --check
cargo clippy -- -D warnings
This project is licensed under the MIT License. See the LICENSE file for more details.