{"_id":"555x402-agg","_rev":"2-28e4fd8d0cb26430da20baa165a2ed7c","name":"555x402-agg","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"555x402-agg","version":"0.1.0","keywords":["solana","payments","x402","usdc","aggregator","facilitator","crypto","web3"],"author":{"name":"Render Network OS"},"license":"MIT","_id":"555x402-agg@0.1.0","maintainers":[{"name":"rndrntwrk","email":"555rendernet.work@gmail.com"}],"homepage":"https://github.com/Render-Network-OS/555x402-agg-sdk#readme","bugs":{"url":"https://github.com/Render-Network-OS/555x402-agg-sdk/issues"},"dist":{"shasum":"fbef329ebf0d7964bcb1a51edbf194d1c0c334c3","tarball":"https://registry.npmjs.org/555x402-agg/-/555x402-agg-0.1.0.tgz","fileCount":6,"integrity":"sha512-ISdmzWAHPfxt/Qn5Kx3W1c0eiPz540OaUzzkr+eIM3tqd3Hzjlzghwr28sUV+4fOiJUVxdCl2rGVrRy9TrMOtQ==","signatures":[{"sig":"MEQCIG0UrFMuzXKdifr5Y427wn7ZPa3Mc+yrEaaWpNvBK17uAiB0fK94D9nnEbNb+aNZyDeYSnJDyide7Harj/UglX3ohA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22127},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"53b8270c2e915d0d7bd8e5689f82e3fabc2e18bf","scripts":{"build":"tsc -p tsconfig.json","pack:dry":"npm pack","publish:dry":"npm publish --dry-run","prepublishOnly":"npm run build"},"_npmUser":{"name":"rndrntwrk","email":"555rendernet.work@gmail.com"},"repository":{"url":"git+https://github.com/Render-Network-OS/555x402-agg-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"Solana payment aggregation SDK with intelligent facilitator routing and instant USDC settlement","directories":{},"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7","@solana/web3.js":"^1.95.3","@solana/spl-token":"^0.4.7"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.2"},"_npmOperationalInternal":{"tmp":"tmp/555x402-agg_0.1.0_1762897714776_0.7881982726239509","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-11-11T21:48:34.664Z","modified":"2025-12-27T05:41:41.090Z","0.1.0":"2025-11-11T21:48:34.979Z"},"bugs":{"url":"https://github.com/Render-Network-OS/555x402-agg-sdk/issues"},"author":{"name":"Render Network OS"},"license":"MIT","homepage":"https://github.com/Render-Network-OS/555x402-agg-sdk#readme","keywords":["solana","payments","x402","usdc","aggregator","facilitator","crypto","web3"],"repository":{"url":"git+https://github.com/Render-Network-OS/555x402-agg-sdk.git","type":"git"},"description":"Solana payment aggregation SDK with intelligent facilitator routing and instant USDC settlement","maintainers":[{"email":"555rendernet.work@gmail.com","name":"glassprism"}],"readme":"# @555x402/agg\n\n> Solana payment aggregation SDK with intelligent facilitator routing and instant USDC settlement\n\n[![npm version](https://img.shields.io/npm/v/@555x402/agg.svg)](https://www.npmjs.com/package/@555x402/agg)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n## Overview\n\nThe AGG (Aggregator) SDK enables developers to accept Solana payments through a unified API that automatically routes to the optimal payment facilitator based on latency, fees, and health. Supports USDC and SOL with instant settlement and webhook notifications.\n\n## Features\n\n- ✅ **Intelligent Routing**: Automatically selects best facilitator (PayAI, Conduit, Internal)\n- ✅ **Instant Settlement**: Sub-second transaction confirmation on Solana\n- ✅ **Low Fees**: 0.5-1% facilitator fees + gasless\n- ✅ **Webhook Notifications**: HMAC-signed callbacks for payment status\n- ✅ **TypeScript**: Full type safety with comprehensive type definitions\n- ✅ **Framework Agnostic**: Works with Next.js, Express, Fastify, vanilla Node\n- ✅ **Idempotent**: Built-in deduplication via idempotency keys\n\n## Installation\n\n```bash\nnpm install @555x402/agg\n# or\npnpm add @555x402/agg\n# or\nyarn add @555x402/agg\n```\n\n## Quick Start\n\n### Basic Usage\n\n```typescript\nimport { AggClient } from '@555x402/agg';\n\nconst client = new AggClient(\n  'your-api-key',\n  'https://agg.rendernet.work/pub/v1' // optional, defaults to production\n);\n\n// Verify and settle a payment\nconst result = await client.verifyAndSettle(\n  paymentHeaderB64, // from X-Payment header\n  {\n    amount: 1.5,  // $1.50 USDC\n    mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'), // USDC\n    recipient: new PublicKey('555Tm1cfV52SrBQmnxXiHMUMrpci8miW3CkLP1Qbmtd7')\n  }\n);\n\nconsole.log('Payment settled:', result.id);\n```\n\n### Express.js Example\n\n```typescript\nimport express from 'express';\nimport { AggClient } from '@555x402/agg';\nimport { PublicKey } from '@solana/web3.js';\n\nconst app = express();\nconst agg = new AggClient(process.env.AGG_API_KEY!);\n\napp.post('/premium-api', async (req, res) => {\n  const paymentHeader = req.headers['x-payment'] as string;\n  \n  if (!paymentHeader) {\n    return res.status(402).json({ \n      error: 'Payment required',\n      price: { amount: 0.01, asset: 'USDC' }\n    });\n  }\n  \n  try {\n    await agg.verifyAndSettle(paymentHeader, {\n      amount: 0.01,\n      mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),\n      recipient: new PublicKey(process.env.TREASURY_WALLET!)\n    });\n    \n    // Payment verified and settled - serve the content\n    res.json({ data: 'premium content' });\n  } catch (error) {\n    res.status(402).json({ error: 'Payment verification failed' });\n  }\n});\n\napp.listen(3000);\n```\n\n### Next.js API Route\n\n```typescript\n// app/api/protected/route.ts\nimport { AggClient } from '@555x402/agg';\nimport { PublicKey } from '@solana/web3.js';\nimport { NextRequest, NextResponse } from 'next/server';\n\nconst agg = new AggClient(process.env.AGG_API_KEY!);\n\nexport async function GET(request: NextRequest) {\n  const paymentHeader = request.headers.get('x-payment');\n  \n  if (!paymentHeader) {\n    return NextResponse.json(\n      { error: 'Payment required', price: { amount: 0.05, asset: 'USDC' }},\n      { status: 402 }\n    );\n  }\n  \n  try {\n    const payment = await agg.verifyAndSettle(paymentHeader, {\n      amount: 0.05,\n      mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),\n      recipient: new PublicKey(process.env.TREASURY_WALLET!)\n    });\n    \n    return NextResponse.json({ \n      data: 'protected data',\n      paymentId: payment.id \n    });\n  } catch {\n    return NextResponse.json(\n      { error: 'Invalid payment' },\n      { status: 402 }\n    );\n  }\n}\n```\n\n## API Reference\n\n### Class: `AggClient`\n\n#### Constructor\n\n```typescript\nnew AggClient(apiKey: string, apiBase?: string)\n```\n\n**Parameters:**\n- `apiKey` (string, required): Your 555x402 API key from the dashboard\n- `apiBase` (string, optional): API base URL. Defaults to `https://agg.rendernet.work/pub/v1`\n\n**Example:**\n```typescript\nconst client = new AggClient('pk_live_abc123');\n\n// Or for devnet testing:\nconst devClient = new AggClient('pk_test_xyz789', 'https://agg-devnet.rendernet.work/pub/v1');\n```\n\n#### Methods\n\n##### `verifyAndSettle(paymentHeaderB64, expected): Promise<PaymentResult>`\n\nVerifies a payment header and settles the transaction through the optimal facilitator.\n\n**Parameters:**\n- `paymentHeaderB64` (string): Base64-encoded payment header from `X-Payment` HTTP header\n- `expected` (object):\n  - `amount` (number): Expected payment amount in token units (e.g., 1.5 for $1.50 USDC)\n  - `mint` (PublicKey): Token mint address (USDC, SOL, etc.)\n  - `recipient` (PublicKey): Wallet address to receive funds\n\n**Returns:** Promise<PaymentResult>\n```typescript\ninterface PaymentResult {\n  id: string;              // Payment order ID\n  status: string;          // 'pending' | 'confirmed' | 'failed'\n  txSignature?: string;    // Solana transaction signature (if confirmed)\n  facilitator?: string;    // Which facilitator processed the payment\n}\n```\n\n**Throws:**\n- `PaymentVerificationError` - Invalid payment header or signature\n- `InsufficientAmountError` - Payment amount less than expected\n- `NetworkError` - API unreachable or timeout\n\n**Example:**\n```typescript\ntry {\n  const result = await client.verifyAndSettle(\n    'eyJhbGc...', // from req.headers['x-payment']\n    {\n      amount: 2.50,\n      mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),\n      recipient: new PublicKey('555Tm1cfV52SrBQmnxXiHMUMrpci8miW3CkLP1Qbmtd7')\n    }\n  );\n  \n  console.log(`Payment ${result.id} settled via ${result.facilitator}`);\n  console.log(`Tx: ${result.txSignature}`);\n} catch (error) {\n  if (error instanceof InsufficientAmountError) {\n    console.error('Payment too low:', error.message);\n  }\n}\n```\n\n##### `getStatus(paymentId): Promise<PaymentStatus>`\n\nRetrieves the current status of a payment.\n\n**Parameters:**\n- `paymentId` (string): Payment order ID from `verifyAndSettle` response\n\n**Returns:** Promise<PaymentStatus>\n```typescript\ninterface PaymentStatus {\n  id: string;\n  status: 'pending' | 'confirmed' | 'failed';\n  amount: number;\n  mint: string;\n  recipient: string;\n  sender: string;\n  txSignature?: string;\n  createdAt: string;      // ISO 8601 timestamp\n  settledAt?: string;     // ISO 8601 timestamp\n}\n```\n\n**Example:**\n```typescript\nconst status = await client.getStatus('pay_abc123xyz');\n\nif (status.status === 'confirmed') {\n  console.log(`Payment confirmed in tx: ${status.txSignature}`);\n} else if (status.status === 'pending') {\n  console.log('Waiting for confirmation...');\n}\n```\n\n### Webhook Verification\n\n#### `verifyWebhookSignature(body, timestamp, signature, secret): boolean`\n\nVerifies HMAC signature of webhook payloads from the AGG service.\n\n**Parameters:**\n- `body` (any): Raw request body (string or object)\n- `timestamp` (string): Value from `X-555-Timestamp` header\n- `signature` (string): Value from `X-555-Signature` header (format: `sha256=<hex>`)\n- `secret` (string): Your webhook secret\n\n**Returns:** boolean - `true` if signature valid, `false` otherwise\n\n**Example (Express):**\n```typescript\nimport { verifyWebhookSignature } from '@555x402/agg';\n\napp.post('/webhooks/agg', express.json(), (req, res) => {\n  const timestamp = req.headers['x-555-timestamp'] as string;\n  const signature = req.headers['x-555-signature'] as string;\n  const secret = process.env.WEBHOOK_SECRET!;\n  \n  if (!verifyWebhookSignature(req.body, timestamp, signature, secret)) {\n    return res.status(401).send('Invalid signature');\n  }\n  \n  // Process webhook\n  const { event, data } = req.body;\n  \n  if (event === 'agg.payment.settled') {\n    console.log(`Payment ${data.id} settled to ${data.to}`);\n    // Update your database, send confirmation email, etc.\n  }\n  \n  res.sendStatus(200);\n});\n```\n\n**Webhook Payload Format:**\n```json\n{\n  \"event\": \"agg.payment.pending | agg.payment.settled | agg.payment.failed\",\n  \"data\": {\n    \"id\": \"pay_abc123\",\n    \"status\": \"settled\",\n    \"amount\": 1500000,\n    \"mint\": \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",\n    \"to\": \"555Tm1cfV52SrBQmnxXiHMUMrpci8miW3CkLP1Qbmtd7\",\n    \"from\": \"sender_wallet_address\",\n    \"txSignature\": \"4vJ9J...\"\n  }\n}\n```\n\n## Advanced Usage\n\n### Polling for Settlement\n\n```typescript\nasync function waitForSettlement(paymentId: string, maxWaitMs = 30000): Promise<PaymentStatus> {\n  const start = Date.now();\n  \n  while (Date.now() - start < maxWaitMs) {\n    const status = await client.getStatus(paymentId);\n    \n    if (status.status === 'confirmed') {\n      return status;\n    }\n    \n    if (status.status === 'failed') {\n      throw new Error('Payment failed');\n    }\n    \n    await new Promise(r => setTimeout(r, 1000)); // Poll every second\n  }\n  \n  throw new Error('Settlement timeout');\n}\n```\n\n### Custom Facilitator Selection\n\nThe AGG router automatically selects the optimal facilitator, but you can influence routing by registering preferred facilitators for your recipient wallet.\n\nContact support to configure facilitator preferences.\n\n### Error Handling\n\n```typescript\nimport { AggClient, PaymentError } from '@555x402/agg';\n\ntry {\n  await client.verifyAndSettle(...);\n} catch (error) {\n  if (error instanceof PaymentError) {\n    switch (error.code) {\n      case 'INVALID_SIGNATURE':\n        // Payment header signature doesn't match\n        break;\n      case 'INSUFFICIENT_AMOUNT':\n        // Payment amount < expected\n        break;\n      case 'INVALID_RECIPIENT':\n        // Recipient mismatch\n        break;\n      case 'FACILITATOR_UNAVAILABLE':\n        // All facilitators down (rare)\n        break;\n      case 'NETWORK_ERROR':\n        // Solana RPC or API unreachable\n        break;\n    }\n  }\n}\n```\n\n## Token Support\n\n### Supported Tokens\n\n| Token | Mint Address | Decimals |\n|-------|--------------|----------|\n| USDC (mainnet) | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | 6 |\n| USDC (devnet) | `4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU` | 6 |\n| SOL (wrapped) | `So11111111111111111111111111111111111111112` | 9 |\n\n### Amount Conversion\n\nUSDC uses 6 decimals:\n- $1.00 = `1000000` micro-units\n- $0.01 = `10000` micro-units\n\nHelper (built-in):\n```typescript\nimport { usdToMicroUsdc, microUsdcToUsd } from '@555x402/agg/utils';\n\nconst microUnits = usdToMicroUsdc(2.50);  // 2500000\nconst usd = microUsdcToUsd(2500000);      // 2.5\n```\n\n## Examples\n\n### 1. Pay-Per-Request API\n\n```typescript\nimport { AggClient } from '@555x402/agg';\nimport { PublicKey } from '@solana/web3.js';\n\nconst agg = new AggClient(process.env.AGG_API_KEY!);\nconst USDC_MINT = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');\n\napp.get('/api/premium-data', async (req, res) => {\n  const payment = req.headers['x-payment'] as string;\n  \n  if (!payment) {\n    return res.status(402).json({\n      error: 'Payment required',\n      price: { amount: 0.10, asset: 'USDC' }\n    });\n  }\n  \n  try {\n    const result = await agg.verifyAndSettle(payment, {\n      amount: 0.10,\n      mint: USDC_MINT,\n      recipient: new PublicKey(process.env.TREASURY!)\n    });\n    \n    // Log for analytics\n    console.log(`Payment ${result.id} from ${result.sender}`);\n    \n    // Serve premium content\n    const data = await fetchPremiumData();\n    res.json({ data });\n  } catch (error) {\n    res.status(402).json({ error: 'Invalid payment' });\n  }\n});\n```\n\n### 2. Webhook Handler (Async Settlement Notification)\n\n```typescript\nimport express from 'express';\nimport { verifyWebhookSignature } from '@555x402/agg';\n\nconst app = express();\n\napp.post('/webhooks/payments', \n  express.raw({ type: 'application/json' }), \n  async (req, res) => {\n    const signature = req.headers['x-555-signature'] as string;\n    const timestamp = req.headers['x-555-timestamp'] as string;\n    const body = req.body.toString();\n    \n    // Verify signature\n    if (!verifyWebhookSignature(\n      body, \n      timestamp, \n      signature, \n      process.env.WEBHOOK_SECRET!\n    )) {\n      return res.status(401).send('Invalid signature');\n    }\n    \n    const payload = JSON.parse(body);\n    \n    // Handle events\n    switch (payload.event) {\n      case 'agg.payment.pending':\n        console.log(`Payment ${payload.data.id} pending...`);\n        break;\n        \n      case 'agg.payment.settled':\n        console.log(`Payment ${payload.data.id} confirmed!`);\n        console.log(`Tx: ${payload.data.txSignature}`);\n        \n        // Update your database\n        await db.payments.update({\n          where: { id: payload.data.id },\n          data: { \n            status: 'settled',\n            txSignature: payload.data.txSignature \n          }\n        });\n        \n        // Send confirmation email\n        await sendEmail(payload.data.to, 'Payment received!');\n        break;\n        \n      case 'agg.payment.failed':\n        console.error(`Payment ${payload.data.id} failed`);\n        // Handle failure (refund, notify user, etc.)\n        break;\n    }\n    \n    res.sendStatus(200);\n  }\n);\n```\n\n### 3. Polling Pattern (No Webhooks)\n\n```typescript\nasync function processPaymentWithPolling(paymentHeader: string) {\n  // Initiate settlement\n  const result = await agg.verifyAndSettle(paymentHeader, {\n    amount: 1.00,\n    mint: USDC_MINT,\n    recipient: TREASURY\n  });\n  \n  console.log(`Payment ${result.id} initiated...`);\n  \n  // Poll for confirmation\n  for (let i = 0; i < 30; i++) {\n    await new Promise(r => setTimeout(r, 1000)); // Wait 1s\n    \n    const status = await agg.getStatus(result.id);\n    \n    if (status.status === 'confirmed') {\n      console.log(`Confirmed! Tx: ${status.txSignature}`);\n      return status;\n    }\n    \n    if (status.status === 'failed') {\n      throw new Error('Payment failed');\n    }\n  }\n  \n  throw new Error('Timeout waiting for confirmation');\n}\n```\n\n### 4. Username-Based Payments\n\n```typescript\n// Pay to a username instead of wallet address\nconst result = await agg.verifyAndSettle(paymentHeader, {\n  amount: 5.00,\n  mint: USDC_MINT,\n  recipient: '@alice'  // AGG resolves username to wallet\n});\n```\n\n## Configuration\n\n### Environment Variables\n\n```bash\n# Required\nAGG_API_KEY=pk_live_your_api_key_here\n\n# Optional\nAGG_API_BASE=https://agg.rendernet.work/pub/v1  # defaults to prod\nWEBHOOK_SECRET=whsec_your_webhook_secret         # for webhook verification\n```\n\n### API Keys\n\nGet your API key from the [555x402 Dashboard](https://dashboard.rendernet.work).\n\n**Key types:**\n- `pk_live_*` - Production keys\n- `pk_test_*` - Devnet/testnet keys\n\n### Rate Limits\n\n- Default: 20 requests/second per API key\n- Burst: 40 requests\n- Contact support for higher limits\n\n## Webhook Configuration\n\n### Setting Up Webhooks\n\n1. Go to Dashboard → Settings → Webhooks\n2. Add your endpoint URL\n3. Copy the webhook secret\n4. Test with the webhook tester\n\n### Webhook Security\n\n**Always verify signatures:**\n```typescript\nimport crypto from 'crypto';\n\nfunction verifyWebhook(body: string, timestamp: string, signature: string, secret: string): boolean {\n  const sig = signature.replace(/^sha256=/, '');\n  const hash = crypto.createHash('sha256').update(body).digest();\n  const mac = crypto.createHmac('sha256', secret)\n    .update(timestamp)\n    .update('.')\n    .update(hash)\n    .digest('hex');\n  \n  try {\n    return crypto.timingSafeEqual(\n      Buffer.from(mac, 'hex'),\n      Buffer.from(sig, 'hex')\n    );\n  } catch {\n    return false;\n  }\n}\n```\n\n**Replay attack protection:**\n- Check `X-555-Timestamp` is within 5 minutes of current time\n- Store processed webhook IDs to prevent duplicates\n\n### Webhook Retry Logic\n\nFailed webhooks are retried with exponential backoff:\n- Attempt 1: Immediate\n- Attempt 2: 60s later\n- Attempt 3: 5min later\n- Attempt 4: 15min later\n- Attempt 5: 1hr later\n- Attempt 6: 6hr later\n- After 6 attempts: moved to dead-letter queue\n\n## Testing\n\n### Unit Tests\n\n```bash\nnpm test\n```\n\n### Integration Tests\n\nSet up a test recipient wallet and API key:\n\n```typescript\nimport { AggClient } from '@555x402/agg';\n\ndescribe('AGG Integration', () => {\n  const client = new AggClient(\n    process.env.AGG_TEST_API_KEY!,\n    'https://agg-devnet.rendernet.work/pub/v1'\n  );\n  \n  it('should settle USDC payment', async () => {\n    const result = await client.verifyAndSettle(mockPaymentHeader, {\n      amount: 0.01,\n      mint: DEVNET_USDC_MINT,\n      recipient: TEST_WALLET\n    });\n    \n    expect(result.status).toBe('pending');\n    expect(result.id).toBeDefined();\n  });\n});\n```\n\n## Troubleshooting\n\n### Common Errors\n\n**\"Invalid API key\"**\n- Verify your API key is correct\n- Check you're using the right environment (live vs test keys)\n\n**\"Payment verification failed\"**\n- Ensure payment header is base64-encoded\n- Check the signature matches the payment data\n- Verify sender has sufficient balance\n\n**\"No healthy facilitator available\"**\n- Rare; indicates all payment facilitators are down\n- Retry after 30 seconds\n- Check [status page](https://status.rendernet.work)\n\n**\"Amount mismatch\"**\n- Payment amount doesn't match expected amount\n- Ensure you're using correct decimal places (USDC = 6, SOL = 9)\n\n### Debug Mode\n\nEnable detailed logging:\n\n```typescript\nconst client = new AggClient(apiKey, apiBase, { debug: true });\n```\n\nThis logs all API requests/responses to console.\n\n## Type Definitions\n\nFull TypeScript definitions are included. Import types:\n\n```typescript\nimport type { \n  PaymentResult, \n  PaymentStatus, \n  Expected,\n  WebhookPayload \n} from '@555x402/agg';\n```\n\n## Changelog\n\n### v0.1.0 (2025-11-11)\n- Initial release\n- `verifyAndSettle` and `getStatus` methods\n- Webhook signature verification\n- TypeScript support\n\n## Contributing\n\nContributions welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) first.\n\n## License\n\nMIT © 555x402\n\n## Support\n\n- **Documentation**: https://docs.rendernet.work\n- **API Reference**: https://docs.rendernet.work/api/agg\n- **Issues**: https://github.com/Render-Network-OS/555x402-agg-sdk/issues\n- **Discord**: https://discord.gg/555x402\n- **Email**: support@rendernet.work\n\n## Related Packages\n\n- [@555x402/hyperlink](https://www.npmjs.com/package/@555x402/hyperlink) - Payment link generation\n- [@vap/sdk](https://www.npmjs.com/package/@vap/sdk) - Verifiable attention protocol\n- [@555x402/solana402-express](https://www.npmjs.com/package/@555x402/solana402-express) - Express middleware\n\n---\n\nBuilt with ❤️ for the Solana ecosystem\n","readmeFilename":"README.md"}