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

@snekfun/sdk

v1.1.0

Published

Api client of splash protocol

Readme

SnekFun SDK

A comprehensive TypeScript SDK for interacting with the SnekFun trading platform on Cardano blockchain.

npm version TypeScript License

🚀 Features

  • 🔐 Secure Wallet Integration - Support for CIP-30 wallets and passkey authentication
  • 📱 Cross-Platform - Works in browsers and mobile environments
  • 🔒 Advanced Security - Iframe-based isolation, anomaly detection, and session management
  • 💱 Trading Operations - Complete trading workflow with multi-step validation
  • 🔑 Key Management - Secure seed container export and temporary key pair generation
  • 📊 Account Management - Profile, security settings, and wallet operations
  • 🎨 Theme Support - Dark/light theme integration
  • 📝 Full TypeScript - Complete type safety and IntelliSense support

📦 Installation

npm install @snekfun/sdk
yarn add @snekfun/sdk

🏁 Quick Start

Login & Basic Operations

import { Account, AssetInfo } from '@snekfun/sdk';

const hostsConfig = {
  apiUrl: 'https://api.snekfun.com',
  walletUrl: 'https://wallet.snekfun.com',
  balanceUrl: 'https://balance.snekfun.com',
  uTxOMonitorUrl: 'https://utxo.snekfun.com',
  submitUrl: 'https://submit.snekfun.com',
  builderUrl: 'https://builder.snekfun.com',
  avatarUploadUrl: 'https://avatar.snekfun.com',
  ipfsUrl: 'https://ipfs.snekfun.com',
};

// Login with CIP-30 wallet
const account = await Account.login({
  hosts: hostsConfig,
  network: 'mainnet',
  wallet: cardanoWallet, // Your CIP-30 wallet instance
  theme: 'dark',
  getTotp: async () => prompt('Enter 2FA code:') || '',
});

console.log('Login successful!');

// Get wallet balance
const balance = await account.wallet.getBalance();
console.log('ADA Balance:', balance.get(AssetInfo.ada)?.amount);

// Sign a transaction
const signedTx = await account.wallet.signTx('84a400818258...');
console.log('Transaction signed:', signedTx);

// Logout when done
await account.logout();

🔧 Core Components

Authentication Methods

The SDK supports multiple authentication approaches depending on your use case:

1. CIP-30 Wallet Login

Full account access with CIP-30 compatible wallet (Eternl, Vespr, Lace, etc.):

const account = await Account.login({
  hosts: hostsConfig,
  network: 'mainnet',
  wallet: cardanoWallet,
  theme: 'dark',
  getTotp: async () => prompt('Enter 2FA code:') || '',
});

console.log('Full account access granted');

2. Passkey Authentication

WebAuthn-based authentication for password-less login:

// Check passkey support in browser
const isSupported = await Account.isPasskeySupported();

if (isSupported) {
  // Get available passkey credentials
  const accounts = await Account.getAvailableAccounts();

  // Login with stored passkey
  const account = await Account.passkeyLogin({
    hosts: hostsConfig,
    network: 'mainnet',
    wallet: cardanoWallet, // Still needs wallet for transactions
    theme: 'dark',
    credentialData: accounts[0],
  });
}

3. Session Restore

Restore previous session without re-authentication:

const account = await Account.restore({
  hosts: hostsConfig,
  network: 'mainnet',
  wallet: cardanoWallet,
  theme: 'dark',
  profile: savedProfile, // Optional: previously saved profile
  seedContainer: savedSeedContainer, // Optional: encrypted seed
  sessionContainer: savedSessionContainer, // Optional: session data
});

4. Mobile Device Login

Authenticate mobile devices using QR code or pairing:

const account = await Account.mobileDeviceLogin({
  hosts: hostsConfig,
  network: 'mainnet',
  wallet: 'mobile',
  theme: 'dark',
  loginSessionUUID: 'uuid-from-qr',
  secret: 'shared-secret',
  onAuthInit: (params) => {
    console.log('Mobile auth initialized');
  },
});

Account Sections

After login, access specialized functionality through account sections:

Profile Management

Manage user profile, avatars, and metadata:

const account = await Account.login(params);

// Get current profile
const profile = account.profile.snapshot();
console.log('Username:', profile.name);
console.log('Avatar:', profile.avatar);

// Subscribe to profile changes
const unsubscribe = account.profile.subscribe((newProfile) => {
  console.log('Profile updated:', newProfile);
});

// Edit profile
const logoFile = document.querySelector('input[type="file"]').files[0];
await account.profile.editProfile({
  username: 'new_username',
  bio: 'Updated biography',
  appConfig: {
    preferredCurrency: 'ada',
    slippage: '30',
  },
  logo: logoFile, // File from input
});

// Trigger profile update
await account.profile.updateProfile();

// Cleanup subscription
unsubscribe();

Security Management

Manage passkeys, 2FA, and security settings:

const account = await Account.login(params);
const security = account.security;

// Check if passkey is supported
if (AccountSecurity.isPasskeySupported()) {
  // Enable passkey authentication
  await security.enablePasskey({ deviceName: 'My Authenticator' });
  console.log('Passkey enabled');

  // Check if passkey is currently enabled
  const passkeyEnabled = await security.isPasskeyEnabled();
  console.log('Passkey enabled:', passkeyEnabled);
}

// Enable two-factor authentication (2FA)
await security.enable2FA(async (initData) => {
  // Display QR code from initData.qr to user
  const totpCode = await getUserTotpCode(initData);

  return {
    getCode: async () => totpCode,
    onSuccess: () => console.log('2FA enabled successfully'),
    onAttemptError: (error) => console.log('Invalid code, retry'),
    onError: (error) => console.log('Setup failed'),
  };
});

// Reset 2FA if user lost access to authenticator
try {
  await security.reset2FA();
  console.log('2FA has been reset');
} catch (error) {
  console.error('2FA is not enabled or reset failed');
}

// Reset passkey for this device
await security.resetPasskey();
console.log('Passkey disabled on this device');

// Revoke all active sessions
await security.revokeAccess();
console.log('All sessions revoked, user logged out');

Wallet Operations

Execute trading operations, deposits, and withdrawals:

const account = await Account.login(params);
const wallet = account.wallet;

// Get balance
const balance = await wallet.getBalance();
const adaAmount = balance.get(AssetInfo.ada)?.amount;
console.log('ADA Balance:', adaAmount);

// Get wallet information
const walletInfo = await wallet.getWalletInfo();
console.log('Wallet address:', walletInfo.address);

// Sign arbitrary data
const message = new TextEncoder().encode('Hello, Cardano!');
const signature = await wallet.signData(message);
console.log('Signature:', signature);

// Sign a transaction
const cbor = '84a400818258...'; // CBOR hex
const signedTx = await wallet.signTransaction(cbor);
console.log('Signed transaction:', signedTx);

// Sign and submit transaction in one call
const txHash = await wallet.signAndSubmitTransaction(cbor);
console.log('Transaction submitted:', txHash);

// Submit already signed transaction
const txHashOnly = await wallet.submitTransaction(cbor);
console.log('Transaction hash:', txHashOnly);

// Deposit operation (transfer to trading account)
const depositTx = await wallet.deposit({
  amount: '100000000', // Lovelace
  hooks: {
    onSuccess: ({ stage, result }) => {
      console.log('Deposit stage:', stage, result);
    },
    onError: ({ stage, error }) => {
      console.error('Deposit failed at', stage, error);
    },
  },
});
console.log('Deposit transaction hash:', depositTx.hash);

// Withdrawal operation (transfer from trading account)
const withdrawTx = await wallet.withdraw({
  amount: '50000000',
  hooks: {
    onSuccess: ({ stage, result }) => {
      console.log('Withdrawal stage:', stage);
    },
    onError: ({ stage, error }) => {
      console.error('Withdrawal failed at', stage);
    },
  },
});
console.log('Withdrawal transaction hash:', withdrawTx.hash);

// Trading operation
const tradeTx = await wallet.trade({
  side: 'BUY', // or 'SELL'
  assetId: 'asset_id_hex',
  amount: 100000000n,
  slippage: 0.05,
  hooks: {
    onSuccess: ({ stage, result }) => {
      console.log('Trade stage:', stage);
    },
    onError: ({ stage, error }) => {
      console.error('Trade failed at', stage);
    },
  },
});
console.log('Trade transaction hash:', tradeTx.hash);

// Launch new token
const logoFile = document.querySelector('input[type="file"]').files[0];
const launchTx = await wallet.launch({
  name: 'My Token',
  ticker: 'MYTKN',
  description: 'A great new token',
  assetType: 'FT', // or 'NFT'
  launchType: 'public', // or 'private'
  initialDeposit: { amount: BigInt('1000000') },
  logo: logoFile,
  twitter: 'https://twitter.com/mytoken',
  discord: 'https://discord.gg/mytoken',
  telegram: 'https://t.me/mytoken',
  website: 'https://mytoken.io',
  hooks: {
    onSuccess: ({ stage, result }) => {
      console.log('Token launch stage:', stage);
    },
    onError: ({ stage, error }) => {
      console.error('Token launch failed at', stage);
    },
  },
});
console.log('Token launch transaction hash:', launchTx.hash);

Funding Wallet (CIP-30 only)

Access funding wallet operations. Available only on CIP-30 authenticated devices:

const account = await Account.login(params); // Must use CIP-30 wallet
const fundingWallet = account.fundingWallet;

// Get wallet address
const address = await fundingWallet.getAddress();
console.log('Funding wallet address:', address.payment.hash);

// Get comprehensive address information
const addressesInfo = await fundingWallet.getAddressesInfo();
console.log('Change address:', addressesInfo.changeAddress);
console.log('Public key hashes:', Array.from(addressesInfo.pkhs));

// Check balance
const balance = await fundingWallet.getBalance();
console.log('ADA Balance:', balance.get(AssetInfo.ada)?.amount);

// Get UTxOs for building transactions
const utxos = await fundingWallet.getUTxOs();
console.log('Available UTxOs:', utxos.length);

// Sign transaction
const cbor = '84a400818258...'; // CBOR hex
const signedCbor = await fundingWallet.signTx(cbor);
console.log('Signed transaction');

// Sign arbitrary data
const message = '48656c6c6f'; // Hex string
const signature = await fundingWallet.signData(message);
console.log('Signature:', signature.signature);

// Verify wallet consistency (useful for session restoration)
try {
  await fundingWallet.compareFundingWallet(savedWalletPkh);
  console.log('Current wallet matches saved wallet');
} catch (error) {
  console.log('Different wallet detected');
}

Cleanup

Always logout when done to clean up sessions:

await account.logout();

🛡️ Error Handling

The SDK provides comprehensive error handling with specific error types:

import { SFError } from '@snekfun/sdk';

try {
  const account = await Account.login(params);
} catch (error) {
  if (SFError.AuthError.is(error)) {
    console.log('Authentication failed:', error.message);
  } else if (SFError.UserDeclinedSignError.is(error)) {
    console.log('User cancelled the operation');
  } else if (SFError.SessionExpiredError.is(error)) {
    console.log('Session expired, please login again');
  } else if (SFError.BackendError.is(error)) {
    console.log('Server error:', error.message);
  }
}

Available Error Types

Authentication & Session:

  • AuthError - Authentication failures
  • AuthInProgressError - Authentication already in progress
  • SessionExpiredError - User session has expired
  • TwoFAAttemptsExceededError - Too many failed 2FA attempts

Wallet & Operations:

  • UserDeclinedSignError - User cancelled signing operation
  • WalletAccountError - Wallet account-related errors
  • WalletApiError - Wallet API communication errors
  • WalletEnablingError - Wallet enabling/connection errors
  • InvalidWalletNetworkError - Wallet connected to wrong network

General:

  • BackendError - Server-side errors
  • OperationError - General operation failures
  • StepOperationCancelledError - Multi-step operation cancelled
  • MobileAuthError - Mobile authentication errors

🔐 Security Considerations

This SDK manages sensitive cryptographic operations and private key material. To ensure secure deployment:

  • Content Security Policy (CSP): Configure strict CSP policies to prevent XSS attacks
  • HTTPS Only: Always use HTTPS in production
  • Iframe Isolation: The SDK uses iframe-based wallet isolation for enhanced security
  • Session Management: Sessions are automatically managed with expiration and anomaly detection
  • Key Storage: Private keys are never exposed to the main application thread

For production deployments, ensure your application environment adheres to these security best practices.

🔧 Configuration

Host Configuration

const hostsConfig = {
  apiUrl: 'https://api.snekfun.com', // Wallet API URL
  walletUrl: 'https://wallet.snekfun.com', // Wallet web application URL
  balanceUrl: 'https://balance.snekfun.com',
  uTxOMonitorUrl: 'https://utxo.snekfun.com',
  submitUrl: 'https://submit.snekfun.com',
  builderUrl: 'https://builder.snekfun.com',
  avatarUploadUrl: 'https://avatar.snekfun.com',
  ipfsUrl: 'https://ipfs.snekfun.com',
};

Network Support

// Mainnet
const account = await Account.login({
  network: 'mainnet',
  // ... other params
});

// Preprod (Preview testnet)
const account = await Account.login({
  network: 'preprod',
  // ... other params
});

🎨 Theming

// Dark theme
const account = await Account.login({
  theme: 'dark',
  // ... other params
});

// Light theme
const account = await Account.login({
  theme: 'light',
  // ... other params
});

📱 Mobile Support

The SDK includes special support for mobile device authentication:

const account = await Account.login(params);

// Initiate mobile device authentication
const { complete, cancel } = account.mobileAuth((event) => {
  if (event.state === 'pending') {
    // Display QR code from event.data.uuid and secret to mobile device
    displayQRCode(event.data.uuid, event.data.secret);
    console.log('QR code valid until:', event.data.validUntil);
  } else if (event.state === 'registered') {
    // Device registered, waiting for user confirmation
    console.log('Device registered, awaiting confirmation');
  } else if (event.state === 'completed') {
    // Authentication completed
    console.log('Mobile authentication completed');
  }
});

// Wait for mobile device to register
const completeAuth = await complete;

// User confirms authentication on mobile device
// Then complete the process
try {
  await completeAuth();
  console.log('Mobile authentication successful');
} catch (error) {
  console.error('Mobile authentication failed:', error);
}

// Or cancel the authentication flow
cancel();

🧪 Testing

cd packages/snekfun-sdk

# Run tests with yarn
yarn test

# Run tests with jest directly
jest

📚 API Documentation

Generate documentation locally from the monorepo root:

yarn docs