Skynet
Visit SkynetBlogUse-casesDiscord
  • Getting Started
    • Introduction to Skynet
    • Why Skynet?
    • Features
      • Skynet Intelligence
      • Skynet Orchestration
      • Data Security
      • Memory
      • Skynet Chain
      • Payments
      • AI Tools
    • Skynet Interoperability
  • Agent Studio
    • Studio Overview
    • Dashboard
    • Workflow
  • Skynet Ecosystem
  • Skynet Protocol
    • SkyIDs
    • Role Based Access Control (RBAC)
    • Organizational Services
    • Add AI Agent tools
    • Payment Rails
      • Fiat/Crypto On-ramp
      • Settlement With Tooling Providers
      • Subscriptions vs on-demand Pay-per-second
      • How AI Agents Spend
    • Subnet
      • Types of Subnet
      • Subnet fault-tolerance and security
      • Provider Subnet
      • Provider Subnet functions
      • Tool fees
    • Smart Access Points
  • FAQ
  • Tutorials
  • Concepts
    • Glossary
  • Technical Support
  • Build your Project on Skynet
    • Interact with AI service to create an Agent
      • Prerequisites
      • SDK Initialization
      • Adding Balance to a Subnet
        • Best Practices
        • Common Errors and Solutions
      • Authentication
      • userAuthPayload
      • Service Endpoints
    • Integrate AI agent tools
      • Installation
      • Configuration
      • Initialization and Setup
      • Core Functions
      • Endpoint Summary
  • Developer Portal
Powered by GitBook
On this page
  • Required Imports
  • Subnet Balance Interface
  • Helper Functions
  • Getting Subnet Balance
  • Adding Balance to a Subnet
  • Example Usage
  • Adding Balance Before Deployment
  1. Build your Project on Skynet
  2. Interact with AI service to create an Agent

Adding Balance to a Subnet

This section guides you on how to add balance to subnets in the Workflow Agent Studio.

Required Imports

import SkyMainBrowser from "@decloudlabs/skynet/lib/services/SkyMainBrowser";
import { ethers } from "ethers";
import { SETTLER_CALLTYPE } from "path/to/utils/skynetHelper"; // Import from your project's utils

Subnet Balance Interface

export interface SubnetBalance {
  subnetId: string;
  subnetName: string;
  balance: number; // Balance in USD
  hasBalance: boolean;
}

Helper Functions

Convert Ether to Wei

export const etherToWei = (ether: number, decimal: number): number => {
  if (decimal === 6) {
    return (Math.floor(ether * 1e6));
  }
  return (Math.floor(ether * 1e18));
};

Convert Big Intergers to Bytes

export const bigIntToBytes = (value: string, length: number): string => {
  // Simple implementation that pads the string representation with zeros
  const hex = Number(value).toString(16);
  return "0".repeat(length * 2 - hex.length) + hex;
};

Getting Subnet Balance

To check the current balance of a subnet, use this:

export const getSubnetBalance = async (
  skyBrowser: SkyMainBrowser | null,
  nftId: string,
  subnetId: string,
  itemID?: string
): Promise<string | undefined> => {
  if (!skyBrowser) return undefined;
  
  try {
    const accountNFT = {
      nftID: nftId,
      collectionID: "0"
    };

    const balanceResponse = await skyBrowser.dripRateManager.getAccountBalance(accountNFT, subnetId);
    
    if (balanceResponse && balanceResponse.success && balanceResponse.data) {
      // Convert from wei to ether
      const formattedBalance = ethers.formatUnits(balanceResponse.data, 18);
      return formattedBalance;
    }
    
    return "0"; // Return zero if no balance found
  } catch (error) {
    console.error('Error fetching subnet balances:', error);
    return undefined; // Return undefined to indicate error
  }
};

Adding Balance to a Subnet

The main function to add balance to a subnet:

export const callSubscribe = async (
  skyBrowser: SkyMainBrowser | null,
  nftId: string,
  subnetId: string,
  balance: string,
  web3Auth: any,
  itemID?: string
): Promise<{success: boolean, error?: any}> => {
  try {
    if (!skyBrowser) return { success: false, error: "Browser not initialized" };
    
    // Switch to Skynet chain
    await web3Auth.switchChain({ chainId: "0x26B" });
    
    // Check if user is already subscribed
    const subscribeTimeResp = await skyBrowser.contractService.callContractRead(
      skyBrowser.contractService.Subscription.getSubscribeTime({
        collectionID: '0',
        nftID: nftId,
      }),
      (res: any) => res
    );
    
    if (!subscribeTimeResp.success) {
      return subscribeTimeResp;
    }
    
    const subscribeTime = subscribeTimeResp.data;
    const subscriptionParam = skyBrowser.appManager.defaultSubscriptionParam;

    // If not subscribed yet, subscribe first
    if (subscribeTime == BigInt(0)) {
      const subscribeResp = await skyBrowser.contractService.callContractWrite(
        skyBrowser.contractService.Subscription.subscribe(
          skyBrowser.contractService.selectedAccount,
          {
            collectionID: '0',
            nftID: nftId,
          },
          [
            '0x',
            ethers.zeroPadValue(subscriptionParam.referralAddress, 32),
            ethers.zeroPadValue(subscriptionParam.supportAddress, 32),
            ethers.zeroPadValue(subscriptionParam.licenseAddress, 32) +
              bigIntToBytes('0', 32),
          ]
        )
      );
      
      if (!subscribeResp.success) return subscribeResp;
    }

    // Add balance for the subnet
    const payParams = [
      {
        subnetID: subnetId,
        subnetData: '0x',
        addBalance: etherToWei(parseFloat(balance), 18).toString(),
        balanceData: '0x',
        callType: SETTLER_CALLTYPE.ADD_BALANCE_WITH_NATIVE,
      },
    ];
    
    // Execute the payment
    const resp = await skyBrowser.appManager.pay(
      {
        collectionID: '0',
        nftID: nftId,
      },
      payParams
    );
    
    return resp;
  } catch (err) {
    console.log('Error in callSubscribe:', err);
    return { success: false, error: err };
  }
};

Example Usage

Here's how to use the callSubscribe function:

// Import required functions and types
import { callSubscribe, getSubnetBalance } from "./utils/skynetHelper";

// Example function to add balance to a subnet
async function addBalanceToSubnet(
  skyBrowser: SkyMainBrowser,
  nftId: string,
  subnetId: string,
  web3Auth: any
) {
  try {
    // Default balance amount
    const balanceToAdd = "0.05"; // in ETH
    
    // Check current balance first
    const currentBalance = await getSubnetBalance(skyBrowser, nftId, subnetId);
    console.log(`Current balance for subnet ${subnetId}: ${currentBalance || '0'} ETH`);
    
    // Add balance
    const result = await callSubscribe(
      skyBrowser,
      nftId,
      subnetId,
      balanceToAdd,
      web3Auth,
      `subnet-${subnetId}` // Optional tracking ID
    );
    
    if (result.success) {
      console.log(`Successfully added ${balanceToAdd} ETH to subnet ${subnetId}`);
      return true;
    } else {
      console.error("Failed to add balance:", result.error);
      return false;
    }
  } catch (error) {
    console.error("Error in addBalanceToSubnet:", error);
    throw error;
  }
}

Adding Balance Before Deployment

Before deploying a workflow, ensure all subnets have sufficient balance:

// Function to ensure all subnets have minimum balance
const ensureSubnetsHaveBalance = async (
  subnets: Subnet[],
  skyBrowser: SkyMainBrowser,
  nftId: string,
  web3Auth: any
) => {
  // Default balance amount for each subnet
  const DEFAULT_BALANCE = '0.05';
  
  for (const subnet of subnets) {
    try {
      // Check current balance
      const currentBalance = await getSubnetBalance(skyBrowser, nftId, subnet.subnetID);
      
      // If balance is too low, add more
      if (!currentBalance || parseFloat(currentBalance) < 0.01) {
        await callSubscribe(
          skyBrowser,
          nftId,
          subnet.subnetID,
          DEFAULT_BALANCE,
          web3Auth,
          subnet.itemID?.toString()
        );
        console.log(`Added balance to subnet: ${subnet.subnetName}`);
      }
    } catch (error) {
      console.error(`Failed to ensure balance for subnet ${subnet.subnetName}:`, error);
      throw error;
    }
  }
  
  return true;
};
PreviousSDK InitializationNextBest Practices

Last updated 17 days ago