Overview

The TrustVault contract manages WLABS staking against AI agent IDs to establish economic trust guarantees. Agents earn higher trust tiers by staking more WLABS, which unlocks benefits like higher API rate limits and membership in more organizations. The contract implements a 5-minute cooldown period for unstaking and automatically unwraps WLABS to native LABS on withdrawal.

**Note: Deployed Address: 0xD4bAE271bCCb8bA7BF13B0B4743d62E61CCF9E0e

**Warning: Important: You must wrap native LABS to WLABS before staking. Use the WLABS contract to convert. You must also approve the TrustVault to spend your WLABS tokens before calling stake().

Trust Tiers

The TrustVault uses deterministic tier thresholds based on staked amounts:

TierNameThresholdBenefits
0Unverified0 LABSAPI blocked, cannot join organizations
1Bronze1,000 LABS1 req/min API rate limit, join 1 organization
2Silver10,000 LABS16 req/min, join 3 organizations
3Gold100,000 LABS166 req/min, join 5 organizations
4Diamond500,000 LABS2700 req/min, join 10 organizations

Constants

ConstantValueDescription
COOLDOWN_PERIOD5 minutesDelay between unstaking and withdrawal
TIER_1_THRESHOLD1,000 LABSBronze tier minimum
TIER_2_THRESHOLD10,000 LABSSilver tier minimum
TIER_3_THRESHOLD100,000 LABSGold tier minimum
TIER_4_THRESHOLD500,000 LABSDiamond tier minimum

Functions

FunctionParametersReturnsDescription
stakeuint256 agentId, uint256 amount-Stake WLABS tokens against an agent (requires prior approval)
unstakeuint256 agentId, uint256 amount-Begin unstaking process (moves tokens to cooldown)
withdrawuint256 agentId-Withdraw tokens after cooldown expires (auto-unwraps to native LABS)
getTrustTieruint256 agentIduint8 tierGet the current trust tier (0-4) based on staked amount
getStakeuint256 agentIduint256 amount, uint256 cooldownAmount, uint256 cooldownEndTimeGet stake information including active and cooldown amounts

Events

EventParametersDescription
Stakeduint256 indexed agentId, uint256 amount, address indexed stakerEmitted when WLABS are staked
Unstakeduint256 indexed agentId, uint256 amount, uint256 cooldownEndTimeEmitted when unstaking begins (cooldown starts)
Withdrawnuint256 indexed agentId, uint256 amount, address indexed recipientEmitted when tokens are withdrawn after cooldown

Usage Example

Stake WLABS and manage trust tier
import { createPublicClient, createWalletClient, http, parseAbi, parseEther } from 'viem';
import { kyaChain } from './chains';

const publicClient = createPublicClient({
  chain: kyaChain,
  transport: http('https://rpc.kyachain.xyz'),
});

const walletClient = createWalletClient({
  chain: kyaChain,
  transport: http('https://rpc.kyachain.xyz'),
});

const TRUST_VAULT = '0xD4bAE271bCCb8bA7BF13B0B4743d62E61CCF9E0e';
const WLABS = '0xEd863CAd86f69D8821f678784c5a47d21626BBF7';
const agentId = 42n;

// Step 1: Approve TrustVault to spend WLABS
const { request: approveReq } = await publicClient.simulateContract({
  address: WLABS,
  abi: parseAbi(['function approve(address guy, uint256 wad) external returns (bool)']),
  functionName: 'approve',
  args: [TRUST_VAULT, parseEther('10000')], // Approve 10,000 WLABS
  account: '0xYourAddress',
});

const approveHash = await walletClient.writeContract(approveReq);
await publicClient.waitForTransactionReceipt({ hash: approveHash });

// Step 2: Stake WLABS to reach Silver tier (10,000 LABS)
const { request: stakeReq } = await publicClient.simulateContract({
  address: TRUST_VAULT,
  abi: parseAbi(['function stake(uint256 agentId, uint256 amount) external']),
  functionName: 'stake',
  args: [agentId, parseEther('10000')],
  account: '0xYourAddress',
});

const stakeHash = await walletClient.writeContract(stakeReq);
await publicClient.waitForTransactionReceipt({ hash: stakeHash });

// Read trust tier
const tier = await publicClient.readContract({
  address: TRUST_VAULT,
  abi: parseAbi(['function getTrustTier(uint256 agentId) external view returns (uint8)']),
  functionName: 'getTrustTier',
  args: [agentId],
});

console.log('Trust tier:', tier); // 2 (Silver)

// Read stake details
const [amount, cooldownAmount, cooldownEndTime] = await publicClient.readContract({
  address: TRUST_VAULT,
  abi: parseAbi([
    'function getStake(uint256 agentId) external view returns (uint256, uint256, uint256)',
  ]),
  functionName: 'getStake',
  args: [agentId],
});

console.log('Active stake:', amount);
console.log('Cooldown amount:', cooldownAmount);

// Begin unstaking (starts 5-minute cooldown)
const { request: unstakeReq } = await publicClient.simulateContract({
  address: TRUST_VAULT,
  abi: parseAbi(['function unstake(uint256 agentId, uint256 amount) external']),
  functionName: 'unstake',
  args: [agentId, parseEther('5000')], // Unstake 5,000 LABS
  account: '0xYourAddress',
});

const unstakeHash = await walletClient.writeContract(unstakeReq);

// After cooldown expires, withdraw (receives native LABS)
const { request: withdrawReq } = await publicClient.simulateContract({
  address: TRUST_VAULT,
  abi: parseAbi(['function withdraw(uint256 agentId) external']),
  functionName: 'withdraw',
  args: [agentId],
  account: '0xYourAddress',
});

const withdrawHash = await walletClient.writeContract(withdrawReq);

ABI

[
  "function stake(uint256 agentId, uint256 amount) external",
  "function unstake(uint256 agentId, uint256 amount) external",
  "function withdraw(uint256 agentId) external",
  "function getTrustTier(uint256 agentId) external view returns (uint8 tier)",
  "function getStake(uint256 agentId) external view returns (uint256 amount, uint256 cooldownAmount, uint256 cooldownEndTime)",
  "event Staked(uint256 indexed agentId, uint256 amount, address indexed staker)",
  "event Unstaked(uint256 indexed agentId, uint256 amount, uint256 cooldownEndTime)",
  "event Withdrawn(uint256 indexed agentId, uint256 amount, address indexed recipient)"
]

On this page