ve-sdk-v2
v0.0.3
Published
TypeScript SDK for interacting with the VeMMT
Downloads
208
Readme
ve-sdk-v2
TypeScript SDK for interacting with the VeMMT
Installation
bun add ve-sdk-v2
# or
npm install ve-sdk-v2Quick Start
import { SuiJsonRpcClient } from "@mysten/sui/jsonRpc";
import { VeMMTSDK } from "ve-sdk-v2";
const client = new SuiJsonRpcClient({
url: "https://fullnode.testnet.sui.io:443",
});
const sdk = new VeMMTSDK({
client,
veMmtObjectId: "0x<VeMMT shared object ID>",
versionObjectId: "0x<Version shared object ID>",
// clockObjectId defaults to "0x6"
});Configuration
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| client | SuiJsonRpcClient | ✅ | — | Sui JSON RPC client |
| veMmtObjectId | string | ✅ | — | VeMMT shared object ID on-chain |
| versionObjectId | string | ✅ | — | Version shared object ID (required for sync operations) |
| clockObjectId | string | — | "0x6" | Sui Clock shared object ID |
Modules
sdk.bond — Bond Operations
All build* methods return a Transaction that can be signed and submitted by the user's wallet.
// Create a Normal bond VotingEscrow (lock MMT until unbondAt)
const tx = sdk.bond.buildCreateBond({
mmtCoinId: "0x<coin object ID>",
amount: 1_000_000_000n, // in MIST
unbondAt: 1_800_000_000_000n, // epoch-aligned timestamp (ms)
recipient: "0x<user address>",
});
// Create a Max bond VotingEscrow
const tx = sdk.bond.buildCreateMaxBond({
mmtCoinId: "0x<coin object ID>",
amount: 1_000_000_000n,
recipient: "0x<user address>",
});
// Add MMT balance to an existing VotingEscrow
const tx = sdk.bond.buildAddBalance({
veId: "0x<VotingEscrow object ID>",
mmtCoinId: "0x<coin object ID>",
amount: 500_000_000n,
});
// Extend unlock time (Normal bond only)
const tx = sdk.bond.buildExtend({
veId: "0x<VotingEscrow object ID>",
unbondAt: 1_900_000_000_000n,
});
// Switch from Normal bond to Max bond
const tx = sdk.bond.buildSetMaxBond({ veId: "0x..." });
// Switch from Max bond back to Normal bond
const tx = sdk.bond.buildSetNormal({ veId: "0x..." });
// Merge two VotingEscrows (mergedVeId is consumed)
const tx = sdk.bond.buildMerge({
primaryVeId: "0x...",
mergedVeId: "0x...",
});
// Split a VotingEscrow into two
const tx = sdk.bond.buildSplit({
veId: "0x...",
splitAmount: 300_000_000n,
recipient: "0x<user address>",
});
// Unbond (Normal bond only, after unbond_at has passed)
const tx = sdk.bond.buildUnbond({
veId: "0x...",
recipient: "0x<user address>",
});sdk.vote — Vote Operations
// Distribute vote power across multiple gauges
const tx = sdk.vote.buildAddVotesBatch({
veId: "0x...",
gaugeIds: ["0x<gauge1>", "0x<gauge2>"],
powerAmounts: [600_000n, 400_000n], // must sum <= ve.vote_power
});sdk.claim — Claim Operations
After an epoch ends and sync.buildSyncGauge has been called, users can claim rewards. After claiming all fees and incentives for an epoch, buildRemoveUnclaimedHistory must be called.
// Claim protocol fee rewards for a past epoch
const tx = sdk.claim.buildClaimFeesForEpoch({
veId: "0x...",
claimEpoch: 42n,
gaugeId: "0x...",
coinXType: "0x2::sui::SUI",
coinYType: "0xabc::usdc::USDC",
recipient: "0x<user address>",
});
// Claim incentive (bribe) rewards for a past epoch
const tx = sdk.claim.buildClaimIncentiveForEpoch({
veId: "0x...",
gaugeId: "0x...",
claimEpoch: 42n,
coinType: "0xabc::token::TOKEN",
recipient: "0x<user address>",
});
// Mark an epoch's rewards as fully claimed (required after all claims)
const tx = sdk.claim.buildRemoveUnclaimedHistory({
veId: "0x...",
epoch: 42n,
});sdk.gaugeIncentive — Gauge Incentive Operations
// Add an incentive (bribe) to a gauge for the current epoch
const tx = sdk.gaugeIncentive.buildAddIncentive({
gaugeId: "0x...",
incentiveCoinId: "0x<coin object ID>",
amount: 1_000_000_000n,
coinType: "0xabc::token::TOKEN",
});sdk.sync — Sync Operations
Must be called (by users or a cron job) after each epoch ends to settle protocol fees before users can claim.
const tx = sdk.sync.buildSyncGauge({
gaugeId: "0x...",
poolId: "0x<CLMM Pool object ID>",
coinXType: "0x2::sui::SUI",
coinYType: "0xabc::usdc::USDC",
});sdk.view — Read-only Queries
These methods call devInspect under the hood and return decoded on-chain data.
// Get current epoch timing info
const epochInfo = await sdk.view.getCurrentEpochInfo();
// Get all gauges (paginated)
const { data, total_count, has_next_page } = await sdk.view.getGauges(0n, 20n);
// Get a single gauge
const gauge = await sdk.view.getGauge("0x<gauge ID>");
// Get a VotingEscrow's full data (balance, votes, unclaimed epochs)
const veData = await sdk.view.getVotingEscrow("0x<VotingEscrow ID>");
// Preview balance and vote_power after adding more MMT
const preview = await sdk.view.previewBalanceChange("0x<VotingEscrow ID>", 500_000_000n);
// Get all unclaimed reward records for a VotingEscrow
const unclaimedData = await sdk.view.getAllUserEpochData("0x<VotingEscrow ID>");
// Get reward data for a specific epoch and gauge
const epochData = await sdk.view.getUserEpochData("0x<VotingEscrow ID>", "0x<gauge ID>", 42n);
// Get aggregated rewards across all active gauges
const globalsRewards = await sdk.view.getGaugeGlobalsRewards();
// Convert a timestamp to its epoch-start timestamp
const epochStart = await sdk.view.getTsEpochStart(Date.now());Transaction Composability
All build* methods accept an optional tx parameter, allowing multiple operations to be composed into a single PTB (Programmable Transaction Block):
import { Transaction } from "@mysten/sui/transactions";
const tx = new Transaction();
// Compose multiple operations in one transaction
sdk.bond.buildAddBalance({ tx, veId: "0x...", mmtCoinId: "0x...", amount: 100n });
sdk.vote.buildAddVotesBatch({ tx, veId: "0x...", gaugeIds: ["0x..."], powerAmounts: [100n] });
// Sign and submit once
await wallet.signAndExecuteTransaction({ transaction: tx });Development
# Install dependencies
bun install
# Type check
bun run typecheck
# Build (outputs to dist/)
bun run build
# Clean build artifacts
bun run clean
# Regenerate on-chain type definitions (testnet)
bun run generate-move-types-testnetRegenerating On-chain Types
When the VeMMT contract is upgraded, regenerate the TypeScript type bindings:
bun run generate-move-types-testnetThis fetches the latest ABI from testnet and updates the files in src/types/testnet/.
Constants
import { VE_MMT_PACKAGE_ID, MMT_COIN_TYPE, BOND_MODE } from "ve-sdk-v2";
// MMT full coin type string
console.log(MMT_COIN_TYPE);
// "0x780070d00abc2dbab4ee58e0207391aa7be0bdb19d4db4d94d9c8bc709ee4142::mmt::MMT"
// Bond mode values
BOND_MODE.NORMAL // 0
BOND_MODE.MAX // 1