
Vechain Core
- 73 installs
- 9 repo stars
- Updated June 11, 2026
- vechain/vechain-ai-skills
Helps with ai & agent building tasks.
About
vechain-core is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- vechain-core
- AI & Agent Building
- AI-coding skill
Vechain Core by the numbers
- 73 all-time installs (skills.sh)
- +2 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #5,587 of 16,544 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/vechain/vechain-ai-skills --skill vechain-coreAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 73 |
|---|---|
| repo stars | ★ 9 |
| Last updated | June 11, 2026 |
| Repository | vechain/vechain-ai-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
VeChain Core Skill
CRITICAL RULES
1. Read reference files FIRST. When the user's request involves any topic in the reference table below, read those files before doing anything else — before writing code, before making decisions. Briefly mention which files you are reading so the user can confirm the skill is active (e.g., "Reading fee delegation reference..."). 2. Information priority for VeChain topics: (a) Reference files in this skill — always the primary source. (b) VeChain MCP tools — use @vechain/mcp-server for on-chain data, transaction building, and live network queries; use Kapa AI MCP for VeChain documentation lookups. (c) Web search — only as a last resort, and only for topics NOT covered in the reference files. 3. Prefer working directly in the main conversation for VeChain tasks. Plan mode and subagents do not inherit skill context and may fall back to web search instead of using reference files. 4. After compaction or context loss, re-read this SKILL.md to restore awareness of the reference table and operating procedure before continuing work.
Scope
Use this Skill for general VeChain development:
- SDK usage (
@vechain/sdk-core,@vechain/sdk-network, ethers adapter) - Fee delegation (VIP-191) — gasless transactions, backend sponsorship, vechain.energy
- Multi-clause transactions — atomic batching of multiple operations
- Dual-token model (VET for value, VTHO for gas)
- Legacy migration from Connex/thor-devkit to VeChain SDK
- General VeChainThor development patterns and reference links
For specialized topics, see the companion skills:
- frontend — Generic frontend patterns: React Query, Turborepo, state management, Chakra UI, i18n, transaction UX
- vechain-kit — VeChain Kit and dapp-kit packages: hooks, components, wallet connection, social login
- smart-contract-development — Solidity, Hardhat, testing, security, gas optimization
- vebetterdao — X2Earn apps, B3TR/VOT3, governance, VeVote
- stargate — NFT staking, validators, delegation, VTHO rewards
Default stack
| Layer | Default | Alternative |
|---|---|---|
| SDK | @vechain/sdk-core + @vechain/sdk-network | @vechain/sdk-ethers-adapter |
| Node | Node 20 LTS (managed via nvm) | -- |
Operating procedure
1. Check Node version
Before installing dependencies or running any command:
- Check if
.nvmrcexists in the project root. If yes, runnvm useto switch to the required version. - If
.nvmrcdoes not exist, create one with20(Node 20 LTS) and runnvm use.
2. Detect project structure
turbo.jsonpresent → follow Turborepo conventions (apps/,packages/*)
3. Clarify before implementing
When the user's request is ambiguous or could be solved multiple ways, ask before building. Do not silently research alternatives and pick one. Separate research from implementation:
- If the scope is unclear, ask the user to narrow it
- If multiple architectures are viable, present trade-offs and let the user choose
- Only proceed to implementation once the approach is agreed upon
4. Implement with VeChain-specific correctness
- Network: always explicit (
mainnet/testnet/solo) - Gas: estimate first, use fee delegation where appropriate
- Transactions: use multi-clause when batching benefits atomicity or UX
- Tokens: VET for value, VTHO for gas (dual-token model)
5. Verify and deliver
A task is not complete until all applicable gates pass:
1. Code compiles — no build errors 2. Tests pass — existing tests still pass; new logic has test coverage 3. Risk notes documented — any signing, fee, or token-transfer implications are called out
Then provide:
- Files changed + diffs
- Install/build/test commands
- Risk notes for signing, fees, token transfers
Reference files
Read the matching files BEFORE doing anything else. See Critical Rules above.
| Topic | File | Read when user mentions... |
|---|---|---|
| Fee delegation | references/fee-delegation.md | gasless, sponsored, VIP-191, delegator, vechain.energy |
| Multi-clause | references/multi-clause-transactions.md | batch, multi-clause, atomic, multiple operations |
| Legacy migration | references/sdk-migration.md | Connex, thor-devkit, migration, deprecated |
| Reference links | references/resources.md | docs URL, npm link, GitHub repo |
Fee Delegation (VIP-191)
When to use
Use when the user asks about:
- Gasless transactions (users don't pay VTHO)
- Sponsored transactions, fee abstraction for onboarding
- Meta-transactions on VeChain, VIP-191 designated gas payer
- Generic Delegator, gas estimation, transaction cost
VIP-191: Designated Gas Payer
- Operates at the transaction level
- Flexible: per-transaction sponsorship decisions
- Both sender and sponsor must be online
- Requires
reserved.features = 1in the transaction body - Best for: selective sponsorship, promotional campaigns, onboarding flows
VIP-191 Implementation
Flow
1. User creates an unsigned transaction with reserved: { features: 1 } 2. User sends the unsigned transaction to the gas payer's service 3. Gas payer evaluates whether to sponsor (checks criteria) 4. Gas payer returns their signature 5. User combines both signatures and submits to the blockchain
Backend: Sign as Both Sender and Gas Payer
import {
Address, Clause, VET, Transaction, HexUInt,
Mnemonic, networkInfo
} from '@vechain/sdk-core';
import { ThorClient } from '@vechain/sdk-network';
const thorClient = ThorClient.at('http://localhost:8669');
// Build clauses
const clauses = [
Clause.transferVET(
Address.of('0x7567d83b7b8d80addcb281a71d54fc7b3364ffed'),
VET.of(10000)
)
];
// Estimate gas
const gasResult = await thorClient.gas.estimateGas(clauses, senderAddress);
// Get current block for blockRef
const bestBlock = await thorClient.blocks.getBestBlockCompressed();
// Build transaction body with fee delegation enabled
const body = {
chainTag: networkInfo.mainnet.chainTag,
blockRef: bestBlock.id.slice(0, 18),
expiration: 32,
clauses,
gasPriceCoef: 0,
gas: gasResult.totalGas,
dependsOn: null,
nonce: Date.now(),
reserved: {
features: 1 // Enable VIP-191 fee delegation
}
};
// Sign with both sender and gas payer private keys
const signedTransaction = Transaction.of(body).signAsSenderAndGasPayer(
HexUInt.of(senderPrivateKey).bytes,
HexUInt.of(gasPayerPrivateKey).bytes
);
// Send
const rawTx = HexUInt.of(signedTransaction.encoded).toString();
const result = await thorClient.transactions.sendRawTransaction(rawTx);
const receipt = await thorClient.transactions.waitForTransaction(result.id);Using a Delegation URL (sponsor service)
import { VeChainProvider, ProviderInternalBaseWallet } from '@vechain/sdk-network';
const provider = new VeChainProvider(
thorClient,
new ProviderInternalBaseWallet(
[{ privateKey: senderPrivateKey, address: senderAddress }],
{
gasPayer: {
delegateUrl: 'https://sponsor-testnet.vechain.energy/by/YOUR_PROJECT_ID'
}
}
),
true // isDelegated = true
);
// Transactions sent via this provider are automatically fee-delegated
const signer = await provider.getSigner(senderAddress);Frontend: Fee Delegation via VeChain Kit
VeChain Kit v2 has two fee delegation modes:
1. Generic Delegator (default -- no cost to app owner)
VeChain Kit auto-enables the Generic Delegator when social login (Privy) or VeChain/ecosystem login is detected. No configuration needed -- users pay their own gas fees using VET, VTHO, or B3TR tokens. The app owner pays nothing.
Default gas token priority: VET → B3TR → VTHO. Users can change this in the VeChain Kit settings UI.
2. App-Sponsored Delegation (app owner pays VTHO)
To sponsor transactions yourself, configure a delegatorUrl:
<VeChainKitProvider
feeDelegation={{
delegatorUrl: 'https://your-delegator.com/delegate',
delegateAllTransactions: true, // true = all users, false = social login only
}}
>Per-Transaction Sponsorship Control
Override delegation on individual transactions via the delegationUrl parameter:
const { sendTransaction } = useSendTransaction({
signerAccountAddress: account?.address ?? '',
});
// Sponsor this specific transaction
await sendTransaction(clauses, 'https://your-delegator.com/delegate');
// Or let the user pay (Generic Delegator)
await sendTransaction(clauses);Gas Estimation (Generic Delegator)
When using the Generic Delegator, show users what they'll pay before confirming:
import { useGenericDelegatorFeeEstimation } from '@vechain/vechain-kit';
const { data: estimation } = useGenericDelegatorFeeEstimation({
clauses,
tokens: ['VET', 'B3TR', 'VTHO'], // Priority order
});
// estimation: { estimatedGas, transactionCost, serviceFee, totalGasUsed, usedToken }Transaction Fee UX (Generic Delegator)
When using the Generic Delegator, implement these alerts:
- Transaction confirmation: Show the exact amount of VET/VTHO/B3TR that will be deducted
- Insufficient funds: Alert if the user lacks balance to cover fees, with the required amount
See the vechain-kit skill (references/kit-hooks.md) for the full useSendTransaction API.
Frontend: Fee Delegation via dapp-kit
If using dapp-kit instead of VeChain Kit, configure delegation at the provider level:
<DAppKitProvider
nodeUrl="https://testnet.vechain.org"
genesis="test"
usePersistence={true}
>Then use useSendTransaction from dapp-kit with a delegation URL:
import { useSendTransaction } from '@vechain/dapp-kit-react';
function DelegatedTransaction() {
const { sendTransaction } = useSendTransaction();
const handleSend = async () => {
const result = await sendTransaction({
clauses: [{ to: '0x...', value: '0x0', data: encodedCallData }],
comment: 'This transaction is sponsored',
delegatorUrl: 'https://sponsor-testnet.vechain.energy/by/YOUR_PROJECT_ID',
});
console.log('Transaction ID:', result.id);
};
return <button onClick={handleSend}>Send (Gasless)</button>;
}Hardhat Configuration with Fee Delegation
// hardhat.config.ts
vechain_testnet_delegated: {
url: 'https://testnet.vechain.org',
accounts: {
mnemonic: process.env.MNEMONIC || '',
count: 3,
path: VET_DERIVATION_PATH
},
delegate: {
url: 'https://sponsor-testnet.vechain.energy/by/YOUR_PROJECT_ID'
},
gas: 'auto',
gasPrice: 'auto'
}Building a Gas Payer Service
For production VIP-191 deployments, build a service that:
1. Receives unsigned transactions from users 2. Validates the transaction (whitelist contracts, check amounts, rate limit) 3. Signs as gas payer if approved 4. Returns the gas payer signature
Example validation logic
function shouldSponsor(tx: TransactionBody): boolean {
// Only sponsor interactions with known contracts
const allowedContracts = ['0x...', '0x...'];
for (const clause of tx.clauses) {
if (!allowedContracts.includes(clause.to?.toLowerCase() ?? '')) {
return false;
}
// Don't sponsor VET transfers
if (BigInt(clause.value) > 0n) {
return false;
}
}
return true;
}Fee Delegation with vechain.energy (managed service)
For quick setup without building your own service:
1. Go to vechain.energy 2. Create a sponsorship project 3. Whitelist the smart contract addresses 4. For VeChain Kit smart accounts, whitelist:
- Mainnet:
0xD7B96cAC488fEE053daAf8dF74f306bBc237D3f5 - Testnet:
0x7C5114ef27a721Df187b32e4eD983BaB813B81Cb
5. Enable email alerts for low VTHO balance 6. Use the generated delegation URL in your provider config
UX and Security Checklist
App-sponsored delegation:
- Always show the user that their transaction is sponsored (no hidden fees)
- Rate-limit sponsorship to prevent abuse
- Whitelist contracts and functions eligible for sponsorship
- Monitor VTHO balance of the gas payer account
- Set reasonable gas limits to prevent griefing
- Log all sponsored transactions for auditing
- Handle delegation service downtime gracefully
Generic Delegator (user-paid):
- Show transaction cost estimate before confirmation (use
useGenericDelegatorFeeEstimation) - Alert users when they have insufficient balance for fees
- Sponsoring transactions via app-sponsored delegation is still recommended to improve UX
Multi-Clause Transactions
When to use
Use when the user asks about:
- Batching multiple operations in one transaction
- Atomic multi-step operations
- Sending to multiple recipients at once
- Combining contract calls with value transfers
- Multi-clause transaction patterns
What are Multi-Clause Transactions?
Multi-clause transactions are a unique VeChainThor feature that allows a single transaction to contain multiple operations (clauses). Each clause has its own recipient, value, and data.
Key Properties
- Atomic execution: All clauses succeed or all fail -- no partial execution
- Sequential processing: Clauses execute in the exact order defined
- Single gas fee: One transaction fee covers all clauses
- Single signature: The sender signs once for all operations
Clause Structure
Each clause contains:
to-- Recipient address (nullfor contract deployment)value-- Amount of VET to transfer (in wei)data-- Input data (for contract calls,'0x'for simple transfers)
Basic Multi-Clause Examples
Multiple VET Transfers
import { Address, Clause, VET, Transaction, HexUInt } from '@vechain/sdk-core';
import { ThorClient } from '@vechain/sdk-network';
const thorClient = ThorClient.at('http://localhost:8669');
const clauses = [
Clause.transferVET(Address.of('0xRecipient1...'), VET.of(100)),
Clause.transferVET(Address.of('0xRecipient2...'), VET.of(200)),
Clause.transferVET(Address.of('0xRecipient3...'), VET.of(300)),
];
const gasResult = await thorClient.gas.estimateGas(clauses, senderAddress);
const bestBlock = await thorClient.blocks.getBestBlockCompressed();
const body = {
chainTag: 0x27, // testnet
blockRef: bestBlock.id.slice(0, 18),
expiration: 32,
clauses,
gasPriceCoef: 0,
gas: gasResult.totalGas,
dependsOn: null,
nonce: Date.now(),
};
const signedTx = Transaction.of(body).sign(privateKey);
const rawTx = HexUInt.of(signedTx.encoded).toString();
const result = await thorClient.transactions.sendRawTransaction(rawTx);Mixed VET and VTHO Transfers
import { Address, Clause, VET, VTHO } from '@vechain/sdk-core';
const clauses = [
// Transfer VET
Clause.transferVET(
Address.of('0xRecipient...'),
VET.of(1000)
),
// Transfer VTHO
Clause.transferVTHOToken(
Address.of('0xRecipient...'),
VTHO.of(500)
),
];Contract Calls with Value Transfer
import { Clause, ABIContract } from '@vechain/sdk-core';
const clauses = [
// First: approve token spending
{
to: tokenContractAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
tokenABI,
'approve',
[spenderAddress, amount]
),
},
// Second: call contract that uses the approved tokens
{
to: dexContractAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
dexABI,
'swap',
[tokenAddress, amount, minOutput]
),
},
];Multi-Clause Reads (Batch Queries)
Read multiple contract values in a single RPC call:
const thorClient = ThorClient.at('https://testnet.vechain.org');
const contract = thorClient.contracts.load(contractAddress, contractABI);
// Batch multiple read operations
const results = await thorClient.contracts.executeMultipleClausesCall([
contract.clause.totalSupply(),
contract.clause.name(),
contract.clause.symbol(),
contract.clause.decimals(),
contract.clause.balanceOf(someAddress),
]);
const [totalSupply, name, symbol, decimals, balance] = results;Frontend Multi-Clause with VeChain Kit (preferred)
Pass an array of clauses to useSendTransaction (see the vechain-kit skill for the full hook API):
const { sendTransaction } = useSendTransaction({
signerAccountAddress: account?.address ?? '',
});
const handleBatch = async () => {
await sendTransaction([
{ to: '0xRecipient1...', value: '0x' + (100e18).toString(16), data: '0x', comment: 'Send 100 VET' },
{ to: contractAddress, value: '0x0', data: encodedFunctionData, comment: 'Contract call', abi: contractFunctionABI },
{ to: '0xRecipient2...', value: '0x' + (50e18).toString(16), data: '0x', comment: 'Send 50 VET' },
]);
};Handles both wallet and social login users automatically. Social login V3 smart accounts use executeBatchWithAuthorization under the hood.
Frontend Multi-Clause with dapp-kit
If using dapp-kit instead of VeChain Kit:
import { useSendTransaction } from '@vechain/dapp-kit-react';
function BatchOperation() {
const { sendTransaction } = useSendTransaction();
const handleBatch = async () => {
const result = await sendTransaction({
clauses: [
{ to: '0xRecipient1...', value: '0x' + (100e18).toString(16), data: '0x' },
{ to: contractAddress, value: '0x0', data: encodedFunctionData },
{ to: '0xRecipient2...', value: '0x' + (50e18).toString(16), data: '0x' },
],
comment: 'Batch: transfer + contract call + transfer',
});
console.log('Transaction ID:', result.id);
};
return <button onClick={handleBatch}>Execute Batch</button>;
}Use Cases
Token Airdrop
const recipients = [
{ address: '0xAddr1...', amount: 100 },
{ address: '0xAddr2...', amount: 200 },
{ address: '0xAddr3...', amount: 150 },
];
const clauses = recipients.map(r => ({
to: tokenContractAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
erc20ABI,
'transfer',
[r.address, ethers.parseEther(r.amount.toString())]
),
}));Approve + Deposit (DeFi Pattern)
const clauses = [
// Step 1: Approve vault to spend tokens
{
to: tokenAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
erc20ABI, 'approve', [vaultAddress, depositAmount]
),
},
// Step 2: Deposit into vault (uses approved tokens)
{
to: vaultAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
vaultABI, 'deposit', [depositAmount]
),
},
];NFT Batch Mint
const tokenURIs = ['ipfs://...1', 'ipfs://...2', 'ipfs://...3'];
const clauses = tokenURIs.map(uri => ({
to: nftContractAddress,
value: '0x0',
data: ABIContract.encodeFunctionInput(
nftABI, 'safeMint', [recipientAddress, uri]
),
}));Contract Deployment + Initialization
const clauses = [
// Deploy contract
Clause.deployContract(contractBytecode),
// Note: You cannot reference the deployed address in subsequent clauses
// because the address is only known after execution.
// For deploy + init, use a factory pattern instead.
];Gas Calculation
Multi-clause transactions follow VeChain's gas formula:
g_total = g_0 + SUM(g_type_i + g_data_i + g_vm_i)Where:
g_0 = 5,000(base transaction gas, paid once)g_type = 16,000per transfer clause;48,000per contract creation clauseg_data= per-clause data costg_vm= per-clause VM execution cost
Estimating Gas
const gasResult = await thorClient.gas.estimateGas(
clauses,
senderAddress,
{ gasPadding: 0.15 } // 15% safety margin
);
console.log('Total gas:', gasResult.totalGas);
console.log('Reverted clauses:', gasResult.revertReasons);Limitations and Gotchas
- No cross-clause references: A clause cannot reference the output (e.g., deployed contract address) of a previous clause
- All-or-nothing: If any clause reverts, the entire transaction reverts
- Gas estimation: Estimate gas for all clauses together, not individually
- Receipt format: The transaction receipt contains an
outputsarray with one entry per clause - Event ordering: Events from clause N appear before events from clause N+1 in the receipt
Receipt Handling
const receipt = await thorClient.transactions.getTransactionReceipt(txId);
// Each clause has its own output in the receipt
for (let i = 0; i < receipt.outputs.length; i++) {
const output = receipt.outputs[i];
console.log(`Clause ${i}:`);
console.log(' Events:', output.events.length);
console.log(' Transfers:', output.transfers.length);
}
// Check if transaction reverted
if (receipt.reverted) {
const reason = await thorClient.transactions.getRevertReason(txId);
console.log('Revert reason:', reason);
}Best Practices
- Use multi-clause for logically related operations that should be atomic
- Estimate gas for the complete clause set, not individual clauses
- Keep clause count reasonable (excessive clauses increase gas cost)
- Combine with fee delegation for the best user experience
- Use multi-clause reads for efficient batch data fetching
- Handle the all-or-nothing nature in UI (inform users all operations are atomic)
Curated Resources (Source-of-Truth First)
MCP Server (Live AI-Powered Docs + Blockchain Data)
The VeChain MCP server gives Claude Code direct access to VeChain documentation search, blockchain queries, token data, VeBetterDAO stats, and StarGate staking info -- all without leaving the editor.
Setup (Claude Code)
Add to ~/.claude/mcp.json:
{
"mcpServers": {
"vechain": {
"command": "npx",
"args": ["-y", "@vechain/mcp-server@latest"],
"env": {
"VECHAIN_NETWORK": "mainnet"
}
}
}
}Set VECHAIN_NETWORK to mainnet, testnet, or solo. Restart Claude Code after adding.
Available Tools (26)
| Category | Tools |
|---|---|
| Docs search | searchDocsVechain, searchDocsVechainKit, searchDocsVebetterDao, searchDocsVevote, searchDocsStargate |
| Blockchain | thorGetBlock, thorGetTransaction, thorGetAccount, thorDecodeEvent |
| Tokens/NFTs | getTokenBalances, getTokenFiatPrice, getTokenRegistry, getNFTs, getNFTContracts |
| VeBetterDAO | getB3TRGlobalOverview, getB3TRAppsLeaderboard, getB3TRProposalsResults, getB3TRProposalComments, getCurrentRound, getGMNFTStatus |
| Staking | getStargateTotalVetStaked, getStargateTokenRewards, getValidators |
| History | getTransactions, getTransfersOfAccount, getHistoryOfAccount |
Kapa.ai Docs MCP (alternative, docs-only)
For docs-only queries via Kapa.ai's hosted infrastructure:
claude mcp add --transport http vechain-docs https://vechain.mcp.kapa.ai---
Core VeChain Documentation
- VeChain Documentation (Core concepts, SDKs, tutorials)
- VeChain Whitepaper
- VeChainThor Transaction Model
- Dual-Token Economic Model
VeChain Kit (preferred for React/Next.js dApps)
- VeChain Kit Documentation
- Should I Use It? (decision framework)
- Installation
- Provider Configuration
- Send Transactions
- Hooks Reference
- Components Reference
- Social Login / Privy Setup
- Smart Accounts
- Fee Delegation Setup
- Theming
- @vechain/vechain-kit npm
VeChain Kit Docs MCP Server
The VeChain Kit documentation site exposes a GitBook-powered MCP server for AI tools. It provides read-only search and retrieval of the latest published docs — useful for looking up hooks, components, configuration, and social login details directly from your AI editor.
Endpoint: https://docs.vechainkit.vechain.org/~gitbook/mcp
Transport: HTTP only (no stdio or SSE).
Claude Code setup:
claude mcp add --transport http vechain-kit-docs https://docs.vechainkit.vechain.org/~gitbook/mcpCursor / VS Code (`mcp.json`):
{
"servers": {
"vechain-kit-docs": {
"url": "https://docs.vechainkit.vechain.org/~gitbook/mcp"
}
}
}This complements the @vechain/mcp-server (which provides blockchain data + multi-site docs search) with direct, always-up-to-date access to the VeChain Kit documentation specifically.
Smart Accounts (Account Abstraction)
- Smart Accounts GitHub (official SimpleAccount + SimpleAccountFactory)
- Smart Accounts Documentation
- DIY Social Login Tutorial (dapp-kit + Privy) (complex, VeChain Kit recommended instead)
- DIY Tutorial Example Repo
Scaffolding
- create-vechain-dapp (
npx create-vechain-dapp@latest) - create-vechain-dapp GitHub (templates: X2Earn, Simple Dapp, Buy Me Coffee, Smart Contract)
VeChain SDK
- VeChain SDK GitHub
- @vechain/sdk-core npm (offline: transactions, signing, encoding)
- @vechain/sdk-network npm (network: ThorClient, providers, contracts)
- @vechain/sdk-errors npm
- @vechain/vechain-contract-types npm (pre-built TypeChain types for VeChain ecosystem contracts)
- @vechain/contract-getters npm (framework-agnostic read-only getters: balances, VNS, avatars, smart accounts)
- SDK Accounts Guide
- SDK Transactions Guide
- SDK Contracts Guide
- SDK ThorClient Guide
DApp Kit (lightweight alternative)
Wallets
- VeWorld Wallet (official wallet -- browser extension + mobile)
- VeWorld Documentation
Smart Contract Development
Hardhat Integration
OpenZeppelin
- OpenZeppelin Contracts
- OpenZeppelin Upgradeable Contracts
- OpenZeppelin Wizard (contract generator)
Solidity
Local Development
VeChain-Specific Features
Fee Delegation
Multi-Clause Transactions
Token Standards
- VIP-180 (Fungible Token) (ERC-20 compatible, superseded by standard ERC-20)
- VIP-181 (Non-Fungible Token) (ERC-721 compatible, superseded by standard ERC-721)
VET Domains
- VET Domains (.vet domain name service)
Ethers.js Compatibility
Testing
Security
- Solidity Security Considerations
- OpenZeppelin Security
- SWC Registry (Smart Contract Weakness Classification)
- Slither (Static Analyzer)
VeBetterDAO (X2Earn Sustainability Apps)
- VeBetterDAO Documentation
- Developer Guide: Get Started
- Reward Distribution
- Sustainability Proofs & Impacts
- Submit Your App
- Test Environment
- X-App-Template (GitHub)
- VeBetterDAO Contracts (GitHub)
- Smart Contract Addresses
StarGate (NFT-Based Staking)
- StarGate Documentation
- Staking Lifecycle
- NFT Tiers
- Rewards Structure
- Validators
- Developer API
- Contracts
- StarGate Contracts (GitHub)
- StarGate dApp
Governance (VeVote)
- VeVote Documentation
- VeVote Platform
- VeVote Monorepo (GitHub)
- VeVote Contracts (GitHub)
- VeChain Governance Overview
VeChain Ecosystem
- VeChain Official Website
- VeChain GitHub Organization
- VeChain Improvement Proposals (VIPs)
- VeChain Explorer (Mainnet)
- VeChain Explorer (Testnet)
Network Endpoints
- Mainnet:
https://mainnet.vechain.org - Testnet:
https://testnet.vechain.org - Thor Solo (local):
http://localhost:8669
Thor REST API (direct HTTP, no SDK needed)
For lightweight reads without the SDK (e.g., serverless functions, scripts):
# VET balance
GET /accounts/{address}
# → { "balance": "0x...", "energy": "0x...", "hasCode": false }
# Token balance (balanceOf via simulated call)
POST /accounts/*
{
"clauses": [{ "to": "0xTokenAddress", "value": "0", "data": "0x70a08231000000000000000000000000{address}" }]
}
# → { "results": [{ "data": "0x...", "gasUsed": ... }] }Common mistake: Do NOT POST /accounts/{tokenAddress} — token reads use POST /accounts/* with clauses.
Token Registry
Public JSON registry of VeChain tokens with metadata and icons:
- Mainnet:
https://vechain.github.io/token-registry/main.json - Testnet:
https://vechain.github.io/token-registry/test.json - Icon URL:
https://vechain.github.io/token-registry/assets/{icon}(whereiconis the hash filename from the JSON)
VET Domain Resolution
For .vet domain lookups outside of React (in React, use VeChain Kit's useVechainDomain hook instead):
- Public API:
https://vet.domains/api/lookup/name/{domain}→{ "addresses": [{ "address": "0x..." }] }
App-Hub Submission
To list your dApp in the VeChain ecosystem directory:
1. Fork vechain/app-hub 2. Create apps/{reversed-domain}/ (e.g., apps/org.myapp/) 3. Add manifest.json + logo.png (512x512) 4. PR to the master branch
Connex / Thor DevKit -> SDK Migration
When to use
Use when the user has Connex, thor-devkit, web3-providers-connex, or @vechain/hardhat-vechain in their project, or asks about migrating from deprecated VeChain packages.
The rule
- New code:
@vechain/sdk-core+@vechain/sdk-networktypes and APIs. - Legacy dependencies: isolate Connex/Thor DevKit usage behind an adapter boundary.
Background
As of December 31, 2024, VeChain deprecated all legacy developer tools in favor of the unified SDK:
| Deprecated Package | Replacement |
|---|---|
@vechain/connex | @vechain/sdk-network (ThorClient) |
thor-devkit | @vechain/sdk-core |
@vechain/hardhat-vechain | @vechain/sdk-hardhat-plugin |
web3-providers-connex | @vechain/sdk-ethers-adapter |
Preferred migration: direct SDK usage
Use @vechain/sdk-core and @vechain/sdk-network directly:
Transaction building (was thor-devkit)
// OLD (thor-devkit)
import { Transaction, secp256k1 } from 'thor-devkit';
const tx = new Transaction({ chainTag: 0x27, ... });
// NEW (@vechain/sdk-core)
import { Transaction, Clause, Address, VET } from '@vechain/sdk-core';
const clauses = [Clause.transferVET(Address.of('0x...'), VET.of(100))];
const signedTx = Transaction.of({ chainTag: 0x27, clauses, ... }).sign(privateKey);Network interaction (was Connex)
// OLD (Connex)
const connex = new Connex({ node: 'https://testnet.vechain.org', network: 'test' });
const account = await connex.thor.account('0x...').get();
// NEW (@vechain/sdk-network)
import { ThorClient } from '@vechain/sdk-network';
const thorClient = ThorClient.at('https://testnet.vechain.org');
const account = await thorClient.accounts.getAccount('0x...');Contract interaction (was Connex.Thor)
// OLD (Connex)
const method = connex.thor.account(contractAddr).method(abiItem);
const result = await method.call(arg1, arg2);
// NEW (@vechain/sdk-network)
const contract = thorClient.contracts.load(contractAddr, abi);
const result = await contract.read.methodName(arg1, arg2);Signing transactions (was Connex.Vendor)
// OLD (Connex)
const result = await connex.vendor.sign('tx', [clause]).request();
// NEW (with dapp-kit v2 - for frontend)
import { useThor } from '@vechain/dapp-kit-react';
const thor = useThor();
// Use thor for contract reads; use useSendTransaction for writes
// NEW (with SDK - for backend/scripts)
const signedTx = Transaction.of(body).sign(privateKey);
const result = await thorClient.transactions.sendRawTransaction(
HexUInt.of(signedTx.encoded).toString()
);Practical boundary layout (when legacy code exists)
Keep these modules separate:
src/vechain/sdk/:- all SDK-first code: ThorClient, Clause builders, contract interaction, typed transactions
src/vechain/legacy/:- adapters for legacy Connex-based libraries
- conversions between Connex types and SDK types
- only at edges where migration is not yet complete
ethers.js adapter
For projects using ethers.js patterns, use @vechain/sdk-ethers-adapter:
import { VeChainProvider } from '@vechain/sdk-ethers-adapter';
// Creates an ethers-compatible provider backed by VeChainThor
const provider = new VeChainProvider(thorClient);Common mistakes to prevent
- Using
useConnexanywhere (deprecated in both VeChain Kit and dapp-kit v2; useuseThorinstead) - Mixing Connex
thorand SDKThorClientin the same module (causes confusion) - Using deprecated
thor-devkitfor new transaction construction (use@vechain/sdk-core) - Importing
web3-providers-connexwhen@vechain/sdk-ethers-adapterexists - Not updating Hardhat plugin (old
@vechain/hardhat-vechainvs new@vechain/sdk-hardhat-plugin)
Decision checklist
If you're about to add a legacy VeChain dependency: 1) Is there an SDK-native equivalent? Prefer SDK. 2) Is the only reason a legacy library? Isolate it at the boundary. 3) Can you use @vechain/sdk-ethers-adapter instead of web3-providers-connex? Prefer the adapter.