@skynetxbt/venice-ai-plugin
Version:
Venice AI Plugin for Skynet Framework - Staking Contract Integration
298 lines (297 loc) • 10.9 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VenicePlugin = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
const core_1 = require("@skynetxbt/core");
const events_1 = require("events");
const ethers_1 = require("ethers");
const StakingContract_1 = require("./StakingContract");
const VeniceToken_1 = require("./VeniceToken");
const constants_1 = require("./constants");
const axios_1 = __importDefault(require("axios"));
class VenicePlugin extends events_1.EventEmitter {
constructor(config = {}) {
super();
this.config = config;
this.name = "venice-plugin";
this.description = "Interactive plugin for Venice AI staking";
this.provider = null;
this.signer = null;
this.apiClient = null;
const stakingConfig = {
contractAddress: config.stakingContractAddress,
privateKey: config.privateKey,
rpcUrl: config.rpcUrl
};
this.stakingContract = new StakingContract_1.StakingContract(stakingConfig);
this.veniceToken = new VeniceToken_1.VeniceToken(config.veniceTokenAddress);
if (config.veniceApiKey && config.veniceBaseUrl) {
this.apiClient = axios_1.default.create({
baseURL: config.veniceBaseUrl,
headers: {
'Authorization': `Bearer ${config.veniceApiKey}`,
'Content-Type': 'application/json'
}
});
}
}
async initialize() {
try {
if (!this.config.rpcUrl) {
throw new Error("RPC URL is required");
}
const provider = new ethers_1.ethers.JsonRpcProvider(this.config.rpcUrl);
let signer;
if (this.config.privateKey) {
signer = new ethers_1.ethers.Wallet(this.config.privateKey, provider);
}
core_1.log.info("Initializing with config:", {
rpcUrl: this.config.rpcUrl,
stakingContractAddress: this.config.stakingContractAddress || constants_1.STAKING_CONTRACT_ADDRESS,
hasSigner: !!signer
});
await this.stakingContract.initialize(provider, signer);
await this.veniceToken.initialize(provider, signer);
this.provider = provider;
this.signer = signer || null;
this.emit("initialized");
}
catch (error) {
throw new Error(`Failed to initialize plugin: ${error instanceof Error ? error.message : String(error)}`);
}
}
async cleanup() {
await this.stakingContract.cleanup();
await this.veniceToken.cleanup();
this.provider = null;
this.signer = null;
this.emit("cleanup");
}
async getVCUsBalance(vvvBalance) {
return (Number(vvvBalance) * 0.212).toString();
}
async getModelInfo(modelId) {
const veniceModel = await axios_1.default.get(`https://api.venice.xyz/models/${modelId}`);
return JSON.stringify(veniceModel.data);
}
async getTokenBalance(address) {
try {
const result = await this.veniceToken.getBalance(address);
if (result.success && result.data) {
return {
success: true,
data: {
raw: result.data,
formatted: ethers_1.ethers.formatUnits(result.data, 18)
}
};
}
return result;
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
/**
* Check allowance for staking contract
*/
async checkAllowance(ownerAddress) {
try {
const result = await this.veniceToken.getAllowance(ownerAddress, this.config.stakingContractAddress || constants_1.STAKING_CONTRACT_ADDRESS);
if (result.success && result.data) {
return {
success: true,
data: {
raw: result.data,
formatted: ethers_1.ethers.formatUnits(result.data, 18)
}
};
}
return result;
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
/**
* Approve staking contract to spend tokens
*/
async approveStaking(amount) {
try {
const amountBigInt = ethers_1.ethers.parseUnits(amount, 18);
return await this.veniceToken.approve(this.config.stakingContractAddress || constants_1.STAKING_CONTRACT_ADDRESS, amountBigInt);
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
// Staking operations
async stake(recipient, amount) {
try {
const amountBigInt = ethers_1.ethers.parseUnits(amount, 18);
return await this.stakingContract.stake(recipient, amountBigInt);
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async initiateUnstake(amount) {
try {
const amountBigInt = ethers_1.ethers.parseUnits(amount, 18);
return await this.stakingContract.initiateUnstake(amountBigInt);
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async finalizeUnstake() {
return await this.stakingContract.finalizeUnstake();
}
async claim() {
return await this.stakingContract.claim();
}
// View functions
async getPendingRewards(userAddress) {
try {
const result = await this.stakingContract.getPendingRewards(userAddress);
if (result.success && result.data) {
return {
success: true,
data: ethers_1.ethers.formatUnits(result.data, 18)
};
}
return {
success: false,
error: result.error
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async getVenicePercentage() {
try {
const result = await this.stakingContract.getVenicePercentage();
if (result.success && result.data) {
return {
success: true,
data: ethers_1.ethers.formatUnits(result.data, 18)
};
}
return {
success: false,
error: result.error
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async getUserStakeInfo(userAddress) {
try {
const result = await this.stakingContract.getUserStakeInfo(userAddress);
if (result.success && result.data) {
const { stakeAmount, pendingRewards, stakeInfo } = result.data;
return {
success: true,
data: {
stakeAmount: ethers_1.ethers.formatUnits(stakeAmount, 18),
pendingRewards: ethers_1.ethers.formatUnits(pendingRewards, 18),
stakeInfo: {
rewardDebt: ethers_1.ethers.formatUnits(stakeInfo.rewardDebt, 18),
cooldownEnd: stakeInfo.cooldownEnd.toString(),
cooldownAmount: ethers_1.ethers.formatUnits(stakeInfo.cooldownAmount, 18)
}
}
};
}
return {
success: false,
error: result.error
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async getStakingStats() {
try {
const result = await this.stakingContract.getStakingStats();
if (result.success && result.data) {
const { totalStaked, emissionRate, cooldownDuration, venicePercentage, accRewardPerShare, lastRewardTimestamp } = result.data;
return {
success: true,
data: {
totalStaked: ethers_1.ethers.formatUnits(totalStaked, 18),
emissionRate: ethers_1.ethers.formatUnits(emissionRate, 18),
cooldownDuration: cooldownDuration.toString(),
venicePercentage: ethers_1.ethers.formatUnits(venicePercentage, 18),
accRewardPerShare: ethers_1.ethers.formatUnits(accRewardPerShare, 36), // ACC_REWARD_SCALE is 1e36
lastRewardTimestamp: lastRewardTimestamp.toString()
}
};
}
return {
success: false,
error: result.error
};
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : String(error)
};
}
}
async getRateLimits() {
if (!this.apiClient) {
throw new Error("Venice API client not initialized. Please provide API key and base URL.");
}
try {
const response = await this.apiClient.get('/api/v1/api_keys/rate_limits');
return response.data;
}
catch (error) {
core_1.log.error(`Failed to fetch rate limits: ${error}`);
return null;
}
}
async getModelRateLimits(modelId) {
const rateLimits = await this.getRateLimits();
if (!rateLimits)
return null;
return rateLimits.data.rateLimits.find(limit => limit.apiModelId === modelId) || null;
}
async getVeniceBalances() {
const rateLimits = await this.getRateLimits();
return rateLimits?.data.balances || null;
}
}
exports.VenicePlugin = VenicePlugin;