zklogin-plus
Version:
A powerful zkLogin plugin for Sui blockchain - inspired by @mysten/enoki
288 lines (222 loc) ⢠7.29 kB
Markdown
A powerful zkLogin plugin for Sui blockchain - inspired by @mysten/enoki
- š **Complete zkLogin Workflow**: 7-step process from key generation to transaction execution
- šÆ **Simple API**: Easy-to-use TypeScript client with event-driven architecture
- šŖ **Multiple Storage Options**: Browser localStorage, sessionStorage, or custom storage
- š **OAuth Integration**: Support for Google, Facebook, Twitch, Apple, and custom providers
- š± **Framework Agnostic**: Works with React, Vue, vanilla JS, or any frontend framework
- š§ **Developer Friendly**: Full TypeScript support with comprehensive error handling
- šØ **Demo App**: Complete demo application showcasing all features
```bash
npm install @mysten/zklogin-plus
yarn add @mysten/zklogin-plus
bun add @mysten/zklogin-plus
```
```typescript
import { ZkLoginClient } from '@mysten/zklogin-plus';
// Initialize the client
const client = new ZkLoginClient({
clientId: 'your-oauth-client-id',
redirectUri: 'https://your-app.com/callback',
network: 'devnet', // or 'testnet', 'mainnet'
});
// Listen to events
client.on('ready', () => {
console.log('ZkLogin is ready for transactions!');
});
client.on('error', (error) => {
console.error('ZkLogin error:', error);
});
// Step 1: Generate ephemeral key pair
await client.generateEphemeralKeyPair();
// Step 2: Redirect to OAuth (Google)
client.redirectToOAuth('google');
// Step 3: Handle OAuth callback (in your callback page)
client.handleOAuthCallback();
// Step 4: Generate user salt
client.generateSalt();
// Step 5: Generate zkLogin address
await client.generateAddress();
// Step 6: Get ZK proof
await client.getZkProof();
// Step 7: Execute transaction
const txDigest = await client.executeTransaction({
recipient: '0x...',
amount: 1000000000n, // 1 SUI in MIST
});
```
```typescript
interface ZkLoginConfig {
/** OAuth client ID */
clientId: string;
/** OAuth redirect URI */
redirectUri: string;
/** Sui network */
network?: 'mainnet' | 'testnet' | 'devnet' | string;
/** ZK proof service endpoint */
proverEndpoint?: string;
/** Faucet endpoint for test tokens */
faucetEndpoint?: string;
/** Storage key prefix */
storagePrefix?: string;
/** Enable debug logging */
debug?: boolean;
}
```
- `generateEphemeralKeyPair(): Promise<EphemeralKeyPairState>`
- `redirectToOAuth(provider: ZkLoginProvider, state?: string): void`
- `handleOAuthCallback(url?: string): JwtState`
- `generateSalt(): UserSaltState`
- `generateAddress(): Promise<ZkLoginAddressState>`
- `getZkProof(): Promise<ZkProofData>`
- `executeTransaction(options?: TransactionOptions): Promise<string>`
- `requestTestTokens(): Promise<void>`
- `refreshBalance(): Promise<string>`
- `reset(): void`
- `getState(): ZkLoginState`
- `step:changed`: Fired when workflow step changes
- `keypair:generated`: Fired when ephemeral key pair is generated
- `jwt:received`: Fired when JWT is received from OAuth
- `salt:generated`: Fired when user salt is generated
- `address:generated`: Fired when zkLogin address is generated
- `proof:received`: Fired when ZK proof is received
- `error`: Fired when an error occurs
- `ready`: Fired when all steps are complete and ready for transactions
```typescript
import {
generateEphemeralKeyPair,
decodeJwtToken,
generateUserSalt,
generateZkLoginAddress,
requestZkProof,
buildZkLoginSignature,
// ... more utilities
} from '@mysten/zklogin-plus';
```
```typescript
import { useEffect, useState } from 'react';
import { ZkLoginClient, type ZkLoginState } from '@mysten/zklogin-plus';
function MyComponent() {
const [client] = useState(() => new ZkLoginClient({
clientId: 'your-client-id',
redirectUri: window.location.origin,
network: 'devnet',
}));
const [state, setState] = useState<ZkLoginState>();
useEffect(() => {
const handleStateChange = () => setState(client.getState());
client.on('step:changed', handleStateChange);
client.on('ready', handleStateChange);
client.on('error', (error) => console.error(error));
setState(client.getState());
return () => {
client.off('step:changed', handleStateChange);
client.off('ready', handleStateChange);
};
}, [client]);
return (
<div>
<h1>Current Step: {state?.currentStep}</h1>
<button onClick={() => client.generateEphemeralKeyPair()}>
Generate Key Pair
</button>
{/* ... more UI */}
</div>
);
}
```
```typescript
import {
BrowserStorage,
BrowserSessionStorage,
MemoryStorage
} from '@mysten/zklogin-plus';
// Custom storage implementation
class CustomStorage implements Storage {
get(key: string): string | null { /* ... */ }
set(key: string, value: string): void { /* ... */ }
remove(key: string): void { /* ... */ }
clear(): void { /* ... */ }
}
```
```typescript
import { ZkLoginError } from '@mysten/zklogin-plus';
try {
await client.generateEphemeralKeyPair();
} catch (error) {
if (error instanceof ZkLoginError) {
console.log('Error code:', error.code);
console.log('Error step:', error.step);
console.log('Error message:', error.message);
}
}
```
Run the demo application to see all features in action:
```bash
git clone https://github.com/your-org/zklogin-plus.git
cd zklogin-plus
bun install
bun run demo
```
The demo will be available at `http://localhost:3000`
```bash
bun run build:lib
bun run demo
bun run lint
bun run format
```
```
zklogin-plus/
āāā lib/
ā āāā client/
ā āāā types/
ā āāā utils/
ā āāā storage/
ā āāā providers/
ā āāā index.ts
āāā src/
āāā dist/
```
| Feature | ZkLogin Plus | @mysten/enoki |
|---------|--------------|---------------|
| zkLogin Support | ā
Full workflow | ā
Basic support |
| OAuth Providers | ā
Multiple providers | ā
Limited |
| Storage Options | ā
Flexible storage | ā Limited |
| Event System | ā
Comprehensive | ā Basic |
| TypeScript | ā
Full support | ā
Full support |
| Demo App | ā
Complete demo | ā No demo |
| Framework Support | ā
Framework agnostic | ā
React focused |
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
Apache-2.0 License - see [LICENSE](LICENSE) for details.
- š [Documentation](https://zklogin-plus.docs.com)
- š [Issue Tracker](https://github.com/your-org/zklogin-plus/issues)
- š¬ [Discord Community](https://discord.gg/zklogin-plus)
---
Made with ā¤ļø by the ZkLogin Plus team