Building Subscription Services with SWIG
SWIG’s token limit feature provides a powerful way to implement subscription-based services on Solana. This guide demonstrates how to create a subscription service that charges users monthly using SWIG’s token limit capabilities.
You can find the complete example code here:
Examples with svm in the file name use LiteSVM for testing. Those without svm in the file name use a local validator. Which you can run with the bun start-validator command.
Overview
In this example, we’ll create a subscription service that:
- Charges users $10 USDC monthly
- Uses SWIG’s token limit feature to enforce the subscription amount and period
- Demonstrates how the limit resets after the specified period
Key Concepts
Token Limits
SWIG’s token limit feature allows you to:
- Set a maximum amount of tokens that can be transferred within a specified block period
- Automatically reset the limit after the period expires
- Track limits per token mint (supporting multiple tokens)
Block Period
In this example, we use a block period of 216,000 blocks, which approximates one month given Solana’s average block time of 400ms:
// 400ms per block
// 1 month ≈ 30 days * 24 hours * 60 minutes * 60 seconds * (1/0.4) blocks/second
// ≈ 216,000 blocks
Implementation
The example demonstrates:
- Creating a SWIG wallet with root authority
- Setting up a subscription service authority with token limits
- Processing subscription paymentsI
- Handling period resets
Here’s a key snippet showing how to set up the subscription authority:
// Set subscription service authority with 0.1 SOL monthly limit
// 400ms per block, so ~216000 blocks per month
const subscriptionActions = Actions.set()
.solRecurringLimit({
recurringAmount: BigInt(0.1 * LAMPORTS_PER_SOL), // 0.1 SOL
window: BigInt(216000),
})
.get();
const addSubscriptionAuthorityIx = await getAddAuthorityInstructions(
swig,
rootRole.id,
createEd25519AuthorityInfo(subscriptionServiceKeypair.publicKey),
subscriptionActions,
{ payer: rootKeypair.publicKey },
);
// Set subscription service authority with 0.1 SOL recurring limit
const recurringActions = Actions.set()
.solRecurringLimit({
recurringAmount: BigInt(0.1 * LAMPORTS_PER_SOL),
window: BigInt(20), // block-based window
})
.get();
const addAuthorityIx = await getAddAuthorityInstructions(
swig,
rootRole.id,
createEd25519AuthorityInfo(subscription.address),
recurringActions,
);
Use Cases
This pattern enables various subscription-based services:
-
SaaS Applications
- Monthly software subscriptions
- Tiered service plans
- Usage-based billing
-
Content Platforms
- Premium content access
- Streaming services
- Digital publication subscriptions
-
Gaming Services
- Monthly game passes
- Premium features access
- In-game subscription benefits
-
DeFi Services
- Trading fee subscriptions
- Premium analytics access
- Automated trading services
Complete Example
For a complete working example that includes both client and server implementations, check out the SWIG SDK Example Repository. This repository demonstrates:
- Frontend subscription management
- Backend subscription processing
- Error handling and edge cases
- User management integration
Best Practices
-
Error Handling
- Always verify transaction success
- Handle failed payments gracefully
- Implement retry mechanisms
-
User Experience
- Notify users before renewal
- Provide clear subscription status
- Implement grace periods
-
Security
- Secure key management
- Rate limiting
- Transaction monitoring