On-chain products

Compose public infrastructure with explicit authority.

VowLabs contracts separate naming, governance, authority, verification, settlement, issuance, pricing, and cross-system evidence. Select a contract for its focused guide; use this page for the conventions they share.

One contract for each activity.

Each page documents its specific integration surface, authority requirements, and Node.js usage. Deployed addresses always come from your selected network’s manifest or registry.

08

VLStaking

One-way stablecoin reserves and notarized Ramp issuance.

Stablecoin → RampRead the guide →
10

VLBurn

Managed-token destruction and notifications.

Assets → burn eventsRead the guide →
12

VLMint

Canonical multi-token balances and ERC-777 wrappers.

Evidence → balancesRead the guide →

Use a provider for reads and a signer for writes.

Examples use ethers v6 and only the ABI fragments they call. Resolve the deployed address from the manifest or registry for the target chain; state-changing calls must be signed by the authority each contract specifies.

import { Contract, JsonRpcProvider, Wallet } from "ethers";

const provider = new JsonRpcProvider(process.env.RPC_URL);
const signer = new Wallet(process.env.SIGNER_PRIVATE_KEY, provider);
const at = (address, abi, writable = false) =>
  new Contract(address, abi, writable ? signer : provider);

Know which key is allowed to act.

Public callers

Reads, registration where permitted, swaps, and governance voting are available to ordinary accounts under each contract’s conditions.

Governance

VLVoting controls upgrades and protocol configuration through executed proposals. Do not invoke voting-only methods directly from an EOA.

Service roles

Relays, verifiers, issuers, and distribution wallets have narrow permissions. One service role should not confer unrelated authority.

Resolve, verify, then transact.

Never copy an address from an example or a different network. Confirm chain ID, contract address, code, and the required role before sending a write. Treat event payloads as input to validate, not as authorization by themselves.

const network = await provider.getNetwork();
if (network.chainId !== EXPECTED_CHAIN_ID) throw new Error("wrong network");

const code = await provider.getCode(CONTRACT_ADDRESS);
if (code === "0x") throw new Error("no contract at configured address");

const registry = at(REGISTRY, ["function resolveName(string) view returns ((string,bytes32,address,uint256,address,bool,uint256))"]);
const record = await registry.resolveName("priceedge.me");
console.log(record.account);