WASM JavaScript API
The WASM JavaScript API provides a modern, async/await interface to dojo.c functionality compiled to WebAssembly. This API is designed for web applications, Node.js backends, rapid prototyping, and developers who prefer JavaScript/TypeScript.
Getting Started
Installation
# Clone & enter the repository
git clone https://github.com/dojoengine/dojo.c && cd dojo.c
# Build WASM module for web clients
wasm-pack build --release --target web
# Build for Node.js backends
wasm-pack build --release --target nodejs
Basic Integration
Browser Integration:<script type="module">
import init, { ToriiClient } from './pkg/dojo_c.js';
async function setup() {
await init(); // Initialize WASM module
const client = await new ToriiClient({
toriiUrl: "http://localhost:8080",
worldAddress: "0x064613f376f05242dfcc9fe360fa2ce1fdd6b00b1ce73dae2ea649ea118fd9be"
});
}
</script>
const { ToriiClient } = require('./pkg/dojo_c');
// Node.js polyfills
global.WebSocket = require('ws');
global.WorkerGlobalScope = global;
async function main() {
const client = await new ToriiClient({
toriiUrl: 'http://127.0.0.1:8080',
worldAddress: '0x064613f376f05242dfcc9fe360fa2ce1fdd6b00b1ce73dae2ea649ea118fd9be'
});
const entities = await client.getAllEntities(10);
console.log(entities);
}
Client Management
Client Configuration
Client functions connect your application to the Dojo world state via Torii (the indexer). Use these to fetch current game state, query historical data, and receive real-time updates as the world changes. This is your read interface to the blockchain.
new ToriiClient(config)
Creates a new client instance.
const client = await new ToriiClient({
toriiUrl: "http://localhost:8080",
worldAddress: "0x..."
});
Entity Operations
getEntities(query)
Queries entities with advanced filtering and pagination.
const query = {
pagination: {
limit: 100,
cursor: undefined,
direction: "Forward"
},
clause: {
Keys: {
keys: [playerAddress],
pattern_matching: "FixedLen",
models: ["Position", "Health"]
}
},
no_hashed_keys: false,
historical: false
};
const entities = await client.getEntities(query);
getAllEntities(limit?)
Fetches all entities with optional limit.
const allEntities = await client.getAllEntities(1000);
onEntityUpdated(clause, callback)
Subscribes to real-time entity updates.
const subscription = await client.onEntityUpdated(
{
Keys: {
keys: [undefined], // All entities
pattern_matching: "VariableLen",
models: []
}
},
(entityId, models) => {
console.log('Entity updated:', entityId, models);
}
);
// Cancel subscription when done
subscription.cancel();
updateEntitySubscription(subscription, clauses)
Updates an existing entity subscription with new filters.
Event Operations
getEventMessages(query)
Queries historical event messages.
const events = await client.getEventMessages({
pagination: { limit: 50 },
clause: {
Keys: {
keys: [eventSelector],
pattern_matching: "FixedLen",
models: []
}
},
historical: true
});
onEventMessageUpdated(clause, callback)
Subscribes to real-time event updates.
const eventSub = await client.onEventMessageUpdated(
{
Keys: {
keys: [undefined],
pattern_matching: "VariableLen",
models: []
}
},
(entityId, models) => {
console.log('New event:', entityId, models);
}
);
onStarknetEvent(clauses, callback)
Subscribes to raw Starknet events.
const starknetSub = await client.onStarknetEvent(
[{
keys: [eventSelector],
pattern_matching: "FixedLen",
models: []
}],
(event) => {
console.log('Starknet event:', event);
}
);
Token & Asset Operations
getTokens(query)
Queries token information.
const tokens = await client.getTokens({
contract_addresses: ["0x..."], // Optional filter
token_ids: [], // Optional filter
pagination: { limit: 100 }
});
getTokenBalances(query)
Queries token balances.
const balances = await client.getTokenBalances({
contract_addresses: ["0x..."],
account_addresses: [playerAddress],
token_ids: [],
pagination: { limit: 100 }
});
getTokenCollections(query)
Queries token collections (NFT collections).
const collections = await client.getTokenCollections({
contract_addresses: [],
pagination: { limit: 50 }
});
onTokenUpdated(contract_addresses, token_ids, callback)
Subscribes to token metadata updates.
const tokenSub = await client.onTokenUpdated(
["0x..."], // Contract addresses
[], // Token IDs (empty for all)
(token) => {
console.log('Token updated:', token);
}
);
onTokenBalanceUpdated(contract_addresses, account_addresses, token_ids, callback)
Subscribes to token balance changes.
const balanceSub = await client.onTokenBalanceUpdated(
["0x..."], // Contract addresses
[playerAddress], // Account addresses
[], // Token IDs
(balance) => {
console.log('Balance changed:', balance);
}
);
Transaction Operations
getTransactions(query)
Queries transaction history.
const transactions = await client.getTransactions({
filter: {
transaction_hashes: [],
caller_addresses: [playerAddress],
contract_addresses: [],
entrypoints: ["move", "attack"],
from_block: undefined,
to_block: undefined
},
pagination: { limit: 100 }
});
onTransaction(filter, callback)
Subscribes to new transactions.
const txSub = await client.onTransaction(
{
caller_addresses: [playerAddress],
entrypoints: ["move"]
},
(transaction) => {
console.log('New transaction:', transaction);
}
);
Controller Operations
getControllers(query)
Queries controller information.
const controllers = await client.getControllers({
contract_addresses: [],
pagination: { limit: 100 }
});
Messaging Operations
publishMessage(message, signature)
Publishes a single message.
await client.publishMessage(
{
message: "Hello, Dojo!",
signature: await signMessage(message)
}
);
publishMessageBatch(messages)
Publishes multiple messages in a batch.
await client.publishMessageBatch([
{ message: "Message 1", signature: sig1 },
{ message: "Message 2", signature: sig2 }
]);
Indexer Updates
onIndexerUpdated(callback)
Subscribes to indexer synchronization updates.
const indexerSub = await client.onIndexerUpdated((update) => {
console.log('Indexer update:', update);
});
Subscription Management
updateEntitySubscription(subscription, clause)
Updates an existing entity subscription with new filtering criteria.
updateEventMessageSubscription(subscription, clause)
Updates an existing event message subscription with new filtering criteria.
updateTokenBalanceSubscription(subscription, contract_addresses, account_addresses, token_ids)
Updates an existing token balance subscription with new addresses and token IDs.
Account Operations
Account functions handle the write side of blockchain interaction. Use these to execute game transactions, manage player accounts, and handle cryptographic operations like signing and verification.
Signing Key Operations
SigningKey.fromRandom()
Generates a new random signing key.
import { SigningKey } from './pkg/dojo_c.js';
const signingKey = SigningKey.fromRandom();
const secretScalar = signingKey.secretScalar();
const verifyingKey = signingKey.verifyingKey();
Provider & Account Operations
new Provider(rpc_url)
Creates a new JSON-RPC provider.
import { Provider } from './pkg/dojo_c.js';
const provider = await new Provider("http://localhost:5050");
const chainId = await provider.chainId();
import { Account, SigningKey } from './pkg/dojo_c.js';
// Create account with private key string
const signingKey = SigningKey.fromRandom();
const privateKeyHex = signingKey.secretScalar();
const account = await new Account(provider, privateKeyHex, address);
// Execute transactions
const txHash = await account.executeRaw([{
to: "0x...",
selector: "move",
calldata: ["0x1", "0x2"]
}]);
// Deploy burner account with private key string
const burnerKey = SigningKey.fromRandom();
const burnerPrivateKey = burnerKey.secretScalar();
const burner = await account.deployBurner(burnerPrivateKey);
Data Utilities
ByteArray
class - For handling Cairo byte arrays:
import { ByteArray } from './pkg/dojo_c.js';
const byteArray = new ByteArray("Hello, Dojo!");
const raw = byteArray.toRaw(); // Convert to field elements
const restored = ByteArray.fromRaw(raw); // Restore from field elements
TypedData
class - For encoding typed data:
import { TypedData } from './pkg/dojo_c.js';
const typedData = new TypedData(JSON.stringify(typedDataObject));
const encoded = typedData.encode(accountAddress);
const result = await provider.call(call, blockId);
const chainId = await provider.chainId();
Utility Functions
Cryptographic Functions
poseidonHash(inputs)
Computes Poseidon hash of field elements.
import { poseidonHash } from './pkg/dojo_c.js';
const hash = poseidonHash([
"0x123...",
"0x456..."
]);
starknetKeccak(data)
Computes Starknet-compatible Keccak hash.
import { starknetKeccak } from './pkg/dojo_c.js';
const data = new Uint8Array(Buffer.from("move", "utf8"));
const hash = starknetKeccak(data);
getSelectorFromName(name)
Gets contract function selector from name.
import { getSelectorFromName } from './pkg/dojo_c.js';
const selector = getSelectorFromName("move");
getSelectorFromTag(tag)
Gets selector from Dojo tag.
import { getSelectorFromTag } from './pkg/dojo_c.js';
const selector = getSelectorFromTag("dojo_starter-Position");
Address & Encoding Functions
getContractAddress(class_hash, salt, constructor_calldata, deployer_address)
Computes contract address for deployment.
import { getContractAddress } from './pkg/dojo_c.js';
const address = getContractAddress(
classHash,
salt,
constructorCalldata,
deployerAddress
);
cairoShortStringToFelt(str)
Converts Cairo short string to felt.
parseCairoShortString(felt)
Parses felt as Cairo short string.
Common Issues
WASM Initialization:// Always await init() before using any functions
await init();
// Required polyfills for Node.js
global.WebSocket = require('ws');
global.WorkerGlobalScope = global;
// Cancel subscriptions to prevent memory leaks
subscription.cancel();
Type Safety: Consider using TypeScript for better development experience:
import { ToriiClient, ClientConfig } from './pkg/dojo_c';
const config: ClientConfig = {
toriiUrl: "http://localhost:8080",
worldAddress: "0x..."
};
const client = await new ToriiClient(config);