@oncade/sdk v0.1.13
Oncade SDK
A JavaScript/TypeScript SDK for game developers to integrate with the Oncade purchase platform. This SDK enables games to offer in-game purchases through a PWA webstore and retrieve purchase information.
Installation
npm install @oncade/sdk
# or
yarn add @oncade/sdk
CDN Usage
For direct inclusion in HTML files without using npm/yarn, you can use one of these CDN options:
jsDelivr
<!-- Include axios first (required dependency) -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- Include the Oncade SDK (specific version) -->
<script src="https://cdn.jsdelivr.net/npm/@oncade/sdk@0.1.12/dist/browser/oncade-sdk.min.js"></script>
<!-- Or use the latest version (recommended for development only) -->
<script src="https://cdn.jsdelivr.net/npm/@oncade/sdk/dist/browser/oncade-sdk.min.js"></script>
UNPKG
<!-- Include axios first (required dependency) -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Include the Oncade SDK (specific version) -->
<script src="https://unpkg.com/@oncade/sdk@0.1.12/dist/browser/oncade-sdk.min.js"></script>
<!-- Or use the latest version (recommended for development only) -->
<script src="https://unpkg.com/@oncade/sdk/dist/browser/oncade-sdk.min.js"></script>
Note about versioning:
- For production environments, it's recommended to pin to a specific version (e.g.,
@0.1.12
) to avoid unexpected changes.- For development or testing, you can use the latest version by omitting the version number.
- When a new version is released, you should test it thoroughly before updating your production code.
Features
- Game server initialization and authentication
- Session management with persistent tokens
- Purchase catalog management
- Purchase initiation and URL generation
- Transaction history retrieval
- Deep link parameter parsing
- Developer tip URL generation
New Features: Storage, Affiliates, and Leaderboards (WIP)
Storage API
const storage = sdk.storage({ gameId: 'your-game-id' });
// Read a value
const { value, version } = await storage.get<string>('myKey');
// Write a value
await storage.set('myKey', 'newValue');
// Subscribe to changes
const unsubscribe = storage.onChange('myKey', ({ value, version }) => {
console.log('Value changed:', value, version);
});
Affiliates API
const link = sdk.createAffiliateLink({
gameId: 'your-game-id',
sessionId: 'user-session-id',
itemId: 'optional-item-id'
});
console.log('Affiliate link:', link);
Leaderboards API (not yet implemented)
// Submit a score
await sdk.leaderboards.submit({
gameId: 'your-game-id',
boardId: 'daily',
sessionId: 'user-session-id',
score: 123
});
// Fetch leaderboard rows
const rows = await sdk.leaderboards.fetch({
gameId: 'your-game-id',
boardId: 'daily',
limit: 10
});
console.log('Leaderboard:', rows);
Reminder: When testing new features, please update your tests and verify the new API functionality.
Telemetry
// Track custom gameplay events
sdk.track('level_complete', { level: 3, time: 142 });
// Manually flush queued events (optional)
await sdk.flushTelemetry();
Remote Configuration
// Fetch a single config value with optional default
const difficulty = await sdk.getConfig<number>('enemy.difficulty', 1);
// Subscribe to changes
const unsubscribe = sdk.onConfigChange<number>('enemy.difficulty', (val) => {
console.log('Difficulty updated:', val);
});
// Get the entire config object
const allConfig = await sdk.getAllConfig();
Usage
Initializing the SDK
import OncadeSDK from '@oncade/sdk';
const sdk = new OncadeSDK({
apiKey: 'your-api-key',
gameId: 'your-game-id',
environment: 'production' // Optional: 'production' (default), 'development', or 'staging'
});
// Initialize the SDK
// This will also create or validate a session token
await sdk.initialize();
Session Management
The SDK automatically manages session tokens for users. When initialize()
is called, the SDK will:
- Check for an existing session token in localStorage (in browser environments)
- Send the token to the server for validation
- If the token is valid, continue using it
- If the token is invalid or missing, create a new session token
The session token is automatically included in all API requests and purchase URLs. This allows the server to identify the user and maintain their session across requests.
You can check the session status and handle authentication as needed:
// Check session status and authenticate if needed
async function ensureAuthenticated() {
const sessionInfo = await sdk.getSessionInfo();
if (!sessionInfo.isValid) {
console.log('No valid session. Please initialize the SDK first.');
return false;
}
if (!sessionInfo.hasUserId) {
console.log('Session exists but no user associated. Redirecting to login...');
const loginUrl = sdk.getLoginURL({
gameId: sdk.config.gameId,
redirectUrl: window.location.href
});
window.location.href = loginUrl; // or window.open(loginUrl, '_blank');
return false;
}
return true;
}
// Use this before operations that require authentication
async function getPurchaseHistory() {
if (!(await ensureAuthenticated())) {
return;
}
const purchases = await sdk.getPurchasedItems();
console.log('Purchases:', purchases);
}
Purchase Flow
The purchase flow involves the following steps:
- Initialize the SDK to create a session
- Generate a purchase URL with the session token
- Redirect the user to the purchase URL
- If the user is not logged in, they will be prompted to log in
- After login, their session will be associated with their user ID
- The user can then complete the purchase
Initiating a Purchase
const itemId = 'item-456';
const affiliateCode = 'affiliate-789'; // Optional
const purchaseUrl = await sdk.initiatePurchase(itemId, affiliateCode);
if (purchaseUrl) {
// Redirect the player to this URL to complete the purchase
console.log('Purchase URL:', purchaseUrl);
}
Generating a Purchase URL Directly
You can also generate a purchase URL without initiating a purchase:
const purchaseUrl = sdk.generatePurchaseURL({
itemId: 'item-456',
affiliateCode: 'affiliate-789',
redirectUrl: 'https://yourgame.com/success'
});
if (purchaseUrl) {
// Redirect the player to this URL to complete the purchase
console.log('Purchase URL:', purchaseUrl);
}
Retrieving Purchase History
const purchasedItems = await sdk.getPurchasedItems();
console.log('Purchased items:', purchasedItems);
Retrieving Transaction History
const transactions = await sdk.getTransactionHistory();
console.log('Transaction history:', transactions);
Handling Store Links
const url = 'https://store.oncade.com?affiliateCode=affiliate-789';
const params = sdk.handleStoreLink(url);
console.log('Affiliate Code:', params.affiliateCode);
User Authentication and Session Association
You can generate a login URL to allow users to authenticate and associate their session with their user account:
// Get the current session token
const { sessionToken } = sdk.getSessionInfo();
// Generate a login URL
const loginUrl = sdk.generateLoginURL({
sessionToken: sessionToken,
gameId: 'your-game-id',
redirectUrl: 'https://yourgame.com/after-login'
});
console.log('Login URL:', loginUrl);
// Redirect the user to the login URL
window.location.href = loginUrl;
When a user completes the login process, their user ID will be associated with their session, allowing you to track their purchases and other activities.
Generating a Tip URL
You can generate a tip URL to allow users to give tips to the developer:
// Generate a tip URL
const tipUrl = sdk.getTipURL({
gameId: 'your-game-id',
redirectUrl: 'https://yourgame.com/after-tip',
amount: 500 // Optional: amount in cents (e.g., 500 = $5.00)
});
console.log('Tip URL:', tipUrl);
// Redirect the user to the tip URL or open in a new window
window.location.href = tipUrl;
// or
window.open(tipUrl, '_blank');
This allows players to support the game directly with monetary tips of any amount.
Browser Usage
The SDK can be used directly in a browser environment in several ways:
Option 1: Using a CDN
<!-- Include axios first (required dependency) -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- Include the Oncade SDK from jsDelivr (specific version) -->
<!-- <script src="https://cdn.jsdelivr.net/npm/@oncade/sdk@0.1.12/dist/browser/oncade-sdk.min.js"></script> -->
<!-- Include the Oncade SDK from jsDelivr (latest version) -->
<script src="https://cdn.jsdelivr.net/npm/@oncade/sdk/dist/browser/oncade-sdk.min.js"></script>
<!-- Or include from UNPKG (specific version) -->
<!-- <script src="https://unpkg.com/@oncade/sdk@0.1.12/dist/browser/oncade-sdk.min.js"></script> -->
<!-- Or include from UNPKG (latest version) -->
<!-- <script src="https://unpkg.com/@oncade/sdk/dist/browser/oncade-sdk.min.js"></script> -->
<script>
// The SDK is available as a global variable
const sdk = new OncadeSDK({
apiKey: 'your-api-key',
gameId: 'your-game-id',
environment: 'development' // Optional: 'production' (default), 'development', or 'staging'
});
// Initialize the SDK
sdk.initialize().then(initialized => {
if (initialized) {
console.log('SDK initialized successfully');
}
});
</script>
Option 2: Using a Module Bundler (Webpack, Rollup, etc.)
import axios from 'axios';
import OncadeSDK from '@oncade/sdk/browser';
const sdk = new OncadeSDK({
apiKey: 'your-api-key',
gameId: 'your-game-id'
});
// Initialize the SDK
sdk.initialize().then(initialized => {
if (initialized) {
console.log('SDK initialized successfully');
}
});
Option 3: Using ES Modules Directly in the Browser
<script type="module">
// Import axios from CDN
import axios from 'https://cdn.jsdelivr.net/npm/axios/dist/esm/axios.min.js';
// Import the SDK from a specific version (if available as ESM)
// import OncadeSDK from 'https://cdn.jsdelivr.net/npm/@oncade/sdk@0.1.12/dist/browser/oncade-sdk.esm.js';
// Or import the latest version (if available as ESM)
import OncadeSDK from 'https://cdn.jsdelivr.net/npm/@oncade/sdk/dist/browser/oncade-sdk.esm.js';
const sdk = new OncadeSDK({
apiKey: 'your-api-key',
gameId: 'your-game-id'
});
// Initialize the SDK
sdk.initialize().then(initialized => {
if (initialized) {
console.log('SDK initialized successfully');
}
});
</script>
Note: The ESM version may not be available yet. If you need ESM support, consider adding an ESM build to your webpack configuration.
API Reference
Configuration
apiKey
: Your API key for authenticationgameId
: Your game's unique identifierenvironment
: The environment for the SDK (optional: 'production' (default), 'development', or 'staging')
Methods
initialize()
: Initialize the SDK, verify credentials, and manage session tokensgetSessionInfo()
: Get the current session information including session tokenclearSession()
: Clear the current session datasetPurchaseCatalog(items)
: Set or update the purchase cataloggetStoreCatalog()
: Get the current store cataloggetStoreItem(itemId)
: Get a specific store item by IDinitiatePurchase(itemId, affiliateCode?, redirectUrl?)
: Initiate a purchase and get a URLgeneratePurchaseURL(options)
: Generate a purchase URL without initiating a purchasegenerateLoginURL(options)
: Generate a login URL for user authentication and session associationgetTipURL(options)
: Generate a tip URL for users to give a tip to the developergetPurchasedItems()
: Get a list of items purchased by the current usergetTransactionHistory()
: Get transaction history for the current usersyncTransactionHistory()
: Sync transaction history from the serverhandleStoreLink(url)
: Extract parameters from a store linkparseDeepLinkParams(url)
: Parse parameters from a deep link URL
Testing
npm test
# or
yarn test
License
MIT
LLM Integration Guide
If you're using an AI assistant to help integrate this SDK into your game, here are specific instructions to guide the process:
For AI Assistants: How to Integrate @oncade/sdk into a JavaScript Game
Install the package:
npm install @oncade/sdk # or yarn add @oncade/sdk
Import and initialize the SDK:
import OncadeSDK from '@oncade/sdk'; // Create an instance with required configuration const sdk = new OncadeSDK({ apiKey: 'GAME_API_KEY', // You can get a free API key from https://oncade-devportal.vercel.app/ gameId: 'GAME_ID', // You can get your game ID from the https://oncade-devportal.vercel.app/ environment: 'production' // Or 'development' for testing }); // Initialize the SDK (typically in your game's startup sequence) async function initializeStore() { try { await sdk.initialize(); console.log('Store SDK initialized successfully'); return true; } catch (error) { console.error('Failed to initialize store:', error); return false; } }
Set up the purchase catalog:
async function setupStoreCatalog() { // Define your in-game purchasable items const catalog = [ { id: 'currency_small', type: 'currency', name: '100 Coins', description: 'A small pack of in-game coins', price: 99, // in cents (0.99 USD) imageUrl: 'https://yourgame.com/assets/coins_small.png' }, { id: 'premium_skin', type: 'item', name: 'Premium Character Skin', description: 'Exclusive character appearance', price: 499, // in cents (4.99 USD) imageUrl: 'https://yourgame.com/assets/premium_skin.png' } ]; try { const success = await sdk.setPurchaseCatalog(catalog); return success; } catch (error) { console.error('Failed to set up store catalog:', error); return false; } }
Note: Store entries can also be created and edited directly in the developer portal at https://oncade-devportal.vercel.app/ instead of programmatically setting them through the SDK.
Implement the purchase flow:
// Call this function when player clicks "Buy" on an item async function purchaseItem(itemId) { try { // Get the purchase URL const purchaseUrl = await sdk.initiatePurchase(itemId); if (purchaseUrl) { // For web games: redirect to the purchase URL window.open(purchaseUrl, '_blank'); // For mobile games using a WebView: use the appropriate native bridge // Example: window.webkit.messageHandlers.openUrl.postMessage(purchaseUrl); return true; } return false; } catch (error) { console.error('Failed to initiate purchase:', error); return false; } }
Check for completed purchases:
// Call this when your game starts or after returning from the store async function checkPurchases() { try { const purchases = await sdk.getPurchasedItems(); // Process each purchased item for (const purchase of purchases) { // Grant the item to the player based on the purchase type if (purchase.type === 'currency') { // Add currency to player's account addCurrencyToPlayer(purchase.amount); } else if (purchase.type === 'item') { // Add item to player's inventory addItemToInventory(purchase.id); } // Mark the purchase as processed in your game markPurchaseAsProcessed(purchase.transactionId); } return purchases; } catch (error) { console.error('Failed to check purchases:', error); return []; } }
Important: For consumable items like virtual currency, you will need to implement your own tracking system to manage consumption of that currency after it's been added to the player's account.
Handle returning from purchase:
// Call this when your game is loaded or resumed function handleReturnFromPurchase() { // Check if we're returning from a purchase (URL parameters or app state) const currentUrl = window.location.href; const params = sdk.parseDeepLinkParams(currentUrl); if (params.purchaseComplete) { // Show a success message showPurchaseSuccessMessage(); // Check for new purchases checkPurchases(); } }
Complete integration example:
// Game initialization async function initGame() { // Initialize the store const storeInitialized = await initializeStore(); if (storeInitialized) { // Set up the catalog await setupStoreCatalog(); // Check for existing purchases await checkPurchases(); // Handle return from purchase if applicable handleReturnFromPurchase(); } // Continue with normal game initialization // ... } // Call this when player clicks the store button function openStore() { // Show your in-game store UI // When player selects an item to buy, call: // purchaseItem(selectedItemId); } // Start the game initGame();
Error handling best practices:
// Implement proper error handling async function safeStoreFunctionCall(asyncFunction) { try { return await asyncFunction(); } catch (error) { if (error.response && error.response.status === 401) { // Handle authentication errors console.error('Authentication error, trying to reinitialize'); await sdk.initialize(); return await asyncFunction(); } else { // Handle other errors console.error('Store operation failed:', error); showErrorToUser('Store operation failed. Please try again later.'); return null; } } }
Testing your integration:
// Test function to verify SDK integration async function testSDKIntegration() { try { // Test initialization const initialized = await sdk.initialize(); console.log('SDK initialization:', initialized ? 'SUCCESS' : 'FAILED'); // Test catalog retrieval const catalog = await sdk.getStoreCatalog(); console.log('Catalog items:', catalog.length); // Test session info const sessionInfo = sdk.getSessionInfo(); console.log('Session token exists:', !!sessionInfo.sessionToken); return true; } catch (error) { console.error('Integration test failed:', error); return false; } } // Run this in development to verify your integration // testSDKIntegration();
Remember to:
- Replace placeholder values with actual game-specific information
- Register your game in the Oncade developer portal (https://oncade-devportal.vercel.app/) to get your API key and game ID
- Implement proper error handling and transaction verification
- Test thoroughly in development environment before going to production
- Adapt the code to fit your game's architecture and design patterns
Wagering Integration
The Oncade SDK supports on-chain wagering between players. Follow these steps to integrate wagering into your client game:
- Install the Oncade SDK:
yarn add @oncade/sdk
Initialize the SDK in your game:
import OncadeSDK from '@oncade/sdk'; const sdk = new OncadeSDK({ apiKey: 'YOUR_API_KEY', // Provided after signup gameId: 'YOUR_GAME_ID', // Create or retrieve from portal environment: 'production' // or 'development' }); await sdk.initialize();
List existing wager sessions (optional):
const sessions = await sdk.listWagerSessions(); console.log('Wager Sessions:', sessions);
- Create a new wager session:
const { sessionId } = await sdk.createWagerSession({}); // Generate a URL to view and place bets const url = sdk.getWagerSessionURL(sessionId); window.open(url, '_blank');
- After gameplay, submit a score to resolve the wager:
await sdk.submitWagerScore(sessionId, { score: playerScore, // Numeric result of the game timeUsed: elapsedMilliseconds // Time taken to complete });
The DevPortal UI at /wager-sessions/{sessionId}
provides a rich React component for placing bets, sharing via QR code, and handling on-chain deposits, withdrawals, and resolution. Your game only needs to navigate to that URL and submit scores after gameplay.