@glowlabs-org/utils
v0.2.172
Published
A library containing all typechain types and addresses relating to the glow guarded launch
Readme
Glow Labs Utils
This repository contains utils for interacting with Glow labs data sources
Install
# peer deps (versions compatible with this library)
pnpm add @glowlabs-org/utils ethers@^6 viem@^2 merkletreejs decimal.jsRequirements
- Node >= 16 (tested up to 20)
- Ethers v6 (peer-dependency)
- Viem v2 (peer-dependency)
- MerkletreeJS
Example Usage
import { createWeeklyReport } from "@glowlabs-org/utils";
import * as fs from "fs";
const GCA_URLS = ["http://xx.xx.xx.xx:xxxxx"];
const apiUrl = "https://URL/headline_farm_stats";
const main = async () => {
const report = await createWeeklyReport({
gcaUrls: GCA_URLS,
apiUrl: apiUrl,
week: 37,
});
//Save to 37.json
fs.writeFileSync("37.json", JSON.stringify(report, null, 4));
};Forwarder SDK (framework-agnostic)
Below is a minimal example showing how to forward USDC using a standard ethers signer. The same call works in Node or in a browser (e.g. MetaMask’s window.ethereum).
import { useForwarder } from "@glowlabs-org/utils";
import { Wallet, JsonRpcProvider, parseUnits } from "ethers";
// Use Infura, Alchemy or any JSON-RPC endpoint
const provider = new JsonRpcProvider("https://sepolia.infura.io/v3/<API_KEY>");
// A local private key, or rely on a browser wallet by passing `provider.getSigner()`
const signer = new Wallet(process.env.PRIVATE_KEY!, provider);
// Chain id 11155111 = Sepolia
const forwarder = useForwarder(signer, 11155111);
await forwarder.forwardTokens({
amount: parseUnits("10", 6), // 10 USDC (6 dp)
userAddress: await signer.getAddress(),
type: "PayProtocolFee",
applicationId: "123",
currency: "USDC",
});
console.log("Tx hash:", forwarder.isProcessing ? "pending…" : "sent");See src/lib/hooks/use-forwarder.ts for all available helpers (approveToken, checkTokenBalance, estimateGasForForward, etc.).
Control-API SDK (framework-agnostic)
The Control API provides a comprehensive set of routers for interacting with the Glow protocol. All methods are promise-based and framework-agnostic – usable in Node, Deno, or the browser.
Quick Start
import { ControlRouter } from "@glowlabs-org/utils";
const controlApi = ControlRouter("https://control-api.glowlabs.org");
// Read-only queries
const balance = await controlApi.fetchGctlBalance("0xYourWallet");
const price = await controlApi.fetchGctlPrice();
// Mutations
await controlApi.stakeGctl({
wallet: "0xYourWallet",
regionId: 42,
amount: "1000000",
signature: "0x…",
deadline: "1728000000",
nonce: "1",
});ControlRouter
Main router for GCTL token operations, balances, and staking.
Queries:
fetchGctlBalance(wallet)→string- Get GCTL balance for a walletfetchCommittedBalance(wallet)→string- Get committed GCTL balancefetchGctlPrice()→string- Current GCTL price in USDCfetchGlwPrice()→string- Current GLW price in USDCfetchCirculatingSupply()→string- Circulating supply of GCTLfetchHoldersCount()→number- Total number of GCTL holdersfetchLastNonce(wallet)→string- Last nonce for wallet (type:WalletNonce)fetchMintedEvents(page?, limit?)→MintedEventsResponse- Paginated minted eventsfetchStakeEvents(page?, limit?, regionId?)→StakeEventsResponse- Paginated stake eventsfetchPendingTransfers(page?, limit?, type?)→PendingTransfersResponse- Pending transfers with optional type filterfetchTransferDetails(txId)→TransferDetails- Details for a specific transferfetchFailedOperations(page?, limit?)→FailedOperationsResponse- Failed operationsfetchRegionStake(regionId)→RegionStake- Total stake for a regionfetchWalletRegionStake(wallet, regionId)→WalletRegionStake- Wallet's stake in a regionfetchWalletRegionUnlocked(wallet, regionId)→WalletRegionUnlocked- Unlocked amount for wallet in regionfetchWalletRegionCommittedBalance(wallet, regionId)→WalletRegionCommittedBalance- Committed balancefetchGlwRegionRewards()→GlwRegionRewardsResponse- GLW rewards by regionfetchFarmRewardSplits(farmId)→FarmRewardSplit[]- Reward splits for a farmfetchMigrationAmount(wallet)→MigrationAmountResponse- Migration amount for wallet
Mutations:
stakeGctl(request)- Stake GCTL to a region (type:StakeRequest)unstakeGctl(request)- Unstake GCTL from a region (type:StakeRequest)restakeGctl(request)- Move stake between regions (type:RestakeRequest)retryFailedOperation(operationId)→RetryFailedOperationResponse- Retry a failed operationpayProtocolDepositUsingStakedControl(request)→PayProtocolDepositUsingStakedControlResponse- Pay protocol deposit using staked GCTLmigrateUser(request)→MigrateUserResponse- Migrate user from v1 to v2
Processing Flags:
isStaking,isUnstaking,isRestaking,isRetryingFailedOperation,isPayingProtocolDepositUsingStakedControl,isMigratingUser
WalletsRouter
Router for wallet-specific data including balances, farms, and rewards.
Queries:
fetchAllWallets()→ControlWallet[]- All wallets with balancesfetchWalletByAddress(wallet)→WalletDetails- Wallet details including regions and farmsfetchWalletMintedEvents(wallet, page?, limit?)→MintedEvent[]- Minted events for walletfetchWalletStakeEvents(wallet, page?, limit?, regionId?)→StakedEvent[]- Stake events for walletfetchWalletWeeklyRewards(wallet, query?)→WalletWeeklyRewardsResponse- Weekly rewards aggregated by payment currency (query:WeeklyRewardsQuerywithstartWeek,endWeek,paymentCurrency,limit)
Key Types:
WalletDetails- IncludescontrolBalance,stakedControl,committedControl,regions(array ofWalletRegionStakeTotal), andownedFarms(array ofWalletFarmInfowith reward splits)WalletWeeklyRewardsResponse- Containssummary(WeeklyRewardsSummary) andrewards(array ofWeeklyReward)
RegionRouter
Router for geographic regions, activation, and regional data.
Queries:
fetchRegions(params?)→RegionWithMetadata[]- All regions, optionally filtered byisActivefetchRegionByIdOrSlug(idOrSlug)→RegionDetails- Detailed region info including farms and applicationsfetchActivationConfig(regionCode)→ActivationConfig- Activation thresholds and requirementsfetchActivationEvents(regionId?)→ActivationEvent[]- Activation event timelinefetchRegionSolarFarms(regionId)→SponsoredFarm[]- Solar farms in a regionfetchActiveSummary()→ActiveRegionsSummaryResponse- Chart-ready data with 4-epoch historyfetchRecentActivity()→RecentRegionActivityResponse- 24h and 7d activity statisticsfetchRegionWeeklyRewards(regionId, query?)→RegionWeeklyRewardsResponse- Weekly rewards aggregated by payment currency (query:RegionWeeklyRewardsQuery)getRegionByCode(code)→RegionWithMetadata | null- Get region by code, merges bundled metadata
Mutations:
applyInstallerCertification(payload)→InstallerApplicationResponse- Apply for installer certification (type:InstallerApplicationPayload)
Cached Data:
regions- Cached regions arrayisLoading- Loading state flag
Key Types:
RegionWithMetadata- Includes activation progress (stake, farms, installers)RegionDetails- Full region view with farms, applications, and carbon creditsActiveRegionsSummaryResponse- Historical data with metadata, totals, per-region data, and aggregate timelineRegionWeeklyRewardsResponse- Summary and rewards array by week and payment currency
FarmsRouter
Router for solar farm operations, rewards, and scoring.
Queries:
fetchFarmRewardSplits(farmId)→FarmRewardSplit[]- Current reward splits for a farmfetchSponsoredFarms(sponsorWallet?)→SponsoredFarm[]- All sponsored farms, optionally filtered by sponsorfetchWalletFarmsWithRewards(walletAddress)→FarmWithRewards[]- Farms where wallet has reward splits, with calculated weekly rewardsfetchFarmWeeklyRewards(farmId, query?)→FarmWeeklyRewardsResponse- Weekly rewards aggregated by payment currency (query:FarmWeeklyRewardsQuery)
Mutations:
estimateRewardScore(params)→RewardScoreResponse- Calculate reward score for a potential farm (type:EstimateRewardScoreParams)estimateRewardScoresBatch(params)→EstimateRewardScoresBatchResponse- Calculate reward scores for multiple farms (type:EstimateRewardScoresBatchParams)calculateMiningScoresBatch(params)→MiningScoresBatchResponse- Calculate mining scores for existing farms (type:MiningScoresBatchParams)
Key Types:
SponsoredFarm- Complete farm details including location, capacity, pictures, and reward splitsFarmWithRewards- ExtendsSponsoredFarmwithuserWeeklyRewards(UserWeeklyRewards)RewardScoreResponse- Comprehensive reward estimates including weekly PD/GLW rewards, USD values, and region infoMiningScoreResponse- Mining ROI calculation with GLW rewards and lifetime estimatesFarmWeeklyRewardsResponse- Summary and rewards array by week and payment currency
KickstarterRouter
Router for region kickstarter campaigns and commitments.
Queries:
fetchKickstarters()→Kickstarter[]- All kickstartersfetchKickstarter(idOrSlug)→KickstarterDetails- Detailed kickstarter info including contributors and farmsfetchKickstartersByWallet(wallet)→Kickstarter[]- Kickstarters by creator walletfetchRegionCommitments(regionId, query?)→KickstarterCommitmentsResponse- Paginated commitments (query:KickstarterCommitmentsQuerywithpage,limit,finalized)
Mutations:
createKickstarter(payload)→KickstarterCreateResponse- Create a new kickstarter (type:CreateKickstarterPayload)commitKickstarter(kickstarterId, payload)→CommitKickstarterResponse- Commit GCTL to a kickstarter (type:CommitKickstarterPayload)
Processing Flags:
isCreatingKickstarter
Key Types:
Kickstarter- Basic kickstarter info with status, targets, and progress flagsKickstarterDetails- ExtendsKickstarterwith contributors, farm count, applications, and sponsored farmsKickstarterStatus- Status enum:draft,collecting-support,completed,failed,cancelled
Using Individual Routers
Each router can be imported and used independently:
import {
ControlRouter,
WalletsRouter,
RegionRouter,
FarmsRouter,
KickstarterRouter,
} from "@glowlabs-org/utils";
const baseUrl = "https://control-api.glowlabs.org";
const control = ControlRouter(baseUrl);
const wallets = WalletsRouter(baseUrl);
const regions = RegionRouter(baseUrl);
const farms = FarmsRouter(baseUrl);
const kickstarters = KickstarterRouter(baseUrl);
// Use any router
const balance = await control.fetchGctlBalance("0x...");
const walletDetails = await wallets.fetchWalletByAddress("0x...");
const regionList = await regions.fetchRegions({ isActive: true });
const farmSplits = await farms.fetchFarmRewardSplits("farm-id");
const allKickstarters = await kickstarters.fetchKickstarters();Optional Sentry integration (Next.js)
This library ships with built-in, optional Sentry hooks. If Sentry isn’t configured, everything no-ops safely.
1) Install Sentry for Next.js
pnpm add @sentry/nextjs
# or: npx @sentry/wizard -i nextjsSet env vars (build-time for source maps, and runtime DSN):
# build-time (CI) – for source maps upload
SENTRY_AUTH_TOKEN=... # keep secret
SENTRY_ORG=your-org
SENTRY_PROJECT=your-project
# runtime (browser/server)
NEXT_PUBLIC_SENTRY_DSN=https://<key>@o<org>.ingest.sentry.io/<project>
NEXT_PUBLIC_SENTRY_ENABLED=trueWrap your Next config to enable source maps upload (optional but recommended):
// next.config.js
const { withSentryConfig } = require("@sentry/nextjs");
const nextConfig = {
/* your config */
};
module.exports = withSentryConfig(nextConfig, { silent: true });2) Initialize Sentry and wire the utils once
App Router (recommended):
// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";
import { configureSentry } from "@glowlabs-org/utils/browser";
Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN });
configureSentry({
enabled: process.env.NEXT_PUBLIC_SENTRY_ENABLED !== "false",
client: Sentry,
defaultContext: { app: "web", env: process.env.NEXT_PUBLIC_VERCEL_ENV },
});// sentry.server.config.ts
import * as Sentry from "@sentry/nextjs";
import { configureSentry } from "@glowlabs-org/utils";
Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN });
configureSentry({
enabled: process.env.NEXT_PUBLIC_SENTRY_ENABLED !== "false",
client: Sentry,
defaultContext: { runtime: "server" },
});That’s it. All mutations in ControlRouter, FarmsRouter, KickstarterRouter, and the hooks (useForwarder, useOffchainFractions) will automatically add breadcrumbs and capture exceptions with useful context (wallets, ids, region, baseUrl, etc.).
Disable Sentry (locally or per environment)
import { configureSentry } from "@glowlabs-org/utils";
configureSentry({ enabled: false });You can also skip calling configureSentry entirely – the library will quietly no-op unless a Sentry client is provided or found globally.
The metadata file re-exports handy arrays:
import {
allRegions,
usStates,
countries,
} from "@glowlabs-org/utils/dist/region-metadata";Contributions
For contributions, feel free to open a PR or raise an issue.
