Skip to main content
OpenKey can replace browser wallet extensions (MetaMask, WalletConnect, etc.) as the signer for TinyCloud Web SDK. This means users can authenticate to TinyCloud using their OpenKey-managed Ethereum keys, with passkey-based login instead of a browser extension.

Why Use OpenKey with TinyCloud

  • No browser extension required: Users do not need MetaMask or any wallet installed
  • Passkey-based authentication: Biometric or hardware key login instead of seed phrases
  • TEE key security: Private keys are sealed inside a hardware enclave
  • Lower onboarding friction: Non-crypto-native users can get started without understanding wallets
  • Same cryptographic guarantees: OpenKey produces standard Ethereum signatures that TinyCloud verifies the same way as any wallet

Architecture

OpenKey and TinyCloud integration flow
Instead of the wallet extension signing the SIWE message, OpenKey’s TEE-managed key signs it. From TinyCloud’s perspective, the signature is indistinguishable from one produced by MetaMask.

Setup

1

Install dependencies

npm install @tinycloud/web-sdk @openkey/sdk
2

Initialize OpenKey and TinyCloud

import { OpenKey, OpenKeyEIP1193Provider } from '@openkey/sdk';
import { TinyCloudWeb } from '@tinycloud/web-sdk';

const openkey = new OpenKey({
  appName: 'My TinyCloud App',
});
3

Connect with OpenKey and create provider

Use OpenKey to get the user’s Ethereum address and create an EIP-1193 provider.
// Connect with OpenKey (passkey auth + key selection)
const authResult = await openkey.connect();
console.log('OpenKey address:', authResult.address);

// Create EIP-1193 provider from OpenKey
const provider = new OpenKeyEIP1193Provider(openkey, authResult);
4

Initialize TinyCloud with OpenKey provider

Pass the OpenKey provider to TinyCloud and sign in.
// Initialize TinyCloud with the OpenKey provider
const tc = new TinyCloudWeb({
  providers: { web3: { driver: provider } },
});

// Sign in - TinyCloud uses OpenKey for signing automatically
await tc.signIn();

console.log('TinyCloud session:', tc.address());
5

Use TinyCloud normally

Once signed in, all TinyCloud operations work exactly the same as with a browser wallet.
// Store data in the user's space
const putResult = await tc.kv.put('profile', {
  name: 'Alice',
  wallet: 'openkey',
});

// Retrieve data
const getResult = await tc.kv.get('profile');
if (getResult.ok) {
  console.log(getResult.data.data);
}

Complete Example

import { OpenKey, OpenKeyEIP1193Provider } from '@openkey/sdk';
import { TinyCloudWeb } from '@tinycloud/web-sdk';

async function main() {
  const openkey = new OpenKey({ appName: 'My App' });

  // Step 1: Connect with OpenKey
  const authResult = await openkey.connect();
  console.log('Connected via OpenKey:', authResult.address);

  // Step 2: Create EIP-1193 provider and initialize TinyCloud
  const provider = new OpenKeyEIP1193Provider(openkey, authResult);
  const tc = new TinyCloudWeb({
    providers: { web3: { driver: provider } },
  });

  // Step 3: Sign in to TinyCloud
  await tc.signIn();
  console.log('TinyCloud session active:', tc.address());

  // Step 4: Use TinyCloud KV storage
  await tc.kv.put('settings', { theme: 'dark', lang: 'en' });
  const result = await tc.kv.get('settings');
  if (result.ok) {
    console.log('Settings:', result.data.data);
  }
}

main().catch(console.error);

Session Management

Check if there’s an existing session before initiating a new sign-in flow:
import { OpenKey, OpenKeyEIP1193Provider } from '@openkey/sdk';
import { TinyCloudWeb } from '@tinycloud/web-sdk';

const openkey = new OpenKey({ appName: 'My App' });

// Check if there's an existing session
if (tc.session()) {
  console.log('Session active:', tc.address());
} else {
  // Need to connect with OpenKey and sign in
  const authResult = await openkey.connect();
  const provider = new OpenKeyEIP1193Provider(openkey, authResult);

  const tc = new TinyCloudWeb({
    providers: { web3: { driver: provider } },
  });

  await tc.signIn();
}

Delegations with OpenKey

Delegations work the same way regardless of whether the signer is OpenKey or a browser wallet. The primary DID is derived from the Ethereum address, which is the same whether the key is in MetaMask or OpenKey.
// Alice (using OpenKey) delegates to Bob
const delegation = await tc.createDelegation({
  delegateDID: bob.did, // Use the recipient's primary DID (tc.did after signIn)
  actions: ['tinycloud.kv/get', 'tinycloud.kv/list'],
  path: 'shared/',
  expiryMs: 7 * 24 * 60 * 60 * 1000, // 7 days in milliseconds
});
Use the recipient’s primary DID (tc.did after signIn) for delegations. This applies regardless of the signer being used. See the Delegations guide for details.

Comparison: OpenKey vs. Browser Wallet

AspectBrowser Wallet (MetaMask)OpenKey
InstallationBrowser extension requiredNone (web-based)
Key storageUser’s device (local)TEE (server-side, sealed)
AuthenticationWallet unlock (password)Passkey (biometric)
Seed phraseUser must back upNot applicable
Signing UXExtension popupOpenKey popup/iframe
Works on mobileRequires mobile wallet appWorks in any browser
TinyCloud compatibilityNativeVia custom signer

Next Steps