WrapHub uses subgraphs to power token activity tables and summary metrics. The frontend still reads balances, allowances, registry state, and transaction receipts directly from RPC.
Wrapper events:
- wrap events
- unwrap requests
- unwrap finalizations
- confidential transfers
Faucet events:
- Sepolia
WrapHubFaucet.Claimed
The subgraph stores public metadata and encrypted handles only. It does not decrypt confidential amounts.
Token pages use WrapperSummary.
| Metric | Meaning |
|---|---|
| Wraps | Number of indexed wrap events |
| Unwraps | Number of indexed finalized unwraps |
| Transfers | Number of indexed confidential transfer events |
| Latest | Timestamp of the latest indexed activity |
| Faucet claims | Number of indexed Sepolia faucet claims for the underlying token |
Metrics are accurate for the indexed range. Full-history accuracy requires each wrapper datasource to start at or before the wrapper deployment block.
subgraph/subgraph.yaml Sepolia official wrappers, faucet, and factory templates
subgraph/subgraph.local.yaml Local Hardhat wrappers, faucet, and factory templates
Each manifest is separate because each deployment targets one network.
cd subgraph
npm install
npm run build
npm run build:localStart Graph Node, Postgres, and IPFS:
cd subgraph
npm run docker:upRun Hardhat and deploy local contracts:
cd hardhat
npm run chain
npm run deploy:localhostCreate and deploy the local subgraph:
cd subgraph
npm run create:local
npm run deploy:localPoint the frontend at the local endpoint:
NEXT_PUBLIC_WRAPHUB_LOCAL_SUBGRAPH_URL=http://localhost:8000/subgraphs/name/wraphub/localSubgraph Studio:
cd subgraph
npx graph auth <THE_GRAPH_STUDIO_DEPLOY_KEY>
npm run deploy:sepoliaGoldsky:
cd subgraph
npm run build
goldsky subgraph deploy wraphub-sepolia/v0.0.3 --path buildgraph build overwrites build/subgraph.yaml with the manifest you just built. Deploy to Goldsky immediately after building the target network.
Configure:
NEXT_PUBLIC_WRAPHUB_SEPOLIA_SUBGRAPH_URL=https://...
NEXT_PUBLIC_WRAPHUB_LOCAL_SUBGRAPH_URL=http://localhost:8000/subgraphs/name/wraphub/localWrapHub selects the endpoint by pair.chainId.
Start blocks matter. They control how much history the indexer sees.
Use:
cd subgraph
npm run start-blocks
npm run start-blocks:writeThe script can discover deployment-like start blocks from archive RPC access and apply a safety buffer. If archive RPC is unavailable, use verified deployment blocks or earliest known event blocks.
WrapHub's ConfidentialTokenFactory separates deployment from indexing:
createConfidentialTokenemitsWrapperDeployedrecordPairForIndexingemitsTokenWrappedwhen a maintainer lists a pair
The subgraph listens for TokenWrapped only. That matches the product rule that activity indexing begins after maintainer List, not after user deploy.
Both Sepolia and local manifests include:
- A factory datasource listening for
TokenWrapped - A
FactoryWrappertemplate that reuses the existing wrapper event handlers - Factory mapping code that calls
FactoryWrapper.createWithContext(...)with the underlying ERC-20 address from the factory event
Flow:
Maintainer List
-> recordPairForIndexing
-> TokenWrapped(factory)
-> handleFactoryTokenWrapped
-> FactoryWrapper.createWithContext(confidentialToken, { underlying, chainId })
-> handleWrapped / handleUnwrapRequested / ... on the new wrapper address
This gives WrapHub automatic activity indexing for Create wrapper and Add custom pair submissions without manually editing the manifest for every wrapper address.
| Step | What happens |
|---|---|
| Maintainer clicks List | Factory emits TokenWrapped through recordPairForIndexing |
| Subgraph factory datasource catches the event | handleFactoryTokenWrapped runs |
| Template instance is created | New FactoryWrapper datasource with underlying + chain context |
| Wrapper events fire later | Existing wrapper handlers run on the new address |
Template-based indexing requires one manifest setup. After that, newly factory-deployed wrappers are tracked without manually editing subgraph.yaml for each address.
After npm run deploy:localhost, confirm these addresses match your manifest/env:
ConfidentialTokenFactory=0x0165878A594ca255338adfa4d48449f69242Eb8F
NEXT_PUBLIC_CONFIDENTIAL_TOKEN_FACTORY_HARDHAT_ADDRESS=0x0165878A594ca255338adfa4d48449f69242Eb8FRebuild and redeploy the local subgraph:
cd subgraph
npm run build:local
npm run deploy:localCreate a wrapper from /registry/create, wrap a small amount, then confirm TokenActivity appears for the new wrapper address.
Sepolia factory indexing is configured in subgraph/subgraph.yaml:
ConfidentialTokenFactorySepolia
address: 0x43F7F7432ACbbDb6969594Bd591e91Bd861DdeBa
startBlock: 11210804
FactoryWrapper template on network: sepoliaFrontend env:
NEXT_PUBLIC_CONFIDENTIAL_TOKEN_FACTORY_SEPOLIA_ADDRESS=0x43F7F7432ACbbDb6969594Bd591e91Bd861DdeBa
NEXT_PUBLIC_WRAPHUB_SEPOLIA_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmq7zytlz55i201y1468xfisr/subgraphs/wraphub-sepolia/v0.0.3/gnAfter updating the manifest:
cd subgraph
npm run build
goldsky subgraph deploy wraphub-sepolia/v0.0.3 --path buildTo verify the dynamic path:
- Create or submit a custom pair.
- Maintainer clicks List.
- Confirm
TokenWrappedappears on Etherscan for the factory transaction. - Confirm activity begins appearing on the pair page once the subgraph syncs.
Add the wrapper to the right manifest:
- kind: ethereum/contract
name: WrapperSepoliaCUSDC
network: sepolia
source:
address: "0x..."
abi: Wrapper
startBlock: 12345678
context:
chainId:
type: Int
data: 11155111
underlying:
type: String
data: "0x..."
mapping:
kind: ethereum/events
apiVersion: 0.0.9
language: wasm/assemblyscript
entities:
- TokenActivity
- WrapperSummary
abis:
- name: Wrapper
file: ./abis/Wrapper.json
eventHandlers:
- event: Wrapped(indexed address,uint256)
handler: handleWrapped
- event: UnwrapRequested(indexed address,indexed bytes32,bytes32)
handler: handleUnwrapRequested
- event: UnwrapFinalized(indexed address,indexed bytes32,bytes32,uint64)
handler: handleUnwrapFinalized
- event: ConfidentialTransfer(indexed address,indexed address,indexed bytes32)
handler: handleConfidentialTransfer
file: ./src/mapping.tsThen rebuild and deploy the affected network.
- Wrap count is the number of indexed wrap events.
- Unwrap count is finalized unwraps, not just requests.
- Confidential transfer count tracks encrypted transfer events.
- Encrypted amounts remain encrypted.
- Faucet claims are indexed only for Sepolia.
- If a subgraph starts late, metrics are accurate from that start block onward.