@pixels-online/pixels-client-js-sdk
v1.21.0
Published
Pixels Client JS SDK
Readme
Pixels BuildOn Client JS SDK
A powerful TypeScript SDK for integrating Pixels BuildOn offerwall functionality into web applications and games. This SDK provides real-time offer management, player progression tracking, and reward handling capabilities.
🚀 Features
- Real-time Offer Management - Live updates via Server-Sent Events (SSE)
- Player Progression Tracking - Monitor player stats, achievements, and conditions
- Reward System Integration - Handle various reward types (coins, items, exp, etc.)
- Event-Driven Architecture - React to offer events and player actions
- TypeScript Support - Full type safety and IntelliSense support
- Flexible Configuration - Customizable asset resolution and hooks
- Multi-Environment Support - Local, Test, staging, and production environments
- Auto-Reconnection - Robust connection management with retry logic
📦 Installation
npm install @pixels-online/pixels-client-js-sdk🔧 Quick Start
1. Basic Setup
import { OfferwallClient } from '@pixels-online/pixels-client-js-sdk';
const client = new OfferwallClient({
env: 'test', // or 'live' for production
tokenProvider: async () => {
// Fetch JWT token from your server. We recommend using our server-side SDK on your server for JWT creation
const response = await fetch('/api/auth/pixels-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
return data.token;
},
assetResolver: (_, id: string) => {
return {
name: exampleGameLib[id]?.name || 'Unknown2',
image: exampleGameLib[id]?.image,
};
},
fallbackRewardImage: 'https://example.com/default-reward.png',
hooks: {
onOfferSurfaced: (offer) => {
var random = Math.random() < 0.5;
return random; // 50% chance to show the offer
},
},
autoConnect: true,
});2. Initialize and Connect
// Initialize the client
await client.initialize();
// Listen for offers
client.on('offersUpdated', (offers) => {
console.log('Available offers:', offers);
displayOffersInUI(offers);
});
// Listen for player updates
client.on('playerUpdated', (player) => {
console.log('Player snapshot updated:', player.snapshot);
console.log('Player data updated:', player.data);
updatePlayerStatsUI(player);
});3. Claim Offers
// Claim an offer
try {
const result = await client.claimOffer(offerId);
console.log('Offer claimed successfully:', result);
} catch (error) {
console.error('Failed to claim offer:', error);
}📊 Player Data Structure
The SDK provides player information through the IClientPlayer interface:
interface IClientPlayer {
snapshot: IPlayerSnapshot; // Core player data (levels, currencies, achievements, etc.)
data?: IPlayerData | null; // Additional game-specific data
}Accessing Player Information
// Get the current player
const player = client.getPlayer();
if (player) {
// Access core player data
console.log('Player ID:', player.snapshot.playerId);
console.log('Player level:', player.snapshot.levels?.combat?.level);
console.log('Currency balance:', player.snapshot.currencies?.gold?.balance);
// Access additional player data (if available)
if (player.data) {
console.log('Additional currencies:', player.data.currencies);
}
}🎯 Configuration Options
OfferwallConfig
interface OfferwallConfig {
/** Environment: 'test' | 'live' | custom endpoint */
env: 'test' | 'live' | (string & {});
/** Auto-connect on initialization (default: false) */
autoConnect?: boolean;
/** Enable auto-reconnection (default: true) */
reconnect?: boolean;
/** Reconnection delay in ms (default: 1000) */
reconnectDelay?: number;
/** Max reconnection attempts (default: 5) */
maxReconnectAttempts?: number;
/** Enable debug logging (default: false) */
debug?: boolean;
/** Event hooks for custom logic */
hooks?: Partial<OfferwallHooks>;
/** Custom asset resolver for rewards */
assetResolver?: AssetResolver;
/** Fallback image for unknown rewards */
fallbackRewardImage: string;
/** JWT token provider function */
tokenProvider: TokenProvider;
}🎨 Asset Resolution
Customize how rewards are displayed in your game:
const gameAssets = {
gems: { name: 'Gems', image: '/assets/gems.png' },
gold: { name: 'Gold Coins', image: '/assets/gold.png' },
sword_1: { name: 'Iron Sword', image: '/assets/sword_iron.png' },
};
const client = new OfferwallClient({
// ... other config
assetResolver: (reward, assetId) => {
const asset = gameAssets[assetId];
if (asset) {
return { name: asset.name, image: asset.image };
}
return { name: `Unknown Item (${assetId})`, image: null };
},
});🎣 Event Hooks
Implement custom logic with event hooks:
const client = new OfferwallClient({
// ... other config
hooks: {
// Control which offers to show
onOfferSurfaced: (offer) => {
// Custom logic to determine if offer should be shown
const currentPlayer = client.getPlayer();
return currentPlayer?.snapshot.levels?.overall?.level >= offer.minLevel;
},
// Handle successful offer claims
onOfferClaimed: async (offer, rewards) => {
console.log('Offer completed!', { offer, rewards });
// Award rewards in your game
await showConfetti(rewards);
},
// Handle connection events
onConnect: () => {
console.log('Connected to Pixels BuildOn');
showConnectionStatus('connected');
},
onDisconnect: () => {
console.log('Disconnected from Pixels BuildOn');
showConnectionStatus('disconnected');
},
},
});📡 Events
Listen to various events emitted by the client:
// Offer-related events
client.on('offersUpdated', (offers) => {
/* Handle offers update */
});
client.on('offerAdded', (offer) => {
/* Handle new offer */
});
client.on('offerRemoved', (offerId) => {
/* Handle offer removal */
});
client.on('offerUpdated', (offer) => {
/* Handle offer changes */
});
// Player-related events
client.on('playerUpdated', (player) => {
/* Handle player data changes */
});
// Connection events
client.on('connected', () => {
/* Handle connection */
});
client.on('disconnected', () => {
/* Handle disconnection */
});
client.on('reconnecting', (attempt) => {
/* Handle reconnection attempts */
});
// Error events
client.on('error', (error) => {
/* Handle errors */
});🏗️ API Reference
OfferwallClient Methods
initialize(): Promise<void>
Initialize the client and establish connection.
disconnect(): Promise<void>
Disconnect from the service.
refreshOffersAndPlayer(): { offers: IClientOffer[], player: IClientPlayer }
Refresh and get all current offers.
claimOffer(offerId: string): Promise<ClaimResult>
Claim an offer and receive rewards.
getConnectionState(): ConnectionState
Get current connection status.
Utility Functions
import { meetsConditions, AssetHelper } from '@pixels-online/pixels-client-js-sdk';
// Check if player meets offer conditions
const canClaim = meetsConditions(player.snapshot, offer.surfacingConditions);
// Asset helper utilities
const assetHelper = new AssetHelper(assetResolver, fallbackImage);
const rewardAsset = assetHelper.resolveRewardAsset(reward, assetId);🧪 Testing
The SDK includes comprehensive test coverage:
# Run all tests
npm test
# Run unit tests
npm run test:unit
# Run integration tests
npm run test:integration
# Run e2e tests
npm run test:e2e
# Run with coverage
npm run test:coverage
# Watch mode
npm run test:watch🌍 Environments
The SDK supports multiple environments:
test- Sandbox environment for developmentlive- Production environmentstaging- Staging environmentpreview- Preview environmentdev- Development environment- Custom URL - Provide your own endpoint
� Migration Guide
v1.0.0+ Breaking Changes
Player Data Structure Update
The player data structure has been updated to provide better separation between core player data and additional game-specific data:
- Old:
IClientPlayerSnapshot(flat structure) - New:
IClientPlayer(structured withsnapshotanddataproperties)
Migration Steps:
// Before (v0.x)
const player = client.getPlayer(); // IClientPlayerSnapshot
const level = player.levels?.combat?.level;
const gold = player.currencies?.gold?.balance;
// After (v1.0+)
const player = client.getPlayer(); // IClientPlayer
const level = player.snapshot.levels?.combat?.level;
const gold = player.snapshot.currencies?.gold?.balance;
// Access additional data (new feature)
const additionalCurrencies = player.data?.currencies;Event Handler Updates:
// Before
client.on('playerUpdated', (playerSnapshot) => {
updateUI(playerSnapshot.currencies);
});
// After
client.on('playerUpdated', (player) => {
updateUI(player.snapshot.currencies);
// Also handle additional data if needed
if (player.data) {
handleAdditionalData(player.data);
}
});�📋 Requirements
- Node.js 16+
- TypeScript 4.5+ (if using TypeScript)
- Modern browser with EventSource support
🤝 Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the AGPLv3 License - see the LICENSE.md file for details.
🔗 Links
📞 Support
For support and questions:
- Create an issue on GitLab
- Contact the Pixels team
Made with ❤️ by the Pixels team
