gun-eth
v3.0.4
Published
A GunDB plugin for Ethereum, and Web3
Downloads
2,622
Maintainers
Readme
Gun-ETH 🔫
A powerful Gun.js plugin that extends its capabilities by adding advanced blockchain and cryptographic features to create more secure and private decentralized applications.
✨ Why Gun-ETH?
- 🎯 Powerful Extension: Adds advanced blockchain and cryptographic features to Gun.js
- 🌐 Seamless Integration: Perfectly integrates with Gun.js while maintaining simplicity
- 🔒 Advanced Privacy: Implements stealth transactions, proof chain, and encrypted data
- 🚀 Modern Architecture: Intuitive APIs for easy Web3 functionality implementation
🚀 Quick Start
Installation
npm install gun-eth
# or
yarn add gun-eth
Basic Configuration
import Gun from 'gun';
import { GunEth } from 'gun-eth';
import { ethers } from 'ethers';
// Configure Gun with peers
const gun = Gun({
peers: ['http://localhost:8765/gun']
});
// Initialize GunEth
const gunEth = await GunEth.init('localhost'); // or 'mainnet', 'sepolia', etc.
Signer Configuration
Gun-ETH provides two ways to configure the signer:
- Manual Configuration (Recommended for Production)
import { setSigner, getSigner } from 'gun-eth';
// Configure with explicit RPC URL and private key
await setSigner(
"https://your-rpc-url",
"your-private-key"
);
// Get the configured signer
const signer = await getSigner();
- MetaMask Fallback (Development-Friendly)
import { getSigner } from 'gun-eth';
// Will automatically use MetaMask if available
try {
const signer = await getSigner();
console.log("Connected with address:", await signer.getAddress());
} catch (error) {
console.error("No valid provider found");
}
The signer selection follows these priorities:
- Uses manually configured signer if set via
setSigner()
- Falls back to MetaMask if available and no manual configuration
- Throws an error if no valid provider is found
Error Handling
try {
const gunEth = await GunEth.init({
gun,
chain: 'localhost'
});
} catch (error) {
console.error('Initialization error:', error);
}
📚 Documentation
🔐 Gun-Ethereum Integration
ETH -> GUN Conversion
try {
// Create signature with Ethereum wallet
const signature = await GunEth.createSignature(GunEth.MESSAGE_TO_SIGN);
// Convert to Gun SEA compatible keypair
const gunKeyPair = await GunEth.ethToGunAccount(signature);
console.log('Generated Gun SEA keypair:', gunKeyPair);
// The keypair contains keys generated by Gun SEA:
// {
// pub: "SEA-public-key",
// priv: "SEA-private-key",
// epub: "SEA-encryption-public-key",
// epriv: "SEA-encryption-private-key"
// }
} catch (error) {
console.error('Conversion error:', error);
}
GUN -> ETH Conversion
try {
// Requires the SEA private key generated by Gun
const ethAccount = await GunEth.gunToEthAccount(gunSEAPrivateKey);
console.log('Ethereum account:', ethAccount);
} catch (error) {
console.error('Conversion error:', error);
}
🔒 Stealth Chain
// Initialize Gun
const gun = Gun();
await GunEth.init({ gun, chain: 'localhost' });
try {
// Publish stealth keys
const signature = await GunEth.createSignature(GunEth.MESSAGE_TO_SIGN);
await gun.publishStealthKeys(signature);
// Generate stealth address
const stealthInfo = await gun.generateStealthAddress(
recipientAddress,
signature,
{} // Additional options if needed
);
console.log('Generated stealth address:', stealthInfo);
// Returns:
// {
// stealthAddress: "0x...", // The generated stealth address
// senderPublicKey: "...", // The sender's public key
// spendingPublicKey: "..." // The recipient's spending public key
// }
// Announce the payment
await gun.announceStealthPayment(
stealthInfo.stealthAddress,
stealthInfo.senderPublicKey,
stealthInfo.spendingPublicKey,
signature,
{ onChain: true } // Optional: announce on-chain
);
} catch (error) {
console.error('Stealth operation error:', error);
}
// Monitor stealth events
gun.monitorStealthEvents((event) => {
console.log('New stealth event:', event);
});
⛓️ Proof Chain
try {
// Write data with proof
await gun.proof('users', null, {
name: 'Alice',
age: 25
}, (ack) => {
if (ack.err) {
console.error('Write error:', ack.err);
return;
}
console.log('Data written successfully:', {
nodeId: ack.nodeId,
txHash: ack.txHash
});
});
// Verify data integrity
await gun.proof('users', 'nodeId123', null, (ack) => {
if (ack.err) {
console.error('Verification error:', ack.err);
return;
}
console.log('Verification completed:', ack.ok);
});
} catch (error) {
console.error('Proof operation error:', error);
}
🫧 Encrypted Bubbles
// Initialize Bubble Client
import { BubbleClient } from 'gun-eth';
const bubbleClient = new BubbleClient({
providerUrl: "http://localhost:3000/api",
signer: signer, // Your Ethereum signer
keypair: { // Your encryption keypair
epub: "your-encryption-public-key",
epriv: "your-encryption-private-key"
}
});
// Create and manage bubbles
const bubble = await bubbleClient.createBubble("My Bubble", {
isPrivate: true
});
// Write encrypted content
await bubbleClient.writeBubble(
bubble.id,
"secret.txt",
"My secret content"
);
// Read and decrypt content
const result = await bubbleClient.readBubble(
bubble.id,
"secret.txt"
);
// Share with another user
await bubbleClient.shareBubble(
bubble.id,
recipientAddress,
{ granteeEpub: recipientPublicKey }
);
🔄 Bubble Providers
Gun-ETH offers three types of providers for managing encrypted bubbles:
Base Provider
import { BaseBubbleProvider } from 'gun-eth';
class CustomProvider extends BaseBubbleProvider {
async handleCreateBubble(options) { }
async handleWriteBubble(bubbleId, fileName, content) { }
async handleReadBubble(bubbleId, fileName) { }
async handleGrantPermission(bubbleId, granteeAddress) { }
}
GUN Provider
import { GUNBubbleProvider } from 'gun-eth';
const gunProvider = new GUNBubbleProvider({
gun: gunInstance,
signer: signer,
keypair: keypair
});
// Stores data directly in GUN's graph
await gunProvider.handleCreateBubble({
name: "GUN Bubble",
isPrivate: true
});
Hybrid Provider
import { HybridBubbleProvider } from 'gun-eth';
const hybridProvider = new HybridBubbleProvider({
gun: gunInstance,
signer: signer,
keypair: keypair,
storage: customStorageAdapter
});
// Supports both GUN and external storage
await hybridProvider.handleCreateBubble({
name: "Hybrid Bubble",
isPrivate: true,
useExternal: true
});
📋 Templates
Gun-ETH provides ready-to-use templates for common implementations:
Client Template
// template-bubble-client.js
const CONFIG = {
RPC_URL: process.env.RPC_URL,
PRIVATE_KEY: process.env.PRIVATE_KEY,
PROVIDER_URL: "http://localhost:3000/api",
GUN_PEERS: ['http://localhost:8765/gun'],
DECRYPTED_FILES_DIR: './decrypted-files'
};
// Initialize client with configuration
const client = await initializeClient();
// Example usage
const bubble = await client.createBubble("Test Bubble");
await client.writeBubble(bubble.id, "test.txt", "content");
const result = await client.readBubble(bubble.id, "test.txt");
Provider Template
// template-bubble-provider.js
const CONFIG = {
RPC_URL: process.env.RPC_URL,
PRIVATE_KEY: process.env.PRIVATE_KEY,
GUN_PEERS: "http://localhost:8765/gun",
GUN_DIR: "radata",
BUBBLES_DIR: "bubbles"
};
// Initialize provider with configuration
const app = express();
const gun = Gun(gunOptions);
const provider = new HybridBubbleProvider(CONFIG);
// API endpoints
app.post('/bubble', handleCreateBubble);
app.post('/bubble/:id/write', handleWriteBubble);
app.get('/bubble/:id', handleReadBubble);
🏗️ Architecture
Gun-ETH is structured in independent modules:
- Core: Base functionality and Gun.js integration
- Stealth: Private transaction implementation
- Proof: Verification and anchoring system
- Crypto: Cryptographic utilities
- Utils: Common support functions
🌟 Features
Secure Backup System
- End-to-end encryption
- Version control
- Decentralized storage
Advanced Privacy
- Stealth transactions
- Private communications
- On-chain announcements
Data Integrity
- Cryptographic verification
- Blockchain anchoring
- Change monitoring
Web3 Integration
- Seamless Gun/Ethereum account conversion
- Signature and authentication support
- Complete key management
🤝 Contributing
Contributions are welcome! Please:
- 🍴 Fork the repository
- 🌿 Create your feature branch (
git checkout -b feature/AmazingFeature
) - 💾 Commit your changes (
git commit -m 'Add: amazing feature'
) - 📤 Push to the branch (
git push origin feature/AmazingFeature
) - 🔄 Open a Pull Request
📄 License
MIT © 2024 Scobru