Pi Apps Frontend Javascript SDK Documentation

repository·master·Indexed 24 days ago

https://github.com/pi-apps/pi-platform-docs

Documentation for integrating Pi Network features into web applications served within the Pi Browser. Covers the Pi Apps JS SDK v2.0 for user authentication, User-To-App (U2A) payments, and the Developer Ad Network (Interstitial, Rewarded, and Banner ads). Includes guidance on using the Pi Developer Portal for app registration, network configuration (Mainnet vs. Testnet), and requirements for App-To-User (A2U) payments via backend SDKs.

Tokens
14.6K
Snippets
27
Records
60
Agent score
84%

What's inside Pi Apps JS SDK

  1. Authenticate with the Platform API

    master

    The Platform API uses two authorization mechanisms depending on the endpoint requirements:

    1. Access token authorization: Used for endpoints related to user data (e.g., /me). These can be called from either your frontend or backend. Use the Bearer scheme.
    2. Server API Key authorization: Used for sensitive operations that must be performed from your backend (e.g., payments, ads verification). Never expose your Server API Key in client-side JavaScript. Use the Key scheme.

    Base Path: api.minepi.com/v2

    Authorization: Bearer <user access token>
    # OR
    Authorization: Key <your Server API Key>
  2. How Pi Sign-in works (OAuth 2.0 Implicit Flow)

    master

    Pi Sign-in uses the OAuth 2.0 implicit flow, which is a simplified flow designed for browser-based applications. It requires no backend exchange and no client secret.

    The Flow:

    1. Redirect: You redirect the user to the authorization server's /oauth/authorize endpoint with your client_id, redirect_uri, scope, and an optional state value.
    2. Authentication: The user authenticates and approves your app within the Pi Browser.
    3. Callback: The server redirects the browser back to your redirect_uri. The access token is appended to the URL fragment (the part after #), not as a query parameter.
    4. Token Retrieval: Your front-end JavaScript reads the token from the fragment, verifies the state to prevent CSRF, and uses the token to call the Pi API.

    Note: Currently, implicit flow is the only supported flow. You are issued a client_id only; there is no client_secret.

  3. Request a payment from your app to a user (App-To-User)

    master

    To send Pi from your app to a user, you cannot use this frontend JS SDK. You must use one of Pi Network's backend SDKs corresponding to your server-side language.

    All payments require a Server-Side Approval flow (for User-to-App) and/or a Server-Side Completion flow (for all types) to ensure all parties remain in sync.

  4. Supported Ad Types in Pi App Platform

    master

    The Pi App Platform supports three types of advertisements:

    1. Interstitial Ads: Full-screen ads typically displayed at natural transition points, such as between game levels or activities.
    2. Rewarded Ads: Full-screen ads shown to users in exchange for an in-app reward (e.g., extra lives in a game). These require the user to be authenticated.
    3. Banner Ads: Overlay ads at the top or bottom of the screen. These are not currently supported via the Pi SDK directly. Instead, they can be enabled via the Developer Portal as 'Loading Banner Ads', which automatically display while your application is loading.
  5. Understand PiNet Metadata Support flows

    master

    PiNet allows your application to expose metadata tags (like OpenGraph and Twitter Cards) to increase app recognition. There are two ways to implement this:

    1. frontend flow (Default): PiNet scrapes metadata directly from your application's HTML files, similar to how bots operate. This is ideal for SSR (Server-Side Rendering) apps or apps with a single set of metadata for the entire application. You simply need to ensure your HTML contains the correct meta tags.
    2. backend flow: PiNet communicates with your backend via a GET request to provide dynamic metadata. This is the recommended solution for Single Page Applications (SPAs) where metadata needs to be generated dynamically per page.
  6. How the Pi Payment flow works

    master

    Payments in the Pi Platform are wrappers around blockchain transactions that synchronize your app, the Pi Blockchain, and Pi Servers. The process follows a three-phase lifecycle to ensure security and synchronization:

    Phase I: Payment creation and Server-Side Approval

    1. Creation: The app's frontend calls createPayment. The Payment Flow UI opens but is locked.
    2. Approval Trigger: The JS SDK triggers onReadyForServerApproval and provides a PaymentID.
    3. Server Communication: Your frontend must send this PaymentID to your backend server.
    4. Approval: Your server calls the Pi Server /approve API. This unlocks the UI for the user.

    Phase II: User interaction and blockchain transaction

    • The user interacts with the Payment Flow UI to confirm, sign, and submit the transaction to the Pi Blockchain.
    • This phase is handled entirely by the Pi Apps Platform and the Pi Wallet.
    • Note: The payment flow remains open after submission until Phase III is complete.

    Phase III: Server-Side Completion

    1. Completion Trigger: The JS SDK triggers onReadyForServerCompletion and provides the blockchain transaction identifier (TxID).
    2. Server Communication: Your frontend sends the TxID to your backend server.
    3. Completion: Your server calls the Pi Server /complete API. This verifies the transaction and allows the payment flow UI to close.
    4. Finalization: Once the flow closes, your app becomes visible again, and you can update your UI to show a confirmation screen.
  7. How App-to-user (A2U) payments work

    master

    A2U payments involve interacting with both the Pi Blockchain and the Pi backend.

    • Pi Blockchain: Acts as the single source of truth for the actual exchange of Pi.
    • Pi Backend: Used to enhance user experience and developer reliability. It provides understandable memos in the user's wallet, links back to your app, and helps prevent technical errors like double payments due to server faults.

    Key Benefits

    • User Privacy: Enables safe access to a user's wallet address only upon their consent and intent to receive Pi.
    • Wallet Accuracy: The API returns the current user wallet if a change was necessary, preventing payments to deprecated or inaccessible addresses.
    • Error Recovery: By informing the Pi backend before and after a blockchain transaction, you can recover metadata and transaction details if a technical issue prevents your local database from recording the event. This helps avoid accidental depletion of app wallets.
    • Ecosystem Integration: Payments made via the A2U API appear in the user's wallet as coming from your specific app rather than an unknown address, allowing for future features like direct links back to your app or product thumbnails.
  8. Configure and complete the App Checklist

    master

    After registering an app, use the App Checklist to track the required setup steps. Steps unlock sequentially as you complete them:

    1. Configure Hosting: The first step in the checklist.
    2. Connect App Wallet: Once hosting is configured, the App Wallet button becomes enabled. Follow the instructions to create and connect a wallet to your app.
    3. Review Documentation: After connecting the wallet, the checklist will provide documentation to guide you through the remaining configuration steps.
  9. Migrate Legacy Projects to Mainnet

    master

    Projects created before 26/07/2022 are considered Legacy Projects and are locked to the Pi Testnet. They cannot be updated to Mainnet. To move to Mainnet, follow these steps:

    1. Create a Mainnet Project:
      • Select Mainnet as the network.
      • Provide the desired URL (this will be the URL Pioneers use in the Pi Browser; ownership is verified later).
      • Set a Payment Wallet. Note: Until a specific app wallet is created, the creator's wallet address is used. If the creator does not have a Mainnet Migration wallet, transactions will fail.
    2. Create a Testnet Project:
      • Select Testnet.
      • Use a URL different from the Mainnet URL.
      • Set access permissions. This project can be linked to the Mainnet project created in step 1.
    3. Link to Brainstorm (if applicable): You can link one developer portal project to a brainstorm project.
  10. Handle the OAuth redirect callback

    master

    After authentication, the browser redirects to your redirect_uri with data in the URL fragment (#). You must parse this fragment in your front-end JavaScript.

    Success Case

    URL format: https://yourapp.com/callback#access_token=xxxxx&token_type=Bearer&expires_in=3600&state=abc123

    Fragment Parameters:

    • access_token: The bearer token.
    • token_type: Always Bearer.
    • expires_in: Lifetime in seconds.
    • state: The echoed CSRF value. You must verify this matches the state you sent.

    Failure Case

    URL format: https://yourapp.com/callback#error=access_denied&state=abc123

    Error Values:

    • access_denied: User declined consent.
    • expired: Request timed out.
    • cancelled: User cancelled before approval.
    • server_error: Unexpected server error.

    Implementation Example

    const params = new URLSearchParams(window.location.hash.slice(1));
    const expectedState = sessionStorage.getItem("pi_oauth_state");
    sessionStorage.removeItem("pi_oauth_state");
    
    if (params.get("state") !== expectedState) {
      throw new Error("State mismatch — possible CSRF, aborting.");
    }
    
    const error = params.get("error");
    if (error) {
      console.error("Pi Sign-in failed:", error);
    } else {
      const accessToken = params.get("access_token");
    
      const me = await fetch("https://api.minepi.com/v2/me", {
        headers: { Authorization: `Bearer ${accessToken}` },
      }).then((r) => r.json());
    
      // Use me.uid to create your own session
    }
    
    // Clear the token from the URL history
    history.replaceState(null, "", window.location.pathname);
    const params = new URLSearchParams(window.location.hash.slice(1));
    const expectedState = sessionStorage.getItem("pi_oauth_state");
    sessionStorage.removeItem("pi_oauth_state");
    
    if (params.get("state") !== expectedState) {
      throw new Error("State mismatch — possible CSRF, aborting.");
    }
    
    const error = params.get("error");
    if (error) {
      // handle access_denied / expired / cancelled / server_error
      console.error("Pi Sign-in failed:", error);
    } else {
      const accessToken = params.get("access_token");
    
      const me = await fetch("https://api.minepi.com/v2/me", {
        headers: { Authorization: `Bearer ${accessToken}` },
      }).then((r) => r.json());
    
      // me = { uid, username, ... } — create your own session keyed on me.uid
    }
    
    // Clear the token from the URL so it isn't left in history
    history.replaceState(null, "", window.location.pathname);
  11. Configure Pi Sign-in in the Developer Portal

    master

    Before integrating, you must complete these steps in the Pi Developer Portal:

    1. Verify your app domain

    Pi Sign-in only redirects to domains you own.

    • Set Your App's URL (e.g., https://yourapp.com) in the Configuration page.
    • Complete domain verification by placing the provided validation key in a file at https://yourapp.com/validation-key.txt and clicking Verify Domain.
    • Note: Until verified, you can only use loopback redirect URIs (e.g., localhost) for local development.

    2. Enable Pi Sign-in

    • Navigate to the Pi Sign-in section of your app.
    • Toggle Enabled to ON.
    • Copy your OAuth Client ID (this is public; there is no client secret).

    3. Register your redirect URIs

    • Add your callback URIs under Redirect URIs (one per line).
    • Production URIs must use https:// and must belong to your verified domain.
    • Loopback hosts (localhost, 127.0.0.1, [::1]) are always allowed and can use http://.