Appearance
Using the SDK
Use the SDK to integrate Stack into your app in minutes. The SDK is available in Typescript and Javascript.
Get Started
Get your API key
Sign up at stack.so/signup to get your API key and create a point system. You can continue to track your point system in the Stack dashboard.
Install
Add the SDK to your project.
bash
npm install @stackso/js-core
Initialize the client
Use the StackClient
to initialize the client, providing your API key and point system id from the Stack dashboard.
typescript
import {StackClient} from "@stackso/js-core";
// Initialize the client
const stack = new StackClient({
// Get your API key and point system id from the Stack dashboard (stack.so)
apiKey: "YOUR_API_KEY",
pointSystemId: "YOUR_POINT_SYSTEM_ID",
});
Add points and tag the event
Tagging each point assignment with an event name is important for tracking and analytics.
typescript
await stack.track("user_signup", {
points: 10,
account: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57"
});
await stack.track("user_signup", {
points: 15,
account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5",
});
Get points for an account
Get the points for an account using the getPoints
method, providing the account address.
typescript
await stack.getPoints("0x627306090abaB3A6e1400e9345bC60c78a8BEf57");
// => 10
Parameters
account
: The Ethereum address for which you want to get the points.
Returns
number
: The total points for the account.
Get points for a list of accounts
You can also use getPoints
with an array. Simply pass an array of account addresses to get the points for multiple accounts.
typescript
await stack.getPoints([
"0x627306090abaB3A6e1400e9345bC60c78a8BEf57",
"0x2eeb301387D6BDa23E02fa0c7463507c68b597B5"
]);
// => [
// {account: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57", points: 10},
// {account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5", points: 15}
// ]
Get points by eventType
You can also filter by eventType when fetching points.
typescript
await stack.getPoints([
"0x627306090abaB3A6e1400e9345bC60c78a8BEf57",
"0x2eeb301387D6BDa23E02fa0c7463507c68b597B5"
], { event: "user_signup" });
// => [
// {account: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57", points: 10},
// {account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5", points: 15}
// ]
Get a leaderboard
Get the leaderboard using the getLeaderboard
method. The latest version returns an object with the leaderboard, metadata, and stats. The response defaults to the top 100 users, and you can specify the limit and offset to paginate through the leaderboard. Stats includes the total number of users in the leaderboard.
typescript
await stack.getLeaderboard();
// =>{
// leaderboard: [
// {
// address: '0x28B4DE9c45AF6cb1A5a46c19909108f2BB74a2BE',
// points: 25,
// identities: [Object]
// },
// {
// address: '0x4d0c5acFb9C448Cb5dd869d9E6e5697Aa2a12Ec5',
// points: 25,
// identities: [Object]
// },
// {
// address: '0x302aE9D5BDD8f5125b1182cdd966Ff4eEd3E3aCF',
// points: 15,
// identities: [Object]
// },
// metadata: {
// label: '',
// name: '',
// description: '',
// bannerUrl: '',
// primaryColor: '#e64747',
// createdAt: '2024-05-08T18:33:38.818Z',
// url: 'https://stack.so/leaderboard/leaderboard-40a3-782251'
// },
// stats: { total: 14 },
//}
Parameters
limit
: The number of users to return in the leaderboard. Default is 100.offset
: The number of users to skip in the leaderboard. Default is 0.
Returns
leaderboard
address
: The Ethereum address of the user.points
: The total points of the user.identities
: The identities associated with the user, e.g. Farcaster, Lens, ENS.
metadata
label
: The label of the leaderboard.name
: The name of the leaderboard.description
: The description of the leaderboard.bannerUrl
: The URL of the banner image for the leaderboard.primaryColor
: The primary color of the leaderboard.createdAt
: The creation date of the leaderboard.url
: The URL of the leaderboard.
stats
total
: The total number of users in the point system (useful for pagination).
// Pagination
const {leaderboard, stats} = await stack.getLeaderboard({limit: 10, offset: 20});
// Iterate through the leaderboard until we reach stats.total.
Get events
Get the events for a specific event name using the getEvents
method.
typescript
await stack.getEvents({
address: "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E", // optional filter by address
event: 'test_event', // optional filter by event name
limit: 1, // optional, for pagination
offset: 1 // optional, for pagination
});
// Returns an array of events
// => [
// {
// event: 'test_event',
// address: '0xCC65fA278B917042822538c44ba10AD646824026',
// timestamp: '2024-03-23T16:14:24.898Z',
// points: 200,
// metadata: {}
// }
// ]
Get Leaderboard Rank
Get the rank of an account in the leaderboard using the getLeaderboardRank
method.
typescript
await stack.getLeaderboardRank("0x2eeb301387D6BDa23E02fa0c7463507c68b597B5");
// {
// address: '0x627306090abaB3A6e1400e9345bC60c78a8BEf57',
// rank: 1,
// points: 10
// }
Handling duplicate events
The SDK provides a parameter uniqueId
that uniquely identifies an event type for your point system and will only track the first event we receive with this uniqueId
.
typescript
// sending this "user_first_referral" event twice will result in only
// the first one being processed
await stack.track("user_first_referral", {
points: 15,
account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5",
uniqueId: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5",
});
Some ideas for uniqueId
include:
A unique identifier in your system
For example, a userId that is associated with multiple EOAs that you want to prevent from being double counted.
typescript
// Sending this "user_first_referral" event twice will result in only
// the first one being processed.
await stack.track("user_first_referral", {
points: 15,
account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5",
uniqueId: "2540-4a99-83c2-3d7f", // a unique userId in your system
});
A unique timeframe
For a wallet you only want to log at most 1 event per day, using a date string in the uniqueId (e.g. 2024-04-01
) – will prevent the same event from being logged more than once per day.
typescript
await stack.track("DailyWalletLogin", {
points: 15,
account: "0x2eeb301387D6BDa23E02fa0c7463507c68b597B5",
uniqueId: `${(new Date()).toISOString().split('T')[0]}-0x2eeb301387D6BDa23E02fa0c7463507c68b597B5`,
});
Best Practices
- Make sure to keep your API key secure and do not expose it in client-side code.
- Use meaningful event names that clearly describe the action being performed.
- Consider using the
uniqueId
parameter to prevent duplicate events from being tracked, especially for critical actions. - Regularly monitor your point system in the Stack dashboard to ensure accurate tracking and make any necessary adjustments.