0.1.13 • Published 4 months ago

@oncade/sdk v0.1.13

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

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:

  1. Check for an existing session token in localStorage (in browser environments)
  2. Send the token to the server for validation
  3. If the token is valid, continue using it
  4. 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:

  1. Initialize the SDK to create a session
  2. Generate a purchase URL with the session token
  3. Redirect the user to the purchase URL
  4. If the user is not logged in, they will be prompted to log in
  5. After login, their session will be associated with their user ID
  6. 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 authentication
  • gameId: Your game's unique identifier
  • environment: The environment for the SDK (optional: 'production' (default), 'development', or 'staging')

Methods

  • initialize(): Initialize the SDK, verify credentials, and manage session tokens
  • getSessionInfo(): Get the current session information including session token
  • clearSession(): Clear the current session data
  • setPurchaseCatalog(items): Set or update the purchase catalog
  • getStoreCatalog(): Get the current store catalog
  • getStoreItem(itemId): Get a specific store item by ID
  • initiatePurchase(itemId, affiliateCode?, redirectUrl?): Initiate a purchase and get a URL
  • generatePurchaseURL(options): Generate a purchase URL without initiating a purchase
  • generateLoginURL(options): Generate a login URL for user authentication and session association
  • getTipURL(options): Generate a tip URL for users to give a tip to the developer
  • getPurchasedItems(): Get a list of items purchased by the current user
  • getTransactionHistory(): Get transaction history for the current user
  • syncTransactionHistory(): Sync transaction history from the server
  • handleStoreLink(url): Extract parameters from a store link
  • parseDeepLinkParams(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

  1. Install the package:

    npm install @oncade/sdk
    # or
    yarn add @oncade/sdk
  2. 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;
      }
    }
  3. 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.

  4. 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;
      }
    }
  5. 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.

  6. 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();
      }
    }
  7. 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();
  8. 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;
        }
      }
    }
  9. 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:

  1. Install the Oncade SDK:
    yarn add @oncade/sdk
  2. 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();
  3. List existing wager sessions (optional):

    const sessions = await sdk.listWagerSessions();
    console.log('Wager Sessions:', sessions);
  4. 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');
  5. 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.

0.1.13

4 months ago

0.1.12

6 months ago

0.1.11

6 months ago

0.1.10

7 months ago

0.1.9

7 months ago

0.1.8

7 months ago

0.1.7

7 months ago

0.1.6

7 months ago

0.1.5

7 months ago

0.1.4

7 months ago

0.1.3

7 months ago

0.1.2

7 months ago

0.1.1

7 months ago

0.1.0

7 months ago