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;
};
Last updated