Token System API
Overview
The Token System API allows users to earn, spend, and manage tokens within the application. It provides endpoints for token transactions, balance checks, and staking operations.
Types
TokenBalance
Represents a user's token balance and related information.
type TokenBalance {
id: ID!
userId: Int!
balance: BigDecimal!
lastActivityDate: DateTime
createdAt: DateTime!
updatedAt: DateTime!
}
TokenTransaction
Records individual token transactions including earnings, spending, and staking operations.
type TokenTransaction {
id: ID!
userId: ID!
amount: Float!
type: TokenTransactionType!
adVendor: String
region: String
createdAt: DateTime!
}
TokenTransactionType
Enum representing different types of token transactions.
enum TokenTransactionType {
EARN # From watching ads
SPEND # From using VPN
STAKE # For staking tokens
UNSTAKE # For unstaking tokens
}
DailyStats
Provides daily statistics for token activities.
type DailyStats {
watchedAds: Int!
remainingAds: Int!
tokensEarned: Float!
tokensSpent: Float!
}
RemainingLimits
Shows remaining limits for token-earning activities.
type RemainingLimits {
remainingDailyAds: Int!
remainingHourlyAds: Int!
nextHourlyReset: DateTime!
nextDailyReset: DateTime!
}
Queries
Get Token Balance
Retrieves the current token balance for the authenticated user.
query {
getTokenBalance {
id
userId
balance
lastActivityDate
createdAt
updatedAt
}
}
Get Daily Stats
Retrieves daily statistics for token activities.
query {
getMyDailyStats {
watchedAds
remainingAds
tokensEarned
tokensSpent
}
}
Get Remaining Limits
Retrieves remaining limits for token-earning activities.
query {
getMyRemainingLimits {
remainingDailyAds
remainingHourlyAds
nextHourlyReset
nextDailyReset
}
}
Mutations
Earn Tokens
Earn tokens by watching ads or completing other activities.
mutation {
earnTokens(
adVendor: String!
region: String!
) {
id
balance
lastActivityDate
}
}
Input Parameters
adVendor
: The provider of the ad (required)region
: The region where the ad was viewed (required)
Spend Tokens
Spend tokens on VPN services or other features.
mutation {
spendTokens(
minutes: Int!
activeDevices: Int!
) {
id
balance
lastActivityDate
}
}
Input Parameters
minutes
: Number of minutes to spend tokens on (required)activeDevices
: Number of active devices (required)
Staking System
TokenStakingConfig
Configuration for token staking options.
type TokenStakingConfig {
id: ID!
name: String!
baseApy: Float!
bonusApyPerMonth: Float!
minimumLockDays: Int!
maximumLockDays: Int!
minimumStakeAmount: Float!
maximumStakeAmount: Float
isActive: Boolean!
requirements: [TokenStakingRequirement!]!
}
Stake Tokens
Stake tokens to earn rewards.
mutation {
stakeTokens(input: StakeTokensInput!) {
id
amount
stakedAt
lockPeriodDays
rewardRate
}
}
Input Type
input StakeTokensInput {
amount: Float!
lockPeriodDays: Int!
}
Unstake Tokens
Retrieve staked tokens after the lock period.
mutation {
unstakeTokens(stakeId: ID!) {
id
amount
unstakedAt
}
}
Error Handling
The API uses standard GraphQL error handling. Common errors include:
INSUFFICIENT_TOKENS
: User doesn't have enough tokens for the requested operationRATE_LIMIT_EXCEEDED
: User has exceeded rate limits for earning tokensINVALID_STAKE_AMOUNT
: Staking amount doesn't meet minimum requirementsLOCK_PERIOD_NOT_ENDED
: Attempt to unstake before lock period ends
Best Practices
-
Token Balance Updates
- Always check token balance before spending operations
- Handle insufficient token errors gracefully
- Update UI immediately after successful transactions
-
Rate Limiting
- Check remaining limits before initiating earn operations
- Implement exponential backoff for retry attempts
- Cache rate limit status locally to reduce API calls
-
Staking Operations
- Verify staking requirements before attempting stake
- Monitor lock periods for unstaking operations
- Keep track of APY changes for user notifications
Examples
Check Balance and Spend Tokens
const CHECK_AND_SPEND = `
query checkAndSpend {
getTokenBalance {
balance
}
getMyRemainingLimits {
remainingDailyAds
}
}
`;
const SPEND_TOKENS = `
mutation spend($minutes: Int!, $devices: Int!) {
spendTokens(minutes: $minutes, activeDevices: $devices) {
balance
}
}
`;
// Usage Example
const checkBalance = async () => {
const { data } = await client.query({ query: CHECK_AND_SPEND });
if (data.balance >= requiredAmount) {
await client.mutate({
mutation: SPEND_TOKENS,
variables: { minutes: 60, devices: 2 },
});
}
};
Stake Tokens
const STAKE_TOKENS = `
mutation stake($amount: Float!, $days: Int!) {
stakeTokens(input: { amount: $amount, lockPeriodDays: $days }) {
id
amount
rewardRate
}
}
`;
// Usage Example
const stakeTokens = async () => {
const { data } = await client.mutate({
mutation: STAKE_TOKENS,
variables: {
amount: 1000,
days: 30,
},
});
console.log("Staking successful:", data);
};