Feat/add networks (#1303)

* No commit suggestions generated

* No commit suggestions generated

* No commit suggestions generated
This commit is contained in:
Prad Nukala
2025-10-12 11:23:20 -04:00
committed by GitHub
parent 40eadc995e
commit ebfa2b062a
97 changed files with 3979 additions and 16119 deletions
-173
View File
@@ -1,173 +0,0 @@
---
title: Requesting Permissions
description: A guide to setting up and managing wallet connections with the Sonr decentralized identity system
icon: "shield-check"
---
Sonr provides a seamless and secure way for users to connect their wallets to decentralized applications. This guide covers the different methods for establishing and managing wallet connections, from simple browser-based interactions to backend service integrations.
## The Sonr Connection Model
Unlike traditional Web3 wallets that require browser extensions, Sonr uses a combination of WebAuthn and Decentralized Identifiers (DIDs) to create a secure, passwordless connection experience.
<CardGroup>
<Card title="User-Centric" href="/blockchain/modules/did/">
Users control their identity and grant permissions to applications, not the
other way around.
</Card>
<Card title="Passwordless" href="/blockchain/modules/did/">
WebAuthn enables biometric and security key authentication, eliminating the
need for seed phrases.
</Card>
<Card title="Multi-Device" href="/blockchain/modules/dwn/">
Users can securely access their Vault from any device with a modern web
browser.
</Card>
</CardGroup>
## Connecting in the Browser
For web applications, the Sonr SDK provides a simple way to initiate a wallet connection.
<Steps>
<Step>
### 1. Initialize the SDK
First, initialize the Sonr SDK in your application. For this example, we'll use the CDN version.
```html
<script type="module">
import { Sonr } from "https://cdn.jsdelivr.net/npm/@sonr/sdk";
const sonr = new Sonr({ httpUrl: "http://localhost:1317" });
</script>
```
</Step>
<Step>
### 2. Request Authentication
Use the `sonr.authenticate()` method to prompt the user to connect their wallet. This will trigger the browser's WebAuthn flow.
```javascript
async function connectWallet() {
try {
const session = await sonr.authenticate();
console.log("Wallet connected!", session);
// You now have a secure session with the user's Vault
} catch (error) {
console.error("Failed to connect wallet:", error);
}
}
```
</Step>
<Step>
### 3. Handle the Session
The `session` object returned from `authenticate()` contains the user's DID and a UCAN token with the requested permissions. You can use this session to interact with the user's Vault.
```javascript
// Example: Get the user's balance
const balance = await session.vault.getAccountBalance();
console.log("User balance:", balance);
```
</Step>
</Steps>
## Backend Wallet Connections
For backend services, you can use the Sonr SDK to interact with user Vaults on behalf of your application.
<Steps>
<Step>
### 1. Service Registration
Your backend service must be registered on the Sonr network. This provides your service with its own DID and allows it to request permissions from users.
{/* Service registration documentation is referenced but not yet available in the docs structure */}
</Step>
<Step>
### 2. Requesting Permissions
Your service can request permissions from users by generating a UCAN request. This is typically done through a user-facing application.
```typescript
// Example: Requesting permission to read a user's profile
const ucanRequest = await sonr.ucan.request({
audience: "did:sonr:your-service-did",
resource: `dwn://user-did/profile/read`,
});
// Present this request to the user to be signed by their Vault
```
</Step>
<Step>
### 3. Using Delegated Capabilities
Once a user has approved your request, you will receive a delegated UCAN token. You can use this token to perform actions on the user's behalf.
```go
// Example: Using a delegated UCAN in a Go backend
import "github.com/sonr-io/sonr/x/sonr/pkgs/sdk"
func GetUserProfile(userDID string, delegatedUcan string) (*Profile, error) {
sonr, _ := sdk.NewSonr(rpcEndpoint, "")
// Use the delegated UCAN to access the user's profile
profile, err := sonr.GetUserProfile(userDID, delegatedUcan)
if err != nil {
return nil, err
}
return profile, nil
}
```
</Step>
</Steps>
## Managing Connections
### Checking Connection Status
You can check the current connection status at any time:
```javascript
const session = await sonr.getSession();
if (session) {
console.log("User is connected:", session.did);
} else {
console.log("User is not connected.");
}
```
### Disconnecting
To disconnect a wallet, simply clear the session from your application's state:
```javascript
await sonr.logout();
console.log("User has been disconnected.");
```
This will revoke the current session's UCAN token, but it will not remove any permissions the user has granted to your service.
## Security Considerations
- **UCAN Scopes**: Always request the minimum permissions necessary for your application to function.
- **Token Storage**: Securely store delegated UCAN tokens on your backend. Never expose them on the client-side.
- **Revocation**: Your application should handle UCAN revocations gracefully.
## Next Steps
- [Sending Payments](/highway/wallets/sending-payments)
- [Understanding UCANs](/blockchain/modules/svc/ucan)
- [Explore DWN Architecture](/blockchain/modules/dwn/)
-233
View File
@@ -1,233 +0,0 @@
---
title: "Motor WASM Service Worker Usage"
description: "Comprehensive guide to using the Motor WASM service worker for secure browser-based DWN and Wallet APIs"
icon: "microchip"
sidebarTitle: "Motor WASM"
---
<Info>
Motor is a WebAssembly service worker providing secure, client-side cryptographic operations and decentralized web node (DWN) capabilities.
</Info>
## Overview
Motor is a WebAssembly-powered service worker that enables:
- Secure client-side cryptographic operations
- Decentralized Web Node (DWN) APIs
- Cross-platform support for browsers and Node.js
<CardGroup cols={2}>
<Card title="DWN API" icon="database">
Create, read, update, and delete records with optional encryption
</Card>
<Card title="Wallet API" icon="wallet" color="#22863a">
UCAN token generation, digital signatures, and verification
</Card>
</CardGroup>
## Prerequisites
<Check>
- Node.js 20+ and pnpm
- Browser with Service Worker support
- HTTP/HTTPS server for WASM files
</Check>
## Installation
<CodeGroup>
```bash npm
npm install @sonr.io/es
```
```bash pnpm
pnpm add @sonr.io/es
```
```bash yarn
yarn add @sonr.io/es
```
</CodeGroup>
## Usage Examples
### Basic Initialization
<Tabs>
<Tab title="Browser Auto-Detection">
```typescript
import { createMotorPlugin } from '@sonr.io/es/client/motor';
// Automatically detects browser vs Node.js environment
const plugin = await createMotorPlugin();
// Get issuer DID
const issuer = await plugin.getIssuerDID();
console.log('Issuer DID:', issuer.issuer_did);
```
</Tab>
<Tab title="Browser Service Worker">
```typescript
import { createMotorPluginForBrowser } from '@sonr.io/es/client/motor';
const plugin = await createMotorPluginForBrowser('/motor-worker', {
auto_register_worker: true,
worker_scope: '/',
debug: true,
});
// Create UCAN origin token
const tokenResponse = await plugin.newOriginToken({
audience_did: 'did:sonr:audience123',
attenuations: [{ can: ['sign', 'verify'], with: 'vault://my-vault' }],
});
```
</Tab>
<Tab title="Node.js">
```typescript
import { createMotorPluginForNode } from '@sonr.io/es/client/motor';
const plugin = await createMotorPluginForNode('http://localhost:8080', {
max_retries: 3,
retry_delay: 1000,
timeout: 5000,
debug: true,
});
```
</Tab>
</Tabs>
### Record Operations
<CodeGroup>
```typescript DWN Create
const createResult = await plugin.createRecord({
schema: 'https://schema.org/Person',
data: JSON.stringify({ name: 'Alice Smith' }),
is_encrypted: false,
});
```
```typescript DWN Read
const record = await plugin.readRecord({
record_id: createResult.record_id,
});
```
```typescript DWN Update
await plugin.updateRecord({
record_id: createResult.record_id,
data: JSON.stringify({ name: 'Alice Johnson' }),
});
```
```typescript DWN Delete
const deleteResult = await plugin.deleteRecord({
record_id: createResult.record_id,
});
```
</CodeGroup>
### Encrypted Records
```typescript
const sensitiveData = {
ssn: '123-45-6789',
medical_record: 'Confidential information',
};
const encryptedRecord = await plugin.createRecord({
schema: 'https://schema.org/MedicalRecord',
data: JSON.stringify(sensitiveData),
is_encrypted: true, // Enable encryption
});
// Automatic decryption on read
const decryptedRecord = await plugin.readRecord({
record_id: encryptedRecord.record_id,
});
```
## Deployment
<Tabs>
<Tab title="Development">
```bash
cd dist/wasm
python3 -m http.server 8080
# Access at http://localhost:8080/test.html
```
</Tab>
<Tab title="Production (Nginx)">
```nginx
location /motor/ {
alias /path/to/dist/wasm/;
# CORS and MIME types
add_header 'Access-Control-Allow-Origin' '*';
location ~ \.wasm$ {
add_header 'Content-Type' 'application/wasm';
}
}
```
</Tab>
<Tab title="CDN">
```html
<script src="https://cdn.example.com/motor/wasm_exec.js"></script>
<script>
navigator.serviceWorker.register(
'https://cdn.example.com/motor/motr-sw.js'
);
</script>
```
</Tab>
</Tabs>
## Troubleshooting
<Accordion title="Common Issues">
<Accordion.Panel title="Service Worker Not Registering">
- Ensure HTTPS or localhost
- Check browser console
- Verify service worker file path
</Accordion.Panel>
<Accordion.Panel title="WASM Module Loading">
- Check MIME type: `application/wasm`
- Verify CORS headers
- Match `wasm_exec.js` with Go version
</Accordion.Panel>
</Accordion>
## Browser Compatibility
| Browser | Minimum Version | Support |
|---------|----------------|---------|
| Chrome | 89+ | Full |
| Firefox | 89+ | Full |
| Safari | 15.4+ | Good |
| Edge | 89+ | Full |
<Warning>
Requires HTTPS or localhost for service worker functionality
</Warning>
## Performance Tips
<Tip>
- Use TinyGo for smaller WASM binaries
- Enable browser caching
- Lazy load Motor plugin
- Limit service worker scope
</Tip>
## Support
- **GitHub**: [Issues](https://github.com/sonr-io/sonr/issues)
- **Docs**: [Motor WASM Documentation](https://docs.sonr.io/motor-wasm)
- **Discord**: [Sonr Community](https://discord.gg/sonr)
-172
View File
@@ -1,172 +0,0 @@
---
title: "PDK Environment Configuration"
description: "Comprehensive guide to configuring the Pluggable Development Kit (PDK) for Sonr plugins"
icon: "gear"
---
# PDK Environment Configuration
The Pluggable Development Kit (PDK) provides a flexible configuration system for managing plugin environments, MPC enclaves, and runtime settings.
## Environment Variables
### Core PDK Variables
| Variable | Type | Description | Default |
| -------------- | -------- | --------------------------------- | ------------------ |
| `chain_id` | `string` | Target blockchain network | `"sonr-testnet-1"` |
| `enclave` | `object` | MPC enclave configuration | `{}` |
| `vault_config` | `object` | Vault and key management settings | `{}` |
| `log_level` | `string` | Logging verbosity | `"info"` |
## Enclave Configuration
### Basic Enclave Setup
```json
{
"enclave": {
"id": "unique-enclave-identifier",
"key_type": "secp256k1",
"threshold": 2,
"participants": [
{ "id": "participant1", "public_key": "..." },
{ "id": "participant2", "public_key": "..." }
]
}
}
```
### Advanced Enclave Parameters
```json
{
"enclave": {
"security_level": "high",
"attestation_mode": "remote",
"key_rotation_interval": "1h",
"backup_strategy": "distributed"
}
}
```
## Vault Configuration
### Key Management Settings
```json
{
"vault_config": {
"storage_backend": "ipfs",
"encryption": {
"algorithm": "aes-256-gcm",
"key_derivation": "pbkdf2"
},
"access_control": {
"mode": "role-based",
"default_role": "viewer"
}
}
}
```
## Logging Configuration
```json
{
"log_level": "debug",
"log_format": "json",
"log_outputs": [
{ "type": "stdout" },
{ "type": "file", "path": "/var/log/sonr/pdk.log" }
]
}
```
## Performance Tuning
```json
{
"performance": {
"max_concurrent_tasks": 10,
"task_timeout": "5m",
"memory_limit": "512MB",
"cpu_allocation": 2
}
}
```
## Security Hardening
```json
{
"security": {
"require_mfa": true,
"allowed_key_types": ["secp256k1", "ed25519"],
"audit_logging": true,
"rate_limiting": {
"max_requests_per_minute": 100
}
}
}
```
## Plugin-Specific Configuration
```json
{
"plugins": {
"motor": {
"mpc_mode": "distributed",
"token_generation_rate_limit": 10
},
"did": {
"supported_methods": ["did:key", "did:sonr"]
}
}
}
```
## Environment Loading Precedence
1. Environment Variables
2. Configuration Files
3. Default Values
## Best Practices
- Use environment-specific configurations
- Implement strict access controls
- Rotate encryption keys regularly
- Monitor and log configuration changes
- Use minimal privilege principles
## Example Configuration Loading
```go
func loadPDKConfiguration() (*PDKConfig, error) {
// Load from environment variables
config := &PDKConfig{}
// Override with config file if exists
configFile, err := ioutil.ReadFile("/etc/sonr/pdk.json")
if err == nil {
json.Unmarshal(configFile, config)
}
return config, nil
}
```
## Troubleshooting
- Check `log_level` for detailed diagnostics
- Validate JSON configuration syntax
- Verify key and enclave configurations
## Advanced Topics
For more complex PDK configurations, refer to:
- [DWN Plugin Documentation](/blockchain/modules/dwn/plugin)
- [DWN Architecture Overview](/blockchain/modules/dwn/architecture)
-438
View File
@@ -1,438 +0,0 @@
---
title: "Sign in with Sonr: Developer Guide"
description: "OAuth 2.0 authentication for decentralized applications with UCAN capabilities"
sidebarTitle: "Sign in with Sonr"
icon: "key"
---
<Info>
This guide covers OAuth 2.0 authentication for decentralized applications using Sonr's advanced Web3 capabilities.
</Info>
## Overview
Sign in with Sonr provides OAuth 2.0 authentication for decentralized applications, combining traditional OAuth flows with Web3 capabilities through UCAN (User Controlled Authorization Networks) delegation.
<CardGroup cols={2}>
<Card title="OAuth 2.0 + OIDC" icon="lock">
Industry-standard authentication with OpenID Connect
</Card>
<Card title="WebAuthn Support" icon="fingerprint">
Passwordless authentication with hardware security
</Card>
<Card title="UCAN Capabilities" icon="network">
Fine-grained permission delegation for Web3
</Card>
<Card title="Decentralized Identity" icon="id-card">
W3C DID-based identity management
</Card>
</CardGroup>
## Quick Start
### Installation
<CodeGroup>
```bash npm
npm install @sonr.io/ui
```
```bash pnpm
pnpm add @sonr.io/ui
```
```bash yarn
yarn add @sonr.io/ui
```
</CodeGroup>
### Basic Implementation
<CodeGroup>
```tsx React
import { SignInWithSonr } from '@sonr.io/ui';
function App() {
return (
<SignInWithSonr
clientId="your-client-id"
redirectUri="http://localhost:3000/callback"
scopes={['openid', 'profile', 'vault:read']}
/>
);
}
```
</CodeGroup>
## Configuration
### OAuth Client Registration
<CodeGroup>
```typescript Configuration
const clientConfig = {
clientId: 'your-client-id',
clientSecret: 'your-client-secret', // Only for confidential clients
redirectUris: ['http://localhost:3000/callback'],
grantTypes: ['authorization_code', 'refresh_token'],
responseTypes: ['code'],
scopes: ['openid', 'profile', 'vault:read', 'vault:write'],
tokenEndpointAuthMethod: 'none', // For public clients
};
```
</CodeGroup>
### Environment Variables
<CodeGroup>
```env OAuth Endpoints
# OAuth Endpoints
NEXT_PUBLIC_SONR_CLIENT_ID=your-client-id
NEXT_PUBLIC_REDIRECT_URI=http://localhost:3000/callback
NEXT_PUBLIC_AUTH_URL=https://auth.sonr.io/oauth/authorize
NEXT_PUBLIC_TOKEN_URL=https://auth.sonr.io/oauth/token
NEXT_PUBLIC_USERINFO_URL=https://auth.sonr.io/oauth/userinfo
```
</CodeGroup>
## OAuth Scopes & UCAN Capabilities
<Tabs>
<Tab title="Standard Scopes">
<table>
<thead>
<tr>
<th>Scope</th>
<th>Description</th>
<th>UCAN Capabilities</th>
</tr>
</thead>
<tbody>
<tr>
<td>`openid`</td>
<td>OpenID Connect identity</td>
<td>Basic identity claims</td>
</tr>
<tr>
<td>`profile`</td>
<td>User profile information</td>
<td>Name, picture, metadata</td>
</tr>
<tr>
<td>`email`</td>
<td>Email address</td>
<td>Email and verification status</td>
</tr>
<tr>
<td>`offline_access`</td>
<td>Refresh token issuance</td>
<td>Long-lived access</td>
</tr>
</tbody>
</table>
</Tab>
<Tab title="Vault Scopes">
<table>
<thead>
<tr>
<th>Scope</th>
<th>Description</th>
<th>UCAN Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>`vault:read`</td>
<td>Read vault contents</td>
<td>`vault/read`, `vault/list`</td>
</tr>
<tr>
<td>`vault:write`</td>
<td>Modify vault contents</td>
<td>`vault/write`, `vault/create`, `vault/update`</td>
</tr>
<tr>
<td>`vault:delete`</td>
<td>Delete vault items</td>
<td>`vault/delete`</td>
</tr>
<tr>
<td>`vault:admin`</td>
<td>Full vault control</td>
<td>All vault actions</td>
</tr>
</tbody>
</table>
</Tab>
</Tabs>
## Integration Examples
<Tabs>
<Tab title="React Hooks">
<CodeGroup>
```tsx React Hooks
import { useSignInWithSonr } from '@sonr.io/ui';
function LoginComponent() {
const {
user,
token,
isAuthenticated,
isLoading,
signIn,
signOut,
refreshToken,
} = useSignInWithSonr({
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000/callback',
scopes: ['openid', 'profile', 'vault:read'],
});
if (isLoading) return <div>Loading...</div>;
if (isAuthenticated) {
return (
<div>
<p>Welcome, {user.name}!</p>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
return <button onClick={signIn}>Sign in with Sonr</button>;
}
```
</CodeGroup>
</Tab>
<Tab title="Next.js App Router">
<CodeGroup>
```tsx Next.js Layout
// app/layout.tsx
import { AuthProvider } from '@/components/AuthProvider';
export default function RootLayout({ children }) {
return (
<html>
<body>
<AuthProvider>{children}</AuthProvider>
</body>
</html>
);
}
```
```tsx Auth Provider
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
import { OAuth2Client } from '@sonr.io/ui';
const AuthContext = createContext();
export function AuthProvider({ children }) {
const [client] = useState(() => new OAuth2Client({
clientId: process.env.NEXT_PUBLIC_SONR_CLIENT_ID,
redirectUri: process.env.NEXT_PUBLIC_REDIRECT_URI,
}));
// ... authentication logic
return (
<AuthContext.Provider value={{ client, /* ... */ }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);
```
</CodeGroup>
</Tab>
</Tabs>
## Advanced Features
### Custom Authorization
<CodeGroup>
```tsx Custom Authorization
<SignInWithSonr
clientId="your-client-id"
redirectUri="http://localhost:3000/callback"
authorizationUrl="https://auth.sonr.io/oauth/authorize"
state={generateRandomState()} // CSRF protection
scopes={['openid', 'profile', 'vault:admin']}
// Additional parameters
onAuthStart={() => console.log('Starting auth...')}
onAuthError={(error) => console.error('Auth failed:', error)}
/>
```
</CodeGroup>
### Token Management
<CodeGroup>
```typescript Token Management
const client = new OAuth2Client(config);
// Check authentication status
if (client.isAuthenticated()) {
// Get current access token
const accessToken = client.getAccessToken();
// Refresh token before expiry
const newToken = await client.refreshToken();
// Get user information
const userInfo = await client.getUserInfo();
// Revoke tokens on logout
await client.logout();
}
```
</CodeGroup>
## Security Considerations
<Warning>
Always implement robust security practices when integrating authentication.
</Warning>
### PKCE Implementation
<CodeGroup>
```typescript PKCE Configuration
const client = new OAuth2Client({
clientId: 'public-client',
pkce: true, // Enabled by default for public clients
});
```
</CodeGroup>
### State Parameter Prevention
<CodeGroup>
```typescript State Validation
// Generate random state
const state = crypto.randomUUID();
sessionStorage.setItem('oauth_state', state);
// Validate on callback
const returnedState = params.get('state');
const savedState = sessionStorage.getItem('oauth_state');
if (returnedState !== savedState) {
throw new Error('State mismatch - possible CSRF attack');
}
```
</CodeGroup>
## Troubleshooting
<Accordion title="Common Authentication Issues">
<AccordionItem title="CORS Errors">
- Ensure your redirect URI is whitelisted
- Check allowed origins in OAuth server config
</AccordionItem>
<AccordionItem title="Invalid Grant">
- Authorization code can only be used once
- Code expires after 10 minutes
- Verify redirect URI matches exactly
</AccordionItem>
<AccordionItem title="Token Expiry">
- Implement automatic refresh before expiry
- Handle refresh token rotation
</AccordionItem>
</Accordion>
<Note>
Enable debug mode for additional troubleshooting insights:
```typescript
const client = new OAuth2Client({
clientId: 'your-client-id',
debug: true, // Enable console logging
});
```
</Note>
## API Reference
### SignInWithSonr Props
```typescript
interface SignInWithSonrProps {
clientId: string;
redirectUri: string;
authorizationUrl?: string;
scopes?: string[];
state?: string;
variant?: 'default' | 'outline' | 'ghost' | 'dark';
size?: 'default' | 'sm' | 'lg';
isLoading?: boolean;
text?: string;
showLogo?: boolean;
onAuthStart?: () => void;
onAuthError?: (error: Error) => void;
}
```
## Resources
<CardGroup cols={2}>
<Card
title="OAuth 2.0 Specification"
href="https://datatracker.ietf.org/doc/html/rfc6749"
>
RFC 6749 - OAuth 2.0 Authorization Framework
</Card>
<Card
title="OpenID Connect"
href="https://openid.net/specs/openid-connect-core-1_0.html"
>
Core specification for identity layers
</Card>
<Card
title="UCAN Specification"
href="https://github.com/ucan-wg/spec"
>
User Controlled Authorization Networks
</Card>
<Card
title="WebAuthn"
href="https://www.w3.org/TR/webauthn/"
>
Web Authentication API specification
</Card>
</CardGroup>
## Support
<CardGroup cols={3}>
<Card
title="GitHub"
icon="github"
href="https://github.com/sonr-io/sonr"
>
Report issues or contribute
</Card>
<Card
title="Documentation"
icon="book"
href="https://sonr.dev"
>
Explore full documentation
</Card>
<Card
title="Discord"
icon="discord"
href="https://discord.gg/sonr"
>
Join our community
</Card>
</CardGroup>
-286
View File
@@ -1,286 +0,0 @@
---
title: "Sonr Vault Plugin with Dexie.js Persistence"
description: "Comprehensive guide to using the Sonr Vault Plugin with persistent storage and multi-account support"
sidebarTitle: "Vault Plugin Usage"
icon: "lock"
---
# Sonr Vault Plugin: Persistent Storage and Account Management
## Overview
The Sonr Vault Plugin provides a powerful, secure, and flexible way to manage cryptographic operations with persistent storage using Dexie.js and IndexedDB. This guide will walk you through the plugin's features, setup, and advanced usage patterns.
<Callout type="info">
**Key Features**
- 🔐 Account-based database separation
- 💾 Automatic token persistence
- 🔄 Cross-browser IndexedDB support
- ⚡ Backward compatibility
- 🧹 Automatic token and session cleanup
</Callout>
## Installation
Install the Sonr Vault Plugin in your project:
<CodeGroup>
```bash npm
npm install @sonr.io/es
```
```bash yarn
yarn add @sonr.io/es
```
```bash pnpm
pnpm add @sonr.io/es
```
</CodeGroup>
## Basic Usage
### Without Persistence (Default)
The vault plugin is designed to be backward compatible. By default, it operates without persistent storage:
```typescript
import { createVaultClient } from '@sonr.io/es/plugins/vault';
// Create a vault client without persistence
const vault = createVaultClient();
// Initialize the vault
await vault.initialize();
// Create tokens and perform operations as before
const token = await vault.newOriginToken({
audience_did: 'did:example:123',
});
```
### With Persistence Enabled
Enable persistent storage with a simple configuration:
```typescript
import { createVaultClient } from '@sonr.io/es/plugins/vault';
// Create a vault client with persistence
const vault = createVaultClient({
enablePersistence: true,
autoCleanup: true, // Automatically clean up expired tokens
cleanupInterval: 3600000 // Cleanup every hour (in milliseconds)
});
// Initialize with an account address for database separation
const accountAddress = 'sonr1abc123...';
await vault.initialize('/plugin.wasm', accountAddress);
// Tokens are now automatically persisted
const token = await vault.newOriginToken({
audience_did: 'did:example:123',
});
```
## Advanced Features
### Multi-Account Support
Seamlessly switch between accounts and manage their individual databases:
```typescript
// Switch to a different account
await vault.switchAccount('sonr1account2');
// List all accounts with persisted data
const accounts = await vault.listPersistedAccounts();
// Remove an account's data
await vault.removeAccount('sonr1account1');
```
### Token Management
Manually manage persisted tokens:
```typescript
// Get all saved tokens
const tokens = await vault.getPersistedTokens();
// Save a specific token
await vault.saveToken({
token: 'eyJ...',
issuer: 'did:sonr:example',
address: 'sonr1abc...',
});
// Remove expired tokens
await vault.removeExpiredTokens();
```
### State Management
Control vault state persistence:
```typescript
// Manually save current state
await vault.persistState();
// Load persisted state
const state = await vault.loadPersistedState();
// Clear all persisted data for the current account
await vault.clearPersistedState();
```
## Storage Management
Use the `VaultStorageManager` for advanced storage operations:
```typescript
import { VaultStorageManager } from '@sonr.io/es/plugins/vault';
const storageManager = new VaultStorageManager({
enablePersistence: true,
});
// Request persistent storage
const isPersisted = await storageManager.requestPersistentStorage();
// Check storage status and estimate
const status = await storageManager.tryPersistWithoutPromptingUser();
const estimate = await storageManager.getStorageEstimate();
```
## Configuration Options
Customize the vault's storage behavior:
<TypeTable
columns={[
{ name: 'enablePersistence', type: 'boolean', description: 'Enable IndexedDB storage' },
{ name: 'storageQuotaRequest', type: 'number', description: 'Storage quota to request in bytes' },
{ name: 'autoCleanup', type: 'boolean', description: 'Enable automatic token/session cleanup' },
{ name: 'cleanupInterval', type: 'number', description: 'Cleanup interval in milliseconds' }
]}
/>
## Browser Compatibility
The Vault Plugin works with most modern browsers:
<Table>
<TableHead>
<TableRow>
<TableCell>Browser</TableCell>
<TableCell>Minimum Version</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Chrome/Edge</TableCell>
<TableCell>23+</TableCell>
</TableRow>
<TableRow>
<TableCell>Firefox</TableCell>
<TableCell>16+</TableCell>
</TableRow>
<TableRow>
<TableCell>Safari</TableCell>
<TableCell>10+</TableCell>
</TableRow>
<TableRow>
<TableCell>Opera</TableCell>
<TableCell>15+</TableCell>
</TableRow>
<TableRow>
<TableCell>iOS Safari</TableCell>
<TableCell>10+</TableCell>
</TableRow>
<TableRow>
<TableCell>Chrome for Android</TableCell>
<TableCell>All versions</TableCell>
</TableRow>
</TableBody>
</Table>
## Storage Limits
Storage availability varies by browser:
<Table>
<TableHead>
<TableRow>
<TableCell>Browser</TableCell>
<TableCell>Storage Limit</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Chrome/Edge</TableCell>
<TableCell>60% of total disk space</TableCell>
</TableRow>
<TableRow>
<TableCell>Firefox</TableCell>
<TableCell>50% of free disk space</TableCell>
</TableRow>
<TableRow>
<TableCell>Safari</TableCell>
<TableCell>Starts at 1GB, can request more</TableCell>
</TableRow>
<TableRow>
<TableCell>Mobile Browsers</TableCell>
<TableCell>Varies by device</TableCell>
</TableRow>
</TableBody>
</Table>
## Security Considerations
<Callout type="warning">
- Databases are isolated by account address
- No private keys or sensitive cryptographic material are stored
- Only UCAN tokens and metadata are persisted
- Always use HTTPS in production
- Consider encrypting sensitive data before storage
</Callout>
## Troubleshooting
### Storage Not Persisting
1. Verify you're running on HTTPS
2. Check that IndexedDB is enabled in browser settings
3. Confirm available storage quota
4. Explicitly request persistent storage
```typescript
try {
await vault.initialize('/plugin.wasm', accountAddress);
} catch (error) {
if (error.code === 'VAULT_NOT_INITIALIZED') {
// Handle initialization error
}
}
```
## Migration Guide
To migrate from non-persistent to persistent storage:
```typescript
// Before (non-persistent)
const vault = createVaultClient();
await vault.initialize();
// After (with persistence)
const vault = createVaultClient({
enablePersistence: true,
});
await vault.initialize('/plugin.wasm', accountAddress);
```
<Callout type="success">
**No other code changes are required!** All existing methods work the same way.
</Callout>
-191
View File
@@ -1,191 +0,0 @@
---
title: Getting Started with Browser/ESM
description: A quick start guide for using Sonr in web browsers with WebAuthn integration
sidebarTitle: Browser Quickstart
icon: "globe"
---
This guide will walk you through creating a simple web application that interacts with the Sonr network directly from the browser. We will use the Sonr JavaScript SDK to create a new user identity, claim a Vault, and send a transaction.
## Prerequisites
- A local Sonr network running. See the [Validator Setup Guide](/quickstart/validators) for instructions
- A modern web browser with WebAuthn support (Chrome, Firefox, Safari, Edge)
## 1. Project Setup
<Steps>
<Step>
### Create an HTML File
Create a new `index.html` file and add the following basic structure:
```html
<!DOCTYPE html>
<html>
<head>
<title>Sonr Browser Quickstart</title>
<script type="module" src="app.js"></script>
</head>
<body>
<h1>Sonr Browser Quickstart</h1>
<button id="create-identity">Create Identity</button>
<div id="output"></div>
</body>
</html>
```
</Step>
<Step>
### Create a JavaScript File
Create a new `app.js` file in the same directory. This is where we will write our application logic.
</Step>
<Step>
### Install the Sonr SDK
For this quickstart, we will use the Sonr SDK from a CDN. Add the following script tag to the `<head>` of your `index.html` file:
```html
<script type="module">
import { Sonr, WebAuthn } from "https://cdn.jsdelivr.net/npm/@sonr/sdk";
window.Sonr = Sonr;
window.WebAuthn = WebAuthn;
</script>
```
</Step>
</Steps>
## 2. Creating an Identity
Now, let's add the logic to create a new user identity and claim a Vault.
<Steps>
<Step>
### Add Event Listener
In `app.js`, add an event listener to the "Create Identity" button:
```javascript
document
.getElementById("create-identity")
.addEventListener("click", async () => {
const output = document.getElementById("output");
output.innerHTML = "Creating identity...";
try {
// Code to create identity will go here
} catch (error) {
output.innerHTML = `Error: ${error.message}`;
}
});
```
</Step>
<Step>
### Implement Identity Creation
Inside the event listener, use the `WebAuthn.createCredential` method to create a new WebAuthn credential and the `Sonr.claimVault` method to claim a new Vault on the network.
```javascript
// Inside the try block
const credential = await WebAuthn.createCredential({
rp: { name: "Sonr Quickstart" },
user: {
id: new Uint8Array(16), // Should be a unique user ID
name: "user@example.com",
displayName: "Test User",
},
});
output.innerHTML = `Credential created: ${credential.id}`;
const sonr = new Sonr({ httpUrl: "http://localhost:1317" });
const vault = await sonr.claimVault(credential);
output.innerHTML = `Vault claimed! DID: ${vault.did}`;
```
<Note type="warning">
In a real application, the user ID should be a unique and stable identifier
for the user, not a random value.
</Note>
</Step>
</Steps>
## 3. Running the Application
To run the application, you need a simple web server. You can use the `http-server` package for this.
```bash
# Install http-server
npm install -g http-server
# Start the server
http-server
```
Now, open your browser and navigate to `http://localhost:8080`. When you click the "Create Identity" button, your browser will prompt you to create a new passkey using your device's biometrics or a security key.
## 4. Sending a Transaction
Once you have a Vault, you can use it to send transactions.
<Steps>
<Step>
### Add a Send Button
Add a new button to your `index.html` file:
```html
<button id="send-transaction" disabled>Send Transaction</button>
```
</Step>
<Step>
### Implement Transaction Sending
In `app.js`, add an event listener to the new button. This will use the `sonr.send` method to send a transaction.
```javascript
let vaultInstance;
// After claiming the vault...
vaultInstance = vault;
document.getElementById("send-transaction").disabled = false;
document
.getElementById("send-transaction")
.addEventListener("click", async () => {
const output = document.getElementById("output");
output.innerHTML = "Sending transaction...";
try {
const result = await vaultInstance.send({
to: "snr1..._recipient_address_...",
amount: "1000000usnr", // 1 SNR
});
output.innerHTML = `Transaction successful! TxHash: ${result.txhash}`;
} catch (error) {
output.innerHTML = `Error: ${error.message}`;
}
});
```
</Step>
</Steps>
## Next Steps
Congratulations! You have successfully created a web application that interacts with the Sonr network. From here, you can explore more advanced features:
- **Service Registration**: Register your application as a trusted service on the network
- **UCAN Authorization**: Request and manage user permissions for your application
- **Cross-Chain Operations**: Interact with other blockchains through IBC
-521
View File
@@ -1,521 +0,0 @@
---
title: Getting Started with Golang
description: A quick start guide for building applications with Sonr using the Go Client SDK
sidebarTitle: Golang Quickstart
icon: "golang"
---
This guide provides a walkthrough for setting up a Go project to interact with the Sonr network using the official Go Client SDK. You will learn how to configure the client, manage keys, query the blockchain, send transactions, and use advanced features like WebAuthn gasless transactions.
## Prerequisites
- A local Sonr network running. See the [Validator Setup Guide](/quickstart/validators) for instructions
- Go version 1.24 or higher
## 1. Project Setup
<Steps>
<Step>
### Initialize a Go Module
Create a new directory for your project and initialize a Go module:
```bash
mkdir sonr-go-quickstart
cd sonr-go-quickstart
go mod init github.com/your-username/sonr-go-quickstart
```
</Step>
<Step>
### Add the Sonr Client SDK Dependency
Add the Sonr Client SDK to your project's dependencies:
```bash
go get github.com/sonr-io/sonr/client
```
</Step>
</Steps>
## 2. Client Configuration and Setup
Let's set up the Sonr client with proper configuration and key management.
<Steps>
<Step>
### Create the Main File
Create a new file named `main.go`.
</Step>
<Step>
### Initialize the Client
Add the following code to `main.go` to initialize the Sonr client:
```go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/sonr-io/sonr/client/config"
"github.com/sonr-io/sonr/client/keys"
"github.com/sonr-io/sonr/client/sonr"
"github.com/sonr-io/sonr/client/tx"
)
func main() {
// Use local network configuration
cfg := config.LocalNetwork()
// Establish gRPC connection
conn, err := grpc.Dial(
cfg.GRPC,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatal("Failed to connect:", err)
}
defer conn.Close()
// Create the Sonr client
client, err := sonr.NewClient(&cfg, conn)
if err != nil {
log.Fatal("Failed to create client:", err)
}
fmt.Println("Sonr client initialized successfully!")
fmt.Printf("Connected to: %s\n", cfg.ChainID)
}
```
</Step>
<Step>
### Create a Keyring Manager
Add key management to handle wallet operations:
```go
// Initialize keyring manager (using test backend for development)
keyringManager, err := keys.NewKeyringManager(
"test", // backend: test, file, os
".sonr-keys", // directory for keys
cfg.ChainID, // chain ID
)
if err != nil {
log.Fatal("Failed to create keyring:", err)
}
// Create a new wallet
walletIdentity, mnemonic, err := keyringManager.CreateWallet(
context.Background(),
"my-wallet", // wallet name
"", // passphrase (empty for test backend)
)
if err != nil {
log.Fatal("Failed to create wallet:", err)
}
fmt.Printf("Wallet created!\n")
fmt.Printf("Address: %s\n", walletIdentity.Address)
fmt.Printf("DID: %s\n", walletIdentity.DID)
fmt.Printf("Mnemonic: %s\n", mnemonic)
```
<Note type="warning">
**Important**: In production, use secure keyring backends like "os" or "file" with proper passphrase protection. Never expose mnemonics in your code.
</Note>
</Step>
</Steps>
## 3. Querying the Blockchain
Now, let's query the blockchain using the unified query client.
<Steps>
<Step>
### Create a Query Client
Add the query client to your application:
```go
import (
"github.com/sonr-io/sonr/client/query"
)
// Create query client
queryClient, err := query.NewQueryClient(conn, &cfg)
if err != nil {
log.Fatal("Failed to create query client:", err)
}
```
</Step>
<Step>
### Query Account Balance
Query an account's balance:
```go
// Query account balance
address := walletIdentity.Address // or any other address
balance, err := queryClient.Balance(
context.Background(),
address,
cfg.StakingDenom, // "usnr"
)
if err != nil {
log.Printf("Failed to query balance: %v", err)
} else {
fmt.Printf("Balance for %s: %s %s\n",
address,
balance.Balance.Amount.String(),
balance.Balance.Denom,
)
}
// Query all balances for an account
allBalances, err := queryClient.AllBalances(
context.Background(),
address,
nil, // pagination
)
if err != nil {
log.Printf("Failed to query all balances: %v", err)
} else {
fmt.Printf("All balances: %v\n", allBalances.Balances)
}
```
</Step>
<Step>
### Query Module-Specific Data
Query DID documents and other module data:
```go
import (
"github.com/sonr-io/sonr/client/modules/did"
)
// Create DID module client
didClient := did.NewDIDClient()
// Query DID document (if exists)
didID := "did:sonr:example123"
didDoc, err := queryClient.GetDID(context.Background(), didID)
if err != nil {
log.Printf("DID not found: %v", err)
} else {
fmt.Printf("DID Document: %+v\n", didDoc)
}
// List all DIDs with pagination
didList, err := queryClient.ListDIDs(
context.Background(),
&query.ListOptions{
Limit: 10,
Offset: 0,
},
)
if err != nil {
log.Printf("Failed to list DIDs: %v", err)
} else {
fmt.Printf("Found %d DIDs\n", len(didList.DIDs))
}
```
</Step>
</Steps>
## 4. Building and Broadcasting Transactions
Let's build and broadcast transactions using the transaction builder.
<Steps>
<Step>
### Create a Transaction Builder
Initialize the transaction builder with gas estimation:
```go
// Create transaction builder
txBuilder, err := tx.NewTxBuilder(&cfg, conn)
if err != nil {
log.Fatal("Failed to create tx builder:", err)
}
// Create broadcaster
broadcaster, err := tx.NewBroadcaster(&cfg, conn)
if err != nil {
log.Fatal("Failed to create broadcaster:", err)
}
// Create gas estimator
gasEstimator := tx.NewGasEstimator(conn, &cfg)
```
</Step>
<Step>
### Send Tokens Between Accounts
Build and broadcast a bank send transaction:
```go
import (
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
// Create a second wallet to receive funds
receiver, _, err := keyringManager.CreateWallet(
context.Background(),
"receiver-wallet",
"",
)
if err != nil {
log.Fatal("Failed to create receiver wallet:", err)
}
// Create send message
amount := sdk.NewCoins(sdk.NewInt64Coin("usnr", 1000000)) // 1 SNR
sendMsg := &banktypes.MsgSend{
FromAddress: walletIdentity.Address,
ToAddress: receiver.Address,
Amount: amount,
}
// Build transaction
txBuilder = txBuilder.
AddMessage(sendMsg).
WithMemo("Test transaction").
WithGasLimit(200000)
// Estimate gas
gasEstimate, err := gasEstimator.EstimateGas(
context.Background(),
[]sdk.Msg{sendMsg},
)
if err != nil {
log.Printf("Gas estimation failed: %v", err)
} else {
fmt.Printf("Estimated gas: %d\n", gasEstimate.GasLimit)
txBuilder = txBuilder.WithGasLimit(gasEstimate.GasLimit)
}
// Calculate and set fee
fee := gasEstimator.CalculateFee(
gasEstimate.GasLimit,
cfg.GasPrice,
cfg.StakingDenom,
)
txBuilder = txBuilder.WithFee(fee)
// Sign the transaction
signedTx, err := txBuilder.Sign(context.Background(), keyringManager)
if err != nil {
log.Fatal("Failed to sign transaction:", err)
}
// Broadcast the transaction
result, err := broadcaster.BroadcastTx(context.Background(), signedTx)
if err != nil {
log.Fatal("Failed to broadcast transaction:", err)
}
fmt.Printf("Transaction successful!\n")
fmt.Printf("TxHash: %s\n", result.TxHash)
fmt.Printf("Height: %d\n", result.Height)
fmt.Printf("Gas Used: %d\n", result.GasUsed)
```
</Step>
</Steps>
## 5. WebAuthn Gasless Transactions (Advanced)
Sonr supports gasless WebAuthn registration, allowing users to onboard without holding tokens.
<Steps>
<Step>
### Initialize WebAuthn Client
Set up the WebAuthn client for gasless operations:
```go
import (
"github.com/sonr-io/sonr/client/auth"
)
// Create WebAuthn client
webauthnClient := auth.NewWebAuthnClient(
keyringManager,
"localhost", // Relying Party ID
"Sonr Local", // Relying Party Name
)
// Create gasless transaction manager
gaslessManager := auth.NewGaslessTransactionManager(
txBuilder,
broadcaster,
&cfg,
)
// Create WebAuthn gasless client
gaslessClient := auth.NewWebAuthnGaslessClient(
webauthnClient,
gaslessManager,
&cfg,
)
```
</Step>
<Step>
### Initiate Gasless Registration
Start a gasless WebAuthn registration:
```go
// Begin gasless registration
registrationResult, err := gaslessClient.RegisterGasless(
context.Background(),
"alice", // username
"Alice Smith", // display name
)
if err != nil {
log.Fatal("Failed to initiate registration:", err)
}
fmt.Printf("Registration initiated!\n")
fmt.Printf("Gasless eligible: %v\n", registrationResult.GaslessEligible)
fmt.Printf("Estimated gas: %d\n", registrationResult.EstimatedGas)
// The challenge would be sent to a browser for completion
// In a real application, you'd handle the browser response
```
</Step>
<Step>
### Check Gasless Eligibility
Verify if a transaction is eligible for gasless processing:
```go
// Check if messages are eligible for gasless
msgs := []sdk.Msg{
&didtypes.MsgRegisterWebAuthnCredential{
Controller: "sonr1...",
Username: "alice",
},
}
isEligible := gaslessManager.IsEligibleForGasless(msgs)
fmt.Printf("Transaction eligible for gasless: %v\n", isEligible)
// Estimate gas for gasless transaction
gasNeeded := gaslessManager.EstimateGaslessGas(
"/did.v1.MsgRegisterWebAuthnCredential",
)
fmt.Printf("Gas needed for gasless WebAuthn: %d\n", gasNeeded)
```
</Step>
</Steps>
## 6. Working with DID Module
Create and manage decentralized identities:
<Steps>
<Step>
### Create a DID Document
```go
import (
didtypes "github.com/sonr-io/sonr/x/did/types"
)
// Create DID document
didDoc := &didtypes.DidDocument{
Id: "did:sonr:" + walletIdentity.Address,
Controller: walletIdentity.Address,
VerificationMethod: []*didtypes.VerificationMethod{
{
Id: "did:sonr:" + walletIdentity.Address + "#key-1",
VerificationMethodKind: didtypes.VerificationMethodKind_Ed25519VerificationKey2020,
Controller: "did:sonr:" + walletIdentity.Address,
PublicKeyMultibase: "z6MkhaXgBZD...", // Your public key
},
},
Service: []*didtypes.Service{
{
Id: "did:sonr:" + walletIdentity.Address + "#dwn",
ServiceKind: didtypes.ServiceKind_DecentralizedWebNode,
SingleEndpoint: "https://dwn.example.com",
},
},
}
// Create the message
createDIDMsg, err := didClient.CreateDID(
walletIdentity.Address,
didDoc,
)
if err != nil {
log.Fatal("Failed to create DID message:", err)
}
// Add to transaction and broadcast
txBuilder = txBuilder.
ClearMessages().
AddMessage(createDIDMsg).
WithMemo("Create DID")
// Sign and broadcast as shown earlier
```
</Step>
</Steps>
## Next Steps
This quickstart has covered the fundamentals of the Sonr Go Client SDK:
- **Client Configuration**: Setting up connections and network configurations
- **Key Management**: Creating and managing wallets with the keyring
- **Querying**: Reading blockchain state and module data
- **Transactions**: Building, signing, and broadcasting transactions
- **Gas Estimation**: Calculating optimal gas limits and fees
- **WebAuthn**: Gasless onboarding with WebAuthn credentials
- **DID Module**: Creating decentralized identities
### Advanced Topics to Explore:
- **DWN Module**: Manage decentralized web nodes and data records
- **Service Module**: Register and verify services with domain verification
- **UCAN Integration**: Implement capability-based authorization
- **Multi-signature**: Create and manage multi-sig accounts
- **IBC Transfers**: Cross-chain token transfers
- **Custom Modules**: Interact with your own custom modules
### Useful Resources:
- [Client SDK API Reference](https://pkg.go.dev/github.com/sonr-io/sonr/client)
- [Cosmos SDK Documentation](https://docs.cosmos.network)
- [Sonr GitHub Repository](https://github.com/sonr-io/sonr)
-190
View File
@@ -1,190 +0,0 @@
---
title: Getting Started with ReactJS
description: A quick start guide for building applications with Sonr using JavaScript and TypeScript
sidebarTitle: React Quickstart
icon: "react"
---
This guide will show you how to set up a Node.js project with TypeScript and use the Sonr SDK to interact with the Sonr network.
## Prerequisites
- A local Sonr network running. See the [Validator Setup Guide](/quickstart/validators) for instructions
- Node.js version 16 or higher
- npm or yarn
## 1. Project Setup
<Steps>
<Step>
### Initialize a New Project
Create a new directory for your project and initialize it with npm:
```bash
mkdir sonr-ts-quickstart
cd sonr-ts-quickstart
npm init -y
```
</Step>
<Step>
### Install Dependencies
Install the Sonr SDK and TypeScript:
```bash
npm install @sonr/sdk typescript ts-node @types/node
```
</Step>
<Step>
### Configure TypeScript
Create a `tsconfig.json` file in your project root with the following configuration:
```json
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
```
</Step>
</Steps>
## 2. Creating a Wallet
Now, let's create a new TypeScript file and add the logic to create a new Sonr wallet.
<Steps>
<Step>
### Create the Main File
Create a new file named `index.ts`.
</Step>
<Step>
### Implement Wallet Creation
Add the following code to `index.ts` to create a new wallet and log its address and mnemonic:
```typescript
import { Sonr } from "@sonr/sdk";
async function main() {
console.log("Creating a new Sonr wallet...");
const sonr = new Sonr({ httpUrl: "http://localhost:1317" });
const wallet = await sonr.createWallet();
console.log(`Wallet created!`);
console.log(`Address: ${wallet.address}`);
console.log(`Mnemonic: ${wallet.mnemonic}`);
}
main().catch(console.error);
```
<Note type="warning">
**Important**: In a real application, you must store the mnemonic securely.
Never expose it in client-side code.
</Note>
</Step>
<Step>
### Run the Script
Execute the script using `ts-node`:
```bash
npx ts-node index.ts
```
You should see the new wallet's address and mnemonic printed to the console.
</Step>
</Steps>
## 3. Querying the Blockchain
Let's query the blockchain to get the balance of our new wallet.
<Steps>
<Step>
### Get Account Balance
Modify your `index.ts` file to query the account balance after creating the wallet. You will need to fund this account from the localnet faucet for it to have a balance.
```typescript
// ... after creating the wallet
console.log("Querying account balance...");
// The localnet validator has funds, so we'll use its address for the query
const validatorAddress = "snr1..._validator_address_..."; // Replace with the actual validator address from your localnet
const balance = await sonr.getAccountBalance(validatorAddress);
console.log(`Balance for ${validatorAddress}:`, balance);
```
</Step>
<Step>
### Run the Script Again
Run the script to see the account balance:
```bash
npx ts-node index.ts
```
</Step>
</Steps>
## 4. Sending a Transaction
Finally, let's send a transaction from one account to another.
<Steps>
<Step>
### Implement Transaction Sending
For this step, you will need two wallets. You can create a second one using the same `createWallet` method. Ensure both wallets have funds from the localnet faucet.
```typescript
// ... inside your main function
const wallet1 = await sonr.createWallet(); // Fund this from the faucet
const wallet2 = await sonr.createWallet();
console.log(`Sending 1 SNR from ${wallet1.address} to ${wallet2.address}`);
const result = await wallet1.send({
to: wallet2.address,
amount: "1000000usnr", // 1 SNR
});
console.log(`Transaction successful! TxHash: ${result.txhash}`);
```
</Step>
</Steps>
## Next Steps
This quickstart has shown you the basics of interacting with the Sonr network using our TypeScript SDK. You can now explore more advanced topics:
- **Service Registration**: Register your application as a trusted service
- **UCAN Authorization**: Implement capability-based permissions
- **Smart Contract Interaction**: Call and query smart contracts on the Sonr network
@@ -1,155 +0,0 @@
---
title: "DWN Plugin Architecture"
description: "Deep dive into the Decentralized Web Node (DWN) plugin system and integration"
sidebarTitle: "WASM Architecture"
icon: "puzzle"
---
# DWN Plugin Architecture
The Sonr project implements a flexible and secure plugin system for Decentralized Web Nodes (DWN), enabling modular and extensible functionality.
## Overview
The plugin architecture is designed to:
- Support dynamic loading of WebAssembly (WASM) plugins
- Provide a standardized interface for plugin interactions
- Enable secure, isolated execution of plugins
## Core Components
### Plugin Manager
The `PluginManager` manages plugin lifecycle and interactions:
```go
type PluginManager struct {
plugins map[string]Plugin
actors map[string]Actor
}
type Plugin interface {
Initialize(config map[string]any) error
Execute(method string, payload []byte) ([]byte, error)
Close() error
}
```
### Plugin Configuration
Plugins are configured through a structured configuration:
```go
type PluginConfig struct {
ID string // Unique plugin identifier
Type string // Plugin type (e.g., "motor", "crypto")
Path string // WASM module path
Environment map[string]any // Plugin-specific environment variables
}
```
## Loading and Initializing Plugins
### Basic Plugin Loading
```go
func (pm *PluginManager) LoadPlugin(config PluginConfig) error {
// Load WASM module
module, err := extism.Load(config.Path)
if err != nil {
return err
}
// Initialize plugin
plugin := &WASMPlugin{
module: module,
config: config,
}
// Store in plugin registry
pm.plugins[config.ID] = plugin
}
```
### Actor-Based Plugin Management
```go
func (pm *PluginManager) CreateActor(pluginID string) (*Actor, error) {
plugin, exists := pm.plugins[pluginID]
if !exists {
return nil, errors.New("plugin not found")
}
actor := NewActor(plugin)
pm.actors[actor.ID] = actor
return actor, nil
}
```
## Plugin Execution Workflow
1. Plugin is loaded from WASM module
2. Configuration is applied
3. Plugin is initialized
4. Specific methods can be invoked through a standardized interface
### Example Plugin Execution
```go
func ExecutePluginMethod(pluginID, method string, payload []byte) ([]byte, error) {
plugin := pluginManager.plugins[pluginID]
return plugin.Execute(method, payload)
}
```
## Configuration and Environment
### Plugin Environment Variables
```json
{
"motor_plugin": {
"enclave_config": { ... },
"chain_id": "sonr-testnet-1",
"log_level": "debug"
}
}
```
## Error Handling and Logging
```go
type PluginError struct {
Code string
Message string
Details map[string]any
}
```
## Security Considerations
- WASM plugins run in an isolated sandbox
- Limited access to system resources
- Runtime restrictions prevent malicious behavior
- Cryptographic verification of plugin modules
## Plugin Types
1. **Crypto Plugins**: Cryptographic operations
2. **Motor Plugins**: MPC and token management
3. **DID Plugins**: Decentralized Identity operations
4. **Custom Plugins**: Application-specific extensions
## Best Practices
- Keep plugins small and focused
- Use standardized interfaces
- Implement comprehensive error handling
- Validate all plugin inputs
- Monitor plugin performance
## Advanced Configuration
For advanced plugin configuration and deployment, refer to the [PDK Configuration Guide](/blockchain/modules/dwn/configuration).
View File
-173
View File
@@ -1,173 +0,0 @@
---
title: "@sonr.io/ui"
sidebarTitle: "@sonr.io/ui"
description: "A package for Sonr's centralized shadcn/ui component library"
icon: "palette"
---
# @sonr.io/ui
## Overview
The `@sonr.io/ui` package serves as our centralized shadcn/ui component library, providing a consistent and accessible design system across Sonr's ecosystem. Leveraging the power of shadcn/ui, we've created a fully customizable and type-safe component library with a primary color of `#17c2ff`.
<Callout type="info">
Our UI package is built to provide maximum flexibility while maintaining
strict design consistency.
</Callout>
## Component Migration Strategy
### Before: Custom Button Component
Previously, our Button component relied on manual variant classes and custom implementations:
```tsx
// Old Implementation
const Button = ({ variant, className, ...props }) => {
const variantClasses = {
primary: "bg-blue-500 text-white",
secondary: "bg-gray-200 text-black",
// Multiple manual variant definitions
};
return (
<button className={`${variantClasses[variant]} ${className}`} {...props} />
);
};
```
### After: Shadcn Button Implementation
Our new implementation uses `cva` (class-variance-authority) and the `cn` utility for robust variant management:
```tsx
// New Implementation
import { buttonVariants } from "@sonr.io/ui/components/ui/button";
import { cn } from "@sonr.io/ui/lib/utils";
const Button = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
);
};
```
<Callout type="success">
Key Improvements: - Type-safe variant management - Enhanced accessibility -
Consistent theming - Reduced bundle size
</Callout>
## Theme Configuration
### Color System
Our primary theme color is `#17c2ff`, defined in HSL format for maximum flexibility:
```css
:root {
--primary-h: 200; /* Hue */
--primary-s: 100%; /* Saturation */
--primary-l: 59%; /* Lightness */
--primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}
```
### CSS Variables Structure
```css
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 200 100% 59%;
--primary-foreground: 210 40% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
/* Additional theme variables */
}
```
## Usage Guide
### Importing Components
Import components directly from the `@sonr.io/ui` package:
```tsx
import { Button } from "@sonr.io/ui/components/ui/button";
import { Input } from "@sonr.io/ui/components/ui/input";
```
### Adding New Components
Use the shadcn CLI within the `packages/ui` directory:
```bash
# Navigate to packages/ui
cd packages/ui
# Add a new component
npx shadcn-ui@latest add button
```
<Callout type="warning">
Always add components from the `packages/ui` directory to maintain our
centralized component management.
</Callout>
## Architecture Patterns
### Monorepo Structure
```
sonr/
├── packages/
│ └── ui/
│ ├── components/
│ │ └── ui/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts
│ └── styles/
│ └── globals.css
```
### Key Principles
- **Single Source of Truth**: All UI components live in `packages/ui`
- **No Local `components.json`**: Centralized configuration
- **Turbo-powered Build Pipeline**: Efficient component compilation
## Global Styles Integration
In your application's main entry point:
```tsx
import "@sonr.io/ui/styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
```
## Best Practices
1. Always use the centralized components from `@sonr.io/ui`
2. Prefer `cn()` utility for dynamic className composition
3. Leverage TypeScript for type-safe component usage
4. Use CSS variables for theming consistency
<Callout type="tip">
Remember: Our UI library is designed to be both flexible and consistent. When
in doubt, refer to the components in `@sonr.io/ui`.
</Callout>
-173
View File
@@ -1,173 +0,0 @@
---
title: "@sonr.io/ui"
sidebarTitle: "@sonr.io/ui"
description: "A package for Sonr's centralized shadcn/ui component library"
icon: "palette"
---
# @sonr.io/ui
## Overview
The `@sonr.io/ui` package serves as our centralized shadcn/ui component library, providing a consistent and accessible design system across Sonr's ecosystem. Leveraging the power of shadcn/ui, we've created a fully customizable and type-safe component library with a primary color of `#17c2ff`.
<Callout type="info">
Our UI package is built to provide maximum flexibility while maintaining
strict design consistency.
</Callout>
## Component Migration Strategy
### Before: Custom Button Component
Previously, our Button component relied on manual variant classes and custom implementations:
```tsx
// Old Implementation
const Button = ({ variant, className, ...props }) => {
const variantClasses = {
primary: "bg-blue-500 text-white",
secondary: "bg-gray-200 text-black",
// Multiple manual variant definitions
};
return (
<button className={`${variantClasses[variant]} ${className}`} {...props} />
);
};
```
### After: Shadcn Button Implementation
Our new implementation uses `cva` (class-variance-authority) and the `cn` utility for robust variant management:
```tsx
// New Implementation
import { buttonVariants } from "@sonr.io/ui/components/ui/button";
import { cn } from "@sonr.io/ui/lib/utils";
const Button = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
);
};
```
<Callout type="success">
Key Improvements: - Type-safe variant management - Enhanced accessibility -
Consistent theming - Reduced bundle size
</Callout>
## Theme Configuration
### Color System
Our primary theme color is `#17c2ff`, defined in HSL format for maximum flexibility:
```css
:root {
--primary-h: 200; /* Hue */
--primary-s: 100%; /* Saturation */
--primary-l: 59%; /* Lightness */
--primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}
```
### CSS Variables Structure
```css
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 200 100% 59%;
--primary-foreground: 210 40% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
/* Additional theme variables */
}
```
## Usage Guide
### Importing Components
Import components directly from the `@sonr.io/ui` package:
```tsx
import { Button } from "@sonr.io/ui/components/ui/button";
import { Input } from "@sonr.io/ui/components/ui/input";
```
### Adding New Components
Use the shadcn CLI within the `packages/ui` directory:
```bash
# Navigate to packages/ui
cd packages/ui
# Add a new component
npx shadcn-ui@latest add button
```
<Callout type="warning">
Always add components from the `packages/ui` directory to maintain our
centralized component management.
</Callout>
## Architecture Patterns
### Monorepo Structure
```
sonr/
├── packages/
│ └── ui/
│ ├── components/
│ │ └── ui/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts
│ └── styles/
│ └── globals.css
```
### Key Principles
- **Single Source of Truth**: All UI components live in `packages/ui`
- **No Local `components.json`**: Centralized configuration
- **Turbo-powered Build Pipeline**: Efficient component compilation
## Global Styles Integration
In your application's main entry point:
```tsx
import "@sonr.io/ui/styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
```
## Best Practices
1. Always use the centralized components from `@sonr.io/ui`
2. Prefer `cn()` utility for dynamic className composition
3. Leverage TypeScript for type-safe component usage
4. Use CSS variables for theming consistency
<Callout type="tip">
Remember: Our UI library is designed to be both flexible and consistent. When
in doubt, refer to the components in `@sonr.io/ui`.
</Callout>
-173
View File
@@ -1,173 +0,0 @@
---
title: "@sonr.io/ui"
sidebarTitle: "@sonr.io/ui"
description: "A package for Sonr's centralized shadcn/ui component library"
icon: "palette"
---
# @sonr.io/ui
## Overview
The `@sonr.io/ui` package serves as our centralized shadcn/ui component library, providing a consistent and accessible design system across Sonr's ecosystem. Leveraging the power of shadcn/ui, we've created a fully customizable and type-safe component library with a primary color of `#17c2ff`.
<Callout type="info">
Our UI package is built to provide maximum flexibility while maintaining
strict design consistency.
</Callout>
## Component Migration Strategy
### Before: Custom Button Component
Previously, our Button component relied on manual variant classes and custom implementations:
```tsx
// Old Implementation
const Button = ({ variant, className, ...props }) => {
const variantClasses = {
primary: "bg-blue-500 text-white",
secondary: "bg-gray-200 text-black",
// Multiple manual variant definitions
};
return (
<button className={`${variantClasses[variant]} ${className}`} {...props} />
);
};
```
### After: Shadcn Button Implementation
Our new implementation uses `cva` (class-variance-authority) and the `cn` utility for robust variant management:
```tsx
// New Implementation
import { buttonVariants } from "@sonr.io/ui/components/ui/button";
import { cn } from "@sonr.io/ui/lib/utils";
const Button = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
);
};
```
<Callout type="success">
Key Improvements: - Type-safe variant management - Enhanced accessibility -
Consistent theming - Reduced bundle size
</Callout>
## Theme Configuration
### Color System
Our primary theme color is `#17c2ff`, defined in HSL format for maximum flexibility:
```css
:root {
--primary-h: 200; /* Hue */
--primary-s: 100%; /* Saturation */
--primary-l: 59%; /* Lightness */
--primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}
```
### CSS Variables Structure
```css
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 200 100% 59%;
--primary-foreground: 210 40% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
/* Additional theme variables */
}
```
## Usage Guide
### Importing Components
Import components directly from the `@sonr.io/ui` package:
```tsx
import { Button } from "@sonr.io/ui/components/ui/button";
import { Input } from "@sonr.io/ui/components/ui/input";
```
### Adding New Components
Use the shadcn CLI within the `packages/ui` directory:
```bash
# Navigate to packages/ui
cd packages/ui
# Add a new component
npx shadcn-ui@latest add button
```
<Callout type="warning">
Always add components from the `packages/ui` directory to maintain our
centralized component management.
</Callout>
## Architecture Patterns
### Monorepo Structure
```
sonr/
├── packages/
│ └── ui/
│ ├── components/
│ │ └── ui/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts
│ └── styles/
│ └── globals.css
```
### Key Principles
- **Single Source of Truth**: All UI components live in `packages/ui`
- **No Local `components.json`**: Centralized configuration
- **Turbo-powered Build Pipeline**: Efficient component compilation
## Global Styles Integration
In your application's main entry point:
```tsx
import "@sonr.io/ui/styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
```
## Best Practices
1. Always use the centralized components from `@sonr.io/ui`
2. Prefer `cn()` utility for dynamic className composition
3. Leverage TypeScript for type-safe component usage
4. Use CSS variables for theming consistency
<Callout type="tip">
Remember: Our UI library is designed to be both flexible and consistent. When
in doubt, refer to the components in `@sonr.io/ui`.
</Callout>
-173
View File
@@ -1,173 +0,0 @@
---
title: "@sonr.io/ui"
sidebarTitle: "@sonr.io/ui"
description: "A package for Sonr's centralized shadcn/ui component library"
icon: "palette"
---
# @sonr.io/ui
## Overview
The `@sonr.io/ui` package serves as our centralized shadcn/ui component library, providing a consistent and accessible design system across Sonr's ecosystem. Leveraging the power of shadcn/ui, we've created a fully customizable and type-safe component library with a primary color of `#17c2ff`.
<Callout type="info">
Our UI package is built to provide maximum flexibility while maintaining
strict design consistency.
</Callout>
## Component Migration Strategy
### Before: Custom Button Component
Previously, our Button component relied on manual variant classes and custom implementations:
```tsx
// Old Implementation
const Button = ({ variant, className, ...props }) => {
const variantClasses = {
primary: "bg-blue-500 text-white",
secondary: "bg-gray-200 text-black",
// Multiple manual variant definitions
};
return (
<button className={`${variantClasses[variant]} ${className}`} {...props} />
);
};
```
### After: Shadcn Button Implementation
Our new implementation uses `cva` (class-variance-authority) and the `cn` utility for robust variant management:
```tsx
// New Implementation
import { buttonVariants } from "@sonr.io/ui/components/ui/button";
import { cn } from "@sonr.io/ui/lib/utils";
const Button = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
);
};
```
<Callout type="success">
Key Improvements: - Type-safe variant management - Enhanced accessibility -
Consistent theming - Reduced bundle size
</Callout>
## Theme Configuration
### Color System
Our primary theme color is `#17c2ff`, defined in HSL format for maximum flexibility:
```css
:root {
--primary-h: 200; /* Hue */
--primary-s: 100%; /* Saturation */
--primary-l: 59%; /* Lightness */
--primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}
```
### CSS Variables Structure
```css
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 200 100% 59%;
--primary-foreground: 210 40% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
/* Additional theme variables */
}
```
## Usage Guide
### Importing Components
Import components directly from the `@sonr.io/ui` package:
```tsx
import { Button } from "@sonr.io/ui/components/ui/button";
import { Input } from "@sonr.io/ui/components/ui/input";
```
### Adding New Components
Use the shadcn CLI within the `packages/ui` directory:
```bash
# Navigate to packages/ui
cd packages/ui
# Add a new component
npx shadcn-ui@latest add button
```
<Callout type="warning">
Always add components from the `packages/ui` directory to maintain our
centralized component management.
</Callout>
## Architecture Patterns
### Monorepo Structure
```
sonr/
├── packages/
│ └── ui/
│ ├── components/
│ │ └── ui/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts
│ └── styles/
│ └── globals.css
```
### Key Principles
- **Single Source of Truth**: All UI components live in `packages/ui`
- **No Local `components.json`**: Centralized configuration
- **Turbo-powered Build Pipeline**: Efficient component compilation
## Global Styles Integration
In your application's main entry point:
```tsx
import "@sonr.io/ui/styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
```
## Best Practices
1. Always use the centralized components from `@sonr.io/ui`
2. Prefer `cn()` utility for dynamic className composition
3. Leverage TypeScript for type-safe component usage
4. Use CSS variables for theming consistency
<Callout type="tip">
Remember: Our UI library is designed to be both flexible and consistent. When
in doubt, refer to the components in `@sonr.io/ui`.
</Callout>
-173
View File
@@ -1,173 +0,0 @@
---
title: "@sonr.io/ui"
sidebarTitle: "@sonr.io/ui"
description: "A package for Sonr's centralized shadcn/ui component library"
icon: "palette"
---
# @sonr.io/ui
## Overview
The `@sonr.io/ui` package serves as our centralized shadcn/ui component library, providing a consistent and accessible design system across Sonr's ecosystem. Leveraging the power of shadcn/ui, we've created a fully customizable and type-safe component library with a primary color of `#17c2ff`.
<Callout type="info">
Our UI package is built to provide maximum flexibility while maintaining
strict design consistency.
</Callout>
## Component Migration Strategy
### Before: Custom Button Component
Previously, our Button component relied on manual variant classes and custom implementations:
```tsx
// Old Implementation
const Button = ({ variant, className, ...props }) => {
const variantClasses = {
primary: "bg-blue-500 text-white",
secondary: "bg-gray-200 text-black",
// Multiple manual variant definitions
};
return (
<button className={`${variantClasses[variant]} ${className}`} {...props} />
);
};
```
### After: Shadcn Button Implementation
Our new implementation uses `cva` (class-variance-authority) and the `cn` utility for robust variant management:
```tsx
// New Implementation
import { buttonVariants } from "@sonr.io/ui/components/ui/button";
import { cn } from "@sonr.io/ui/lib/utils";
const Button = ({
variant = "default",
size = "default",
className,
...props
}) => {
return (
<button
className={cn(buttonVariants({ variant, size }), className)}
{...props}
/>
);
};
```
<Callout type="success">
Key Improvements: - Type-safe variant management - Enhanced accessibility -
Consistent theming - Reduced bundle size
</Callout>
## Theme Configuration
### Color System
Our primary theme color is `#17c2ff`, defined in HSL format for maximum flexibility:
```css
:root {
--primary-h: 200; /* Hue */
--primary-s: 100%; /* Saturation */
--primary-l: 59%; /* Lightness */
--primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l));
}
```
### CSS Variables Structure
```css
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 200 100% 59%;
--primary-foreground: 210 40% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
/* Additional theme variables */
}
```
## Usage Guide
### Importing Components
Import components directly from the `@sonr.io/ui` package:
```tsx
import { Button } from "@sonr.io/ui/components/ui/button";
import { Input } from "@sonr.io/ui/components/ui/input";
```
### Adding New Components
Use the shadcn CLI within the `packages/ui` directory:
```bash
# Navigate to packages/ui
cd packages/ui
# Add a new component
npx shadcn-ui@latest add button
```
<Callout type="warning">
Always add components from the `packages/ui` directory to maintain our
centralized component management.
</Callout>
## Architecture Patterns
### Monorepo Structure
```
sonr/
├── packages/
│ └── ui/
│ ├── components/
│ │ └── ui/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── ...
│ ├── lib/
│ │ └── utils.ts
│ └── styles/
│ └── globals.css
```
### Key Principles
- **Single Source of Truth**: All UI components live in `packages/ui`
- **No Local `components.json`**: Centralized configuration
- **Turbo-powered Build Pipeline**: Efficient component compilation
## Global Styles Integration
In your application's main entry point:
```tsx
import "@sonr.io/ui/styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
```
## Best Practices
1. Always use the centralized components from `@sonr.io/ui`
2. Prefer `cn()` utility for dynamic className composition
3. Leverage TypeScript for type-safe component usage
4. Use CSS variables for theming consistency
<Callout type="tip">
Remember: Our UI library is designed to be both flexible and consistent. When
in doubt, refer to the components in `@sonr.io/ui`.
</Callout>