Intro
This guide shows you how to index and query USDT0 on Stable using Ormi’s 0xGraph. By the end, you’ll have a live subgraph that tracks transfers, mints, burns and related events, and you’ll be able to query USDT0 activity with GraphQL.Prerequisites
1. Create and configure your subgraph project
1.1 Get your Ormi API key
- Log in to Ormi and go to your dashboard.
- From the dashboard, create an API key for deployments.

1.2 Install Graph CLI
On your local machine, run the following in your terminal:Copy
Ask AI
npm install -g @graphprotocol/graph-cli
1.3 Create a directory for your subgraph
Copy
Ask AI
mkdir usdt0-stable
cd usdt0-stable
usdt0-stable in this example.
1.4 Initialize the project
Run bash in the directory folderCopy
Ask AI
npm init -y
1.5 Install dependencies
Copy
Ask AI
npm install --save-dev @graphprotocol/graph-ts
npm install --save-dev assemblyscript
1.6 Create the required files
You will need:- subgraph.yaml
- schema.graphql
- mappings/USDT0.ts
- abis/USDT0.json
usdt0-stable folder.
Directory layout
Copy
Ask AI
usdt0-stable/
├─ abis/
│ └─ USDT0.json
│
├─ mappings/
│ └─ USDT0.ts
│
├─ schema.graphql
│
├─ subgraph.yaml
│
├─ generated/
│ ├─ schema.ts
│ └─ USDT0/
│ └─ USDT0.ts
│
├─ build/
│ └─ USDT0/
│ └─ USDT0.wasm
│
├─ node_modules/
node_modules/ after installing dependencies - that is expected.
1.7 subgraph.yaml
Copy
Ask AI
specVersion: 1.2.0
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum
name: USDT0
network: stable
source:
address: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"
abi: USDT0
startBlock: 2443970
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Token
- Account
- Transfer
- Mint
- Burn
- BlocklistChange
- Authorization
abis:
- name: USDT0
file: ./abis/USDT0.json
eventHandlers:
- event: Transfer(indexed address,indexed address,uint256)
handler: handleTransfer
- event: Mint(indexed address,uint256)
handler: handleMint
- event: Burn(indexed address,uint256)
handler: handleBurn
- event: CrosschainMint(indexed address,uint256,indexed address)
handler: handleCrosschainMint
- event: CrosschainBurn(indexed address,uint256,indexed address)
handler: handleCrosschainBurn
- event: BlockPlaced(indexed address)
handler: handleBlockPlaced
- event: BlockReleased(indexed address)
handler: handleBlockReleased
- event: DestroyedBlockedFunds(indexed address,uint256)
handler: handleDestroyedBlockedFunds
- event: AuthorizationUsed(indexed address,indexed bytes32)
handler: handleAuthorizationUsed
- event: AuthorizationCanceled(indexed address,indexed bytes32)
handler: handleAuthorizationCanceled
- event: LogUpdateNameAndSymbol(string,string)
handler: handleLogUpdateNameAndSymbol
- event: OwnershipTransferred(indexed address,indexed address)
handler: handleOwnershipTransferred
- event: LogSetOFTContract(indexed address)
handler: handleLogSetOFTContract
file: ./mappings/USDT0.ts
1.8 schema.graphql
Copy
Ask AI
type Token @entity(immutable: false) {
id: ID! # contract address
name: String!
symbol: String!
decimals: Int!
totalSupply: BigInt! # derived from Mint/Burn/Crosschain*/DestroyedBlockedFunds
createdAtBlock: BigInt!
createdAtTimestamp: BigInt!
transferCount: BigInt!
mintCount: BigInt!
burnCount: BigInt!
crosschainMintCount: BigInt!
crosschainBurnCount: BigInt!
owner: Account
oftContract: Bytes
}
type Account @entity(immutable: false) {
id: ID! # address
balance: BigInt! # derived solely from events
isBlocked: Boolean! # derived from BlockPlaced/BlockReleased
createdAtBlock: BigInt!
createdAtTimestamp: BigInt!
transferCount: BigInt!
}
type Transfer @entity(immutable: true) {
id: ID! # txHash-logIndex
token: Token!
from: Account
to: Account
value: BigInt!
txHash: Bytes!
blockNumber: BigInt!
timestamp: BigInt!
}
type Mint @entity(immutable: true) {
id: ID!
token: Token!
to: Account!
amount: BigInt!
isCrosschain: Boolean!
sender: Account
txHash: Bytes!
blockNumber: BigInt!
timestamp: BigInt!
}
type Burn @entity(immutable: true) {
id: ID!
token: Token!
from: Account
amount: BigInt!
isCrosschain: Boolean!
sender: Account
txHash: Bytes!
blockNumber: BigInt!
timestamp: BigInt!
}
type BlocklistChange @entity(immutable: true) {
id: ID!
user: Account!
isBlocked: Boolean!
destroyedBalance: BigInt
txHash: Bytes!
blockNumber: BigInt!
timestamp: BigInt!
}
type Authorization @entity(immutable: false) {
id: ID! # `${authorizer}-${nonce}`
authorizer: Account!
nonce: Bytes!
used: Boolean!
canceled: Boolean!
txHashUsed: Bytes
txHashCanceled: Bytes
}
1.9 Mapping files in typescript
Copy
Ask AI
// mappings/USDT0.ts
import { BigInt, Address, Bytes } from "@graphprotocol/graph-ts";
import {
Transfer as TransferEvent,
Mint as MintEvent,
Burn as BurnEvent,
CrosschainMint as CrosschainMintEvent,
CrosschainBurn as CrosschainBurnEvent,
BlockPlaced,
BlockReleased,
DestroyedBlockedFunds,
AuthorizationUsed,
AuthorizationCanceled,
LogUpdateNameAndSymbol,
OwnershipTransferred,
LogSetOFTContract,
} from "../generated/USDT0/USDT0";
import { Token, Account, Transfer, Mint, Burn, BlocklistChange, Authorization } from "../generated/schema";
const USDT0_ADDRESS = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736";
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
// Helpers
function createEventId(txHash: Bytes, logIndex: BigInt): string {
return txHash.toHex() + "-" + logIndex.toString();
}
function getToken(eventBlockNumber: BigInt, eventTimestamp: BigInt): Token {
let token = Token.load(USDT0_ADDRESS);
if (token == null) {
token = new Token(USDT0_ADDRESS);
token.name = "USDT0";
token.symbol = "USDT0";
token.decimals = 6;
token.totalSupply = BigInt.zero();
token.createdAtBlock = eventBlockNumber;
token.createdAtTimestamp = eventTimestamp;
token.transferCount = BigInt.zero();
token.mintCount = BigInt.zero();
token.burnCount = BigInt.zero();
token.crosschainMintCount = BigInt.zero();
token.crosschainBurnCount = BigInt.zero();
}
return token as Token;
}
function getAccount(addr: Address, blockNumber: BigInt, timestamp: BigInt): Account {
let id = addr.toHex();
let account = Account.load(id);
if (account == null) {
account = new Account(id);
account.balance = BigInt.zero();
account.isBlocked = false;
account.createdAtBlock = blockNumber;
account.createdAtTimestamp = timestamp;
account.transferCount = BigInt.zero();
}
return account as Account;
}
// Handlers
export function handleTransfer(event: TransferEvent): void {
let token = getToken(event.block.number, event.block.timestamp);
let from = getAccount(event.params.from, event.block.number, event.block.timestamp);
let to = getAccount(event.params.to, event.block.number, event.block.timestamp);
let value = event.params.value;
// compare strings directly instead of using .equals()
if (from.id != ZERO_ADDRESS) {
from.balance = from.balance.minus(value);
from.transferCount = from.transferCount.plus(BigInt.fromI32(1));
from.save();
}
if (to.id != ZERO_ADDRESS) {
to.balance = to.balance.plus(value);
to.transferCount = to.transferCount.plus(BigInt.fromI32(1));
to.save();
}
token.transferCount = token.transferCount.plus(BigInt.fromI32(1));
token.save();
let transfer = new Transfer(createEventId(event.transaction.hash, event.logIndex));
transfer.token = token.id;
transfer.from = from.id;
transfer.to = to.id;
transfer.value = value;
transfer.txHash = event.transaction.hash;
transfer.blockNumber = event.block.number;
transfer.timestamp = event.block.timestamp;
transfer.save();
}
export function handleMint(event: MintEvent): void {
let token = getToken(event.block.number, event.block.timestamp);
let to = getAccount(event.params._destination, event.block.number, event.block.timestamp);
let amount = event.params._amount;
to.balance = to.balance.plus(amount);
to.save();
token.totalSupply = token.totalSupply.plus(amount);
token.mintCount = token.mintCount.plus(BigInt.fromI32(1));
token.save();
let mint = new Mint(createEventId(event.transaction.hash, event.logIndex));
mint.token = token.id;
mint.to = to.id;
mint.amount = amount;
mint.isCrosschain = false;
mint.sender = null;
mint.txHash = event.transaction.hash;
mint.blockNumber = event.block.number;
mint.timestamp = event.block.timestamp;
mint.save();
}
export function handleBurn(event: BurnEvent): void {
let token = getToken(event.block.number, event.block.timestamp);
let from = getAccount(event.params.from, event.block.number, event.block.timestamp);
let amount = event.params.amount;
from.balance = from.balance.minus(amount);
from.save();
token.totalSupply = token.totalSupply.minus(amount);
token.burnCount = token.burnCount.plus(BigInt.fromI32(1));
token.save();
let burn = new Burn(createEventId(event.transaction.hash, event.logIndex));
burn.token = token.id;
burn.from = from.id;
burn.amount = amount;
burn.isCrosschain = false;
burn.sender = null;
burn.txHash = event.transaction.hash;
burn.blockNumber = event.block.number;
burn.timestamp = event.block.timestamp;
burn.save();
}
export function handleCrosschainMint(event: CrosschainMintEvent): void {
let token = getToken(event.block.number, event.block.timestamp);
let to = getAccount(event.params.to, event.block.number, event.block.timestamp);
let sender = getAccount(event.params.sender, event.block.number, event.block.timestamp);
let amount = event.params.amount;
to.balance = to.balance.plus(amount);
to.save();
token.totalSupply = token.totalSupply.plus(amount);
token.crosschainMintCount = token.crosschainMintCount.plus(BigInt.fromI32(1));
token.save();
let mint = new Mint(createEventId(event.transaction.hash, event.logIndex));
mint.token = token.id;
mint.to = to.id;
mint.amount = amount;
mint.isCrosschain = true;
mint.sender = sender.id;
mint.txHash = event.transaction.hash;
mint.blockNumber = event.block.number;
mint.timestamp = event.block.timestamp;
mint.save();
}
export function handleCrosschainBurn(event: CrosschainBurnEvent): void {
let token = getToken(event.block.number, event.block.timestamp);
let from = getAccount(event.params.from, event.block.number, event.block.timestamp);
let sender = getAccount(event.params.sender, event.block.number, event.block.timestamp);
let amount = event.params.amount;
from.balance = from.balance.minus(amount);
from.save();
token.totalSupply = token.totalSupply.minus(amount);
token.crosschainBurnCount = token.crosschainBurnCount.plus(BigInt.fromI32(1));
token.save();
let burn = new Burn(createEventId(event.transaction.hash, event.logIndex));
burn.token = token.id;
burn.from = from.id;
burn.amount = amount;
burn.isCrosschain = true;
burn.sender = sender.id;
burn.txHash = event.transaction.hash;
burn.blockNumber = event.block.number;
burn.timestamp = event.block.timestamp;
burn.save();
}
export function handleBlockPlaced(event: BlockPlaced): void {
let user = getAccount(event.params._user, event.block.number, event.block.timestamp);
user.isBlocked = true;
user.save();
let change = new BlocklistChange(createEventId(event.transaction.hash, event.logIndex));
change.user = user.id;
change.isBlocked = true;
change.destroyedBalance = null;
change.txHash = event.transaction.hash;
change.blockNumber = event.block.number;
change.timestamp = event.block.timestamp;
change.save();
}
export function handleBlockReleased(event: BlockReleased): void {
let user = getAccount(event.params._user, event.block.number, event.block.timestamp);
user.isBlocked = false;
user.save();
let change = new BlocklistChange(createEventId(event.transaction.hash, event.logIndex));
change.user = user.id;
change.isBlocked = false;
change.destroyedBalance = null;
change.txHash = event.transaction.hash;
change.blockNumber = event.block.number;
change.timestamp = event.block.timestamp;
change.save();
}
export function handleDestroyedBlockedFunds(event: DestroyedBlockedFunds): void {
let token = getToken(event.block.number, event.block.timestamp);
let user = getAccount(event.params._blockedUser, event.block.number, event.block.timestamp);
let amount = event.params._balance;
token.totalSupply = token.totalSupply.minus(amount);
token.save();
user.balance = BigInt.zero();
user.save();
let change = new BlocklistChange(createEventId(event.transaction.hash, event.logIndex));
change.user = user.id;
change.isBlocked = user.isBlocked;
change.destroyedBalance = amount;
change.txHash = event.transaction.hash;
change.blockNumber = event.block.number;
change.timestamp = event.block.timestamp;
change.save();
}
export function handleAuthorizationUsed(event: AuthorizationUsed): void {
let authorizer = getAccount(event.params.authorizer, event.block.number, event.block.timestamp);
let id = authorizer.id + "-" + event.params.nonce.toHex();
let auth = Authorization.load(id);
if (auth == null) {
auth = new Authorization(id);
auth.authorizer = authorizer.id;
auth.nonce = event.params.nonce;
auth.used = false;
auth.canceled = false;
}
auth.used = true;
auth.txHashUsed = event.transaction.hash;
auth.save();
}
export function handleAuthorizationCanceled(event: AuthorizationCanceled): void {
let authorizer = getAccount(event.params.authorizer, event.block.number, event.block.timestamp);
let id = authorizer.id + "-" + event.params.nonce.toHex();
let auth = Authorization.load(id);
if (auth == null) {
auth = new Authorization(id);
auth.authorizer = authorizer.id;
auth.nonce = event.params.nonce;
auth.used = false;
auth.canceled = false;
}
auth.canceled = true;
auth.txHashCanceled = event.transaction.hash;
auth.save();
}
export function handleLogUpdateNameAndSymbol(event: LogUpdateNameAndSymbol): void {
let token = getToken(event.block.number, event.block.timestamp);
token.name = event.params.name;
token.symbol = event.params.symbol;
token.save();
}
export function handleOwnershipTransferred(event: OwnershipTransferred): void {
let token = getToken(event.block.number, event.block.timestamp);
let newOwner = getAccount(event.params.newOwner, event.block.number, event.block.timestamp);
token.owner = newOwner.id;
token.save();
}
export function handleLogSetOFTContract(event: LogSetOFTContract): void {
let token = getToken(event.block.number, event.block.timestamp);
token.oftContract = event.params.oftContract;
token.save();
}
1.9 ABIs
Copy
Ask AI
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"BlockPlaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"BlockReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_blockedUser","type":"address"},{"indexed":false,"internalType":"uint256","name":"_balance","type":"uint256"}],"name":"DestroyedBlockedFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oftContract","type":"address"}],"name":"LogSetOFTContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"LogUpdateNameAndSymbol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_destination","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECEIVE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addToBlockedList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_blockedUser","type":"address"}],"name":"destroyBlockedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTrusted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"multiTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oftContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeFromBlockedList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oftContract","type":"address"}],"name":"setOFTContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"updateNameAndSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"}]
2. Build the Subgraph
Generate types:Copy
Ask AI
graph codegen

Copy
Ask AI
graph build

3. Deploy the Subgraph to Ormi
Return to your API key from the dashboard. Replace<graph-name> and <API key> with your actual values
Copy
Ask AI
graph deploy <graph-name> --node https://subgraph.api.ormilabs.com/deploy --ipfs https://subgraph.api.ormilabs.com/ipfs --deploy-key <API key>

Track sync status
You can check syncing in the dashboard by going to the Subgraphs tab:
4. Query USDT0
Click on the button where the red arrow is pointing.

Sample query
Run this query to fetch the latest transfersCopy
Ask AI
{
transfers(first: 10, orderBy: timestamp, orderDirection: desc) {
id
from {
id
}
to {
id
}
value
blockNumber
timestamp
txHash
}
}
