Shogun SDK Documentation v1.1.4 - v1.9.3

Shogun Core πŸ“¦

npm License TypeScript

Shogun Core is a comprehensive SDK for building decentralized applications (dApps) that simplifies authentication, wallet management, and decentralized data storage. It combines GunDB's peer-to-peer networking with modern authentication standards and blockchain integration to provide a secure, user-friendly foundation for Web3 applications.

  • πŸ” Multiple Authentication Methods: Traditional username/password, WebAuthn (biometrics), Web3 (MetaMask), Nostr, and OAuth
  • 🌐 Decentralized Storage: Built on GunDB for peer-to-peer data synchronization
  • πŸ”Œ Plugin System: Extensible architecture with built-in plugins for various authentication methods
  • πŸ“± Reactive Programming: RxJS integration for real-time data streams
  • πŸ›‘οΈ Security: End-to-end encryption and secure key management
  • 🎯 TypeScript: Full TypeScript support with comprehensive type definitions
  • πŸ“‘ Event System: Typed event system for monitoring authentication and data changes
  • πŸ”‘ Cryptographic Wallets: Automatic derivation of Bitcoin and Ethereum wallets from user keys
  • βœ… Type Consistency: Unified return types across all authentication methods
  • Removed Deprecated Functions: Eliminated handleSimpleOAuth and Alby support
  • Simplified API: Removed redundant updateUserAlias (use changeUsername instead)
  • Debug Functions Cleanup: Removed debug-only functions like clearAllStorageData, exportPair
  • Error Handler Optimization: Removed debug statistics and debug helper functions
  • Cache Management: Removed optional cache functions for cleaner API
  • Bundle Size Reduction: Estimated 15-20% reduction in bundle size
  • Unified Return Types: All authentication methods now use consistent AuthResult and SignUpResult types
  • Enhanced SignUpResult: Extended to support OAuth redirects and provider-specific data
  • Type Safety: Fixed TypeScript inconsistencies across all plugins
  • API Standardization: All plugins implement unified login() and signUp() interfaces
npm install shogun-core
# or
yarn add shogun-core
import { ShogunCore } from "shogun-core";

// Define your list of Gun peers
const relays = [
"wss://ruling-mastodon-improved.ngrok-free.app/gun",
"https://gun-manhattan.herokuapp.com/gun",
"https://peer.wallie.io/gun",
];

// Initialize Shogun Core with plugins
const shogun = new ShogunCore({
peers: relays,
scope: "my-awesome-app",
authToken: "YOUR_GUN_SUPER_PEER_SECRET", // Optional, for private peers

// Enable and configure Web3 (e.g., MetaMask) authentication
web3: {
enabled: true,
},

// Enable and configure WebAuthn (biometrics, security keys)
webauthn: {
enabled: true,
rpName: "My Awesome App", // Name of your application
rpId: window.location.hostname, // Relying party ID
},

// Enable and configure Nostr
nostr: {
enabled: true,
},

// Enable and configure OAuth providers
oauth: {
enabled: true,
usePKCE: true, // Recommended for SPAs
providers: {
google: {
clientId: "YOUR_GOOGLE_CLIENT_ID",
clientSecret: "YOUR_GOOGLE_CLIENT_SECRET", // For server-side flow
redirectUri: "http://localhost:3000/auth/callback",
scope: ["openid", "email", "profile"],
},
},
},
});

// Initialize the SDK
await shogun.initialize();

console.log("Shogun Core initialized!");

Shogun Core provides a unified plugin system for different authentication methods. Each plugin implements standardized login() and signUp() methods that return consistent AuthResult and SignUpResult objects.

// Authentication result interface - used by login methods
interface AuthResult {
success: boolean;
error?: string;
userPub?: string; // User's public key
username?: string; // Username or identifier
sessionToken?: string; // Session token if applicable
authMethod?: AuthMethod; // Authentication method used
sea?: {
// GunDB SEA pair for session persistence
pub: string;
priv: string;
epub: string;
epriv: string;
};
// OAuth-specific properties
redirectUrl?: string; // OAuth redirect URL
pendingAuth?: boolean; // Indicates pending OAuth flow
message?: string; // Status message
provider?: string; // OAuth provider name
isNewUser?: boolean; // True if this was a registration
user?: {
// OAuth user data
userPub?: string;
username?: string;
email?: string;
name?: string;
picture?: string;
oauth?: {
provider: string;
id: string;
email?: string;
name?: string;
picture?: string;
lastLogin: number;
};
};
}

// Sign up result interface - used by signUp methods βœ… ENHANCED
interface SignUpResult {
success: boolean;
userPub?: string;
username?: string;
pub?: string;
error?: string;
message?: string;
wallet?: any;
isNewUser?: boolean;
authMethod?: AuthMethod; // βœ… ADDED
sessionToken?: string; // βœ… ADDED
sea?: { pub: string; priv: string; epub: string; epriv: string }; // SEA pair for session persistence
// OAuth flow support - βœ… ADDED
redirectUrl?: string;
pendingAuth?: boolean;
provider?: string;
user?: OAuthUserInfo; // βœ… ADDED
}

// Supported authentication methods
type AuthMethod =
| "password"
| "webauthn"
| "web3"
| "nostr"
| "oauth"
| "bitcoin"
| "pair";

Direct username/password authentication using ShogunCore methods:

// Sign up a new user - Returns SignUpResult βœ…
const signUpResult: SignUpResult = await shogun.signUp("username", "password");
if (signUpResult.success) {
console.log("User created:", signUpResult.username);
console.log("Is new user:", signUpResult.isNewUser);
console.log("Auth method:", signUpResult.authMethod);
}

// Login with username and password - Returns AuthResult βœ…
const loginResult: AuthResult = await shogun.login("username", "password");
if (loginResult.success) {
console.log("Logged in as:", loginResult.username);
console.log("User public key:", loginResult.userPub);
}

Ethereum wallet authentication via MetaMask or other Web3 providers:

const web3Plugin = shogun.getPlugin<Web3ConnectorPlugin>("web3");

if (web3Plugin && web3Plugin.isAvailable()) {
// Connect to MetaMask
const connectionResult = await web3Plugin.connectMetaMask();

if (connectionResult.success) {
const address = connectionResult.address!;

// Login with Web3 wallet - Returns AuthResult βœ…
const loginResult: AuthResult = await web3Plugin.login(address);
if (loginResult.success) {
console.log("Web3 login successful");
console.log("User public key:", loginResult.userPub);
}

// Register new user with Web3 wallet - Returns SignUpResult βœ…
const signUpResult: SignUpResult = await web3Plugin.signUp(address);
if (signUpResult.success) {
console.log("Web3 registration successful");
console.log("Is new user:", signUpResult.isNewUser);
}
}
}

// Plugin Interface - βœ… FIXED TYPES
interface Web3ConnectorPluginInterface {
// Authentication methods
login(address: string): Promise<AuthResult>; // βœ… CORRECT
signUp(address: string): Promise<SignUpResult>; // βœ… FIXED

// Connection methods
isAvailable(): boolean;
connectMetaMask(): Promise<ConnectionResult>;
getProvider(): Promise<ethers.JsonRpcProvider | ethers.BrowserProvider>;
getSigner(): Promise<ethers.Signer>;

// Credential management
generateCredentials(address: string): Promise<ISEAPair>;
generatePassword(signature: string): Promise<string>;
verifySignature(message: string, signature: string): Promise<string>;
}

Biometric and hardware key authentication:

const webauthnPlugin = shogun.getPlugin<WebauthnPlugin>("webauthn");

if (webauthnPlugin && webauthnPlugin.isSupported()) {
// Register new user with WebAuthn - Returns SignUpResult βœ…
const signUpResult: SignUpResult = await webauthnPlugin.signUp("username");
if (signUpResult.success) {
console.log("WebAuthn registration successful");
console.log("User public key:", signUpResult.userPub);
}

// Authenticate existing user - Returns AuthResult βœ…
const loginResult: AuthResult = await webauthnPlugin.login("username");
if (loginResult.success) {
console.log("WebAuthn authentication successful");
console.log("Auth method:", loginResult.authMethod); // "webauthn"
}
}

// Plugin Interface - βœ… FIXED TYPES
interface WebauthnPluginInterface {
// Authentication methods
login(username: string): Promise<AuthResult>; // βœ… CORRECT
signUp(username: string): Promise<SignUpResult>; // βœ… FIXED

// Capability checks
isSupported(): boolean;

// WebAuthn-specific methods
register(username: string, displayName?: string): Promise<WebAuthnCredential>;
authenticate(username?: string): Promise<WebAuthnCredential>;
generateCredentials(
username: string,
pair?: ISEAPair | null,
login?: boolean
): Promise<WebAuthnUniformCredentials>;
}

Bitcoin wallet and Nostr protocol authentication:

const nostrPlugin = shogun.getPlugin<NostrConnectorPlugin>("nostr");

if (nostrPlugin && nostrPlugin.isAvailable()) {
// Connect to Nostr wallet (Bitcoin extension)
const connectionResult = await nostrPlugin.connectNostrWallet();

if (connectionResult.success) {
const address = connectionResult.address!;

// Login with Nostr/Bitcoin wallet - Returns AuthResult βœ…
const loginResult: AuthResult = await nostrPlugin.login(address);
if (loginResult.success) {
console.log("Nostr login successful");
console.log("Auth method:", loginResult.authMethod); // "nostr"
}

// Register with Nostr/Bitcoin wallet - Returns SignUpResult βœ…
const signUpResult: SignUpResult = await nostrPlugin.signUp(address);
if (signUpResult.success) {
console.log("Nostr registration successful");
console.log("Is new user:", signUpResult.isNewUser);
}
}
}

// Plugin Interface - βœ… FIXED TYPES
interface NostrConnectorPluginInterface {
// Authentication methods
login(address: string): Promise<AuthResult>; // βœ… CORRECT
signUp(address: string): Promise<SignUpResult>; // βœ… FIXED

// Connection methods
isAvailable(): boolean;
connectBitcoinWallet(
type?: "alby" | "nostr" | "manual"
): Promise<ConnectionResult>;
connectNostrWallet(): Promise<ConnectionResult>;

// Credential and signature management
generateCredentials(
address: string,
signature: string,
message: string
): Promise<NostrConnectorCredentials>;
verifySignature(
message: string,
signature: string,
address: string
): Promise<boolean>;
generatePassword(signature: string): Promise<string>;
}

Social login with external providers (Google, GitHub, etc.):

const oauthPlugin = shogun.getPlugin<OAuthPlugin>("oauth");

if (oauthPlugin && oauthPlugin.isSupported()) {
// Get available providers
const providers = oauthPlugin.getAvailableProviders(); // ["google", "github", ...]

// Initiate signup with OAuth - Returns SignUpResult with redirect βœ…
const signUpResult: SignUpResult = await oauthPlugin.signUp("google");
if (signUpResult.success && signUpResult.redirectUrl) {
// Redirect user to OAuth provider
window.location.href = signUpResult.redirectUrl;
}

// Handle OAuth callback (after redirect back from provider) - Returns AuthResult βœ…
const callbackResult: AuthResult = await oauthPlugin.handleOAuthCallback(
"google",
authCode, // From URL params
state // From URL params
);

if (callbackResult.success) {
console.log("OAuth authentication successful");
if (callbackResult.user) {
console.log("User email:", callbackResult.user.email);
console.log("User name:", callbackResult.user.name);
}
}
}

// Plugin Interface - βœ… FIXED TYPES
interface OAuthPluginInterface {
// Authentication methods
login(provider: OAuthProvider): Promise<AuthResult>; // βœ… CORRECT
signUp(provider: OAuthProvider): Promise<SignUpResult>; // βœ… FIXED

// OAuth flow management
isSupported(): boolean;
getAvailableProviders(): OAuthProvider[];
initiateOAuth(provider: OAuthProvider): Promise<OAuthConnectionResult>;
completeOAuth(
provider: OAuthProvider,
authCode: string,
state?: string
): Promise<OAuthConnectionResult>;
handleOAuthCallback(
provider: OAuthProvider,
authCode: string,
state: string
): Promise<AuthResult>;

// Credential management
generateCredentials(
userInfo: OAuthUserInfo,
provider: OAuthProvider
): Promise<OAuthCredentials>;
}

You can also use Shogun Core directly in the browser by including it from a CDN. This is ideal for static sites or lightweight applications.

<!DOCTYPE html>
<html>
<head>
<title>Shogun Core in Browser</title>
</head>
<body>
<h1>My dApp</h1>
<!-- Required dependencies for Shogun Core -->
<script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gun/sea.js"></script>

<!-- Shogun Core library -->
<script src="https://cdn.jsdelivr.net/npm/shogun-core/dist/browser/shogun-core.js"></script>

<script>
// The script exposes a global `initShogun` function
const shogun = initShogun({
peers: ["https://gun-manhattan.herokuapp.com/gun"],
scope: "my-browser-app",
web3: { enabled: true },
webauthn: {
enabled: true,
rpName: "My Browser dApp",
rpId: window.location.hostname,
},
});

console.log("Shogun Core initialized in browser!", shogun);

async function connectWallet() {
if (shogun.hasPlugin("web3")) {
const web3Plugin = shogun.getPlugin("web3");
try {
const provider = await web3Plugin.getProvider();
const signer = provider.getSigner();
const address = await signer.getAddress();
await web3Plugin.login(address);
console.log("Logged in with address:", address);
} catch (error) {
console.error("Web3 login failed:", error);
}
}
}
</script>
</body>
</html>
  • login(username: string, password: string): Promise<AuthResult> - Authenticate with username/password
  • loginWithPair(pair: ISEAPair): Promise<AuthResult> - Authenticate directly with a GunDB SEA pair
  • signUp(username: string, password: string, email?: string, pair?: ISEAPair | null): Promise<SignUpResult> - Create new user account
  • logout(): void - Logout current user
  • isLoggedIn(): boolean - Check if user is authenticated
  • getPlugin<T>(name: string): T | undefined - Get plugin by name
  • hasPlugin(name: string): boolean - Check if plugin exists
  • register(plugin: ShogunPlugin): void - Register custom plugin
  • unregister(pluginName: string): void - Remove plugin
  • on<K extends keyof ShogunEventMap>(eventName: K, listener: Function): this - Subscribe to typed events
  • off<K extends keyof ShogunEventMap>(eventName: K, listener: Function): this - Unsubscribe from events
  • emit<K extends keyof ShogunEventMap>(eventName: K, data?: ShogunEventMap[K]): boolean - Emit custom events
interface ShogunSDKConfig {
peers?: string[]; // GunDB peer URLs
scope?: string; // Application scope
authToken?: string; // GunDB super peer secret
appToken?: string; // Application token

// Plugin configurations
webauthn?: {
enabled?: boolean;
rpName?: string;
rpId?: string;
};

web3?: {
enabled?: boolean;
};

nostr?: {
enabled?: boolean;
};

oauth?: {
enabled?: boolean;
usePKCE?: boolean;
providers?: Record<string, any>;
};

// Timeouts
timeouts?: {
login?: number;
signup?: number;
operation?: number;
};
}

Shogun Core provides a comprehensive typed event system for monitoring authentication and data changes:

// Available events with their data types
interface ShogunEventMap {
"auth:login": AuthEventData; // User logged in
"auth:logout": void; // User logged out
"auth:signup": AuthEventData; // New user registered
"wallet:created": WalletEventData; // Wallet derived from user keys
"gun:put": GunDataEventData; // Data written to GunDB
"gun:get": GunDataEventData; // Data read from GunDB
"gun:set": GunDataEventData; // Data updated in GunDB
"gun:remove": GunDataEventData; // Data removed from GunDB
"gun:peer:add": GunPeerEventData; // Peer added
"gun:peer:remove": GunPeerEventData; // Peer removed
"gun:peer:connect": GunPeerEventData; // Peer connected
"gun:peer:disconnect": GunPeerEventData; // Peer disconnected
"plugin:registered": { name: string; version?: string; category?: string }; // Plugin registered
"plugin:unregistered": { name: string }; // Plugin unregistered
debug: { action: string; [key: string]: any }; // Debug information
error: ErrorEventData; // Error occurred
}

// Listen for authentication events with full type safety
shogun.on("auth:login", (data) => {
console.log("User logged in:", data.username);
console.log("Authentication method:", data.method);
if (data.provider) {
console.log("OAuth provider:", data.provider);
}
});

shogun.on("auth:logout", () => {
console.log("User logged out");
});

shogun.on("auth:signup", (data) => {
console.log("New user signed up:", data.username);
});

// Nota: in v1.7.0 l'evento `wallet:created` non Γ¨ emesso dal core

// Listen for errors
shogun.on("error", (error) => {
console.error("Shogun error:", error.message);
});

Nota: la derivazione automatica dei wallet e l'evento wallet:created sono sperimentali e non garantiti in v1.7.0.

Shogun Core includes comprehensive error handling with typed errors:

import { ShogunError, ErrorType } from "shogun-core";

try {
await shogun.login("username", "password");
} catch (error) {
if (error instanceof ShogunError) {
switch (error.type) {
case ErrorType.AUTHENTICATION:
console.error("Invalid credentials");
break;
case ErrorType.NETWORK:
console.error("Network connection failed");
break;
default:
console.error("Unknown error:", error.message);
}
}
}

We welcome contributions! Please see our Contributing Guide for details.

This project is licensed under the MIT License - see the LICENSE file for details.

SHOGUN CORE

Core library for Shogun Ecosystem

This project includes a comprehensive test suite that covers:

  • Validation Utils (src/__tests__/utils/validation.test.ts)

    • Username validation
    • Email validation
    • OAuth provider validation
    • Username generation from identity
    • Deterministic password generation
  • Error Handler (src/__tests__/utils/errorHandler.test.ts)

    • Error creation and handling
    • Error statistics and logging
    • Retry logic
    • External logger integration
  • Event Emitter (src/__tests__/utils/eventEmitter.test.ts)

    • Event registration and emission
    • Listener management
    • Error handling in listeners
    • Symbol events support
  • Storage (src/__tests__/storage/storage.test.ts)

    • Memory and localStorage operations
    • Error handling
    • Test mode behavior
    • Data persistence
  • ShogunCore (src/__tests__/integration/shogunCore.test.ts)
    • Plugin system validation
    • Authentication methods
    • Event system
    • Configuration handling
    • Error handling
  • Compatibility (src/__tests__/browser/compatibility.test.ts)
    • localStorage availability
    • Crypto API support
    • WebAuthn detection
    • Web3 provider detection
    • Event system compatibility
    • TextEncoder/TextDecoder support
    • Fetch API compatibility
    • URL API compatibility
    • Performance API compatibility
    • Console API compatibility

You can eseguire i test sia dalla root del monorepo sia entrando nella cartella shogun-core.

Inside shogun-core/ directory:

# Install deps
yarn install

# Tutti i test (una sola esecuzione) con coverage
yarn test:ci

# Watch mode
yarn test:watch

# Coverage (report HTML in coverage/lcov-report/index.html)
yarn coverage

# Solo i test dei plugin
yarn test src/__tests__/plugins

# Evita conflitti di config Jest (se servisse)
yarn jest --ci --coverage --watchAll=false --config jest.config.js

From repository root (senza cambiare directory):

# Install deps
yarn --cwd shogun-core install

# Tutti i test con coverage (CI‑like)
yarn --cwd shogun-core test:ci

# Solo plugin tests
yarn --cwd shogun-core test src/__tests__/plugins

# Coverage
yarn --cwd shogun-core coverage

# Watch mode
yarn --cwd shogun-core test:watch

# Se compaiono piΓΉ configurazioni Jest, specifica esplicitamente il config file
yarn --cwd shogun-core jest --ci --coverage --watchAll=false --config jest.config.js

CI & QA scripts:

# Mutation testing (Stryker) – piΓΉ lento, richiede devDeps installate
yarn --cwd shogun-core mutation

# SAST (Semgrep) – richiede semgrep installato (es. `pip install semgrep`)
yarn --cwd shogun-core sast

The test suite provides comprehensive coverage of:

  • βœ… Utility Functions - 100% coverage
  • βœ… Error Handling - 100% coverage
  • βœ… Event System - 100% coverage
  • βœ… Storage Operations - 100% coverage
  • βœ… Plugin System - API validation
  • βœ… Browser Compatibility - Cross-browser support
  • βœ… Configuration Validation - Config handling

These tests are designed to be realistic and non-intrusive:

  • No codebase modifications - Tests work with existing code
  • Comprehensive coverage - All public APIs tested
  • Error resilience - Tests error handling and edge cases
  • Browser compatibility - Cross-browser support validation
  • Performance aware - Tests don't impact runtime performance
src/__tests__/
β”œβ”€β”€ setup.ts # Global test setup
β”œβ”€β”€ utils/
β”‚ β”œβ”€β”€ validation.test.ts # Validation utility tests
β”‚ β”œβ”€β”€ errorHandler.test.ts # Error handling tests
β”‚ └── eventEmitter.test.ts # Event system tests
β”œβ”€β”€ storage/
β”‚ └── storage.test.ts # Storage operation tests
β”œβ”€β”€ integration/
β”‚ └── shogunCore.test.ts # Core integration tests
└── browser/
└── compatibility.test.ts # Browser compatibility tests

When adding new tests:

  1. Follow the existing test structure
  2. Use descriptive test names
  3. Test both success and failure cases
  4. Mock external dependencies appropriately
  5. Ensure tests are isolated and repeatable