A developer-friendly & framework-agnostic Rust client for the Mysten Seal encryption system. The
crate works with any Sui setup: keep the default stack (SealClient) or swap in
your own HTTP transport, Sui client, signer, and cache.
- Modular
BaseSealClientso you can replace each layer. - Ready-to-use
SealClientspecializations forsui_sdk::SuiClientandreqwest(with optionalmokacaching). - Session keys act like short-lived JWTs, so wallets do not sign every request.
- Encryption helpers return recovery keys for break-glass scenarios.
- Bridging types let you use both
MystenLabs/suiandsui-rust-sdkAPIs.
A comprehensive guide is available here.
Use the git dependency and set the tag to the desired crate version in MAJOR.MINOR.PATCH format.
[dependencies]
seal-sdk-rs = { git = "https://github.com/gfusee/seal-sdk-rs", tag = "0.0.5" }A full detailed flow is available in the guide.
use seal_sdk_rs::base_client::KeyServerConfig;
use seal_sdk_rs::native_sui_sdk::client::seal_client::SealClient;
use seal_sdk_rs::session_key::SessionKey;
use std::str::FromStr;
use std::collections::HashMap;
use seal_sdk_rs::generic_types::ObjectID;
use seal_sdk_rs::native_sui_sdk::sui_sdk::SuiClientBuilder;
use seal_sdk_rs::native_sui_sdk::sui_sdk::wallet_context::WalletContext;
use seal_sdk_rs::native_sui_sdk::sui_types::Identifier;
use seal_sdk_rs::native_sui_sdk::sui_types::programmable_transaction_builder::ProgrammableTransactionBuilder;
async fn encrypt_and_decrypt(
package_id: ObjectID,
key_server_id: ObjectID,
) -> anyhow::Result<()> {
let sui_client = SuiClientBuilder::default()
.build("https://fullnode.testnet.sui.io:443")
.await?;
let client = SealClient::new(sui_client);
let (encrypted, _) = client
.encrypt_bytes(
package_id,
b"demo-id".to_vec(),
1,
vec![KeyServerConfig::new(key_server_id, None)],
b"hello seal".to_vec(),
)
.await?;
let mut wallet = WalletContext::new("<path to the config file>".as_ref()).unwrap();
let session_key = SessionKey::new(package_id, 5, &mut wallet).await?;
let mut builder = ProgrammableTransactionBuilder::new();
let id_arg = builder.pure(b"demo-id".to_vec())?;
builder.programmable_move_call(
package_id.into(),
Identifier::from_str("wildcard")?,
Identifier::from_str("seal_approve")?,
vec![],
vec![id_arg],
);
let plaintext = client
.decrypt_object_bytes(&bcs::to_bytes(&encrypted)?, builder.finish(), &session_key, HashMap::new())
.await?;
assert_eq!(plaintext, b"hello seal");
Ok(())
}BaseSealClientaccepts custom HTTP, Sui, cache, and error types.SealClientLeakingCacheandSealClientMokaCacheshow different cache strategies.SessionKeylets wallets sign once per TTL window (JWT analogy).- Encrypt helpers return
(EncryptedObject, [u8; 32])so you can decide what to do with the recovery key. - Bridging traits (
ObjectID,SuiAddress,BCSSerializableProgrammableTransaction) let you mix Sui SDK ecosystems.
Integration tests spin up a Sui localnet and a flexible number of Seal servers. Some scenarios crash servers on purpose so the suite covers failure paths and recovery behaviour.
- Implement
SuiClientto target a different Sui SDK version. - Implement
HttpClientfor a custom transport (only apostmethod is required). - Implement
SealCachefor your own cache (add request coalescing if you can). - Implement
Signerwhen you want to mint session keys withoutWalletContext.
| Feature | Description |
|---|---|
client |
Enables reqwest + HTTP abstractions. Included by default. |
native-tls |
Uses native TLS with reqwest. Included by default. |
native-sui-sdk |
Pulls in the MystenLabs/sui crates and adapters. Included by default. |
moka-client |
Adds the SealClientMokaCache specialization. |
Disable the default features if you plan to provide your own stack.
See CONTRIBUTING.md.