📚 Ressources Liées
🚀 Solutions DazNode
DazNode simplifie votre parcours Bitcoin/Lightning avec des solutions clé en main.
- ✅ Setup automatisé en 1-clic
- ✅ Support expert inclus
- ✅ ROI optimisé garanti
RGB - Développement 💻
Temps de lecture estimé : 25 minutes
Vue d'Ensemble 🌍
Ce guide vous accompagne dans l'intégration de RGB dans vos applications, depuis les concepts de base jusqu'aux implémentations avancées.
Architecture de Développement 🏗️
┌───────────────────┐
│ Votre Application │
├───────────────────┤
│ RGB SDK/API │
├───────────────────┤
│ RGB Core │
├───────────────────┤
│ Bitcoin Network │
└───────────────────┘
Installation des Outils 🛠️
RGB SDK pour Rust
# Cargo.toml
[dependencies]
rgb-sdk = "0.10"
rgb-core = "0.10"
rgb-wallet = "0.10"
bitcoin = "0.30"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
RGB SDK pour JavaScript/TypeScript
# Installation via npm
npm install @rgb-protocol/rgb-sdk
npm install @rgb-protocol/bitcoin-js
# Ou via yarn
yarn add @rgb-protocol/rgb-sdk @rgb-protocol/bitcoin-js
RGB SDK pour Python
# Installation via pip
pip install rgb-python
pip install bitcoin-python
# Installation depuis les sources
git clone https://github.com/RGB-WG/rgb-python
cd rgb-python && pip install -e .
Premiers Pas avec l'API 🚀
Configuration Initiale (Rust)
use rgb_sdk::*;
use bitcoin::Network;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configuration du client RGB
let config = RgbConfig {
network: Network::Testnet,
data_dir: "./rgb-data".into(),
electrum_server: "electrum.example.com:50002".into(),
};
// Initialisation du client
let client = RgbClient::new(config).await?;
println!("Client RGB initialisé avec succès !");
Ok(())
}
Configuration Initiale (JavaScript)
import { RgbClient, Network } from '@rgb-protocol/rgb-sdk';
async function initRgb() {
const config = {
network: Network.Testnet,
dataDir: './rgb-data',
electrumServer: 'electrum.example.com:50002'
};
const client = new RgbClient(config);
await client.initialize();
console.log('Client RGB initialisé !');
return client;
}
Configuration Initiale (Python)
import asyncio
from rgb_python import RgbClient, Network
async def init_rgb():
config = {
'network': Network.TESTNET,
'data_dir': './rgb-data',
'electrum_server': 'electrum.example.com:50002'
}
client = RgbClient(config)
await client.initialize()
print("Client RGB initialisé !")
return client
# Utilisation
client = asyncio.run(init_rgb())
Gestion des Portefeuilles 💼
Création d'un Portefeuille (Rust)
use rgb_sdk::wallet::*;
use bip32::ExtendedPrivKey;
// Génération d'un nouveau portefeuille
let mnemonic = generate_mnemonic()?;
let seed = mnemonic_to_seed(&mnemonic, None)?;
let master_key = ExtendedPrivKey::new_master(Network::Testnet, &seed)?;
// Création du portefeuille RGB
let wallet = RgbWallet::new(master_key, Network::Testnet)?;
println!("Adresse Bitcoin : {}", wallet.next_bitcoin_address()?);
println!("Mémonique : {}", mnemonic);
Opérations sur Portefeuille (JavaScript)
import { RgbWallet, generateMnemonic } from '@rgb-protocol/rgb-sdk';
class WalletManager {
async createWallet() {
const mnemonic = generateMnemonic();
this.wallet = new RgbWallet({ mnemonic, network: 'testnet' });
await this.wallet.initialize();
return {
mnemonic,
bitcoinAddress: await this.wallet.getNextBitcoinAddress(),
rgbAddress: await this.wallet.getRgbAddress()
};
}
async getBalance(assetId = null) {
if (assetId) {
return await this.wallet.getAssetBalance(assetId);
}
return await this.wallet.getBitcoinBalance();
}
async listAssets() {
return await this.wallet.listAssets();
}
}
Création d'Actifs 🎨
Token Fongible (Rust)
use rgb_sdk::contract::fungible::*;
async fn create_token(
client: &RgbClient,
name: &str,
ticker: &str,
supply: u64,
genesis_utxo: OutPoint
) -> Result<AssetId, RgbError> {
let contract_data = FungibleContract {
name: name.to_string(),
ticker: ticker.to_string(),
precision: 8,
supply,
inflatable: false,
burnable: false,
metadata: None,
};
let asset_id = client.issue_fungible(
contract_data,
genesis_utxo,
None // pas de fee custom
).await?;
println!("Token créé avec l'ID : {}", asset_id);
Ok(asset_id)
}
NFT Collection (JavaScript)
class NftCreator {
constructor(rgbClient) {
this.client = rgbClient;
}
async createCollection({
name,
description,
maxItems,
baseUri,
genesisUtxo
}) {
const contractData = {
schema: 'RGB21',
name,
description,
maxItems,
metadata: {
baseUri,
createdAt: new Date().toISOString()
}
};
const assetId = await this.client.issueNonFungible(
contractData,
genesisUtxo
);
console.log(`Collection créée : ${assetId}`);
return assetId;
}
async mintNft(assetId, tokenData, recipientUtxo) {
const nftData = {
name: tokenData.name,
description: tokenData.description,
image: tokenData.image,
attributes: tokenData.attributes
};
return await this.client.mintNft(assetId, nftData, recipientUtxo);
}
}
Transactions et Transferts 🔄
Transfert Simple (Rust)
use rgb_sdk::transfer::*;
async fn transfer_tokens(
client: &RgbClient,
asset_id: AssetId,
amount: u64,
recipient_address: &str
) -> Result<Txid, RgbError> {
// Création de la facture destinataire
let invoice = client.create_invoice(
asset_id,
amount,
recipient_address
).await?;
// Exécution du transfert
let txid = client.transfer(
invoice,
None // frais automatiques
).await?;
println!("Transfert effectué : {}", txid);
Ok(txid)
}
Batch Transfer (JavaScript)
class TransferManager {
constructor(rgbClient) {
this.client = rgbClient;
}
async batchTransfer(transfers) {
const batch = [];
for (const transfer of transfers) {
const invoice = await this.client.createInvoice({
assetId: transfer.assetId,
amount: transfer.amount,
recipientAddress: transfer.recipient
});
batch.push(invoice);
}
// Exécution en lot pour économiser les frais
const txid = await this.client.batchTransfer(batch);
console.log(`Batch transfer complété : ${txid}`);
return txid;
}
async getTransferHistory(assetId) {
return await this.client.getAssetHistory(assetId);
}
}
Intégration Lightning Network ⚡
Canal RGB-Lightning (Rust)
use rgb_sdk::lightning::*;
async fn setup_rgb_channel(
client: &RgbClient,
peer_pubkey: PublicKey,
channel_capacity: u64,
rgb_assets: Vec<AssetId>
) -> Result<ChannelId, RgbError> {
let channel_config = RgbChannelConfig {
capacity: channel_capacity,
supported_assets: rgb_assets,
fee_rate: FeeRate::default(),
};
let channel_id = client.open_rgb_channel(
peer_pubkey,
channel_config
).await?;
println!("Canal RGB ouvert : {}", channel_id);
Ok(channel_id)
}
async fn lightning_payment(
client: &RgbClient,
invoice: &str,
asset_id: AssetId,
amount: u64
) -> Result<PaymentHash, RgbError> {
let payment = client.pay_rgb_invoice(
invoice,
asset_id,
amount
).await?;
Ok(payment.hash)
}
Paiements Instantanés (JavaScript)
class LightningRgbPayments {
constructor(rgbClient, lnClient) {
this.rgb = rgbClient;
this.ln = lnClient;
}
async createRgbInvoice(assetId, amount, description) {
const invoice = await this.rgb.createLightningInvoice({
assetId,
amount,
description,
expiry: 3600 // 1 heure
});
return invoice;
}
async payRgbInvoice(invoice, assetId) {
// Vérification du solde
const balance = await this.rgb.getAssetBalance(assetId);
const invoiceData = await this.rgb.decodeInvoice(invoice);
if (balance < invoiceData.amount) {
throw new Error('Solde insuffisant');
}
// Paiement via Lightning
const payment = await this.ln.payInvoice(invoice, {
assetId,
maxFee: invoiceData.amount * 0.01 // 1% max fee
});
return payment;
}
}
Sécurité et Validation 🛡️
Validation de Contrats (Rust)
use rgb_sdk::validation::*;
async fn validate_asset(
client: &RgbClient,
asset_id: AssetId
) -> Result<ValidationReport, RgbError> {
let report = client.validate_asset_full(asset_id).await?;
match report.status {
ValidationStatus::Valid => {
println!("Actif valide : {}", asset_id);
},
ValidationStatus::Invalid(errors) => {
println!("Actif invalide : {:?}", errors);
return Err(RgbError::InvalidAsset(errors));
},
ValidationStatus::Unknown => {
println!("Statut de validation inconnu");
}
}
Ok(report)
}
// Vérification des transitions
async fn validate_transition(
client: &RgbClient,
transition_id: &str
) -> Result<bool, RgbError> {
let is_valid = client.validate_transition(transition_id).await?;
if !is_valid {
return Err(RgbError::InvalidTransition);
}
Ok(true)
}
Gestion des Erreurs (JavaScript)
class RgbErrorHandler {
static handle(error) {
switch (error.type) {
case 'INSUFFICIENT_FUNDS':
return {
message: 'Solde insuffisant',
action: 'fund_wallet',
details: error.details
};
case 'INVALID_ASSET':
return {
message: 'Actif invalide ou non reconnu',
action: 'verify_asset',
details: error.details
};
case 'NETWORK_ERROR':
return {
message: 'Erreur réseau',
action: 'retry',
retryable: true
};
default:
return {
message: 'Erreur inconnue',
action: 'contact_support',
details: error
};
}
}
static async retry(operation, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
const handled = this.handle(error);
if (!handled.retryable || i === maxRetries - 1) {
throw error;
}
// Attente exponentielle
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, i) * 1000)
);
}
}
}
}
Tests et Débogage 🔍
Tests Unitaires (Rust)
#[cfg(test)]
mod tests {
use super::*;
use rgb_sdk::test_utils::*;
#[tokio::test]
async fn test_token_creation() {
let client = create_test_client().await;
let genesis_utxo = create_test_utxo(&client).await;
let asset_id = create_token(
&client,
"Test Token",
"TEST",
1000000,
genesis_utxo
).await.unwrap();
// Vérification
let asset_info = client.get_asset_info(asset_id).await.unwrap();
assert_eq!(asset_info.name, "Test Token");
assert_eq!(asset_info.ticker, "TEST");
}
#[tokio::test]
async fn test_transfer() {
let client = create_test_client().await;
let asset_id = create_test_asset(&client).await;
let recipient = "rgb:test:recipient123";
let amount = 1000;
let txid = transfer_tokens(
&client,
asset_id,
amount,
recipient
).await.unwrap();
assert!(txid.to_string().len() == 64);
}
}
Tests d'Intégration (JavaScript)
import { describe, it, expect, beforeEach } from 'vitest';
import { RgbTestClient } from '@rgb-protocol/rgb-sdk/testing';
describe('RGB Integration Tests', () => {
let client;
let wallet;
beforeEach(async () => {
client = new RgbTestClient();
await client.initialize();
wallet = await client.createTestWallet();
await wallet.fund(1000000); // 0.01 BTC
});
it('should create and transfer tokens', async () => {
// Création du token
const assetId = await client.issueToken({
name: 'Test Token',
ticker: 'TEST',
supply: 1000000
});
expect(assetId).toBeDefined();
// Transfert
const recipient = await client.createTestWallet();
const txid = await wallet.transfer({
assetId,
amount: 1000,
recipient: recipient.address
});
expect(txid).toBeDefined();
// Vérification des soldes
const senderBalance = await wallet.getBalance(assetId);
const recipientBalance = await recipient.getBalance(assetId);
expect(senderBalance).toBe(999000);
expect(recipientBalance).toBe(1000);
});
});
Monitoring et Analytics 📊
Métriques de Performance (Rust)
use rgb_sdk::metrics::*;
struct RgbMetrics {
client: RgbClient,
metrics_collector: MetricsCollector,
}
impl RgbMetrics {
async fn collect_metrics(&self) -> RgbStats {
let stats = RgbStats {
total_assets: self.client.count_assets().await?,
total_transactions: self.client.count_transactions().await?,
wallet_balance: self.client.get_total_balance().await?,
network_fees_paid: self.client.get_fees_paid().await?,
validation_success_rate: self.calculate_validation_rate().await?,
};
self.metrics_collector.record(stats.clone()).await?;
stats
}
async fn get_asset_analytics(&self, asset_id: AssetId) -> AssetAnalytics {
AssetAnalytics {
holder_count: self.client.count_asset_holders(asset_id).await?,
transaction_volume: self.client.get_asset_volume(asset_id).await?,
price_history: self.client.get_price_history(asset_id).await?,
velocity: self.calculate_velocity(asset_id).await?,
}
}
}
Alertes et Notifications (JavaScript)
class RgbMonitoring {
constructor(client, alertManager) {
this.client = client;
this.alerts = alertManager;
this.thresholds = {
lowBalance: 0.001, // BTC
highFees: 1000, // sats
validationFailures: 5 // par heure
};
}
async startMonitoring() {
setInterval(async () => {
await this.checkBalances();
await this.checkFees();
await this.checkValidations();
}, 60000); // Toutes les minutes
}
async checkBalances() {
const balance = await this.client.getBitcoinBalance();
if (balance < this.thresholds.lowBalance) {
await this.alerts.send({
type: 'LOW_BALANCE',
message: `Solde Bitcoin faible : ${balance} BTC`,
severity: 'warning',
action: 'Fund wallet with Bitcoin'
});
}
}
async checkFees() {
const recentTxs = await this.client.getRecentTransactions(10);
const avgFee = recentTxs.reduce((sum, tx) => sum + tx.fee, 0) / recentTxs.length;
if (avgFee > this.thresholds.highFees) {
await this.alerts.send({
type: 'HIGH_FEES',
message: `Frais élevés détectés : ${avgFee} sats`,
severity: 'info',
suggestion: 'Consider waiting for lower network fees'
});
}
}
}
Ressources et Documentation 📚
Documentation Officielle
Exemples de Code
Communauté Développeur
Conseil d'Expert : 💡 Commencez par les exemples simples sur testnet, puis progressez vers des implémentations plus complexes. La validation côté client de RGB nécessite une approche de développement différente des smart contracts traditionnels.
Automatisez votre Success Lightning Network
Suite complète DazNode : Hardware + Logiciel + Support Expert
✅ +3.2% ROI optimisé = 320€/an sur 10k€ capital
✅ Setup 15min vs 12h configuration manuelle
✅ Support 24/7 + communauté 500+ experts