Skip to Content

Quick Start

Before integration, make sure your Embed Mode setup is completed in TaskOn dashboard:

And ensure you already have:

  • A resolved embed domain (for example https://your_embed_domain.com)
  • Your TaskOn keys (for example TASKON_CLIENT_ID and TASKON_PRIVATE_KEY)

This guide shows the recommended host integration flow:

  1. Create TaskOnEmbed
  2. Call init()
  3. Listen to lifecycle events
  4. Handle login when loginRequired is emitted
  5. Sync logout when host user logs out
  6. Clean up with destroy() when unmounting

Install

npm install @taskon/embed

Prepare a Container

Place a container element in your page. The SDK mounts its iframe inside it:

<div id="taskon-embed" style="width: 100%; height: 100%;"></div>

Basic Integration

import { TaskOnEmbed, trackVisit } from "@taskon/embed"; // Optional conversion analytics (run once per page load) await trackVisit(); const embed = new TaskOnEmbed({ baseUrl: "https://your_embed_domain.com", containerElement: "#taskon-embed", }); embed.on("loginRequired", () => { // Open host login UI (modal/redirect/etc.) openLoginModal(); }); embed.on("routeChanged", (fullPath) => { // Optional: sync iframe route to host URL // window.history.replaceState(null, "", `/taskon${fullPath}`); console.log("TaskOn route changed:", fullPath); }); embed.on("taskCompleted", (event) => { console.log("Task completed:", event.taskName, event.rewards); }); await embed.init();

Login Example

Call embed.login(...) after user signs in to your host system:

const email = "[email protected]"; // Fetch signature from your backend const signed = await fetch("/your/api", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "Email", account: email, }), }).then((res) => res.json()); await embed.login({ type: "Email", account: email, signature: signed.signature, timestamp: signed.timestamp, });

Skip Re-signing with isAuthorized()

If the account is already authorized (cached), you can call login() without a fresh signature — only fetch one when needed:

const isAuthorized = await embed.isAuthorized("Email", email); if (isAuthorized) { await embed.login({ type: "Email", account: email }); } else { const signed = await fetch("/your/api", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "Email", account: email }), }).then((res) => res.json()); await embed.login({ type: "Email", account: email, signature: signed.signature, timestamp: signed.timestamp, }); }

Login with an EVM Wallet

For wallet users, use type: "WalletAddress" and pass the wallet provider (required for on-chain operations):

async function loginToTaskOnWithWallet(address: string, provider: any) { const isAuthorized = await embed.isAuthorized("WalletAddress", address); if (isAuthorized) { await embed.login({ type: "WalletAddress", account: address, provider }); return; } // Backend signs with type "evm" for wallet accounts const signed = await fetch("/your/api", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "evm", account: address }), }).then((res) => res.json()); await embed.login({ type: "WalletAddress", account: address, signature: signed.signature, timestamp: signed.timestamp, provider, }); }

Backend: Generate the Signature

The /your/api endpoint referenced above must sign the request server-side with your private key, using signMessage from @taskon/embed/node. Never ship TASKON_PRIVATE_KEY to the browser:

import { signMessage } from "@taskon/embed/node"; // Example Express.js endpoint app.post("/your/api", (req, res) => { const { account, type } = req.body; // type: "Email" | "evm" // Verify the user is authenticated in YOUR system first if (!isUserAuthenticated(req)) { return res.status(401).json({ error: "Unauthorized" }); } try { const result = signMessage( process.env.TASKON_CLIENT_ID!, type === "Email" ? "Email" : "evm", account, process.env.TASKON_PRIVATE_KEY!, // Base64-encoded RSA private key ); res.json(result); // { signature, timestamp } } catch { res.status(500).json({ error: "Signature generation failed" }); } });

Logout Example

Call embed.logout(...) when host user logs out:

// Recommended: keep authorization cache for fast re-login await embed.logout(); // Optional: clear authorization cache completely // await embed.logout({ clearAuth: true });

SPA Cleanup

Always destroy the instance when route/view unmounts:

embed.destroy();

Next Steps

Last updated on