Configuration
Complete configuration reference for the Client SDK
The Client SDK is highly configurable to fit various integration scenarios. This page documents all available configuration options.
Configuration Interface
Prop
Type
Prop
Type
Required Options
env
The environment to connect to:
test(recommended for development) -https://api.sandbox.pixels.xyzlive(production) -https://api.pixels.xyz
// Development
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});
// Production
const client = new OfferwallClient({
env: 'live',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});// Development
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});
// Production
var client = new OfferwallClient(new OfferwallConfig
{
Env = "live",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});Environment Recommendation
Always use test environment during development and live for production.
tokenProvider
Required: Yes
A function that returns a JWT token for authenticating with the Stacked API. This token should be generated server-side using the Analytics SDK.
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => {
const response = await fetch('/api/stacked-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
return data.token;
},
fallbackRewardImage: '/default-reward.png'
});var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () =>
{
var httpClient = new HttpClient();
var response = await httpClient.PostAsync(
"https://your-server.com/api/stacked-token",
null
);
var json = await response.Content.ReadAsStringAsync();
var tokenData = JsonSerializer.Deserialize<TokenResponse>(json);
return tokenData.Token;
},
FallbackRewardImage = "/default-reward.png"
});Security Warning
Never hardcode JWT tokens or API keys in client-side code. Always fetch tokens from a secure server endpoint.
The SDK will automatically call this function:
- On initial connection
- When the current token expires (less than 1 minute remaining)
- When a token validation error occurs
fallbackRewardImage
Required: Yes
The default image URL to use for rewards that don't have an image specified. This ensures all rewards can be displayed visually.
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/images/default-reward.png'
});
// or use a CDN URL
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: 'https://cdn.example.com/rewards/default.png'
});var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/images/default-reward.png"
});
// or use a CDN URL
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "https://cdn.example.com/rewards/default.png"
});Optional Connection Options
autoConnect
Default: false
Whether to automatically connect when the client is instantiated. If false, you must manually call initialize() or InitializeAsync().
// Auto-connect on creation
const client = new OfferwallClient({
env: 'test',
autoConnect: true,
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});
// Client is connecting automatically
// Manual connection
const client = new OfferwallClient({
env: 'test',
autoConnect: false, // or omit this option
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});
await client.initialize(); // Connect manually// Auto-connect on creation
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
AutoConnect = true,
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});
// Client is connecting automatically
// Manual connection
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
AutoConnect = false, // or omit this option
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});
await client.InitializeAsync(); // Connect manuallyWhen to Use Auto-Connect
Use autoConnect: true when you want the SDK to connect immediately on page load. Use false when you want to control when the connection happens (e.g., after user login).
reconnect
Default: true
Whether to automatically reconnect if the connection is lost.
const client = new OfferwallClient({
env: 'test',
reconnect: true, // Enable auto-reconnection
reconnectDelay: 1000,
maxReconnectAttempts: 5,
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
Reconnect = true, // Enable auto-reconnection
ReconnectDelay = 1000,
MaxReconnectAttempts = 5,
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});When enabled, the SDK will:
- Detect connection loss
- Wait for
reconnectDelaymilliseconds - Attempt to reconnect
- Use exponential backoff for subsequent attempts (2x delay each time)
- Give up after
maxReconnectAttemptsattempts
reconnectDelay
Default: 1000 (1 second)
The initial delay (in milliseconds) before attempting to reconnect after a disconnection. Each subsequent attempt uses exponential backoff (delay × 2).
const client = new OfferwallClient({
env: 'test',
reconnectDelay: 2000, // Wait 2 seconds before first reconnection attempt
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});
// Reconnection timeline:
// 1st attempt: 2000ms (2s)
// 2nd attempt: 4000ms (4s)
// 3rd attempt: 8000ms (8s)
// 4th attempt: 16000ms (16s)
// 5th attempt: 32000ms (32s)var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
ReconnectDelay = 2000, // Wait 2 seconds before first reconnection attempt
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});
// Reconnection timeline:
// 1st attempt: 2000ms (2s)
// 2nd attempt: 4000ms (4s)
// 3rd attempt: 8000ms (8s)
// 4th attempt: 16000ms (16s)
// 5th attempt: 32000ms (32s)Server-Suggested Retry Time
The server can suggest a custom retry time via SSE. When provided, this overrides the reconnectDelay configuration.
maxReconnectAttempts
Default: 5
The maximum number of reconnection attempts before giving up.
const client = new OfferwallClient({
env: 'test',
maxReconnectAttempts: 10, // Try up to 10 times
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
MaxReconnectAttempts = 10, // Try up to 10 times
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});After reaching the maximum attempts, the client will emit a disconnected event with reason: 'max_reconnect_attempts'.
debug
Default: false
Enable debug logging to the console. Useful for development and troubleshooting.
const client = new OfferwallClient({
env: 'test',
debug: true, // Enable debug logs
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png'
});When enabled, you'll see logs like:
[OfferwallClient] Connecting to SSE endpoint...
[SSEConnection] Connection opened
[OfferStore] Set 5 offers
[EventEmitter] Event emitted: refreshvar client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
Debug = true, // Enable debug logs
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png"
});When enabled, you'll see logs like:
[OfferwallClient] Connecting to SSE endpoint...
[SSEConnection] Connection opened
[OfferStore] Set 5 offers
[EventEmitter] Event emitted: refreshProduction Warning
Disable debug logging in production to avoid exposing internal state and improve performance.
Optional Advanced Options
hooks
Default: {}
Lifecycle hooks for custom logic at various points in the SDK lifecycle.
Interface:
Prop
Type
Example:
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/default-reward.png',
hooks: {
beforeConnect: async ({ jwt, endpoint }) => {
console.log('About to connect to:', endpoint);
},
afterOfferClaim: async (offer, rewards) => {
console.log('Claimed rewards:', rewards);
showRewardAnimation(rewards);
},
onOfferSurfaced: (offer) => {
// Return true to emit event, false to suppress
return offer.priority <= 5;
},
onError: (error, context) => {
console.error(`Error in ${context}:`, error);
reportErrorToAnalytics(error);
}
}
});Interface:
Prop
Type
Related Types:
public class ConnectionInfo
{
public string Jwt { get; set; }
public string Endpoint { get; set; }
}Example:
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/default-reward.png",
Hooks = new OfferwallHooks
{
BeforeConnect = async (config) =>
{
Console.WriteLine($"About to connect to: {config.Endpoint}");
},
AfterOfferClaim = async (offer, rewards) =>
{
Console.WriteLine($"Claimed rewards: {rewards.Count}");
ShowRewardAnimation(rewards);
},
OnOfferSurfaced = (offer) =>
{
// Return true to emit event, false to suppress
return offer.Priority <= 5;
},
OnError = (error, context) =>
{
Console.WriteLine($"Error in {context}: {error.Message}");
ReportErrorToAnalytics(error);
}
}
});assetResolver
Default: undefined
A custom function to resolve reward assets (names and images) based on your game's data. This allows you to map reward IDs to your game's asset library.
Type:
type AssetResolver = (identifier: RewardIdentifier) => AssetContent | undefined | null;
interface RewardIdentifier {
rewardId?: string; // Your game's asset ID
kind: 'item' | 'coins' | 'exp' | 'trust_points' | 'loyalty_currency';
}
interface AssetContent {
name?: string;
image?: string;
}Example:
const gameAssets = {
'gold': { name: 'Gold Coins', image: '/assets/gold.png' },
'gems': { name: 'Precious Gems', image: '/assets/gems.png' },
'sword_iron': { name: 'Iron Sword', image: '/assets/weapons/iron-sword.png' },
'potion_health': { name: 'Health Potion', image: '/assets/potions/health.png' },
};
const client = new OfferwallClient({
env: 'test',
tokenProvider: async () => { /* ... */ },
fallbackRewardImage: '/assets/default-reward.png',
assetResolver: (identifier) => {
// identifier.rewardId contains the ID from the offer
const asset = gameAssets[identifier.rewardId || ''];
if (asset) {
return {
name: asset.name,
image: asset.image,
};
}
// Return null to use fallback
return null;
}
});Type:
| Type | Description |
|---|---|
Func<RewardIdentifier, AssetContent?>? | Function that receives reward identifier and returns custom asset content |
Related Types:
public class RewardIdentifier
{
public string? RewardId { get; set; } // Your game's asset ID
public string Kind { get; set; } // "item", "coins", "exp", "trust_points", "loyalty_currency"
}
public class AssetContent
{
public string? Name { get; set; }
public string? Image { get; set; }
}Example:
var gameAssets = new Dictionary<string, AssetContent>
{
["gold"] = new AssetContent { Name = "Gold Coins", Image = "/assets/gold.png" },
["gems"] = new AssetContent { Name = "Precious Gems", Image = "/assets/gems.png" },
["sword_iron"] = new AssetContent { Name = "Iron Sword", Image = "/assets/weapons/iron-sword.png" },
["potion_health"] = new AssetContent { Name = "Health Potion", Image = "/assets/potions/health.png" }
};
var client = new OfferwallClient(new OfferwallConfig
{
Env = "test",
TokenProvider = async () => { /* ... */ },
FallbackRewardImage = "/assets/default-reward.png",
AssetResolver = (identifier) =>
{
// identifier.RewardId contains the ID from the offer
if (gameAssets.TryGetValue(identifier.RewardId ?? "", out var asset))
{
return asset;
}
// Return null to use fallback
return null;
}
});If your resolver returns:
{ name, image }- Uses your custom assetsnullorundefined- Falls back to default name andfallbackRewardImage
Stacked