npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@empereur-rouge/pms-sdk

v0.3.5

Published

TypeScript SDK for PMS (Planetary Monetary System) — wallet management, transactions, NFTs, and DAG interactions

Downloads

662

Readme

@empereur-rouge/pms-sdk

SDK TypeScript officiel pour interagir avec le réseau PMS (Planetary Monetary System).

Installation

npm install @empereur-rouge/pms-sdk
# ou
yarn add @empereur-rouge/pms-sdk
# ou  
pnpm add @empereur-rouge/pms-sdk

Structure de l'API

Le SDK est organisé en deux niveaux :

| Import | Usage | Contenu | |--------|-------|--------| | @empereur-rouge/pms-sdk | 99% des cas | PmsWallet, PmsClient, utils simples | | @empereur-rouge/pms-sdk/src/advanced | Power users | computeBlockId, crypto, types bas niveau |

Démarrage Rapide

import { PmsWallet, PmsClient } from "@empereur-rouge/pms-sdk";

// 1. Créer un wallet
const wallet = PmsWallet.generate();
console.log("Mnemonic:", wallet.mnemonic);
console.log("Address:", wallet.address);

// 2. Connecter au réseau (clé API obligatoire)
const client = new PmsClient({ 
  nodeUrl: "https://node.pms.network",
  apiKey: "pk_live_votre_cle_ici",
});

// 3. Consulter la balance
const balance = await client.getBalance(wallet.address);
console.log("Balance:", balance);

// 4. Envoyer des tokens
const result = await client.send({
  to: "04abc123...",
  amount: "10.0",
  wallet,
});
console.log("Transaction:", result.block_id);

API Reference

PmsWallet - Gestion des Wallets

Le wallet gère les clés cryptographiques (secp256k1) et permet de signer des transactions.

Création de Wallet

// Générer un nouveau wallet (24 mots)
const wallet = PmsWallet.generate();

// Restaurer depuis un mnemonic
const restored = PmsWallet.fromMnemonic("word1 word2 ... word24");

// Importer depuis une clé privée (hex)
const imported = PmsWallet.fromPrivateKey("abc123...");

// Créer depuis une seed (32 bytes)
const seeded = PmsWallet.fromSeed(new Uint8Array(32));

Propriétés

| Propriété | Type | Description | |-----------|------|-------------| | address | string | Adresse publique (clé publique hex non compressée, commence par 04) | | publicKeyHex | string | Clé publique en hexadécimal (identique à address) | | x25519PublicKeyHex | string | Clé publique X25519 pour le chiffrement | | mnemonic | string \| undefined | Phrase mnémonique (24 mots) si disponible |

Méthodes

// Signer un message
const signature: string = wallet.sign(messageBytes);

// Exporter la clé privée (hex)
const privateKey: string = wallet.exportPrivateKey();

// Vérifier une signature (statique)
const isValid: boolean = PmsWallet.verify(message, signature, publicKeyHex);

Validation de Mnemonic

import { isValidMnemonic } from "@empereur-rouge/pms-sdk";

if (isValidMnemonic(userInput)) {
  const wallet = PmsWallet.fromMnemonic(userInput);
}

PmsClient - Client API

Le client permet d'interagir avec l'API REST des nœuds PMS.

Configuration

const client = new PmsClient({
  nodeUrl: "https://node.pms.network",  // URL du nœud principal
  apiKey: "pk_live_votre_cle_ici",       // Clé API (obligatoire)
  seedNodes: [                           // Optionnel: nœuds de secours
    "https://node2.pms.network",
    "https://node3.pms.network",
  ],
  networkId: "pms-mainnet",              // Défaut: "pms-mainnet"
  protocolVersion: 1,                    // Défaut: 1
  timeout: 30000,                        // Timeout en ms (défaut: 30s)
  enableRacing: true,                    // Racing pattern (défaut: true)
});

[!IMPORTANT] La clé API est obligatoire. Obtenez-la depuis votre dashboard PMS ou auprès de l'administrateur du réseau.

Wallet (Custodial — Server-Side)

Ces méthodes créent/restaurent des wallets côté serveur. L'adresse retournée est au format Bech32 (ex: 8e1a...).

// Créer un nouveau wallet (serveur génère les clés)
const wallet = await client.createWallet();
// Réponse (WalletResponse):
// {
//   address: "8e1ahpltzjauwev6lf0jql...",
//   private_key_b64: "2lM0rVdFXX...",
//   private_key_hex: "da5334ad57455d74...",
//   public_key_hex: "04593037fa9d4f6ea2...",
//   x25519_pub_hex: "266bcd33ab2d20d2...",
//   mnemonic_words: ["gain", "space", "color", ...]
// }
// Restaurer un wallet depuis un mnemonic (24 mots BIP39)
const restored = await client.restoreFromMnemonic(
  "gain space color filter buzz bind side before sauce twist slam history chief patch desk chunk way oblige output turtle purchase scare token rapid"
);
console.log(restored.address); // "8e1ahpltzjauwev6lf0jql..."
// Restaurer un wallet depuis une clé privée hex
const imported = await client.restoreFromPrivateKey(
  "da5334ad57455d74e5150e4eb06398ce9cf27762b6f29eac7f82f178bee07406"
);
console.log(imported.address); // même adresse que ci-dessus

[!NOTE] Le mnemonic et la clé privée produisent exactement la même adresse — la dérivation est déterministe.

Méthodes de Lecture

// Lister les ledgers actifs (avec block_count et symbol par ledger)
const ledgers: LedgerInfo[] = await client.listLedgers();
// Réponse:
// [
//   { id: "main", network_id: "mainnet", prefix: "", protocol_version: 1, block_count: 12345, symbol: "PMS" },
//   { id: "gaming", network_id: "gaming-net", prefix: "gam_", protocol_version: 1, block_count: 678, symbol: "GAME" }
// ]

// Filtrer par préfixe de nom (starts_with, case-insensitive sur id, network_id ou symbol)
const gaming = await client.listLedgers({ search: "gam" });
// → [{ id: "gaming", ... }]
// Récupérer les tips du DAG (blocs les plus récents)
const tips: string[] = await client.getTips();
// Réponse: ["4aa21b8f570005b4088c53149c9afedc528d7a47127e915744a1811c11d5956c", "..."]
// Récupérer un bloc par son ID
const block: Block = await client.getBlock(blockId);
// Réponse:
// {
//   id: "4aa21b8f570005b4088c53149c9afedc528d7a47127e915744a1811c11d5956c",
//   parents: ["abc123...", "def456..."],
//   payload: { Plain: { TxUtxo: { ... } } },
//   nonce: 12345
// }
// Récupérer le supply total
const supply: SupplyInfo = await client.getSupply();
// Réponse:
// {
//   circulating: "1000000.00000000",
//   utxo_count: 42567
// }
// Récupérer les UTXOs d'une adresse
const utxos: Utxo[] = await client.getUtxos(address);
// Réponse:
// [
//   {
//     address: "04abc123...",
//     amount: "50.00000000",
//     outpoint: { txid: "tx123...", index: 0 }
//   },
//   {
//     address: "04abc123...",
//     amount: "25.50000000",
//     outpoint: { txid: "tx456...", index: 1 }
//   }
// ]
// Récupérer la balance d'une adresse
const balance: string = await client.getBalance(address);
// Réponse: "75.50000000"
// Récupérer balance + UTXOs détaillés
const info: BalanceInfo = await client.getBalanceInfo(address);
// Réponse:
// {
//   address: "04abc123...",
//   balance: "75.50000000",
//   utxos: [{ address: "...", amount: "...", outpoint: {...} }, ...]
// }
// Récupérer l'historique (Transactions, Mints, Rewards)
const history = await client.getHistory(address, { limit: 50 });
// Réponse:
// {
//   address: "04abc123...",
//   count: 50,
//   items: [
//     { block_id: "...", ts_ms: 1700000000000, payload_type: "Reward", payload: { ... } },
//     { block_id: "...", ts_ms: 1700000050000, payload_type: "TxUtxo", payload: { ... } }
//   ]
// }

// Récupérer l'historique avec déchiffrement automatique des rewards
// (Nécessite le wallet pour déchiffrer les EncryptedRewards)
const historyWithDecrypt = await client.getHistory(address, {
    limit: 50,
    decryptionWallet: myWallet 
});
// Les items "EncryptedReward" déchiffrés apparaîtront comme des "Reward" standards

Activity API

L'Activity API classifie chaque transaction avec un type semantique (fee_received, transfer_in, nft_mint, freeze, etc.), une direction et un montant net. Elle remplace /wallet/history (deprecie).

// Toute l'activite d'un wallet
const activity = await client.getActivity("8eabc...");
// Reponse: { address, items: ActivityItem[], count, has_more, next_after_ts?, next_after_id? }

// Filtrer par type
const fees = await client.getActivity("8eabc...", {
  type: ["fee_received", "reward"],
  limit: 20,
});

// Pagination
const page2 = await client.getActivity("8eabc...", {
  after_ts: activity.next_after_ts,
  after_id: activity.next_after_id,
});

// Filtrer par asset
const edeniteActivity = await client.getActivity("8eabc...", {
  asset_id: "edenite",
});

// Avec dechiffrement des payloads chiffres (EncryptedReward, Encrypted)
// IMPORTANT: ne passer la cle privee que sur TLS
const decrypted = await client.getActivity("8eabc...", {
  x25519_sk_hex: "votre_cle_privee_x25519_hex",
});

Streaming temps reel (SSE) :

const stop = client.streamActivity("8eabc...", {
  type: ["transfer_in", "fee_received"],
  x25519_sk_hex: "votre_cle_privee_x25519_hex", // Optionnel: dechiffrement en temps reel
  onActivity: (item) => {
    console.log(`${item.activity_type}: ${item.amount} (${item.direction})`);
  },
  onError: (err) => console.error("SSE error:", err),
  onClose: () => console.log("Stream closed"),
});

// Plus tard: fermer la connexion
stop();

Methodes d'Ecriture (Transactions)

// Envoyer des tokens
const result = await client.send({
  to: "04destinataire...",
  amount: "100.0",
  wallet: myWallet,
  memo: "Paiement optionnel", // Optionnel
});
// Réponse:
// {
//   status: "inserted",  // ou "already_exists"
//   block_id: "7f3a2b1c..."
// }

NFT - Non-Fungible Tokens

Le SDK supporte les opérations NFT natives du réseau PMS.

Mint NFT (Standard)

La création de NFT est sécurisée par le Coordinateur.

// Le server (Coordinateur) signe et chiffre le NFT pour vous.
const result = await client.mintNft({
  tokenId: "unique-nft-001",
  metadata: {
    name: "Mon NFT",
    description: "Description du NFT",
    uri: "ipfs://QmXxx...",
    nft_type: "art",
  },
  wallet: myWallet, // Votre wallet personnel
});
// Réponse:
// {
//   status: "inserted",
//   token_id: "unique-nft-001",
//   block_id: "a1b2c3d4e5f6..."
// }

[!NOTE] Les métadonnées sont automatiquement chiffrées par le serveur pour le propriétaire et le Coordinateur.

Mint Cube (NFT avec Rareté)

Les Cubes sont des NFTs spéciaux avec rareté et attributs générés par un backend Authority.

// Mint un cube pour un utilisateur
const result = await client.mintCube({
  wallet: myWallet,
  generatorUrl: "https://cube-generator.example.com", // Backend Authority
});
// Réponse (MintCubeResponse):
// {
//   status: "inserted",
//   block_id: "9f8e7d6c5b4a...",
//   token_id: "a1b2c3d4e5f6...64chars...",
//   rarity: "Legendary",
//   roll: 75,
//   attributes: {
//     weight: 50.5,
//     size: 30.2,
//     density: 2.5
//   }
// }

Raretés possibles :

| Rareté | Probabilité | Cubes sur 10M | |--------|-------------|---------------| | Unique | 1/1,000,000 | 10 | | Legendary | 1/100,000 | 100 | | Rare | 1/10,000 | 1,000 | | Uncommon | 1/1,000 | 10,000 | | Common | 1/100 | 100,000 | | Basic | ~99% | ~9,888,890 |

Burn NFT

// Détruit un NFT (seul le propriétaire peut brûler)
const result = await client.burnNft({
  tokenId: "nft-to-destroy",
  wallet: ownerWallet,
});
// Réponse:
// {
//   status: "inserted",
//   block_id: "1a2b3c4d5e6f...",
//   refund: {                       // Uniquement pour les Cubes authentiques
//     amount: "1.23456789",
//     recipient: "04abc123..."
//   }
// }

[!TIP] Les Cubes avec une signature Authority valide génèrent un remboursement automatique calculé selon leurs attributs.

Batch Burn (Destruction Multiple)

Pour détruire plusieurs NFTs en une seule transaction (économie de frais) :

const result = await client.burnNfts({
  tokenIds: ["token-1", "token-2", "token-3"],
  wallet: ownerWallet,
});
// Réponse:
// {
//   status: "burned",
//   token_id: "batch",
//   token_ids: ["token-1", "token-2", "token-3"],
//   refund: { ... } // Remboursement cumulé
// }

API Avancée

Pour les cas d'usage avancés (construction manuelle de blocs, chiffrement custom), importez depuis le module advanced :

import { 
  computeBlockId, 
  checkPowBits,
  encryptPayload, 
  decryptPayload, 
  generateX25519Keypair,
  deriveX25519PublicKey,
} from "@empereur-rouge/pms-sdk/src/advanced";

import type {
  WireBlock,
  PayloadEnvelope,
  TxUtxo,
} from "@empereur-rouge/pms-sdk/src/advanced";

[!WARNING] L'API avancée peut changer sans préavis. Préférez l'API publique pour la stabilité.


Utilitaires (API Publique)

import { 
  parseAmount, 
  formatAmount,
  toHex,
  fromHex,
} from "@empereur-rouge/pms-sdk";

// Convertir les montants
const sats = parseAmount("10.5");      // -> 1050000000n
const formatted = formatAmount(sats);   // -> "10.50000000"

// Conversions hex
const hex = toHex(new Uint8Array([1, 2, 3]));
const bytes = fromHex("010203");

Types TypeScript

Tous les types sont exportés et documentés :

import type {
  // Configuration
  PmsClientConfig,
  
  // Réponses API
  SubmitResponse,
  BalanceInfo,
  SupplyInfo,
  WalletResponse,
  
  // NFT
  NftMetadata,
  MintCubeResponse,
  BurnNftResponse,
  CubeAttributes,
  
  // Blocs & Transactions (lecture)
  Block,
  Utxo,

  // Historique
  WalletHistoryResp,
  HistoryItem,

  // Activity
  ActivityItem,
  ActivityResp,
  ActivityOptions,
  StreamActivityOptions,
  ActivityType,
  ActivityDirection,

  // Ledger
  LedgerInfo,
} from "@empereur-rouge/pms-sdk";

// Types bas niveau (API avancée)
import type {
  WireBlock,
  PayloadEnvelope,
  TxUtxo,
  OutputRef,
  TxOutput,
} from "@empereur-rouge/pms-sdk/src/advanced";

Sécurité

Coordinateur et Minting

En production, seul le Coordinateur peut créer de nouveaux NFTs (y compris les Cubes). Cette restriction est appliquée au niveau du backend via la clé coordinator_pk.

Les NFTs authentiques sont identifiés par le creator qui correspond à la clé publique du Coordinateur.

Chiffrement

Le SDK utilise :

  • secp256k1 pour les signatures (ECDSA, DER-encoded)
  • X25519 pour l'échange de clés
  • AES-256-GCM pour le chiffrement symétrique

Bonnes Pratiques

// ✅ Stocker le mnemonic de façon sécurisée
const wallet = PmsWallet.generate();
// Sauvegarder wallet.mnemonic dans un stockage sécurisé

// ✅ Ne jamais exposer la clé privée
const privateKey = wallet.exportPrivateKey();
// Ne pas logger ou transmettre cette valeur

// ✅ Vérifier les signatures avant d'accepter des données
const isValid = PmsWallet.verify(message, signature, senderPubKey);

Racing Pattern

Le SDK utilise un "racing pattern" pour la soumission des transactions :

  1. Le client maintient une liste de nœuds connus
  2. Lors de submitBlock(), la transaction est envoyée à tous les nœuds en parallèle
  3. La première réponse positive est retournée
  4. Les autres requêtes sont annulées

Cela améliore :

  • La latence (premier nœud qui répond)
  • La fiabilité (tolérance aux pannes)
  • La propagation (le bloc atteint plusieurs nœuds rapidement)
// Désactiver si non souhaité
const client = new PmsClient({
  nodeUrl: "...",
  apiKey: "pk_live_...",
  enableRacing: false,
});

Tests

# Lancer les tests
npm test

# Mode watch
npm run test:watch

# Couverture
npm run test:coverage

Licence

MIT © PMS Team