{"_id":"@bober3r/solana-payment-channels-core","name":"@bober3r/solana-payment-channels-core","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bober3r/solana-payment-channels-core","version":"0.1.0","description":"Core payment channel logic with x402 protocol integration for Solana","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup","build:with-types":"tsup --dts","dev":"tsup src/index.ts --format cjs,esm --watch","test":"vitest run","test:integration":"vitest run tests/integration","test:watch":"vitest","lint":"eslint src --ext .ts","lint:fix":"eslint src --ext .ts --fix","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"keywords":["solana","x402","payment-channels","micropayments","blockchain","web3"],"author":{"name":"BOBER3r"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/BOBER3r/solana-payment-channel-kit.git","directory":"packages/core"},"bugs":{"url":"https://github.com/BOBER3r/solana-payment-channel-kit/issues"},"homepage":"https://github.com/BOBER3r/solana-payment-channel-kit#readme","dependencies":{"@coral-xyz/anchor":"^0.31.1","@noble/ed25519":"^2.1.0","@noble/hashes":"^1.5.0","@solana/spl-token":"^0.4.11","@solana/web3.js":"^1.95.8","@x402-solana/core":"latest","bn.js":"^5.2.1","bs58":"^6.0.0"},"devDependencies":{"@types/bs58":"^4.0.4","@types/node":"^20.19.24","eslint":"^9.17.0","tsup":"^8.3.5","typescript":"^5.9.3","vitest":"^2.1.8"},"engines":{"node":">=18.0.0"},"_id":"@bober3r/solana-payment-channels-core@0.1.0","gitHead":"46bab13f27fd923d3ff1ca80c1d24dbd000ce11d","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-Qk3p96CXgKxw2100gz+USgxTOvPYgVE1SmPWNS5nnDXQCKtllf9hUltxEPGUtDNQ6lAlkhg4/kRX+hVKAZ8FmQ==","shasum":"0e68db30a709525029649d0ded658d5ecf908f4c","tarball":"https://registry.npmjs.org/@bober3r/solana-payment-channels-core/-/solana-payment-channels-core-0.1.0.tgz","fileCount":6,"unpackedSize":292966,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDdb3j4x8suAZVhm0Fb9rZZv6TRNgMphrKfblJ1Kx3tvgIhAJi1Nb32laU41QOam7xVHIRd2rYfrrFxNtGn6lZuNQDO"}]},"_npmUser":{"name":"bober3r","email":"BOBER3r@proton.me"},"directories":{},"maintainers":[{"name":"bober3r","email":"BOBER3r@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/solana-payment-channels-core_0.1.0_1762457180856_0.23928382389221237"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-06T19:26:20.691Z","0.1.0":"2025-11-06T19:26:21.055Z","modified":"2025-11-06T19:26:21.408Z"},"maintainers":[{"name":"bober3r","email":"BOBER3r@proton.me"}],"description":"Core payment channel logic with x402 protocol integration for Solana","homepage":"https://github.com/BOBER3r/solana-payment-channel-kit#readme","keywords":["solana","x402","payment-channels","micropayments","blockchain","web3"],"repository":{"type":"git","url":"git+https://github.com/BOBER3r/solana-payment-channel-kit.git","directory":"packages/core"},"author":{"name":"BOBER3r"},"bugs":{"url":"https://github.com/BOBER3r/solana-payment-channel-kit/issues"},"license":"MIT","readme":"# @bober3r/solana-payment-channels-core\n\n[![npm version](https://badge.fury.io/js/%40bober3r%2Fsolana-payment-channels-core.svg)](https://www.npmjs.com/package/@bober3r/solana-payment-channels-core)\n[![npm downloads](https://img.shields.io/npm/dm/%40bober3r%2Fsolana-payment-channels-core.svg)](https://www.npmjs.com/package/@bober3r/solana-payment-channels-core)\n[![GitHub issues](https://img.shields.io/github/issues/BOBER3r/solana-payment-channel-kit)](https://github.com/BOBER3r/solana-payment-channel-kit/issues)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node.js Version](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)\n\nCore payment channel management for Solana with seamless x402 protocol integration.\n\n## Features\n\n- **Off-chain Payments**: Process payments instantly without blockchain transactions\n- **Cryptographic Security**: Ed25519 signatures for payment authorization\n- **State Management**: Efficient in-memory caching with TTL\n- **Automatic Fallback**: Seamlessly falls back to x402 protocol when channels unavailable\n- **Type-Safe**: Full TypeScript support with comprehensive types\n- **Event-Driven**: Subscribe to channel state changes in real-time\n- **Production-Ready**: Comprehensive error handling and validation\n\n## Installation\n\n```bash\nnpm install @bober3r/solana-payment-channels-core @solana/web3.js @coral-xyz/anchor\n```\n\n## Quick Start\n\n```typescript\nimport { ChannelManager, createChannelConfig } from '@bober3r/solana-payment-channels-core';\nimport { Keypair, PublicKey } from '@solana/web3.js';\n\n// Initialize configuration\nconst config = createChannelConfig('devnet', 'YOUR_PROGRAM_ID');\n\n// Create channel manager\nconst manager = new ChannelManager(config, clientKeypair);\n\n// Open a payment channel\nconst channelId = await manager.openChannel({\n  serverPubkey: new PublicKey('SERVER_PUBLIC_KEY'),\n  initialDeposit: BigInt(10_000_000), // 10 USDC\n});\n\n// Create payment authorization (client-side)\nimport { createPaymentAuthorization } from '@bober3r/solana-payment-channels-core';\n\nconst authorization = await createPaymentAuthorization(\n  Buffer.from(channelId, 'hex'),\n  BigInt(1_000_000), // 1 USDC\n  BigInt(1), // nonce\n  clientKeypair\n);\n\n// Claim payment (server-side)\nconst result = await manager.claimPayment(channelId, {\n  amount: BigInt(1_000_000),\n  authorization,\n});\n\nconsole.log('Payment claimed:', result.success);\nconsole.log('Remaining balance:', result.remainingBalance);\n```\n\n## Architecture\n\n### Payment Flow\n\n```\n┌─────────────┐                    ┌─────────────┐\n│   Client    │                    │   Server    │\n└──────┬──────┘                    └──────┬──────┘\n       │                                  │\n       │ 1. Open Channel (on-chain)      │\n       ├─────────────────────────────────>│\n       │                                  │\n       │ 2. Create Payment Auth          │\n       │    (sign off-chain)             │\n       │                                  │\n       │ 3. Send Authorization           │\n       ├─────────────────────────────────>│\n       │                                  │\n       │                    4. Verify & Process\n       │                       (instant, free)\n       │                                  │\n       │ 5. Payment Confirmed            │\n       │<─────────────────────────────────┤\n       │                                  │\n```\n\n### Integration with x402\n\nThe package seamlessly integrates with the x402 protocol for fallback payments:\n\n```typescript\nimport { ChannelManager, FallbackManager } from '@bober3r/solana-payment-channels-core';\n\nconst manager = new ChannelManager(config, wallet);\nconst fallback = manager.getFallbackManager();\n\n// Automatically determine best payment method\nconst { method, reason } = await fallback.determinePaymentMethod(\n  channelState,\n  amount,\n  serverUrl\n);\n\nif (method === 'channel') {\n  // Use off-chain channel payment (instant, free)\n  const result = await manager.claimPayment(channelId, options);\n} else {\n  // Fall back to x402 on-chain payment\n  const receipt = await fallback.payWithX402({\n    amount,\n    recipient: serverPubkey,\n  });\n}\n```\n\n## API Reference\n\n### ChannelManager\n\nMain class for managing payment channels.\n\n#### Constructor\n\n```typescript\nnew ChannelManager(config: ChannelConfig, wallet: Keypair)\n```\n\n#### Methods\n\n##### openChannel\n\nOpens a new payment channel on-chain.\n\n```typescript\nasync openChannel(options: OpenChannelOptions): Promise<string>\n```\n\n**Parameters:**\n- `options.serverPubkey`: Server's public key\n- `options.initialDeposit`: Initial deposit amount in smallest units\n- `options.expiry?`: Optional expiry date (defaults to 7 days)\n\n**Returns:** Channel ID as hex string\n\n**Throws:**\n- `InsufficientFundsError`: If wallet lacks sufficient USDC\n- `TransactionError`: If transaction fails\n\n##### addFunds\n\nAdds funds to an existing channel.\n\n```typescript\nasync addFunds(channelId: string, amount: bigint): Promise<string>\n```\n\n**Returns:** Transaction signature\n\n##### claimPayment\n\nClaims a payment from a channel (server-side).\n\n```typescript\nasync claimPayment(\n  channelId: string,\n  options: ClaimPaymentOptions\n): Promise<PaymentResult>\n```\n\n**Parameters:**\n- `channelId`: Channel identifier\n- `options.amount`: Payment amount\n- `options.authorization`: Signed payment authorization\n\n**Returns:** Payment result with success status and updated balances\n\n##### closeChannel\n\nCloses a channel and returns remaining funds.\n\n```typescript\nasync closeChannel(channelId: string): Promise<string>\n```\n\n##### getChannelState\n\nRetrieves current channel state from blockchain.\n\n```typescript\nasync getChannelState(channelId: string): Promise<ChannelState>\n```\n\n##### getAllChannels\n\nGets all channels for a public key.\n\n```typescript\nasync getAllChannels(pubkey: PublicKey): Promise<ChannelState[]>\n```\n\n##### subscribeToChannel\n\nSubscribes to channel state changes.\n\n```typescript\nsubscribeToChannel(\n  channelId: string,\n  callback: (state: ChannelState) => void\n): () => void\n```\n\n**Returns:** Unsubscribe function\n\n### ChannelStateManager\n\nManages channel state with in-memory caching.\n\n```typescript\nconst stateManager = new ChannelStateManager({ ttl: 60000 });\n\n// Update state\nstateManager.updateState(channelId, newState);\n\n// Get cached state\nconst state = stateManager.getState(channelId);\n\n// Subscribe to changes\nconst unsubscribe = stateManager.subscribe(channelId, (state) => {\n  console.log('State updated:', state);\n});\n\n// Invalidate cache\nstateManager.invalidate(channelId);\n```\n\n### Signature Utilities\n\n#### createPaymentAuthorization\n\nCreates a signed payment authorization (client-side).\n\n```typescript\nasync function createPaymentAuthorization(\n  channelId: Buffer,\n  amount: bigint,\n  nonce: bigint,\n  signer: Keypair\n): Promise<PaymentAuthorization>\n```\n\n#### verifyPaymentAuthorization\n\nVerifies a payment authorization signature (server-side).\n\n```typescript\nasync function verifyPaymentAuthorization(\n  authorization: PaymentAuthorization,\n  expectedPublicKey: PublicKey\n): Promise<boolean>\n```\n\n#### serializePaymentData\n\nSerializes payment data for signing.\n\n```typescript\nfunction serializePaymentData(\n  channelId: Buffer,\n  amount: bigint,\n  nonce: bigint\n): Buffer\n```\n\n### FallbackManager\n\nManages fallback to x402 protocol.\n\n```typescript\nconst fallback = new FallbackManager({ connection });\n\n// Check if server supports channels\nconst supportsChannels = await fallback.shouldUseChannel(serverUrl);\n\n// Get server capabilities\nconst capabilities = await fallback.getServerCapabilities(serverUrl);\n\n// Determine best payment method\nconst { method, reason } = await fallback.determinePaymentMethod(\n  channelState,\n  amount,\n  serverUrl\n);\n```\n\n## Error Handling\n\nThe package provides comprehensive error classes:\n\n```typescript\nimport {\n  ChannelError,\n  InsufficientFundsError,\n  ChannelNotFoundError,\n  ChannelClosedError,\n  ChannelExpiredError,\n  InvalidSignatureError,\n  InvalidNonceError,\n  TransactionError,\n  ConfigurationError,\n} from '@bober3r/solana-payment-channels-core';\n\ntry {\n  await manager.claimPayment(channelId, options);\n} catch (error) {\n  if (error instanceof InsufficientFundsError) {\n    console.log('Required:', error.required);\n    console.log('Available:', error.available);\n  } else if (error instanceof InvalidNonceError) {\n    console.log('Expected:', error.expected);\n    console.log('Received:', error.received);\n  }\n}\n```\n\n## Configuration\n\n### ChannelConfig\n\n```typescript\ninterface ChannelConfig {\n  rpcUrl: string;\n  network: 'devnet' | 'mainnet-beta';\n  programId: PublicKey;\n  usdcMint: PublicKey;\n  defaultExpiry?: number; // seconds\n  minBalance?: bigint;\n  autoRefillAmount?: bigint;\n}\n```\n\n### Helper Function\n\n```typescript\nimport { createChannelConfig, NETWORKS } from '@bober3r/solana-payment-channels-core';\n\nconst config = createChannelConfig('devnet', programId, {\n  defaultExpiry: 14 * 24 * 60 * 60, // 14 days\n  minBalance: BigInt(500_000), // 0.5 USDC\n});\n```\n\n## Examples\n\n### Client: Opening a Channel\n\n```typescript\nimport { ChannelManager } from '@bober3r/solana-payment-channels-core';\nimport { Keypair } from '@solana/web3.js';\n\nconst client = Keypair.generate();\nconst manager = new ChannelManager(config, client);\n\nconst channelId = await manager.openChannel({\n  serverPubkey: serverPublicKey,\n  initialDeposit: BigInt(10_000_000), // 10 USDC\n});\n\nconsole.log('Channel opened:', channelId);\n```\n\n### Client: Creating Payment Authorization\n\n```typescript\nimport { createPaymentAuthorization } from '@bober3r/solana-payment-channels-core';\n\nconst state = await manager.getChannelState(channelId);\nconst nextNonce = state.nonce + BigInt(1);\n\nconst authorization = await createPaymentAuthorization(\n  Buffer.from(channelId, 'hex'),\n  BigInt(1_000_000), // 1 USDC\n  nextNonce,\n  clientKeypair\n);\n\n// Send authorization to server\nawait fetch(serverUrl, {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ authorization }),\n});\n```\n\n### Server: Processing Payment\n\n```typescript\nimport { ChannelManager, verifyPaymentAuthorization } from '@bober3r/solana-payment-channels-core';\n\n// Receive authorization from client\nconst { authorization } = await request.json();\n\n// Verify and process payment\nconst result = await manager.claimPayment(channelId, {\n  amount: BigInt(1_000_000),\n  authorization,\n});\n\nif (result.success) {\n  console.log('Payment received!');\n  console.log('Remaining balance:', result.remainingBalance);\n  // Provide service to client\n} else {\n  console.error('Payment failed:', result.error);\n}\n```\n\n### Monitoring Channel State\n\n```typescript\nconst unsubscribe = manager.subscribeToChannel(channelId, (state) => {\n  console.log('Channel updated:');\n  console.log('  Balance:', state.currentBalance);\n  console.log('  Nonce:', state.nonce);\n  console.log('  Claimed:', state.claimedAmount);\n\n  // Auto-refill if balance is low\n  if (state.currentBalance < config.minBalance) {\n    manager.addFunds(channelId, config.autoRefillAmount);\n  }\n});\n```\n\n## Best Practices\n\n### Security\n\n1. **Always validate nonces**: Ensure nonces increment to prevent replay attacks\n2. **Verify signatures**: Use `verifyPaymentAuthorization` before processing payments\n3. **Check expiry**: Validate channel hasn't expired before accepting payments\n4. **Secure key storage**: Never expose private keys in client-side code\n\n### Performance\n\n1. **Use caching**: State manager caches reduce RPC calls\n2. **Batch operations**: Open channels for multiple services together\n3. **Monitor balance**: Subscribe to state changes to prevent insufficient funds\n\n### Integration\n\n1. **Fallback strategy**: Always have x402 fallback for when channels unavailable\n2. **Server capabilities**: Check server support before requiring channels\n3. **Graceful degradation**: Handle channel failures smoothly\n\n## License\n\nMIT\n\n## Contributing\n\nContributions welcome! Please see CONTRIBUTING.md for guidelines.","readmeFilename":"README.md","_rev":"1-10cff2e3ba6187d2d32cfb215ffe7425"}