TypeScript SDK
Build Web3 games with TypeScript - no blockchain knowledge required.
The TypeScript SDK is currently under development and has not been released yet. The package @vidya/sdk is not available on npm at this time. This documentation serves as a specification and preview of the upcoming SDK. Stay tuned for the official release!
Getting Started
Installation
npm install @vidya/sdk
# or
yarn add @vidya/sdk
# or
pnpm add @vidya/sdk
Setup & Authentication
import { VidyaSDK, Player } from '@vidya/sdk';
// Initialize with your project ID
const vidya = new VidyaSDK({
projectId: 'your-project-id', // Get from dashboard.vidya.game
environment: 'production' // 'production' | 'testnet' | 'local'
});
// Authenticate player (creates a session)
const session = await vidya.auth.login({
provider: 'google' // 'google' | 'discord' | 'email' | 'apple'
});
// Get the authenticated player object from the session
const player = Player.fromSession(session);
// Now use the player object throughout your game
const items = await vidya.inventory.getItems(player);
Core Configuration
const vidya = new VidyaSDK({
projectId: 'your-project-id', // Required: Your Vidya project ID
environment: 'production', // Required: 'production' | 'testnet' | 'local'
// Optional: Advanced configuration
chain: 'polygon', // Default: 'polygon'
sponsorGas: true, // Default: true - Users don't pay gas
// Optional: Custom contract addresses (rarely needed)
contracts: {
inventory: '0x...',
marketplace: '0x...',
fabricator: '0x...'
}
});
The Player Object
The Vidya SDK uses a Player object to represent users throughout the system. This provides type safety and clear permission management.
Creating Player Objects
There are only two ways to create a Player object:
1. Authenticated Player (Full Access)
// After authentication, create player from session
const player = Player.fromSession(session);
// Or create from a session
const player = Player.fromSession(session);
// This player can read and write
console.log(player.canWrite); // true
2. Read-Only Player (View Only)
// Create a read-only player from a wallet address
const readOnlyPlayer = Player.fromWallet('0x742d35Cc6634C0532925a3b844Bc9e7595f5b123');
// This player can only read data
console.log(readOnlyPlayer.canWrite); // false
console.log(readOnlyPlayer.isReadOnly); // true
Finding Players
When you need to interact with other players, use the lookup methods:
// Find player by username
const otherPlayer = await vidya.player.findByUsername('CoolGamer123');
// Find player by wallet address
const walletPlayer = await vidya.player.findByWallet('0x742d35Cc6634C0532925a3b844Bc9e7595f5b123');
// Find player by ENS name
const ensPlayer = await vidya.player.findByEns('coolplayer.eth');
// Find multiple players at once
const players = await vidya.player.findMultiple({
usernames: ['Player1', 'Player2'],
wallets: ['0x123...', '0x456...']
});
Authentication
Login Methods
// Social login (recommended)
const session = await vidya.auth.login({
provider: 'google' // 'google' | 'discord' | 'email' | 'apple'
});
// Email/password authentication
const session = await vidya.auth.login({
provider: 'email',
email: 'player@example.com',
password: 'secure-password'
});
// Guest mode (instant play)
const session = await vidya.auth.loginAsGuest();
// After login, always create the player object from session
const player = Player.fromSession(session);
Session Management
// Check authentication status
if (vidya.auth.isAuthenticated()) {
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const profile = await vidya.auth.getProfile();
console.log(`Welcome back, ${profile.username}!`);
}
// Listen to auth events
vidya.auth.on('login', (session) => {
const player = Player.fromSession(session);
console.log('Player logged in:', player.playerId);
});
vidya.auth.on('logout', () => {
console.log('Player logged out');
});
// Logout
await vidya.auth.logout();
Core Systems
Inventory System
All inventory operations use Player objects:
// Get current player's inventory
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const items = await vidya.inventory.getItems(player);
// Get another player's inventory (read-only)
const otherPlayer = await vidya.player.findByUsername('FriendName');
const friendItems = await vidya.inventory.getItems(otherPlayer);
// Get a specific item by ID
const sword = await vidya.inventory.getItem(player, 'sword-001');
// Get a specific item by predicate
const legendaryWeapon = await vidya.inventory.getItem(player,
item => item.name === 'Legendary Sword' && item.equipped === false
);
// Find all consumables
const consumables = await vidya.inventory.findItems(player,
item => item.slot === ItemSlot.Consumable
);
// Transfer an item using the item's method
const recipient = await vidya.player.findByWallet('0x456...');
if (sword) {
await sword.transfer(recipient, 1);
}
// Batch transfer (still on inventory module)
const potion = await vidya.inventory.getItem(player, item => item.name === 'Health Potion');
await vidya.inventory.transferBatch({
to: recipient,
items: [
{ item: sword, quantity: 1 },
{ item: potion, quantity: 5 }
]
});
// Equipment management using item methods
const weapon = await vidya.inventory.getItem(player, item =>
item.slot === ItemSlot.Weapon && !item.equipped
);
if (weapon) {
await weapon.equip();
// Later...
await weapon.unequip();
}
// Consume an item
const healthPotion = await vidya.inventory.getMyItem(item =>
item.name === 'Health Potion' && item.quantity > 0
);
if (healthPotion) {
await healthPotion.consume(1);
}
// List an item on marketplace
const rareItem = await vidya.inventory.getMyItem('rare-sword-001');
if (rareItem) {
const listing = await rareItem.list(50, 1, 7); // price, quantity, duration
}
// Get equipped items
const equipped = await vidya.inventory.getEquippedItems(player);
Marketplace System
// Browse marketplace
const listings = await vidya.marketplace.getListings({
category: 'weapons',
minPrice: 10,
maxPrice: 100,
sort: 'price_asc',
limit: 20
});
// Filter by specific seller
const seller = await vidya.player.findByUsername('MerchantKing');
const sellerListings = await vidya.marketplace.getListings({
seller: seller,
category: 'rare-items'
});
// Buy items (requires authentication)
const listings = await vidya.marketplace.getListings();
const swordListing = listings.find(l => l.item.name === 'Rare Sword');
const purchase = await vidya.marketplace.buyItem({
listing: swordListing,
quantity: 2
});
// Create listing using item method
const itemToSell = await vidya.inventory.getMyItem(item =>
item.name === 'Rare Sword' && item.tradeable && !item.equipped
);
if (itemToSell) {
const listing = await itemToSell.list(50, 1, 7); // price, quantity, duration
}
// Or use marketplace module directly
const listing = await vidya.marketplace.createListing({
item: itemToSell,
price: 50, // USD
quantity: 1,
duration: 7 // Days
});
// Get player stats
const myStats = await vidya.marketplace.getStats(player);
Crafting System
// Get craftable recipes for current player
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const recipes = await vidya.crafting.getCraftableRecipes(player);
// Get available recipes
const recipes = await vidya.crafting.getCraftableRecipes(player);
const swordRecipe = recipes.find(r => r.name === 'Epic Sword');
// Check requirements
const canCraft = await vidya.crafting.checkRequirements(player, swordRecipe);
if (!canCraft.success) {
// Get missing items
for (const missing of canCraft.missing) {
console.log(`Need ${missing.required - missing.have} more ${missing.item.name}`);
}
}
// Check if you have materials using item methods
const ironOre = await vidya.inventory.getMyItem('iron-ore-001');
if (ironOre && ironOre.canCraftWith(swordRecipe)) {
console.log('You have iron ore for this recipe!');
}
// Craft item
const result = await vidya.crafting.craftItem({
player: player,
recipe: swordRecipe
});
// Batch crafting
const potionRecipe = recipes.find(r => r.name === 'Health Potion');
const manaRecipe = recipes.find(r => r.name === 'Mana Potion');
const results = await vidya.crafting.craftBatch(player, [
{ recipe: potionRecipe, quantity: 10 },
{ recipe: manaRecipe, quantity: 5 }
]);
// Get crafting history
const history = await vidya.crafting.getHistory(player);
Gacha System
// Get available gacha boxes
const boxes = await vidya.gacha.getBoxes();
const premiumBox = boxes.find(box => box.name === 'Premium Box');
// Open loot box
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const reward = await vidya.gacha.openBox({
player: player,
box: premiumBox
});
// Multi-pull
const rewards = await vidya.gacha.openMultiple({
player: player,
box: premiumBox,
count: 10
});
// Check pity status
const pity = await vidya.gacha.getPityStatus(player, premiumBox);
console.log(`${pity.currentCount}/${pity.guaranteed} until guaranteed rare`);
Leaderboards
// Submit score
await vidya.leaderboard.submitScore({
leaderboardId: 'weekly-score',
score: 15000,
metadata: { level: 45, character: 'warrior' }
});
// Get leaderboard
const leaderboard = await vidya.leaderboard.getLeaderboard('weekly-score', {
type: 'weekly',
limit: 100
});
// Get player rank
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const rank = await vidya.leaderboard.getPlayerRank('weekly-score', player);
console.log(`Rank: ${rank.rank} of ${rank.totalPlayers}`);
// Friends leaderboard
const friendsScores = await vidya.leaderboard.getFriendsLeaderboard('weekly-score');
// Nearby players
const nearby = await vidya.leaderboard.getNearbyPlayers('weekly-score', player, 5);
Social System
// Get social profile
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const profile = await vidya.social.getProfile(player);
// Send friend request
const newFriend = await vidya.player.findByUsername('CoolPlayer');
await vidya.social.sendFriendRequest(newFriend, 'Let\'s team up!');
// Accept friend request
const pendingRequests = await vidya.social.getPendingFriendRequests();
if (pendingRequests.length > 0) {
await vidya.social.acceptFriendRequest(pendingRequests[0].from);
}
// Create guild
const guild = await vidya.social.createGuild({
name: 'Elite Warriors',
tag: 'ELITE',
description: 'Top players only',
maxMembers: 100
});
// Invite to guild
const member = await vidya.player.findByWallet('0x789...');
await vidya.social.inviteToGuild(guild.id, member);
AI NPCs
// Spawn NPC
const npc = await vidya.npc.spawnNPC({
definitionId: 'merchant-001',
location: { x: 100, y: 0, z: 50 }
});
// Interact with NPC
const dialogue = await vidya.npc.interact({
npcId: npc.definition.id,
action: 'talk'
});
// Trade with NPC
const wolfPelt = await vidya.inventory.getMyItem(item =>
item.name === 'Wolf Pelt' && item.quantity >= 10
);
const healthPotion = npc.inventory.find(item => item.name === 'Health Potion');
if (wolfPelt && healthPotion) {
const tradeResult = await vidya.npc.trade({
npc: npc,
buying: [{ item: healthPotion, quantity: 5 }],
selling: [{ item: wolfPelt, quantity: 10 }]
});
}
// Give gift to improve relationship
const rareGem = await vidya.inventory.getMyItem('rare-gem-001');
if (rareGem) {
await vidya.npc.giveGift(npc, rareGem, 1);
}
// Check relationship
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const relationship = await vidya.npc.getRelationship(npc.definition.id, player);
Currency System
// Get balances
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const balances = await vidya.currency.getBalances(player);
// Transfer currency to another player
const recipient = await vidya.player.findByUsername('TeamMate');
await vidya.currency.transfer({
from: player,
to: recipient,
currency: 'gold',
amount: 100
});
// Grant rewards (requires permissions)
await vidya.currency.grant(player, {
gold: 500,
gems: 10
});
// Spend currency
await vidya.currency.spend(player, {
currency: 'gems',
amount: 20,
reason: 'speed-boost-purchase'
});
Advanced Features
Batch Operations
Execute multiple operations efficiently:
const session = vidya.auth.getSession();
const player = Player.fromSession(session);
const friend = await vidya.player.findByWallet('0x456...');
// Create batch
const batch = vidya.createBatch();
// Use the new getItem method
const sword = await vidya.inventory.getMyItem(item =>
item.name === 'Legendary Sword' && item.tradeable
);
if (sword) {
// Use item method for transfer
batch.add(sword.transfer(friend, 1));
}
batch.add(vidya.currency.transfer({
from: player,
to: friend,
currency: 'gold',
amount: 1000
}));
// Execute all at once
const results = await batch.execute();
Error Handling
try {
const listings = await vidya.marketplace.getListings();
const listing = listings[0];
await vidya.marketplace.buyItem({ listing: listing, quantity: 1 });
} catch (error) {
if (error instanceof VidyaError) {
switch (error.code) {
case 'INSUFFICIENT_BALANCE':
console.log(error.message);
break;
case 'PLAYER_NOT_AUTHENTICATED':
await vidya.auth.login({ provider: 'google' });
break;
case 'READ_ONLY_PLAYER':
console.log('Please sign in to perform this action');
break;
}
}
}
Event System
// Module events
vidya.inventory.on('item-received', (event) => {
console.log(`${event.player.playerId} received ${event.item.name}`);
});
vidya.marketplace.on('item-purchased', (event) => {
console.log(`Purchase complete: ${event.listing.item.name}`);
});
// Global events
vidya.on('transaction', (tx) => {
console.log(`Transaction ${tx.id}: ${tx.status}`);
});
Complete Example
import { VidyaSDK, Player } from '@vidya/sdk';
class GameClient {
private vidya: VidyaSDK;
private player: Player;
async initialize() {
// Initialize SDK
this.vidya = new VidyaSDK({
projectId: 'your-project-id',
environment: 'production'
});
// Authenticate
const session = await this.vidya.auth.login({ provider: 'discord' });
this.player = Player.fromSession(session);
// Setup event listeners
this.setupEventListeners();
}
async sendGiftToFriend(friendUsername: string, itemName: string) {
// Find friend
const friend = await this.vidya.player.findByUsername(friendUsername);
// Find item using predicate
const item = await this.vidya.inventory.getMyItem(
i => i.name === itemName && i.tradeable && i.quantity > 0
);
if (!item) {
throw new Error(`Tradeable item '${itemName}' not found in inventory`);
}
// Transfer using item method
await item.transfer(friend, 1);
// Send friend request if not already friends
const friends = await this.vidya.social.getFriends();
const isFriend = friends.some(f => f.player.playerId === friend.playerId);
if (!isFriend) {
await this.vidya.social.sendFriendRequest(friend, 'Thanks for playing!');
}
}
async participateInGuildEvent(guildId: string) {
// Contribute to guild
await this.vidya.social.contributeToGuild(guildId, {
currency: 'gold',
amount: 100
});
// Update leaderboard
await this.vidya.leaderboard.submitScore({
leaderboardId: 'guild-contribution',
score: 100,
metadata: { guildId }
});
}
private setupEventListeners() {
this.vidya.inventory.on('item-received', (event) => {
if (event.player.playerId === this.player.playerId) {
this.showNotification(`Received ${event.item.name}!`);
}
});
this.vidya.social.on('friend-request-received', (event) => {
this.showNotification(`Friend request from ${event.from.playerId}`);
});
}
private showNotification(message: string) {
console.log(`[Notification] ${message}`);
}
}
// Start the game
const game = new GameClient();
game.initialize();
API Reference
For detailed API documentation, see the SDK documentation.
TypeScript Support
The SDK is written in TypeScript and provides full type definitions. Your IDE will provide intelligent code completion and type checking for all SDK methods.
import { VidyaSDK, Player, Item, Listing } from '@vidya/sdk';
// All types are available for your use
function processItem(item: Item) {
console.log(`${item.name}: ${item.quantity}x`);
}
// Type-safe event handling
vidya.inventory.on('item-received', (event: { player: Player; item: Item }) => {
processItem(event.item);
});