Quick Start Guide
This guide provides practical, framework-agnostic examples for integrating the EarnKit SDK into any application. The snippets are designed to be copy-paste ready, with clear placeholders for your own logic.
1. Installation
First, add the EarnKit SDK to your project.
pnpm add earnkit-sdk
# or
yarn add earnkit-sdk
# or
npm install earnkit-sdk
2. Initialization
Import and instantiate the EarnKit
class. You should only do this once per agent in your application. Store the instance where it can be easily accessed.
import { EarnKit, EarnKitApiError } from 'earnkit-sdk';
const agent = new EarnKit({
// Your Agent ID from the EarnKit Dashboard
agentId: process.env.YOUR_AGENT_ID!,
// The base URL for the EarnKit API
baseUrl: process.env.EARNKIT_API_URL!, // https://api.earnkit.com
// Optional: Enable for development logging
debug: true,
});
3. Core Flow: Charging for a Request
This is the most important pattern for monetizing a feature. The logic is wrapped in a try/catch/finally
block to ensure users are never charged for failed requests.
The flow is:
track()
: Before executing your logic, create an event to place a temporary hold on the user’s funds.- Execute Your Logic: Run your core functionality (e.g., call an AI model, perform a computation).
capture()
: If your logic succeeds, finalize the charge.release()
: If your logic fails for any reason, release the hold. This is critical for good user experience.
async function handleMonetizedRequest(userWalletAddress: string) {
// This variable is crucial for the release logic
let eventId: string | null = null;
try {
// 1. Track the event to place a hold on the user's balance
const trackResponse = await agent.track({
walletAddress: userWalletAddress,
});
eventId = trackResponse.eventId;
// 2. Execute your core AI logic or any other monetized feature
const result = await yourCustomFunction();
// 3. If the logic succeeds, capture the event to finalize the charge
await agent.capture({ eventId });
// Optional: Refresh the user's balance in your UI
// refreshBalanceInUI(userWalletAddress);
return result;
} catch (error) {
// 4. If any step fails, release the hold on the funds
if (eventId) {
await agent.release({ eventId });
}
// 5. Handle specific errors from the SDK
if (error instanceof EarnKitApiError) {
// e.g., "Insufficient funds. Please top up your balance."
throw new Error(`API Error: ${error.message}`);
} else {
// Handle other errors (e.g., your custom function failed)
throw new Error("An unexpected error occurred.");
}
}
}
4. User Flow: Topping Up a Balance
This flow shows how to use the SDK to fetch top-up options and process a user’s on-chain transaction. EarnKit provides the transaction details, but your application is responsible for initiating the transaction with the user’s chosen wallet library (e.g., Ethers, Viem, Privy, RainbowKit).
// This is a placeholder for your application's wallet logic.
// It should take a transaction request and return a transaction hash.
async function sendTransactionWithUserWallet(txRequest: {
to: string;
value: bigint;
chainId: number;
}): Promise<{ hash: string }> {
// Replace this with your actual wallet library's implementation
// For example, using Ethers.js:
// const signer = provider.getSigner();
// const tx = await signer.sendTransaction({ to: txRequest.to, value: txRequest.value });
// return { hash: tx.hash };
throw new Error(
"sendTransactionWithUserWallet is a placeholder and needs to be implemented."
);
}
async function handleTopUp(userWalletAddress: string) {
try {
// 1. Fetch the pre-configured purchase options from your dashboard
const { options } = await agent.getTopUpDetails();
if (!options || options.length === 0) {
console.log("No top-up options available.");
return;
}
// 2. Let the user select an option from your UI
// For this example, we'll just use the first one.
const selectedOption = options[0];
// 3. Use the user's wallet to send the on-chain transaction.
// The `to` and `value` come directly from the selected option.
const { hash: txHash } = await sendTransactionWithUserWallet({
to: selectedOption.to,
value: BigInt(selectedOption.value), // IMPORTANT: Use BigInt to avoid precision loss
chainId: 84532, // Example: Base Sepolia. This should match your setup.
});
// 4. Submit the transaction hash to EarnKit for monitoring
await agent.submitTopUpTransaction({
txHash,
walletAddress: userWalletAddress,
amountInEth: selectedOption.amountInEth,
creditsToTopUp: selectedOption.creditsToTopUp,
});
// 5. (Optional but Recommended) Poll for the balance update for a great UX
const initialBalance = await agent.getBalance({ walletAddress: userWalletAddress });
agent.pollForBalanceUpdate({
walletAddress: userWalletAddress,
initialBalance,
onConfirmation: (newBalance) => {
console.log("Top-up successful! New balance:", newBalance);
// Update your UI here
},
onTimeout: () => {
console.log(
"Confirmation is taking longer than expected. Please check back soon."
);
},
});
} catch (error) {
console.error("Top-up failed:", error);
// Handle errors in your UI
}
}