Skip to main content

App Events

App Events are the communication bridge between your app’s logic and UptopiaKit. With App Events, developers can write simple message-based integrations to invoke built-in capabilities of UptopiaKit and supported miniapp platforms — all while keeping your app portable. There are two ways to use App Events:
  • Default App Events (built-in) — a set of standard events that UptopiaKit creates automatically for every app. You can use these immediately, without any dashboard setup.
  • Custom App Events — events you define and configure in the dashboard for app-specific behaviors (the original model described in this document).

How it works

Your app runs inside an UptopiaKit-managed frame. When your app wants to call a capability, it sends a postMessage to the parent window (UptopiaKit) with a specific payload format. UptopiaKit receives the message from the iframe and executes the corresponding logic. High-level flow:
  1. For default events, you can send the documented payloads directly (see Default App Events below).
  2. For custom events, you define an App Event in the dashboard.
  3. In your app code, you send window.parent.postMessage(payload) from inside the iframe.
  4. UptopiaKit validates the message and triggers the requested capability.
  5. For some events, UptopiaKit sends a response message back to your app via postMessage.
For security, prefer sending messages with the correct targetOrigin instead of * when possible.

Default App Events

When a new app is created, UptopiaKit registers these default App Events that you can call immediately from your app code. You do not need to create them in the dashboard.

1) ADD_MINI_APP

Adds your mini app for the current user on the host platform (for example, on Farcaster or The Base App). When triggered, this event asks the host platform to open its native “add miniapp” UI. The exact UX depends on the platform, but typically:
  • The user sees a popup/modal from the platform.
  • After confirmation, your miniapp is added/pinned/installed in the user’s account or client.
Request payload (from app → UptopiaKit)
const payload = {
  name: "ADD_MINI_APP",
};

window.parent.postMessage(payload /*, targetOrigin */);
There is no structured response for this event; handle UI state changes in your app as needed (for example, optimistically updating UI after sending the event or reacting to platform-level changes if exposed elsewhere).

2) COMPOSE_CAST

Opens a share/composer UI (e.g., on Farcaster) with provided text and optional embeds. Request payload
const payload = {
  name: "COMPOSE_CAST",
  data: {
    text: "I just scored 8 on this game. Go play now!",
    embeds: [screenshot1_url, screenshot2_url], // optional
  },
};

window.parent.postMessage(payload /*, targetOrigin */);
Notes:
  • data.text is the full text you want to share.
  • data.embeds is optional; if it’s missing, UptopiaKit will typically default to sharing the app link (platform-specific behavior).

3) OPEN_URL

Opens a URL in the user’s browser from within the miniapp. Request payload
const payload = {
  name: "OPEN_URL",
  data: {
    url: "https://uptopia.xyz",
  },
};

window.parent.postMessage(payload /*, targetOrigin */);
Make sure to validate and sanitize URLs on your side as well.

4) IAP (In-app Purchases)

Triggers in-app purchase flows or lists available IAP packages for the current app. Request payload
const payload = {
  name: "IAP",
  data: {
    packageId: "optional-package-id", // optional – only needed for BUY
    type: "BUY" || "LIST",
  },
};

window.parent.postMessage(payload /*, targetOrigin */);
  • type: 'BUY' — attempts to purchase a specific package.
  • type: 'LIST' — asks UptopiaKit for the list of available IAP packages.
Response payloads (from UptopiaKit → app) Listen for messages in your app:
window.addEventListener("message", (event) => {
  // TODO: check event.origin
  const res = event.data;

  if (res?.type === "IAP_RES") {
    // Result of BUY
    // res.payload: { status: 0 | 1, packageId?: string }
  }

  if (res?.type === "IAP_LIST") {
    // Result of LIST
    // res.payload: Array<{
    //   id: string;
    //   name: string;
    //   packageId: string;
    //   price: number;
    //   description: string;
    //   gameId: string;
    //   status: 'active' | 'inactive';
    // }>
  }
});
Shapes:
// BUY result
const res = {
  type: "IAP_RES",
  payload: {
    status: 0 || 1, // implementation-dependent (e.g. 1 = success, 0 = failed)
    packageId: "string" || undefined,
  },
};

// LIST result
const res = {
  type: "IAP_LIST",
  payload: [
    {
      id: "string",
      name: "string",
      packageId: "string",
      price: 0,
      description: "",
      gameId: "string",
      status: "active" || "inactive",
    },
  ],
};
Your app should interpret status and update UI accordingly.

5) AUTH

Manages basic authentication-related flows and retrieves user information from the underlying miniapp platform account (for example, the user on Farcaster or The Base App). Your app can use this information as a basic authentication layer or to associate in-game / in-app profiles with the platform user:
  • wallet — the user’s wallet address as known by the host/platform (if available).
  • userId — a stable identifier for the user on that platform.
This is not a full OAuth flow; think of it as a lightweight identity + session bridge that lets you link your own user model to the platform user.
Request payload
const payload = {
  name: "AUTH",
  data: {
    packageId: "string", // optional, if your auth or entitlements are tied to a package
    type: "LOGIN" || "LOGOUT" || "GET_USER_INFOR",
  },
};

window.parent.postMessage(payload /*, targetOrigin */);
  • type: "LOGIN" — asks the platform/UptopiaKit to make sure the user is signed in and then returns their identifiers.
  • type: "LOGOUT" — requests a sign-out / session clear for the current user.
  • type: "GET_USER_INFOR" — fetches the current user info if already logged in (without forcing a login flow).
Response payload (from UptopiaKit → app)
window.addEventListener("message", (event) => {
  // TODO: check event.origin
  const res = event.data;

  // For AUTH flows, UptopiaKit sends `res` with the following shape:
  // {
  //   wallet: string;
  //   userId: string;
  // }
});
Shape:
const res = {
  wallet: "string",
  userId: "string",
};
Depending on type and user state, fields may be empty/undefined (for example, after LOGOUT or if the user declined login). Your app can treat (wallet, userId) as the “logged-in user” and map that to your own internal user/session.

Custom App Events

In addition to the default events above, you can still define custom App Events for your specific use cases.

Create a custom App Event

Each custom App Event requires these fields in the dashboard:
  • Name: recommended format is uppercase with underscores, e.g. ABC_XYZ.
  • Type: one of the supported event types (custom types managed by UptopiaKit).
  • Data: a JSON definition for event data (used by the event and for validation/templates).

Supported event types

Some event types are used by default events, and you can also reuse them for your own custom App Events if appropriate:
  • Add Mini App: triggers a popup to add your mini app for users on platforms like Farcaster and The Base App.
  • Compose Cast: triggers a share popup to compose a post on Farcaster (content and a link to open your miniapp).
  • Open URL: opens a URL in the user’s browser from within the miniapp.
  • IAP: triggers IAP flows (BUY/LIST) for in-app purchases.
  • AUTH / other internal types: used by default App Events as described above.
Custom App Events should follow the same name + data contract as default ones.

Payload contract (from your app)

Regardless of default or custom events, your app sends a message from the iframe to the UptopiaKit parent window with this minimal structure:
  • name: string — the App Event Name (e.g., ADD_MINI_APP, COMPOSE_CAST, OPEN_URL, IAP, AUTH, or a custom name).
  • data: object (optional) — runtime values used by the event.
Notes:
  • The Name must match the event you created in the dashboard (for custom events) or one of the default event names above.
  • Only messages from the embedded app running inside UptopiaKit (or its managed preview) are handled.
  • Do not include sensitive information in data.

Listening for responses (from UptopiaKit)

For events that return data (e.g., IAP, AUTH), register a listener in your app:
window.addEventListener("message", (event) => {
  // Always validate origin in production
  // if (event.origin !== 'https://your-uptopia-origin') return;

  const res = event.data;

  // Switch by res.type or by known shape, depending on the event.
  // See the per-event sections above for exact response shapes.
});

Examples

Example: Add Mini App (default)

const payload = {
  name: "ADD_MINI_APP",
};

window.parent.postMessage(payload);

Example: Compose Cast (default)

const payload = {
  name: "COMPOSE_CAST",
  data: {
    text: "I just scored 8 on this game. Go play now!",
    embeds: [screenshot1_url, screenshot2_url], // optional
  },
};

window.parent.postMessage(payload);

Example: Open URL (default)

const payload = {
  name: "OPEN_URL",
  data: {
    url: "https://uptopia.xyz",
  },
};

window.parent.postMessage(payload);

Example: IAP BUY and LIST (default, with response handling)

// BUY
window.parent.postMessage({
  name: "IAP",
  data: {
    type: "BUY",
    packageId: "my-package-id",
  },
});

// LIST
window.parent.postMessage({
  name: "IAP",
  data: {
    type: "LIST",
  },
});

// Listen for responses
window.addEventListener("message", (event) => {
  const res = event.data;

  if (res?.type === "IAP_RES") {
    // handle buy result
  }

  if (res?.type === "IAP_LIST") {
    // handle list of packages
  }
});

Example: AUTH (default)

// Login and get user info from the host platform (Farcaster / The Base App)
window.parent.postMessage({
  name: "AUTH",
  data: {
    type: "LOGIN",
  },
});

// Listen for user info
window.addEventListener("message", (event) => {
  const res = event.data;
  // res: { wallet: string; userId: string }

  // Example: map platform user to your own user/session
  // loginWithPlatformUser(res.userId, res.wallet);
});

Validation and handling

  • UptopiaKit validates the event name, type, and data. Unknown events or invalid payloads may be ignored or rejected.
  • Exact names matter: use the same uppercase-with-underscores Name as defined in the dashboard (for custom events) or one of the documented default names.
  • Ensure the app is Active and running inside an UptopiaKit context; otherwise, the message may not be handled.

Security notes

  • Do not include secrets (API keys, tokens, personal data) in event payloads.
  • Validate and sanitize URLs when using OPEN_URL.
  • Prefer specifying a targetOrigin in postMessage to restrict recipients.