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

@galaxy-kj/core-invisible-wallet

v5.1.1

Published

Galaxy Invisible Wallet System - Seamless wallet management for users

Downloads

375

Readme

@galaxy-kj/core-invisible-wallet

Invisible Wallet System for Galaxy DevKit - Seamless Stellar wallet management with USDC support, path payment swaps, and encrypted backup/restore.

Overview

The Invisible Wallet provides a user-friendly wallet management system that abstracts away the complexity of handling private keys on the Stellar network. Users can create wallets, swap between XLM and USDC, sign external transactions (Trustless Work, Soroban dApps), and back up their keys with industry-standard encryption.

Features

  • Wallet Management: Create, unlock, lock, and manage Stellar wallets
  • XLM / USDC Swaps: Built-in swapXlmUsdc() with pre-configured USDC issuers (testnet & mainnet)
  • Trustline Management: Add trustlines for any Stellar asset (USDC, EURC, etc.)
  • External Transaction Signing: Sign XDR transactions from Trustless Work, Soroban dApps, and other services
  • AES-256-GCM Encryption: Military-grade encryption for private keys
  • Multiple KDF Support: PBKDF2 and Argon2id for key derivation
  • Multiple Backup Formats: Encrypted JSON, QR Code, Paper Wallet, Mnemonic
  • Shamir Secret Sharing: Split backups across multiple parties
  • Session Management: Time-limited sessions with automatic expiration

Installation

npm install @galaxy-kj/core-invisible-wallet

Quick Start

Creating a Wallet

import { InvisibleWalletService } from '@galaxy-kj/core-invisible-wallet';

const networkConfig = {
  network: 'testnet' as const,
  horizonUrl: 'https://horizon-testnet.stellar.org',
  passphrase: 'Test SDF Network ; September 2015',
};

const walletService = new InvisibleWalletService(networkConfig);

const { wallet, session } = await walletService.createWallet(
  {
    userId: 'user_123',
    email: '[email protected]',
    network: networkConfig,
  },
  'SecurePassword123!'
);

console.log('Public Key:', wallet.publicKey);
console.log('Session Token:', session.sessionToken);

Swapping XLM to USDC

The swapXlmUsdc method uses pre-configured USDC issuers per network, no need to specify asset issuers:

// XLM -> USDC
const result = await walletService.swapXlmUsdc(
  wallet.id,
  session.sessionToken,
  'xlm_to_usdc',
  '50',                    // send 50 XLM
  'SecurePassword123!'
);

console.log(`Swapped ${result.inputAmount} XLM -> ${result.outputAmount} USDC`);
console.log(`Price: ${result.price}, Impact: ${result.priceImpact}%`);

// USDC -> XLM
const reverse = await walletService.swapXlmUsdc(
  wallet.id,
  session.sessionToken,
  'usdc_to_xlm',
  '10',                    // send 10 USDC
  'SecurePassword123!',
  2.5                      // optional: max slippage 2.5% (default 1%)
);

Generic Swap (any asset pair)

For swapping between arbitrary assets, use the swap method:

const result = await walletService.swap(
  wallet.id,
  session.sessionToken,
  {
    sendAssetCode: 'XLM',
    destAssetCode: 'EURC',
    destAssetIssuer: 'GDHU...', // issuer public key
    amount: '100',
    type: 'strict_send',       // or 'strict_receive'
    maxSlippage: 1,            // 1%
  },
  'SecurePassword123!'
);

Adding a Trustline

Before receiving any non-native asset (USDC, EURC, etc.), you need a trustline:

await walletService.addTrustline(
  wallet.id,
  session.sessionToken,
  {
    assetCode: 'USDC',
    assetIssuer: 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN',
    limit: '10000', // optional
  },
  'SecurePassword123!'
);

Signing External Transactions (Trustless Work, Soroban)

Sign unsigned XDR transactions from external services:

// Example: signing a Trustless Work escrow transaction
const { signedXdr, hash } = await walletService.signTransaction(
  wallet.id,
  session.sessionToken,
  unsignedXdr,     // XDR string from useFundEscrow, Soroban, etc.
  'SecurePassword123!'
);

console.log('Signed XDR:', signedXdr);
console.log('Tx Hash:', hash);

Checking Balances

const xlmBalance = await walletService.getBalance(wallet.id, 'XLM');
const usdcBalance = await walletService.getBalance(wallet.id, 'USDC');

console.log(`XLM: ${xlmBalance.balance}`);
console.log(`USDC: ${usdcBalance.balance}`);

USDC Configuration

Pre-configured USDC issuers are available via USDC_CONFIG:

import { USDC_CONFIG } from '@galaxy-kj/core-invisible-wallet';

// Testnet
USDC_CONFIG.testnet.issuer // GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5

// Mainnet (Circle)
USDC_CONFIG.mainnet.issuer // GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN

Backup & Restore

Creating a Wallet Backup

import { BackupManager } from '@galaxy-kj/core-invisible-wallet';

const backupManager = new BackupManager();

const backup = await backupManager.createBackup(wallet, 'securePassword', {
  format: 'encrypted-json',
  kdf: 'Argon2',
  label: 'My Primary Wallet Backup'
});

console.log('Backup created:', backup.metadata.checksum);

Restoring from Backup

import { RestoreManager } from '@galaxy-kj/core-invisible-wallet';

const restoreManager = new RestoreManager();

const result = await restoreManager.restoreFromEncryptedJson(
  backup,
  'securePassword',
  { validateChecksum: true }
);

if (result.success) {
  console.log('Wallet restored:', result.data.publicKey);
}

Shamir Secret Sharing

Split your backup across multiple trusted parties:

const shamirBackup = await backupManager.createShamirBackup(wallet, 'password', {
  threshold: 2,
  totalShares: 3
});

const shares = backupManager.distributeShares(shamirBackup);
shares.forEach((item, i) => {
  console.log(`Share ${i + 1}:\n${item.instructions}`);
});

// Later: Restore with any 2 shares
const restored = await restoreManager.restoreFromShamirShares(
  [shares[0].share, shares[1].share],
  'password'
);

Backup Formats

| Format | Description | |--------|-------------| | encrypted-json | Primary format with full metadata and checksums | | qr-code | Mobile-friendly format for easy scanning | | paper-wallet | Printable HTML format for cold storage | | mnemonic | BIP39 standard 12/24 word recovery phrase |

KDF Options

Argon2id (Recommended)

{
  kdf: 'Argon2',
  kdfParams: {
    memoryCost: 65536,  // 64 MB
    timeCost: 3,
    parallelism: 4,
    hashLength: 32,
    type: 'argon2id'
  }
}

PBKDF2 (Compatibility)

{
  kdf: 'PBKDF2',
  kdfParams: {
    iterations: 100000,
    keyLength: 32,
    digest: 'sha256'
  }
}

API Reference

InvisibleWalletService

| Method | Description | |--------|-------------| | createWallet(config, password, deviceInfo?) | Create a new invisible wallet | | createWalletFromMnemonic(config, mnemonic, password, deviceInfo?) | Import wallet from BIP39 mnemonic | | unlockWallet(walletId, password, deviceInfo?) | Unlock wallet and get session | | lockWallet(walletId, sessionToken?) | Lock wallet / revoke sessions | | getBalance(walletId, asset?) | Get balance for an asset | | getAccountInfo(walletId) | Get full Stellar account info | | sendPayment(walletId, sessionToken, params, password) | Send a payment | | addTrustline(walletId, sessionToken, params, password) | Add asset trustline | | swapXlmUsdc(walletId, sessionToken, direction, amount, password, maxSlippage?) | Swap between XLM and USDC | | swap(walletId, sessionToken, params, password) | Swap any asset pair via path payments | | signTransaction(walletId, sessionToken, xdr, password) | Sign external XDR transaction | | getTransactionHistory(walletId, limit?) | Get transaction history | | changePassword(walletId, oldPassword, newPassword) | Change wallet password | | exportBackup(walletId, password) | Export encrypted backup |

BackupManager

| Method | Description | |--------|-------------| | createBackup(wallet, password, options) | Create backup in any format | | createEncryptedJsonBackup(data, password, options) | Create encrypted JSON backup | | createShamirBackup(wallet, password, options) | Create Shamir split backup | | validateBackup(backup) | Validate backup structure | | getBackupInfo(backup) | Get backup metadata | | exportBackupAsString(backup) | Export as JSON string | | exportBackupAsBase64(backup) | Export as Base64 |

RestoreManager

| Method | Description | |--------|-------------| | restoreFromEncryptedJson(backup, password, options) | Restore from encrypted JSON | | restoreFromShamirShares(shares, password, options) | Restore from Shamir shares | | autoRestore(data, password, options) | Auto-detect format and restore |

ShamirManager

| Method | Description | |--------|-------------| | splitSecret(backup, options) | Split backup into shares | | combineShares(shares) | Reconstruct from shares | | validateShare(share) | Validate a single share | | createShareCard(share) | Create distributable card | | parseShareCard(cardData) | Parse share from card |

Environment Variables

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key

Security Considerations

  1. Never store unencrypted private keys
  2. Use Argon2 for new backups (PBKDF2 for legacy compatibility)
  3. Verify checksums before restoring
  4. Distribute Shamir shares to geographically separate locations
  5. Test restoration before relying on a backup
  6. Use strong passwords (minimum 8 characters, uppercase, lowercase, numbers)
  7. privateKey field naming: The Wallet.privateKey field carries encrypted ciphertext (AES-256-GCM format: salt:iv:authTag:ciphertext), not the raw Stellar secret key. Always call decryptPrivateKey(wallet.privateKey, password) before using it with Keypair.fromSecret(). This naming is a legacy convention — the value is never a plaintext secret.
  8. CSPRNG for IDs: All generated identifiers (wallet IDs, event IDs, subscription IDs) use crypto.randomBytes() instead of Math.random() for cryptographic safety

License

MIT