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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@flipflop-sdk/node

v1.3.17

Published

FlipFlop Node.js SDK for programmatic token operations

Downloads

113

Readme

@flipflop-sdk/node

A comprehensive Node.js SDK for FlipFlop token operations on Solana. This library provides programmatic access to token launches, Universal Referral Code (URC) management, batch minting operations, and metadata management.

Installation

npm install @flipflop-sdk/node
# or
yarn add @flipflop-sdk/node

Quick Start

Basic Usage

const { 
  launchToken, 
  mintToken, 
  setUrc, 
  getMintData, 
  getUrcData,
  getSystemConfig,
  generateMetadataUri,
  validateImageFile,
  loadKeypairFromBase58
} = require('@flipflop-sdk/node');

async function example() {
  // Generate metadata URI first
  const metadataResult = await generateMetadataUri({
    rpc: 'https://api.devnet.solana.com',
    name: 'My Token',
    symbol: 'MTK',
    description: 'A sample token for demonstration',
    imagePath: './path/to/token-logo.png'
  });

  if (metadataResult.success) {
    console.log('Metadata URI:', metadataResult.metadataUrl);
    console.log('Image URI:', metadataResult.imageUrl);
  }

  // Launch a new token with metadata
  const launchResult = await launchToken({
    rpc: 'https://api.devnet.solana.com',
    name: 'My Token',
    symbol: 'MTK',
    tokenType: 'meme', // or 'standard'
    uri: metadataResult.metadataUrl, // Use generated metadata URI
    keypairBs58: 'your-base58-private-key'
  });

  console.log('Token launched:', launchResult.mintAddress.toString());
  console.log('Transaction:', launchResult.transactionHash);

  // Set URC code
  const urcResult = await setUrc({
    rpc: 'https://api.devnet.solana.com',
    mint: launchResult.mintAddress.toString(),
    urc: 'MYCODE2024',
    keypairBs58: 'your-base58-private-key'
  });

  console.log('URC set:', urcResult.urc);
  console.log('Usage count:', urcResult.usageCount);

  // Mint tokens (pass a Keypair as `minter`)
  const minter = loadKeypairFromBase58('minter-base58-private-key');
  const mintResult = await mintToken({
    rpc: 'https://api.devnet.solana.com',
    mint: launchResult.mintAddress.toString(),
    urc: 'MYCODE2024',
    minter
  });

  if (mintResult.success) {
    console.log('Mint successful:', mintResult.data?.tx);
    console.log('Token account:', mintResult.data?.tokenAccount.toString());
  }

  // Get token information
  const tokenInfo = await getMintData({
    rpc: 'https://api.devnet.solana.com',
    mint: launchResult.mintAddress.toString()
  });

  console.log('Token name:', tokenInfo.name);
  console.log('Token symbol:', tokenInfo.symbol);
  console.log('Current supply:', tokenInfo.currentSupply);
  console.log('Max supply:', tokenInfo.maxSupply);

  // Get URC information
  const urcInfo = await getUrcData({
    rpc: 'https://api.devnet.solana.com',
    urc: 'MYCODE2024'
  });

  console.log('URC valid:', urcInfo.isValid);
  console.log('Referrer:', urcInfo.referrerMain.toString());
  console.log('Usage count:', urcInfo.usageCount);

  // Get system configuration
  const systemConfig = await getSystemConfig({
    rpc: 'https://api.devnet.solana.com'
  });

  console.log('System manager:', systemConfig.systemManagerAccount.toString());
  console.log('Protocol fee rate:', systemConfig.graduateFeeRate);
}

### TypeScript Usage

```typescript
import { 
  launchToken, 
  mintToken, 
  setUrc, 
  getMintData, 
  getUrcData,
  getSystemConfig,
  generateMetadataUri,
  validateImageFile,
  LaunchTokenOptions,
  LaunchTokenResponse,
  MintTokenOptions,
  MintTokenResponse,
  SetUrcOptions,
  SetUrcResponse,
  GetMintDataOptions,
  GetMintDataResponse,
  GetUrcDataOptions,
  GetUrcDataResponse,
  SystemConfigAccountOptions,
  SystemConfigAccountData,
  GenerateMetadataUriOptions,
  MetadataUploadResponse,
  loadKeypairFromBase58
} from '@flipflop-sdk/node';

async function example() {
  // Generate metadata with type safety
  const metadataOptions: GenerateMetadataUriOptions = {
    rpc: 'https://api.devnet.solana.com',
    name: 'TypeScript Token',
    symbol: 'TST',
    description: 'A TypeScript token example',
    imagePath: './assets/logo.png'
  };

  const metadataResult: MetadataUploadResponse = await generateMetadataUri(metadataOptions);
  
  // Launch token with type safety
  const launchOptions: LaunchTokenOptions = {
    rpc: 'https://api.devnet.solana.com',
    name: 'TypeScript Token',
    symbol: 'TST',
    tokenType: 'standard',
    uri: metadataResult.metadataUrl,
    keypairBs58: 'your-base58-private-key'
  };

  const launchResult: LaunchTokenResponse = await launchToken(launchOptions);
  
  // Set URC with type safety
  const setUrcOptions: SetUrcOptions = {
    rpc: 'https://api.devnet.solana.com',
    mint: launchResult.mintAddress.toString(),
    urc: 'TST_CODE',
    keypairBs58: 'your-base58-private-key'
  };

  const urcResult: SetUrcResponse = await setUrc(setUrcOptions);
  
  // Mint tokens with type safety (note: `minter` is a Keypair)
  const mintOptions: MintTokenOptions = {
    rpc: 'https://api.devnet.solana.com',
    mint: launchResult.mintAddress, // PublicKey
    urc: 'TST_CODE',
    minter: loadKeypairFromBase58('minter-base58-private-key')
  };

  const mintResult = await mintToken(mintOptions);
}

API Reference

Core Functions

generateMetadataUri(options: GenerateMetadataUriOptions): Promise<MetadataUploadResponse>

NEW - Generate metadata URI by uploading image and metadata to Irys network.

Parameters:

interface GenerateMetadataUriOptions {
  rpc: string;           // RPC endpoint URL
  name: string;          // Token name
  symbol: string;        // Token symbol
  description?: string;  // Token description (optional)
  imagePath: string;     // Path to image file
}

Returns:

interface MetadataUploadResponse {
  success: boolean;
  metadataUrl?: string;  // Irys gateway URL for metadata JSON
  imageUrl?: string;     // Irys gateway URL for uploaded image
  error?: string;        // Error message if upload failed
}

Image Requirements:

  • Supported formats: JPEG, PNG, GIF, WebP, AVIF
  • Maximum size: 250KB
  • File validation: Automatic type and size checking

Example:

const result = await generateMetadataUri({
  rpc: 'https://api.devnet.solana.com',
  name: 'My Awesome Token',
  symbol: 'MAT',
  description: 'This is an awesome token for the community',
  imagePath: './assets/token-logo.png'
});

if (result.success) {
  console.log('Metadata URL:', result.metadataUrl);
  console.log('Image URL:', result.imageUrl);
} else {
  console.error('Upload failed:', result.error);
}

validateImageFile(imagePath: string): { valid: boolean; error?: string }

NEW - Validate image file before upload.

Parameters:

  • imagePath: Path to the image file

Returns:

  • valid: Boolean indicating if file is valid
  • error: Error message if validation fails

Example:

const validation = validateImageFile('./logo.png');
if (!validation.valid) {
  console.error('Image validation failed:', validation.error);
}

launchToken(options: LaunchTokenOptions): Promise<LaunchTokenResponse>

Launch a new token with specified parameters.

Parameters:

interface LaunchTokenOptions {
  rpc: string;             // RPC endpoint URL
  name: string;            // Token name
  symbol: string;          // Token symbol
  tokenType: string;       // 'meme' or 'standard'
  uri?: string;            // Metadata URI (optional, use generateMetadataUri)
  keypairBs58?: string;    // Base58 encoded private key
  keypairFile?: string;    // Path to keypair file
}

Returns:

interface LaunchTokenResponse {
  success: boolean;
  transactionHash: string;
  mintAddress: PublicKey;
  configAddress: PublicKey;
  metadata: TokenMetadata;
  configuration: ConfigAccountData;
}

Example:

const result = await launchToken({
  rpc: 'https://api.devnet.solana.com',
  name: 'My Token',
  symbol: 'MTK',
  tokenType: 'meme',
  uri: 'https://gateway.irys.xyz/your-metadata-id', // From generateMetadataUri
  keypairBs58: 'your-base58-private-key'
});

setUrc(options: SetUrcOptions): Promise<SetUrcResponse>

Set Universal Referral Code for a token.

Parameters:

interface SetUrcOptions {
  rpc: string;             // RPC endpoint URL
  urc: string;             // Universal Referral Code
  mint: string;            // Token mint address
  keypairBs58?: string;    // Base58 encoded private key
  keypairFile?: string;    // Path to keypair file
}

Returns:

interface SetUrcResponse {
  transactionHash: string;
  urc: string;
  mint: PublicKey;
  referrer: PublicKey;
  referrerTokenAccount: PublicKey;
  codeHash: PublicKey;
  usageCount: number;
  activatedAt: number;
}

Example:

const result = await setUrc({
  rpc: 'https://api.devnet.solana.com',
  mint: 'TokenMintAddress',
  urc: 'UNIQUECODE',
  keypairBs58: 'your-base58-private-key'
});

mintToken(options: MintTokenOptions): Promise<ApiResponse<MintTokenResponse>>

Mint tokens using a URC code.

Parameters:

interface MintTokenOptions {
  rpc: string;                  // RPC endpoint URL
  minter: Keypair;              // The minter's Keypair (wallet that pays & receives)
  mint: PublicKey;              // Token mint address (a string is also accepted; it will be converted)
  urc: string;                  // Universal Referral Code
  lookupTableAccount?: PublicKey; // Optional; defaults to network LUT from CONFIGS
  skipPreflight?: boolean;      // Optional; skip transaction preflight checks (default: false)
}

Returns:

// Generic API wrapper used across the SDK
interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
}

// Mint call payload on success
interface MintTokenResponse {
  tx: string;              // Transaction signature
  owner: PublicKey;        // Minter's public key
  tokenAccount: PublicKey; // Associated token account that received the mint
}
  • The function resolves to Promise<ApiResponse<MintTokenResponse>>.
  • On success, message is "Mint succeeded" and data contains tx, owner, and tokenAccount.

Example:

const { loadKeypairFromBase58 } = require('@flipflop-sdk/node');

const minter = loadKeypairFromBase58('minter-base58-private-key');
const result = await mintToken({
  rpc: 'https://api.devnet.solana.com',
  mint: 'TokenMintAddress', // string is accepted; SDK will convert internally
  urc: 'UNIQUECODE',
  minter,
  skipPreflight: true // Optional: skip preflight checks for faster execution
});

if (result.success) {
  console.log('tx:', result.data.tx);
  console.log('owner:', result.data.owner.toBase58());
  console.log('tokenAccount:', result.data.tokenAccount.toBase58());
} else {
  console.error('Mint failed:', result.message);
}

Notes:

  • urc must be a valid and active referral code on-chain; the SDK derives and verifies the referral PDA internally.
  • If lookupTableAccount is not provided, the SDK uses the preconfigured LUT for the detected network (via CONFIGS).
  • Common error messages include metadata fetch failures and on-chain validation errors; in such cases you'll receive { success: false, message: 'Mint operation failed: ...' }.

refundToken(options: RefundTokenOptions): Promise<ApiResponse<RefundTokenResponse>>

Request a refund for the caller's tokens according to protocol rules.

Parameters:

interface RefundTokenOptions {
  rpc: string;           // RPC endpoint URL
  mint: PublicKey;       // Token mint address (a string is also accepted; it will be converted)
  owner: Keypair;        // The owner's Keypair (the account that holds tokens to refund)
}

Returns:

interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message?: string;
}

interface RefundTokenResponse {
  tx: string;  // Transaction signature
}

Example (JavaScript):

const { refundToken, loadKeypairFromBase58 } = require('@flipflop-sdk/node');

const owner = loadKeypairFromBase58('owner-base58-private-key');
const result = await refundToken({
  rpc: 'https://api.devnet.solana.com',
  mint: 'TokenMintAddress', // string is accepted; SDK will convert internally
  owner
});

if (result.success) {
  console.log('Refund tx:', result.data.tx);
} else {
  console.error('Refund failed:', result.message);
}

Example (TypeScript):

import { refundToken, RefundTokenOptions } from '@flipflop-sdk/node';
import { PublicKey } from '@solana/web3.js';

const options: RefundTokenOptions = {
  rpc: 'https://api.devnet.solana.com',
  mint: new PublicKey('TokenMintAddress'),
  owner: loadKeypairFromBase58('owner-base58-private-key'),
};

const res = await refundToken(options);

Notes:

  • The owner must match the protocol's refund record for this mint; otherwise you'll receive "Only User Account Allowed".
  • The SDK automatically creates WSOL associated token accounts for the owner and the protocol fee account if missing.
  • Typical on-chain failures include: NotEnoughTokensToRefund, RefundTokensIsZero, UserBalanceNotEnoughForRefund, VaultBalanceNotEnoughForRefund, RefundInProgress, InvalidRefundFeeRate, RefundOnlyAllowedInTargetEras.
  • On success, you'll receive { success: true, data: { tx } }.
  • On failure, message may contain strings like "Error refunding..." or "Something went wrong but you have refund successfully". In rare cases you may see "Mint operation failed: ..." from a shared error handler.

getMintData(options: GetMintDataOptions): Promise<GetMintDataResponse>

Get detailed information about a token.

Parameters:

interface GetMintDataOptions {
  rpc: string;    // RPC endpoint URL
  mint: string;   // Token mint address
}

Returns:

interface GetMintDataResponse {
  mint: PublicKey;
  name: string;
  symbol: string;
  uri: string;
  isMutable: boolean;
  configAccount: PublicKey;
  admin: PublicKey;
  tokenVault: PublicKey;
  feeRate: number;
  targetEras: number;
  initialMintSize: number;
  epochesPerEra: number;
  targetSecondsPerEpoch: number;
  reduceRatio: number;
  maxSupply: number;
  liquidityTokensRatio: number;
  currentSupply: number;
  liquidityTokensSupply: number;
  minterTokensSupply: number;
}

Example:

const info = await getMintData({
  rpc: 'https://api.devnet.solana.com',
  mint: 'TokenMintAddress'
});

getUrcData(options: GetUrcDataOptions): Promise<GetUrcDataResponse>

Get information about a URC code.

Parameters:

interface GetUrcDataOptions {
  rpc: string;    // RPC endpoint URL
  urc: string;    // Universal Referral Code
}

Returns:

interface GetUrcDataResponse {
  urc: string;
  codeHash: PublicKey;
  mint: PublicKey;
  referrerMain: PublicKey;
  referrerAta: PublicKey;
  usageCount: number;
  activeTimestamp: number;
  isValid: boolean;
}

Example:

const info = await getUrcData({
  rpc: 'https://api.devnet.solana.com',
  urc: 'UNIQUECODE'
});

getSystemConfig(options: SystemConfigAccountOptions): Promise<SystemConfigAccountData>

Get system configuration information.

Parameters:

interface SystemConfigAccountOptions {
  rpc: string;    // RPC endpoint URL
}

Returns:

interface SystemConfigAccountData {
  systemConfigAccount: PublicKey;
  systemManagerAccount: PublicKey;
  admin: PublicKey;
  count: number;
  referralUsageMaxCount: number;
  protocolFeeAccount: PublicKey;
  refundFeeRate: number;
  referrerResetIntervalSeconds: number;
  updateMetadataFee: number;
  customizedDeployFee: number;
  initPoolWsolAmount: number;
  graduateFeeRate: number;
  minGraduateFee: number;
  raydiumCpmmCreateFee: number;
}

Example:

const config = await getSystemConfig({
  rpc: 'https://api.devnet.solana.com'
});

Utility Functions

All utility functions and constants can also be imported from the library:

import { 
  initProvider, 
  initProviderNoSigner, 
  loadKeypairFromBase58, 
  loadKeypairFromFile,
  validateImageFile,
  CONFIGS,
  NetworkType 
} from '@flipflop-sdk/node';

Configuration

Network Types

  • mainnet: Production network
  • devnet: Development network
  • local: Local validator

Token Types

  • meme: Aggressive parameters for community tokens
  • standard: Conservative parameters for utility tokens

RPC Endpoints

  • Mainnet: https://api.mainnet-beta.solana.com
  • Devnet: https://api.devnet.solana.com
  • Local: http://127.0.0.1:8899

Irys Network Integration

  • Devnet: https://api-dev.flipflop.plus/api/irys/upload
  • Mainnet: https://api.flipflop.plus/api/irys/upload
  • Gateway: https://gateway.irys.xyz/

Authentication

The SDK supports two methods for providing keypairs:

1. Base58 Encoded Private Key

const result = await launchToken({
  // ... other options
  keypairBs58: 'your-base58-encoded-private-key'
});

2. Keypair File Path

const result = await launchToken({
  // ... other options
  keypairFile: './path/to/keypair.json'
});

Error Handling

All functions throw descriptive errors for validation and runtime issues:

try {
  // Validate image first
  const validation = validateImageFile('./logo.png');
  if (!validation.valid) {
    throw new Error(`Image validation failed: ${validation.error}`);
  }

  // Generate metadata
  const metadataResult = await generateMetadataUri({
    rpc: 'https://api.devnet.solana.com',
    name: 'My Token',
    symbol: 'MTK',
    description: 'My awesome token',
    imagePath: './logo.png'
  });

  if (!metadataResult.success) {
    throw new Error(`Metadata upload failed: ${metadataResult.error}`);
  }

  // Launch token
  const result = await launchToken({
    rpc: 'https://api.devnet.solana.com',
    name: 'My Token',
    symbol: 'MTK',
    tokenType: 'meme',
    uri: metadataResult.metadataUrl,
    keypairBs58: 'invalid-key'
  });
} catch (error) {
  console.error('Operation failed:', error.message);
}

Development

Dependencies

The SDK uses the following key dependencies:

Core Solana Libraries:

  • @coral-xyz/anchor (0.31.1) - Anchor framework for Solana
  • @solana/web3.js (^1.98.0) - Solana Web3 JavaScript API
  • @solana/spl-token (^0.4.9) - SPL Token library
  • @solana/spl-token-metadata (^0.1.6) - Token metadata standard

Utility Libraries:

  • axios (^1.11.0) - HTTP client for API requests
  • form-data (^4.0.4) - Multipart form data for file uploads
  • bn.js (5.2.1) - Big number arithmetic
  • bs58 (^6.0.0) - Base58 encoding/decoding
  • decimal.js (^10.4.3) - Decimal arithmetic
  • sleep-promise (^9.1.0) - Promise-based sleep utility

Building

# Install dependencies
npm install

# Build the library
npm run build

# Run tests
npm test

# Watch mode for development
npm run dev

Testing

# Run all tests
npm test

# Run specific test file
npm test launch.test.ts

# Run tests with coverage
npm run test:coverage

# Run metadata tests (requires network connection)
npm test metadata.test.ts

Note: Metadata tests make real API calls to devnet and require internet connection.

Examples

Complete Token Launch Flow with Metadata

const { 
  generateMetadataUri, 
  launchToken, 
  setUrc, 
  mintToken 
} = require('@flipflop-sdk/node');

async function completeFlowWithMetadata() {
  const rpc = 'https://api.devnet.solana.com';
  const creatorKey = 'creator-base58-private-key';
  const minterKey = 'minter-base58-private-key';
  
  // 1. Generate metadata URI
  console.log('Step 1: Generating metadata...');
  const metadata = await generateMetadataUri({
    rpc,
    name: 'Demo Token',
    symbol: 'DEMO',
    description: 'A demonstration token with custom metadata',
    imagePath: './assets/demo-logo.png'
  });
  
  if (!metadata.success) {
    throw new Error(`Metadata generation failed: ${metadata.error}`);
  }
  
  console.log('Metadata URL:', metadata.metadataUrl);
  console.log('Image URL:', metadata.imageUrl);
  
  // 2. Launch token with metadata
  console.log('Step 2: Launching token...');
  const launch = await launchToken({
    rpc,
    name: 'Demo Token',
    symbol: 'DEMO',
    tokenType: 'standard',
    uri: metadata.metadataUrl,
    keypairBs58: creatorKey
  });
  
  console.log('Token launched:', launch.mintAddress.toString());
  
  // 3. Set URC
  console.log('Step 3: Setting URC...');
  const urc = await setUrc({
    rpc,
    mint: launch.mintAddress.toString(),
    urc: 'DEMO_CODE',
    keypairBs58: creatorKey
  });
  
  console.log('URC set:', urc.urc);
  
  // 4. Mint tokens
  console.log('Step 4: Minting tokens...');
  const mint = await mintToken({
    rpc,
    mint: launch.mintAddress.toString(),
    urc: 'DEMO_CODE',
    keypairBs58: minterKey
  });
  
  console.log('Mint successful:', mint.success);
  
  return {
    metadata: metadata.metadataUrl,
    mint: launch.mintAddress.toString(),
    urc: urc.urc,
    transaction: mint.data?.tx
  };
}

Batch Operations with Metadata Validation

async function batchMintWithValidation() {
  const imagePaths = [
    './assets/logo1.png',
    './assets/logo2.jpg',
    './assets/logo3.gif'
  ];
  
  // Validate all images first
  const validations = imagePaths.map(path => ({
    path,
    validation: validateImageFile(path)
  }));
  
  const validImages = validations.filter(v => v.validation.valid);
  const invalidImages = validations.filter(v => !v.validation.valid);
  
  if (invalidImages.length > 0) {
    console.warn('Invalid images found:');
    invalidImages.forEach(img => {
      console.warn(`- ${img.path}: ${img.validation.error}`);
    });
  }
  
  // Process valid images
  const metadataPromises = validImages.map((img, index) => 
    generateMetadataUri({
      rpc: 'https://api.devnet.solana.com',
      name: `Batch Token ${index + 1}`,
      symbol: `BT${index + 1}`,
      description: `Batch generated token ${index + 1}`,
      imagePath: img.path
    })
  );
  
  const metadataResults = await Promise.all(metadataPromises);
  console.log('Batch metadata generation results:', metadataResults);
  
  return metadataResults;
}

Migration from CLI

CLI to SDK Mapping

| CLI Command | SDK Function | |-------------|-------------| | flipflop launch | launchToken() | | flipflop set-urc | setUrc() | | flipflop mint | mintToken() | | flipflop display-mint | getMintData() | | flipflop display-urc | getUrcData() | | NEW | generateMetadataUri() | | NEW | validateImageFile() |

Migration Example

CLI usage:

flipflop launch --name "MyToken" --symbol "MTK" --keypair-file ./keypair.json --rpc https://api.devnet.solana.com

SDK usage:

const { generateMetadataUri, launchToken } = require('@flipflop-sdk/node');

// Generate metadata first (new capability)
const metadata = await generateMetadataUri({
  rpc: 'https://api.devnet.solana.com',
  name: 'MyToken',
  symbol: 'MTK',
  description: 'My awesome token',
  imagePath: './logo.png'
});

// Launch with metadata
const result = await launchToken({
  name: 'MyToken',
  symbol: 'MTK',
  tokenType: 'standard',
  uri: metadata.metadataUrl,
  rpc: 'https://api.devnet.solana.com',
  keypairFile: './keypair.json'
});

Security

  • Never commit private keys to version control
  • Use environment variables for sensitive configuration
  • Validate all inputs before SDK operations
  • Image Security: Only upload trusted images, validate file types and sizes
  • Metadata Security: Review generated metadata before using in production
  • Consider using Keypair.fromSeed() for deterministic key generation
  • Always verify transaction results before proceeding
  • Network Security: Use HTTPS endpoints for all API calls

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import { 
  LaunchTokenOptions, 
  LaunchTokenResponse,
  MintTokenOptions,
  MintTokenResponse,
  SetUrcOptions,
  SetUrcResponse,
  GetMintDataOptions,
  GetMintDataResponse,
  GetUrcDataOptions,
  GetUrcDataResponse,
  SystemConfigAccountOptions,
  SystemConfigAccountData,
  GenerateMetadataUriOptions,
  MetadataUploadResponse,
  MetadataParams,
  TokenMetadata,
  ConfigAccountData,
  NetworkType
} from '@flipflop-sdk/node';

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass (including metadata tests)
  5. Update documentation for new features
  6. Submit a pull request

License

MIT License - see LICENSE file for details.