@shogun-sdk/accounts
Version:
Shogun with Turnkey: configs, encryption, authentication with Telegram/Turnkey OIDC, etc.
535 lines (421 loc) • 12.2 kB
Markdown
# @shogun-sdk/accounts
TypeScript SDK for Turnkey wallet infrastructure - authentication, wallet creation, and transaction signing.
## Quick Start
### 1. Install the Package
Choose your preferred package manager:
**npm**
```bash
npm install @shogun-sdk/accounts
```
**pnpm**
```bash
pnpm add @shogun-sdk/accounts
```
**yarn**
```bash
yarn add @shogun-sdk/accounts
```
### 2. Configure and Use
Set up Turnkey configuration and start creating wallets:
```typescript
import { getTurnkeyConfig, createUserSubOrg } from '@shogun-sdk/accounts';
// Configure Turnkey
const config = getTurnkeyConfig(
'https://api.turnkey.com', // API base URL
'your-organization-id', // Your organization ID
'your-rp-id' // Relying Party ID for WebAuthn
);
// Create user sub-organization
const subOrg = await createUserSubOrg({
config,
email: 'user@example.com',
username: 'user123',
passkey: {
challenge: 'webauthn-challenge',
attestation: attestationObject
}
});
console.log('Created sub-org:', subOrg);
```
### 3. Explore All Features
Check the [Usage Examples](#usage-examples) and [API Reference](#api-reference) below for authentication, wallet management, and advanced features.
## Features
- 🔐 **Multi-Auth Support** - Passkeys, OAuth, email-based authentication
- 💼 **Wallet Management** - Create and manage Ethereum and Solana wallets
- 🏢 **Sub-Organizations** - Isolated user environments
- 🔑 **API Key Management** - Secure key generation and management
- 📱 **Telegram Integration** - Built-in Telegram authentication
- 🛡️ **Security First** - Industry-standard security practices
- 📝 **TypeScript Ready** - Full type safety and IntelliSense
## Usage Examples
### User Authentication
#### OAuth Authentication
```typescript
import { oauth } from '@shogun-sdk/accounts';
const authResponse = await oauth({
credential: 'oidc-token',
targetPublicKey: 'user-public-key',
targetSubOrgId: 'sub-org-id',
config
});
console.log('OAuth successful:', authResponse);
```
#### Passkey Authentication
```typescript
import { createUserSubOrg } from '@shogun-sdk/accounts';
// Create user with passkey
const subOrg = await createUserSubOrg({
config,
email: 'user@example.com',
username: 'user123',
passkey: {
challenge: 'webauthn-challenge',
attestation: attestationObject
}
});
```
### Wallet Operations
#### Get User Wallets
```typescript
import { getWalletsWithAccounts } from '@shogun-sdk/accounts';
const wallets = await getWalletsWithAccounts(config, 'organization-id');
console.log('User wallets:', wallets);
// Example response:
// [
// {
// walletId: 'wallet-123',
// accounts: [
// { address: '0x...', curve: 'secp256k1', chainType: 'ethereum' },
// { address: 'ABC...', curve: 'ed25519', chainType: 'solana' }
// ]
// }
// ]
```
#### Find Sub-Organization
```typescript
import { getSubOrgIdByEmail, getSubOrgId } from '@shogun-sdk/accounts';
// Find by email
const subOrgId = await getSubOrgIdByEmail(config, 'user@example.com');
// Find by various parameters
const subOrgById = await getSubOrgId(config, {
email: 'user@example.com',
username: 'user123',
publicKey: 'public-key-hex',
oidcToken: 'oidc-token'
});
```
### Client-Side Utilities
#### Local Storage with Expiration
```typescript
import { setItemWithExpiry, getItemWithExpiry } from '@shogun-sdk/accounts';
// Store data with 1 hour expiration
setItemWithExpiry('userSession', { userId: '123', token: 'abc' }, 3600000);
// Retrieve data (returns null if expired)
const session = getItemWithExpiry('userSession');
if (session) {
console.log('Valid session:', session);
} else {
console.log('Session expired or not found');
}
```
#### Public Key Operations
```typescript
import { getPublicKeyFromPrivateKeyHex } from '@shogun-sdk/accounts';
const publicKey = getPublicKeyFromPrivateKeyHex('private-key-hex');
console.log('Derived public key:', publicKey);
```
## Integration Examples
### React Integration
```typescript
import { useTurnkey } from '@turnkey/sdk-react';
import { getTurnkeyConfig } from '@shogun-sdk/accounts';
function WalletComponent() {
const config = getTurnkeyConfig(
process.env.REACT_APP_TURNKEY_API_URL!,
process.env.REACT_APP_TURNKEY_ORG_ID!,
process.env.REACT_APP_TURNKEY_RP_ID!
);
const { turnkey } = useTurnkey({ config });
return (
<div>
<h2>Wallet Management</h2>
{/* Your wallet UI here */}
</div>
);
}
```
### Server-Side Integration
```typescript
import { TurnkeyServerClient } from '@turnkey/sdk-server';
import { ApiKeyStamper } from '@turnkey/sdk-server';
const stamper = new ApiKeyStamper({
apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!,
apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!,
});
const client = new TurnkeyServerClient({
apiBaseUrl: 'https://api.turnkey.com',
organizationId: process.env.TURNKEY_ORG_ID!,
stamper,
});
// Use client for server-side operations
const wallets = await client.getWallets({
organizationId: 'user-sub-org-id'
});
```
## API Reference
### Core Functions
#### `getTurnkeyConfig(apiUrl, orgId, rpId)`
Initialize Turnkey configuration.
**Parameters:**
- `apiUrl`: Turnkey API base URL
- `orgId`: Your organization ID
- `rpId`: Relying Party ID for WebAuthn
**Returns:** Turnkey configuration object
#### `createUserSubOrg(options)`
Creates a new user sub-organization with optional authentication methods.
**Parameters:**
- `config`: Turnkey configuration object
- `username?`: Optional username
- `email?`: User email address
- `passkey?`: WebAuthn passkey configuration
- `oauth?`: OAuth provider configuration
- `wallet?`: Wallet configuration
**Returns:** Created sub-organization details
#### `oauth(options)`
Performs OAuth authentication flow.
**Parameters:**
- `credential`: OIDC token
- `targetPublicKey`: Target public key
- `targetSubOrgId`: Sub-organization ID
- `config`: Turnkey configuration
**Returns:** Authentication response
#### `getWalletsWithAccounts(config, organizationId)`
Retrieves all wallets and accounts for an organization.
**Parameters:**
- `config`: Turnkey configuration
- `organizationId`: Organization ID to query
**Returns:** Array of wallets with their accounts
#### `getSubOrgId(config, param)`
Finds sub-organization ID by various parameters.
**Parameters:**
- `config`: Turnkey configuration
- `param`: Search parameters (email, username, publicKey, or oidcToken)
**Returns:** Sub-organization ID or null
### Authentication Methods
The SDK supports multiple authentication flows:
#### 1. Passkeys (WebAuthn)
```typescript
// Secure, passwordless authentication
const subOrg = await createUserSubOrg({
config,
email: 'user@example.com',
passkey: {
challenge: 'challenge-string',
attestation: attestationObject
}
});
```
#### 2. OAuth Providers
```typescript
// Google, GitHub, and other OAuth providers
const authResult = await oauth({
credential: 'google-oidc-token',
targetPublicKey: 'user-public-key',
targetSubOrgId: 'sub-org-id',
config
});
```
#### 3. Email Recovery
```typescript
// Email-based account recovery
const recovery = await initiateEmailRecovery({
email: 'user@example.com',
config
});
```
#### 4. API Keys
```typescript
// For programmatic access
const apiKey = await createApiKey({
subOrgId: 'user-sub-org',
keyName: 'my-api-key',
config
});
```
### Supported Wallet Types
#### Ethereum Wallets
```typescript
// Secp256k1 curve, compatible with all EVM chains
const ethWallet = {
curve: 'secp256k1',
chainType: 'ethereum',
address: '0x...' // Ethereum address format
};
```
#### Solana Wallets
```typescript
// Ed25519 curve, native Solana support
const solWallet = {
curve: 'ed25519',
chainType: 'solana',
address: 'ABC...' // Base58 Solana address format
};
```
## Error Handling
The SDK includes comprehensive error handling:
```typescript
import { TurnkeyError } from '@shogun-sdk/accounts';
try {
const result = await createUserSubOrg({
config,
email: 'user@example.com'
});
} catch (error) {
if (error instanceof TurnkeyError) {
console.error('Turnkey error:', error.message);
console.error('Error code:', error.code);
} else {
console.error('Unexpected error:', error);
}
}
```
## Security Best Practices
### 1. API Key Protection
```typescript
// ❌ Never expose API keys in client-side code
const apiKey = 'your-api-key'; // DON'T DO THIS
// ✅ Use environment variables on server-side
const apiKey = process.env.TURNKEY_API_PRIVATE_KEY;
```
### 2. Private Key Security
```typescript
// ✅ Private keys are managed by Turnkey infrastructure
// You never handle raw private keys directly
const wallets = await getWalletsWithAccounts(config, orgId);
```
### 3. Session Management
```typescript
// ✅ Use appropriate session timeouts
setItemWithExpiry('session', data, 2 * 60 * 60 * 1000); // 2 hours
```
### 4. HTTPS Only
```typescript
// ✅ Always use HTTPS in production
const config = getTurnkeyConfig(
'https://api.turnkey.com', // Never use HTTP
orgId,
rpId
);
```
## TypeScript Support
The SDK is fully typed with comprehensive TypeScript definitions:
```typescript
import type {
ITurnkeyConfig,
Wallet,
Attestation,
OauthProviderParams,
SubOrgParams,
AuthResult
} from '@shogun-sdk/accounts';
interface CustomWalletConfig extends SubOrgParams {
customField: string;
}
const createCustomWallet = async (config: CustomWalletConfig): Promise<AuthResult> => {
// Your implementation with full type safety
};
```
## Environment Variables
### Client-Side (.env.local for Next.js)
```bash
NEXT_PUBLIC_TURNKEY_API_URL=https://api.turnkey.com
NEXT_PUBLIC_TURNKEY_ORG_ID=your-organization-id
NEXT_PUBLIC_TURNKEY_RP_ID=your-app-domain.com
```
### Server-Side (.env)
```bash
TURNKEY_API_URL=https://api.turnkey.com
TURNKEY_ORG_ID=your-organization-id
TURNKEY_API_PUBLIC_KEY=your-api-public-key
TURNKEY_API_PRIVATE_KEY=your-api-private-key
```
### Example Configuration
```typescript
// Client-side configuration
const clientConfig = getTurnkeyConfig(
process.env.NEXT_PUBLIC_TURNKEY_API_URL!,
process.env.NEXT_PUBLIC_TURNKEY_ORG_ID!,
process.env.NEXT_PUBLIC_TURNKEY_RP_ID!
);
// Server-side configuration
const serverConfig = getTurnkeyConfig(
process.env.TURNKEY_API_URL!,
process.env.TURNKEY_ORG_ID!,
process.env.TURNKEY_RP_ID!
);
```
## Common Use Cases
### 1. User Onboarding with Passkey
```typescript
async function onboardUser(email: string, username: string) {
try {
const subOrg = await createUserSubOrg({
config,
email,
username,
passkey: {
challenge: generateChallenge(),
attestation: await getPasskeyAttestation()
}
});
console.log('User onboarded:', subOrg);
return subOrg;
} catch (error) {
console.error('Onboarding failed:', error);
throw error;
}
}
```
### 2. Social Login Integration
```typescript
async function handleGoogleLogin(googleToken: string) {
try {
const authResult = await oauth({
credential: googleToken,
targetPublicKey: await derivePublicKey(),
targetSubOrgId: await findUserSubOrg(),
config
});
return authResult;
} catch (error) {
console.error('Google login failed:', error);
throw error;
}
}
```
### 3. Wallet Recovery
```typescript
async function recoverWallet(email: string) {
try {
const subOrgId = await getSubOrgIdByEmail(config, email);
if (!subOrgId) {
throw new Error('User not found');
}
const wallets = await getWalletsWithAccounts(config, subOrgId);
return wallets;
} catch (error) {
console.error('Wallet recovery failed:', error);
throw error;
}
}
```
## Support
- [Turnkey Documentation](https://docs.turnkey.com)
- [GitHub Issues](https://github.com/shogun-network/shogun-sdk/issues)
- [Main SDK Documentation](../../README.md)
## Requirements
- **Turnkey Account**: Visit [Turnkey](https://turnkey.com) to create an account
- **Organization Setup**: Configure your organization in Turnkey dashboard
- **HTTPS Environment**: Required for WebAuthn/passkey functionality
## License
ISC