メインコンテンツまでスキップ

「decentralized storage」タグの記事が1件件あります

全てのタグを見る

@mysten/sealで分散暗号化を構築する:開発者向けチュートリアル

· 約16分
Dora Noda
Software Engineer

プライバシーは公共インフラになりつつあります。2025年、開発者にはデータ保存と同じくらい簡単に暗号化を行うツールが必要です。Mysten LabsのSealは、まさにそれを提供します—オンチェーンアクセス制御を備えた分散シークレット管理。このチュートリアルでは、アイデンティティベース暗号化、閾値セキュリティ、プログラマブルアクセスポリシーを使用して安全なWeb3アプリケーションを構築する方法を教えます。


導入:なぜSealがWeb3にとって重要なのか

従来のクラウドアプリケーションは、単一のプロバイダーが暗号化データへのアクセスを制御する集中型キー管理システムに依存しています。便利ですが、これは危険な単一障害点を作り出します。プロバイダーが侵害されたり、オフラインになったり、アクセスを制限することを決定した場合、あなたのデータはアクセス不可能または脆弱になります。

Sealは、このパラダイムを完全に変えます。Mysten LabsがSuiブロックチェーン向けに構築したSealは、分散シークレット管理(DSM)サービスで、以下を可能にします:

  • アイデンティティベース暗号化:コンテンツが環境を離れる前に保護される
  • 閾値暗号化:複数の独立したノード間でキーアクセスを分散
  • オンチェーンアクセス制御:タイムロック、トークンゲーティング、カスタム認証ロジック
  • ストレージ非依存設計:Walrus、IPFS、または任意のストレージソリューションと連携

安全なメッセージングアプリ、ゲート付きコンテンツプラットフォーム、タイムロック資産転送を構築する場合、Sealは必要な暗号プリミティブとアクセス制御インフラストラクチャを提供します。


はじめに

前提条件

開始する前に、以下があることを確認してください:

  • Node.js 18+がインストールされていること
  • TypeScript/JavaScriptの基本的な知識
  • テスト用のSuiウォレット(Sui Walletなど)
  • ブロックチェーンの概念の理解

インストール

npm経由でSeal SDKをインストールします:

npm install @mysten/seal

ブロックチェーンインタラクション用にSui SDKも必要です:

npm install @mysten/sui

プロジェクトセットアップ

新しいプロジェクトを作成し、初期化します:

mkdir seal-tutorial
cd seal-tutorial
npm init -y
npm install @mysten/seal @mysten/sui typescript @types/node

シンプルなTypeScript設定を作成します:

// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

コアコンセプト:Sealの仕組み

コードを書く前に、Sealのアーキテクチャを理解しましょう:

1. アイデンティティベース暗号化(IBE)

公開キーに暗号化する従来の暗号化とは異なり、IBEではアイデンティティ(メールアドレスやSuiアドレスなど)に暗号化できます。受信者は、そのアイデンティティを制御していることを証明できる場合にのみ復号化できます。

2. 閾値暗号化

単一のキーサーバーを信頼する代わりに、Sealはt-of-n閾値スキームを使用します。3-of-5キーサーバーを設定することで、任意の3つのサーバーが協力して復号化キーを提供できますが、2つ以下では不可能です。

3. オンチェーンアクセス制御

アクセスポリシーはSuiスマートコントラクトによって強制されます。キーサーバーが復号化キーを提供する前に、要求者がオンチェーンポリシー要件(トークン所有権、時間制約など)を満たしていることを確認します。

4. キーサーバーネットワーク

分散キーサーバーはアクセスポリシーを検証し、復号化キーを生成します。これらのサーバーは、単一の制御点を確保しないよう、異なる当事者によって運営されます。


基本実装:最初のSealアプリケーション

Suiブロックチェーンポリシーを通じてアクセスを制御し、機密データを暗号化するシンプルなアプリケーションを構築しましょう。

ステップ1:Sealクライアントの初期化

// src/seal-client.ts
import { SealClient } from '@mysten/seal';
import { SuiClient } from '@mysten/sui/client';

export async function createSealClient() {
// テストネット用のSuiクライアントを初期化
const suiClient = new SuiClient({
url: 'https://fullnode.testnet.sui.io'
});

// テストネットキーサーバーでSealクライアントを設定
const sealClient = new SealClient({
suiClient,
keyServers: [
'https://keyserver1.seal-testnet.com',
'https://keyserver2.seal-testnet.com',
'https://keyserver3.seal-testnet.com'
],
threshold: 2, // 2-of-3閾値
network: 'testnet'
});

return { sealClient, suiClient };
}

ステップ2:シンプルな暗号化/復号化

// src/basic-encryption.ts
import { createSealClient } from './seal-client';

async function basicExample() {
const { sealClient } = await createSealClient();

// 暗号化するデータ
const sensitiveData = "これは私の秘密メッセージです!";
const recipientAddress = "0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";

try {
// 特定のSuiアドレス用にデータを暗号化
const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, 'utf-8'),
recipientId: recipientAddress,
// オプション:メタデータを追加
metadata: {
contentType: 'text/plain',
timestamp: Date.now()
}
});

console.log('暗号化されたデータ:', {
ciphertext: encryptedData.ciphertext.toString('base64'),
encryptionId: encryptedData.encryptionId
});

// 後でデータを復号化(適切な認証が必要)
const decryptedData = await sealClient.decrypt({
ciphertext: encryptedData.ciphertext,
encryptionId: encryptedData.encryptionId,
recipientId: recipientAddress
});

console.log('復号化されたデータ:', decryptedData.toString('utf-8'));

} catch (error) {
console.error('暗号化/復号化に失敗しました:', error);
}
}

basicExample();

Suiスマートコントラクトによるアクセス制御

Sealの真の力は、プログラマブルアクセス制御にあります。特定の時間後にのみデータを復号化できるタイムロック暗号化の例を作成しましょう。

ステップ1:アクセス制御コントラクトのデプロイ

まず、アクセスポリシーを定義するMoveスマートコントラクトが必要です:

// contracts/time_lock.move
module time_lock::policy {
use sui::clock::{Self, Clock};
use sui::object::{Self, UID};
use sui::tx_context::{Self, TxContext};

public struct TimeLockPolicy has key, store {
id: UID,
unlock_time: u64,
authorized_user: address,
}

public fun create_time_lock(
unlock_time: u64,
authorized_user: address,
ctx: &mut TxContext
): TimeLockPolicy {
TimeLockPolicy {
id: object::new(ctx),
unlock_time,
authorized_user,
}
}

public fun can_decrypt(
policy: &TimeLockPolicy,
user: address,
clock: &Clock
): bool {
let current_time = clock::timestamp_ms(clock);
policy.authorized_user == user && current_time >= policy.unlock_time
}
}

ステップ2:Sealとの統合

// src/time-locked-encryption.ts
import { createSealClient } from './seal-client';
import { TransactionBlock } from '@mysten/sui/transactions';

async function createTimeLocked() {
const { sealClient, suiClient } = await createSealClient();

// Sui上でアクセスポリシーを作成
const txb = new TransactionBlock();

const unlockTime = Date.now() + 60000; // 1分後にアンロック
const authorizedUser = "0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8";

txb.moveCall({
target: 'time_lock::policy::create_time_lock',
arguments: [
txb.pure(unlockTime),
txb.pure(authorizedUser)
]
});

// ポリシーを作成するトランザクションを実行
const result = await suiClient.signAndExecuteTransactionBlock({
transactionBlock: txb,
signer: yourKeypair, // あなたのSuiキーペア
});

const policyId = result.objectChanges?.find(
change => change.type === 'created'
)?.objectId;

// このポリシーで暗号化
const sensitiveData = "これは1分後にアンロックされます!";

const encryptedData = await sealClient.encrypt({
data: Buffer.from(sensitiveData, 'utf-8'),
recipientId: authorizedUser,
accessPolicy: {
policyId,
policyType: 'time_lock'
}
});

console.log('タイムロックされたデータが作成されました。1分後に復号化を試してください。');

return {
encryptedData,
policyId,
unlockTime
};
}

実用的な例

例1:安全なメッセージングアプリケーション

// src/secure-messaging.ts
import { createSealClient } from './seal-client';

class SecureMessenger {
private sealClient: any;

constructor(sealClient: any) {
this.sealClient = sealClient;
}

async sendMessage(
message: string,
recipientAddress: string,
senderKeypair: any
) {
const messageData = {
content: message,
timestamp: Date.now(),
sender: senderKeypair.toSuiAddress(),
messageId: crypto.randomUUID()
};

const encryptedMessage = await this.sealClient.encrypt({
data: Buffer.from(JSON.stringify(messageData), 'utf-8'),
recipientId: recipientAddress,
metadata: {
type: 'secure_message',
sender: senderKeypair.toSuiAddress()
}
});

// 暗号化されたメッセージを分散ストレージ(Walrus)に保存
return this.storeOnWalrus(encryptedMessage);
}

async readMessage(encryptionId: string, recipientKeypair: any) {
// ストレージから取得
const encryptedData = await this.retrieveFromWalrus(encryptionId);

// Sealで復号化
const decryptedData = await this.sealClient.decrypt({
ciphertext: encryptedData.ciphertext,
encryptionId: encryptedData.encryptionId,
recipientId: recipientKeypair.toSuiAddress()
});

return JSON.parse(decryptedData.toString('utf-8'));
}

private async storeOnWalrus(data: any) {
// Walrusストレージとの統合
// 暗号化されたデータをWalrusにアップロードし
// 取得用のblob IDを返します
}

private async retrieveFromWalrus(blobId: string) {
// blob IDを使用してWalrusから暗号化されたデータを取得
}
}

例2:トークンゲート付きコンテンツプラットフォーム

// src/gated-content.ts
import { createSealClient } from './seal-client';

class ContentGating {
private sealClient: any;
private suiClient: any;

constructor(sealClient: any, suiClient: any) {
this.sealClient = sealClient;
this.suiClient = suiClient;
}

async createGatedContent(
content: string,
requiredNftCollection: string,
creatorKeypair: any
) {
// NFT所有権ポリシーを作成
const accessPolicy = await this.createNftPolicy(
requiredNftCollection,
creatorKeypair
);

// NFTアクセス要件でコンテンツを暗号化
const encryptedContent = await this.sealClient.encrypt({
data: Buffer.from(content, 'utf-8'),
recipientId: 'nft_holders', // NFTホルダー用の特別な受信者
accessPolicy: {
policyId: accessPolicy.policyId,
policyType: 'nft_ownership'
}
});

return {
contentId: encryptedContent.encryptionId,
accessPolicy: accessPolicy.policyId
};
}

async accessGatedContent(
contentId: string,
userAddress: string,
userKeypair: any
) {
// まずNFT所有権を確認
const hasAccess = await this.verifyNftOwnership(
userAddress,
contentId
);

if (!hasAccess) {
throw new Error('アクセスが拒否されました:必要なNFTが見つかりません');
}

// コンテンツを復号化
const decryptedContent = await this.sealClient.decrypt({
encryptionId: contentId,
recipientId: userAddress
});

return decryptedContent.toString('utf-8');
}

private async createNftPolicy(collection: string, creator: any) {
// NFT所有権をチェックするMoveコントラクトを作成
// ポリシーオブジェクトIDを返す
}

private async verifyNftOwnership(user: string, contentId: string) {
// ユーザーが必要なNFTを所有しているかチェック
// NFT所有権についてSuiにクエリ
}
}

例3:タイムロック資産転送

// src/time-locked-transfer.ts
import { createSealClient } from './seal-client';

async function createTimeLockTransfer(
assetData: any,
recipientAddress: string,
unlockTimestamp: number,
senderKeypair: any
) {
const { sealClient, suiClient } = await createSealClient();

// Sui上でタイムロックポリシーを作成
const timeLockPolicy = await createTimeLockPolicy(
unlockTimestamp,
recipientAddress,
senderKeypair,
suiClient
);

// 資産転送データを暗号化
const transferData = {
asset: assetData,
recipient: recipientAddress,
unlockTime: unlockTimestamp,
transferId: crypto.randomUUID()
};

const encryptedTransfer = await sealClient.encrypt({
data: Buffer.from(JSON.stringify(transferData), 'utf-8'),
recipientId: recipientAddress,
accessPolicy: {
policyId: timeLockPolicy.policyId,
policyType: 'time_lock'
}
});

console.log(`資産は${new Date(unlockTimestamp)}までロックされています`);

return {
transferId: encryptedTransfer.encryptionId,
unlockTime: unlockTimestamp,
policyId: timeLockPolicy.policyId
};
}

async function claimTimeLockTransfer(
transferId: string,
recipientKeypair: any
) {
const { sealClient } = await createSealClient();

try {
const decryptedData = await sealClient.decrypt({
encryptionId: transferId,
recipientId: recipientKeypair.toSuiAddress()
});

const transferData = JSON.parse(decryptedData.toString('utf-8'));

// 資産転送を処理
console.log('資産転送のロックが解除されました:', transferData);

return transferData;
} catch (error) {
console.error('転送がまだアンロックされていないか、アクセスが拒否されました:', error);
throw error;
}
}

Walrus分散ストレージとの統合

SealはSuiの分散ストレージソリューションであるWalrusとシームレスに連携します。両方を統合する方法は以下の通りです:

// src/walrus-integration.ts
import { createSealClient } from './seal-client';

class SealWalrusIntegration {
private sealClient: any;
private walrusClient: any;

constructor(sealClient: any, walrusClient: any) {
this.sealClient = sealClient;
this.walrusClient = walrusClient;
}

async storeEncryptedData(
data: Buffer,
recipientAddress: string,
accessPolicy?: any
) {
// Sealで暗号化
const encryptedData = await this.sealClient.encrypt({
data,
recipientId: recipientAddress,
accessPolicy
});

// 暗号化されたデータをWalrusに保存
const blobId = await this.walrusClient.store(
encryptedData.ciphertext
);

// SealとWalrusの両方の情報を含む参照を返す
return {
blobId,
encryptionId: encryptedData.encryptionId,
accessPolicy: encryptedData.accessPolicy
};
}

async retrieveAndDecrypt(
blobId: string,
encryptionId: string,
userKeypair: any
) {
// Walrusから取得
const encryptedData = await this.walrusClient.retrieve(blobId);

// Sealで復号化
const decryptedData = await this.sealClient.decrypt({
ciphertext: encryptedData,
encryptionId,
recipientId: userKeypair.toSuiAddress()
});

return decryptedData;
}
}

// 使用例
async function walrusExample() {
const { sealClient } = await createSealClient();
const walrusClient = new WalrusClient('https://walrus-testnet.sui.io');

const integration = new SealWalrusIntegration(sealClient, walrusClient);

const fileData = Buffer.from('重要なドキュメントの内容');
const recipientAddress = '0x...';

// 暗号化して保存
const result = await integration.storeEncryptedData(
fileData,
recipientAddress
);

console.log('Blob IDで保存されました:', result.blobId);

// 後で取得して復号化
const decrypted = await integration.retrieveAndDecrypt(
result.blobId,
result.encryptionId,
recipientKeypair
);

console.log('取得されたデータ:', decrypted.toString());
}

閾値暗号化の高度な設定

本番アプリケーションでは、複数のキーサーバーでカスタム閾値暗号化を設定したいでしょう:

// src/advanced-threshold.ts
import { SealClient } from '@mysten/seal';

async function setupProductionSeal() {
// 複数の独立したキーサーバーで設定
const keyServers = [
'https://keyserver-1.your-org.com',
'https://keyserver-2.partner-org.com',
'https://keyserver-3.third-party.com',
'https://keyserver-4.backup-provider.com',
'https://keyserver-5.fallback.com'
];

const sealClient = new SealClient({
keyServers,
threshold: 3, // 3-of-5閾値
network: 'mainnet',
// 高度なオプション
retryAttempts: 3,
timeoutMs: 10000,
backupKeyServers: [
'https://backup-1.emergency.com',
'https://backup-2.emergency.com'
]
});

return sealClient;
}

async function robustEncryption() {
const sealClient = await setupProductionSeal();

const criticalData = "ミッションクリティカルな暗号化データ";

// 高いセキュリティ保証で暗号化
const encrypted = await sealClient.encrypt({
data: Buffer.from(criticalData, 'utf-8'),
recipientId: '0x...',
// 最大セキュリティのため全5サーバーを要求
customThreshold: 5,
// 冗長性を追加
redundancy: 2,
accessPolicy: {
// 多要素要件
requirements: ['nft_ownership', 'time_lock', 'multisig_approval']
}
});

return encrypted;
}

セキュリティベストプラクティス

1. キー管理

// src/security-practices.ts

// 良い例:安全なキー導出を使用
import { generateKeypair } from '@mysten/sui/cryptography/ed25519';

const keypair = generateKeypair();

// 良い例:キーを安全に保存(環境変数の例)
const keypair = Ed25519Keypair.fromSecretKey(
process.env.PRIVATE_KEY
);

// 悪い例:キーをハードコードしない
const badKeypair = Ed25519Keypair.fromSecretKey(
"hardcoded-secret-key-12345" // これはしないでください!
);

2. アクセスポリシーの検証

// 暗号化前に必ずアクセスポリシーを検証
async function secureEncrypt(data: Buffer, recipient: string) {
const { sealClient } = await createSealClient();

// 受信者アドレスを検証
if (!isValidSuiAddress(recipient)) {
throw new Error('無効な受信者アドレスです');
}

// ポリシーが存在し有効であることをチェック
const policy = await validateAccessPolicy(policyId);
if (!policy.isValid) {
throw new Error('無効なアクセスポリシーです');
}

return sealClient.encrypt({
data,
recipientId: recipient,
accessPolicy: policy
});
}

3. エラーハンドリングとフォールバック

// 堅牢なエラーハンドリング
async function resilientDecrypt(encryptionId: string, userKeypair: any) {
const { sealClient } = await createSealClient();

try {
return await sealClient.decrypt({
encryptionId,
recipientId: userKeypair.toSuiAddress()
});
} catch (error) {
if (error.code === 'ACCESS_DENIED') {
throw new Error('アクセスが拒否されました:権限を確認してください');
} else if (error.code === 'KEY_SERVER_UNAVAILABLE') {
// バックアップ設定で再試行
return await retryWithBackupServers(encryptionId, userKeypair);
} else if (error.code === 'THRESHOLD_NOT_MET') {
throw new Error('利用可能なキーサーバーが不十分です');
} else {
throw new Error(`復号化に失敗しました: ${error.message}`);
}
}
}

4. データ検証

// 暗号化前にデータを検証
function validateDataForEncryption(data: Buffer): boolean {
// サイズ制限をチェック
if (data.length > 1024 * 1024) { // 1MB制限
throw new Error('暗号化するにはデータが大きすぎます');
}

// 機密パターンをチェック(オプション)
const dataStr = data.toString();
if (containsSensitivePatterns(dataStr)) {
console.warn('警告:データに潜在的に機密のパターンが含まれています');
}

return true;
}

パフォーマンス最適化

1. バッチ操作

// 効率性のため複数の暗号化をバッチ処理
async function batchEncrypt(dataItems: Buffer[], recipients: string[]) {
const { sealClient } = await createSealClient();

const promises = dataItems.map((data, index) =>
sealClient.encrypt({
data,
recipientId: recipients[index]
})
);

return Promise.all(promises);
}

2. キーサーバーレスポンスのキャッシュ

// レイテンシを減らすためキーサーバーセッションをキャッシュ
class OptimizedSealClient {
private sessionCache = new Map();

async encryptWithCaching(data: Buffer, recipient: string) {
let session = this.sessionCache.get(recipient);

if (!session || this.isSessionExpired(session)) {
session = await this.createNewSession(recipient);
this.sessionCache.set(recipient, session);
}

return this.encryptWithSession(data, session);
}
}

Seal統合のテスト

ユニットテスト

// tests/seal-integration.test.ts
import { describe, it, expect } from 'jest';
import { createSealClient } from '../src/seal-client';

describe('Seal統合', () => {
it('データを正常に暗号化および復号化する必要があります', async () => {
const { sealClient } = await createSealClient();
const testData = Buffer.from('テストメッセージ');
const recipient = '0x742d35cc6d4c0c08c0f9bf3c9b2b6c64b3b4f5c6d7e8f9a0b1c2d3e4f5a6b7c8';

const encrypted = await sealClient.encrypt({
data: testData,
recipientId: recipient
});

expect(encrypted.encryptionId).toBeDefined();
expect(encrypted.ciphertext).toBeDefined();

const decrypted = await sealClient.decrypt({
ciphertext: encrypted.ciphertext,
encryptionId: encrypted.encryptionId,
recipientId: recipient
});

expect(decrypted.toString()).toBe('テストメッセージ');
});

it('アクセス制御ポリシーを強制する必要があります', async () => {
// 権限のないユーザーが復号化できないことをテスト
const { sealClient } = await createSealClient();

const encrypted = await sealClient.encrypt({
data: Buffer.from('秘密'),
recipientId: 'authorized-user'
});

await expect(
sealClient.decrypt({
ciphertext: encrypted.ciphertext,
encryptionId: encrypted.encryptionId,
recipientId: 'unauthorized-user'
})
).rejects.toThrow('アクセスが拒否されました');
});
});

本番環境へのデプロイ

環境設定

// config/production.ts
export const productionConfig = {
keyServers: [
process.env.KEY_SERVER_1,
process.env.KEY_SERVER_2,
process.env.KEY_SERVER_3,
process.env.KEY_SERVER_4,
process.env.KEY_SERVER_5
],
threshold: 3,
network: 'mainnet',
suiRpc: process.env.SUI_RPC_URL,
walrusGateway: process.env.WALRUS_GATEWAY,
// セキュリティ設定
maxDataSize: 1024 * 1024, // 1MB
sessionTimeout: 3600000, // 1時間
retryAttempts: 3
};

モニタリングとログ

// utils/monitoring.ts
export class SealMonitoring {
static logEncryption(encryptionId: string, recipient: string) {
console.log(`[SEAL] ${recipient}用にデータ${encryptionId}を暗号化しました`);
// モニタリングサービスに送信
}

static logDecryption(encryptionId: string, success: boolean) {
console.log(`[SEAL] 復号化 ${encryptionId}: ${success ? '成功' : '失敗'}`);
}

static logKeyServerHealth(serverUrl: string, status: string) {
console.log(`[SEAL] キーサーバー ${serverUrl}: ${status}`);
}
}

リソースと次のステップ

公式ドキュメント

コミュニティとサポート

  • Sui Discord: コミュニティサポートのため#sealチャンネルに参加
  • GitHub Issues: バグ報告と機能リクエスト
  • 開発者フォーラム: ディスカッション用Suiコミュニティフォーラム

探索すべき高度なトピック

  1. カスタムアクセスポリシー: Moveコントラクトで複雑な認証ロジックを構築
  2. クロスチェーン統合: 他のブロックチェーンネットワークでSealを使用
  3. エンタープライズキー管理: 独自のキーサーバーインフラストラクチャを設定
  4. 監査とコンプライアンス: 規制環境向けのログとモニタリングを実装

サンプルアプリケーション

  • 安全なチャットアプリ: Sealによるエンドツーエンド暗号化メッセージング
  • ドキュメント管理: アクセス制御付きエンタープライズドキュメント共有
  • デジタル権利管理: 使用ポリシー付きコンテンツ配信
  • プライバシー保護分析: 暗号化データ処理ワークフロー

結論

Sealは、Web3におけるプライバシーと暗号化をインフラストラクチャレベルの関心事にする根本的な変化を表しています。アイデンティティベース暗号化、閾値セキュリティ、プログラマブルアクセス制御を組み合わせることで、開発者に真に安全で分散化されたアプリケーションを構築するための強力なツールを提供します。

Sealで構築することの主な利点には以下があります:

  • 単一障害点の排除: 分散キーサーバーが中央権威を排除
  • プログラマブルセキュリティ: スマートコントラクトベースのアクセスポリシーが柔軟な認証を提供
  • 開発者フレンドリー: TypeScript SDKが既存のWeb3ツールとシームレスに統合
  • ストレージ非依存: Walrus、IPFS、または任意のストレージソリューションと連携
  • 本番環境対応: エンタープライズセキュリティ標準でMysten Labsが構築

ユーザーデータの保護、サブスクリプションモデルの実装、複雑なマルチパーティアプリケーションの構築のいずれであっても、Sealは自信を持って構築するために必要な暗号プリミティブとアクセス制御インフラストラクチャを提供します。

今日から構築を始めて、プライバシーを公共インフラストラクチャの基本的な部分にする開発者の成長するエコシステムに参加しましょう。


構築を始める準備はできましたか? @mysten/sealをインストールして、このチュートリアルの例を試してみてください。分散ウェブは、プライバシーとセキュリティを第一に考えるアプリケーションを待っています。