Claude-skill-registry dojo-events
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dojo-events" ~/.claude/skills/majiayu000-claude-skill-registry-dojo-events && rm -rf "$T"
manifest:
skills/data/dojo-events/SKILL.mdsource content
Dojo.js Events & Token Tracking
When to Use
Use this skill when:
- Subscribing to game events
- Tracking token balances
- Monitoring token transfers
- Tracking achievements and activities
Event Subscriptions
Subscribe to Event Messages
import { ToriiQueryBuilder } from "@dojoengine/sdk"; import { useDojoSDK } from "@dojoengine/sdk/react"; const { sdk } = useDojoSDK(); const [initialEvents, subscription] = await sdk.subscribeEventQuery({ query: new ToriiQueryBuilder<typeof schema>() .addEntityModel("game-GameEvent") .withLimit(100), callback: ({ data, error }) => { if (error) { console.error("Event error:", error); return; } console.log("New event:", data); } }); // Process initial events initialEvents.items.forEach(event => { console.log(event.models.game.GameEvent); }); // Cleanup subscription.cancel();
Get Event Messages (One-time)
const events = await sdk.getEventMessages({ query: new ToriiQueryBuilder<typeof schema>() .addEntityModel("game-PlayerAction") .addOrderBy("game-PlayerAction.timestamp", "Desc") .withLimit(50) });
Token Balance Tracking
Subscribe to Token Balances
const [balances, subscription] = await sdk.subscribeTokenBalance({ // Contract addresses must be full hex strings with 0x prefix contractAddresses: ["0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"], accountAddresses: [playerAddress], callback: (balance) => { console.log("Balance updated:", balance.balance); } }); // Initial balances balances.items.forEach(b => { console.log(`Token: ${b.token_id}, Balance: ${b.balance}`); });
Get Token Balances
const balances = await sdk.getTokenBalances({ contractAddresses: ["0x..."], accountAddresses: [playerAddress], pagination: { limit: 100 } });
Track Balance Updates Only
const subscription = await sdk.onTokenBalanceUpdated({ contractAddresses: ["0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"], accountAddresses: [playerAddress], // Empty array for all tokens (ERC20); for ERC721 use specific IDs: ["0x1", "0x2"] tokenIds: [], callback: (balance) => { updateUI(balance); } });
Token Transfer Tracking
const [transfers, subscription] = await sdk.subscribeTokenTransfer({ contractAddresses: ["0x..."], accountAddresses: [playerAddress], callback: (transfer) => { console.log(`Transfer: ${transfer.from} -> ${transfer.to}`); } });
Token Queries
// Get tokens const tokens = await sdk.getTokens({ contractAddresses: ["0x..."], pagination: { limit: 100 } }); // Get token contracts const contracts = await sdk.getTokenContracts({ contractTypes: ["ERC20", "ERC721"] });
Achievement Tracking
// Get achievements const achievements = await sdk.getAchievements({ worldAddresses: [worldAddress], namespaces: ["game"] }); // Get player achievements const playerAchievements = await sdk.getPlayerAchievements({ playerAddresses: [playerAddress] }); // Subscribe to achievement progress const subscription = await sdk.onAchievementProgressionUpdated({ worldAddresses: [worldAddress], playerAddresses: [playerAddress], callback: (progression) => { console.log("Achievement progress:", progression); } });
Activity Tracking
// Get activities const activities = await sdk.getActivities({ world_addresses: [worldAddress], namespaces: ["game"], caller_addresses: [playerAddress] }); // Subscribe to activities const subscription = await sdk.onActivityUpdated( [worldAddress], ["game"], [playerAddress], (activity) => { console.log("New activity:", activity); } );
Aggregations
// Get aggregated data const aggregations = await sdk.getAggregations({ aggregator_ids: ["total_players", "total_games"], pagination: { limit: 10 } }); // Subscribe to aggregation updates const subscription = await sdk.onAggregationUpdated( ["total_players"], null, (aggregation) => { console.log("Aggregation updated:", aggregation); } );
Update Subscriptions
// Update token balance subscription await sdk.updateTokenBalanceSubscription({ subscription, contractAddresses: newContracts, accountAddresses: newAccounts, tokenIds: [] }); // Update entity subscription await sdk.updateEntitySubscription( subscription, newClause );
React Effect Atoms
For complex async state:
import { createEventQueryAtom, createEventUpdatesAtom } from "@dojoengine/react/effect"; // One-time event query const eventsAtom = createEventQueryAtom(runtime, query); // Live event updates const updatesAtom = createEventUpdatesAtom(runtime, clauses); // Combined query + updates const liveEventsAtom = createEventQueryWithUpdatesAtom(runtime, query, clauses);
Common Pitfalls
- Subscription cleanup: Always cancel subscriptions when component unmounts
- Contract addresses: Must be padded hex strings with 0x prefix
- Token IDs: Format depends on token type (ERC20 vs ERC721)
- Rate limiting: Avoid creating too many subscriptions
- Callback errors: Wrap callbacks in try-catch to prevent unhandled errors