@glowlabs-org/utils 0.2.150 → 0.2.151
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/browser.js +1 -1
- package/dist/cjs/{farms-router-CMpG0RGM.js → farms-router-DWSaZD1T.js} +30 -3
- package/dist/cjs/farms-router-DWSaZD1T.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/lib/control-api/control-router.d.ts +4 -2
- package/dist/cjs/lib/types/index.d.ts +15 -12
- package/dist/esm/browser.js +2 -2
- package/dist/esm/{farms-router-wk3VSuCV.js → farms-router-Cpy_o4_u.js} +30 -3
- package/dist/esm/farms-router-Cpy_o4_u.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/lib/control-api/control-router.d.ts +4 -2
- package/dist/esm/lib/types/index.d.ts +15 -12
- package/package.json +1 -1
- package/src/lib/control-api/control-router.ts +53 -8
- package/src/lib/control-api/region-router.ts +53 -0
- package/src/lib/types/index.ts +17 -12
- package/dist/cjs/farms-router-CMpG0RGM.js.map +0 -1
- package/dist/esm/farms-router-wk3VSuCV.js.map +0 -1
package/dist/esm/index.js
CHANGED
|
@@ -13,8 +13,8 @@ import { parseUnits, formatUnits } from 'viem';
|
|
|
13
13
|
import { MerkleTree } from 'merkletreejs';
|
|
14
14
|
import { solidityPackedKeccak256, keccak256 } from 'ethers';
|
|
15
15
|
import Decimal from 'decimal.js';
|
|
16
|
-
import { H as HUB_URL, U as USDG_WEIGHT_DECIMAL_PRECISION, G as GLOW_WEIGHT_DECIMAL_PRECISION, M as MAX_WEIGHT } from './farms-router-
|
|
17
|
-
export { C as ControlRouter, F as FarmsRouter, d as KICKSTARTER_STATUS, K as KickstarterRouter, O as OFF_CHAIN_PAYMENT_CURRENCIES, P as PAYMENT_CURRENCIES, b as REGIONS, R as RegionRouter, S as STAKING_DIRECTIONS, T as TRANSFER_TYPES, W as WalletsRouter, c as configureSentry, u as useForwarder, a as useOffchainFractions } from './farms-router-
|
|
16
|
+
import { H as HUB_URL, U as USDG_WEIGHT_DECIMAL_PRECISION, G as GLOW_WEIGHT_DECIMAL_PRECISION, M as MAX_WEIGHT } from './farms-router-Cpy_o4_u.js';
|
|
17
|
+
export { C as ControlRouter, F as FarmsRouter, d as KICKSTARTER_STATUS, K as KickstarterRouter, O as OFF_CHAIN_PAYMENT_CURRENCIES, P as PAYMENT_CURRENCIES, b as REGIONS, R as RegionRouter, S as STAKING_DIRECTIONS, T as TRANSFER_TYPES, W as WalletsRouter, c as configureSentry, u as useForwarder, a as useOffchainFractions } from './farms-router-Cpy_o4_u.js';
|
|
18
18
|
|
|
19
19
|
const GENESIS_TIMESTAMP = 1700352000;
|
|
20
20
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StakeRequest, RegionStake, WalletRegionStake, WalletRegionUnlocked, WalletRegionCommittedBalance, TransferDetails, GlwRegionRewardsResponse, MintedEventsResponse, StakeEventsResponse, FailedOperationsResponse, PendingTransfersResponse, PendingTransferType, RestakeRequest, MigrationAmountResponse } from "../types";
|
|
1
|
+
import type { StakeRequest, RegionStake, WalletRegionStake, WalletRegionUnlocked, WalletRegionCommittedBalance, TransferDetails, GlwRegionRewardsResponse, MintedEventsResponse, StakeEventsResponse, FailedOperationsResponse, PendingTransfersResponse, PendingTransferType, RestakeRequest, MigrationAmountResponse, RetryFailedOperationResponse, FarmRewardSplit } from "../types";
|
|
2
2
|
export interface PayProtocolDepositUsingStakedControlRequest {
|
|
3
3
|
wallet: string;
|
|
4
4
|
regionId: number;
|
|
@@ -28,6 +28,7 @@ export declare function ControlRouter(baseUrl: string): {
|
|
|
28
28
|
readonly fetchGctlPrice: () => Promise<string>;
|
|
29
29
|
readonly fetchGlwPrice: () => Promise<string>;
|
|
30
30
|
readonly fetchCirculatingSupply: () => Promise<string>;
|
|
31
|
+
readonly fetchHoldersCount: () => Promise<number>;
|
|
31
32
|
readonly fetchLastNonce: (wallet: string) => Promise<string>;
|
|
32
33
|
readonly fetchMintedEvents: (page?: number, limit?: number) => Promise<MintedEventsResponse>;
|
|
33
34
|
readonly fetchStakeEvents: (page?: number, limit?: number, regionId?: number) => Promise<StakeEventsResponse>;
|
|
@@ -39,11 +40,12 @@ export declare function ControlRouter(baseUrl: string): {
|
|
|
39
40
|
readonly fetchWalletRegionCommittedBalance: (wallet: string, regionId: number) => Promise<WalletRegionCommittedBalance>;
|
|
40
41
|
readonly fetchTransferDetails: (txId: string) => Promise<TransferDetails>;
|
|
41
42
|
readonly fetchGlwRegionRewards: () => Promise<GlwRegionRewardsResponse>;
|
|
43
|
+
readonly fetchFarmRewardSplits: (farmId: string) => Promise<FarmRewardSplit[]>;
|
|
42
44
|
readonly fetchMigrationAmount: (wallet: string) => Promise<MigrationAmountResponse>;
|
|
43
45
|
readonly stakeGctl: (stakeRequest: StakeRequest) => Promise<boolean>;
|
|
44
46
|
readonly unstakeGctl: (unstakeRequest: StakeRequest) => Promise<boolean>;
|
|
45
47
|
readonly restakeGctl: (restakeRequest: RestakeRequest) => Promise<boolean>;
|
|
46
|
-
readonly retryFailedOperation: (operationId: string) => Promise<
|
|
48
|
+
readonly retryFailedOperation: (operationId: string) => Promise<RetryFailedOperationResponse>;
|
|
47
49
|
readonly payProtocolDepositUsingStakedControl: (paymentRequest: PayProtocolDepositUsingStakedControlRequest) => Promise<PayProtocolDepositUsingStakedControlResponse>;
|
|
48
50
|
readonly migrateUser: (migrateRequest: MigrateUserRequest) => Promise<MigrateUserResponse>;
|
|
49
51
|
readonly isStaking: boolean;
|
|
@@ -311,18 +311,14 @@ export interface RegionDetails extends RegionWithMetadata {
|
|
|
311
311
|
carbonCreditsIssued: number;
|
|
312
312
|
carbonCreditsPerWeek: number;
|
|
313
313
|
}
|
|
314
|
-
export interface
|
|
315
|
-
id: string;
|
|
316
|
-
regionId: number;
|
|
317
|
-
wallet: string;
|
|
314
|
+
export interface ActiveRegionSnapshot {
|
|
318
315
|
epoch: number;
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
actionSignatureData: unknown | null;
|
|
316
|
+
totals: {
|
|
317
|
+
gctlStaked: string;
|
|
318
|
+
pendingUnstake: string;
|
|
319
|
+
pendingRestakeOut: string;
|
|
320
|
+
pendingRestakeIn: string;
|
|
321
|
+
};
|
|
326
322
|
}
|
|
327
323
|
export interface ActiveRegionSummary {
|
|
328
324
|
id: number;
|
|
@@ -336,7 +332,7 @@ export interface ActiveRegionSummary {
|
|
|
336
332
|
pendingUnstake: string;
|
|
337
333
|
pendingRestakeOut: string;
|
|
338
334
|
pendingRestakeIn: string;
|
|
339
|
-
|
|
335
|
+
snapshots: ActiveRegionSnapshot[];
|
|
340
336
|
}
|
|
341
337
|
export interface ActiveRegionsSummaryResponse {
|
|
342
338
|
total: {
|
|
@@ -577,4 +573,11 @@ export interface FarmRewardSplitsResponse {
|
|
|
577
573
|
export interface FarmRewardSplitsErrorResponse {
|
|
578
574
|
error: string;
|
|
579
575
|
}
|
|
576
|
+
export interface HoldersCountResponse {
|
|
577
|
+
holders: number;
|
|
578
|
+
}
|
|
579
|
+
export interface RetryFailedOperationResponse {
|
|
580
|
+
success?: boolean;
|
|
581
|
+
queued?: boolean;
|
|
582
|
+
}
|
|
580
583
|
export type { MintedEvent as ControlMintedEvent };
|
package/package.json
CHANGED
|
@@ -19,7 +19,20 @@ import type {
|
|
|
19
19
|
PendingTransferType,
|
|
20
20
|
RestakeRequest,
|
|
21
21
|
MigrationAmountResponse,
|
|
22
|
+
HoldersCountResponse,
|
|
23
|
+
RetryFailedOperationResponse,
|
|
24
|
+
FarmRewardSplitsResponse,
|
|
25
|
+
FarmRewardSplitsErrorResponse,
|
|
26
|
+
FarmRewardSplit,
|
|
22
27
|
} from "../types";
|
|
28
|
+
|
|
29
|
+
interface FetchGctlBalanceResponse {
|
|
30
|
+
gctl_balance: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface FetchCommittedBalanceResponse {
|
|
34
|
+
gctl_committed_balance: string;
|
|
35
|
+
}
|
|
23
36
|
import {
|
|
24
37
|
sentryAddBreadcrumb,
|
|
25
38
|
sentryCaptureException,
|
|
@@ -69,6 +82,9 @@ function parseApiError(error: unknown): string {
|
|
|
69
82
|
// --------------------------------------------------------------------------
|
|
70
83
|
|
|
71
84
|
export function ControlRouter(baseUrl: string) {
|
|
85
|
+
if (!baseUrl) {
|
|
86
|
+
throw new Error("CONTROL API base URL is not set");
|
|
87
|
+
}
|
|
72
88
|
// ----------------------- Internal helpers --------------------------------
|
|
73
89
|
const request = async <T>(path: string, init?: RequestInit): Promise<T> => {
|
|
74
90
|
const res = await fetch(`${baseUrl}${path}`, init);
|
|
@@ -82,7 +98,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
82
98
|
// ----------------------- GETters -----------------------------------------
|
|
83
99
|
const fetchGctlBalance = async (wallet: string): Promise<string> => {
|
|
84
100
|
try {
|
|
85
|
-
const data = await request<
|
|
101
|
+
const data = await request<FetchGctlBalanceResponse>(
|
|
86
102
|
`/balance/${wallet}`
|
|
87
103
|
);
|
|
88
104
|
return (data?.gctl_balance ?? "0").toString();
|
|
@@ -93,7 +109,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
93
109
|
|
|
94
110
|
const fetchCommittedBalance = async (wallet: string): Promise<string> => {
|
|
95
111
|
try {
|
|
96
|
-
const data = await request<
|
|
112
|
+
const data = await request<FetchCommittedBalanceResponse>(
|
|
97
113
|
`/committed-balance/${wallet}`
|
|
98
114
|
);
|
|
99
115
|
return (data?.gctl_committed_balance ?? "0").toString();
|
|
@@ -138,6 +154,15 @@ export function ControlRouter(baseUrl: string) {
|
|
|
138
154
|
}
|
|
139
155
|
};
|
|
140
156
|
|
|
157
|
+
const fetchHoldersCount = async (): Promise<number> => {
|
|
158
|
+
try {
|
|
159
|
+
const data = await request<HoldersCountResponse>(`/holders/count`);
|
|
160
|
+
return data.holders;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
throw new Error(parseApiError(error));
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
141
166
|
// Build pagination query helper
|
|
142
167
|
const buildPaginationQuery = (page?: number, limit?: number) => {
|
|
143
168
|
const p = page ?? 1;
|
|
@@ -225,6 +250,21 @@ export function ControlRouter(baseUrl: string) {
|
|
|
225
250
|
}
|
|
226
251
|
};
|
|
227
252
|
|
|
253
|
+
const fetchFarmRewardSplits = async (
|
|
254
|
+
farmId: string
|
|
255
|
+
): Promise<FarmRewardSplit[]> => {
|
|
256
|
+
try {
|
|
257
|
+
if (!farmId) throw new Error("Farm ID is required");
|
|
258
|
+
const data = await request<
|
|
259
|
+
FarmRewardSplitsResponse | FarmRewardSplitsErrorResponse
|
|
260
|
+
>(`/farms/${encodeURIComponent(farmId)}/reward-splits`);
|
|
261
|
+
if ("error" in data) throw new Error(data.error);
|
|
262
|
+
return data.rewardSplits ?? [];
|
|
263
|
+
} catch (error) {
|
|
264
|
+
throw new Error(parseApiError(error));
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
228
268
|
// Exposed query with error parsing
|
|
229
269
|
const getTransferDetails = async (txId: string): Promise<TransferDetails> => {
|
|
230
270
|
try {
|
|
@@ -399,7 +439,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
399
439
|
|
|
400
440
|
const retryFailedOperation = async (
|
|
401
441
|
operationId: string
|
|
402
|
-
): Promise<
|
|
442
|
+
): Promise<RetryFailedOperationResponse> => {
|
|
403
443
|
isRetryingFailedOperation = true;
|
|
404
444
|
try {
|
|
405
445
|
sentryAddBreadcrumb({
|
|
@@ -408,11 +448,14 @@ export function ControlRouter(baseUrl: string) {
|
|
|
408
448
|
level: "info",
|
|
409
449
|
data: { baseUrl, operationId },
|
|
410
450
|
});
|
|
411
|
-
await request(
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
451
|
+
const response = await request<RetryFailedOperationResponse>(
|
|
452
|
+
`/operations/failed/${operationId}/retry`,
|
|
453
|
+
{
|
|
454
|
+
method: "POST",
|
|
455
|
+
headers: { "Content-Type": "application/json" },
|
|
456
|
+
}
|
|
457
|
+
);
|
|
458
|
+
return response;
|
|
416
459
|
} catch (error) {
|
|
417
460
|
sentryCaptureException(error, {
|
|
418
461
|
action: "retryFailedOperation",
|
|
@@ -520,6 +563,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
520
563
|
fetchGctlPrice,
|
|
521
564
|
fetchGlwPrice,
|
|
522
565
|
fetchCirculatingSupply,
|
|
566
|
+
fetchHoldersCount,
|
|
523
567
|
fetchLastNonce,
|
|
524
568
|
fetchMintedEvents,
|
|
525
569
|
fetchStakeEvents,
|
|
@@ -531,6 +575,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
531
575
|
fetchWalletRegionCommittedBalance,
|
|
532
576
|
fetchTransferDetails: getTransferDetails,
|
|
533
577
|
fetchGlwRegionRewards,
|
|
578
|
+
fetchFarmRewardSplits,
|
|
534
579
|
fetchMigrationAmount,
|
|
535
580
|
|
|
536
581
|
// Mutations
|
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* # Regions Router
|
|
5
|
+
*
|
|
6
|
+
* This router wraps the Control API endpoints that power Kickstarter-style
|
|
7
|
+
* activation across geographic regions. It surfaces read APIs for activation
|
|
8
|
+
* progress plus the installer certification mutation.
|
|
9
|
+
*
|
|
10
|
+
* ## Components
|
|
11
|
+
* - **router.ts**: exports the `RegionRouter` factory with helpers for each
|
|
12
|
+
* endpoint:
|
|
13
|
+
* - `GET /regions/all` – list regions with activation progress (stake, farms,
|
|
14
|
+
* installers). Accepts optional `?isActive=true|false` filter.
|
|
15
|
+
* - `GET /regions/:idOrSlug` – return region VCR view.
|
|
16
|
+
* - `GET /regions/active/summary` – aggregate GLW/week distribution, pending
|
|
17
|
+
* restakes, and recent epoch snapshots for active regions.
|
|
18
|
+
* - `GET /regions/solar-farms/:regionId` – list sponsored farms for a region.
|
|
19
|
+
* - `POST /regions/installers/apply` – certify an installer via signature.
|
|
20
|
+
* - `GET /regions/activation-events` – activation-event timeline, optional
|
|
21
|
+
* `regionId` filter.
|
|
22
|
+
* - `GET /regions/activation-config` – static activation thresholds and
|
|
23
|
+
* campaign duration for a region code.
|
|
24
|
+
* - **getters.ts**: shared data aggregation utilities used by the router
|
|
25
|
+
* implementation.
|
|
26
|
+
* - **db/schema.ts**: Drizzle schema for `regions`, `region_kickstarters`,
|
|
27
|
+
* `solar_farms`, `certified_installers`, and `region_activation_events`.
|
|
28
|
+
* - **constants**: activation thresholds imported from `@src/constants`:
|
|
29
|
+
* ```ts
|
|
30
|
+
* import {
|
|
31
|
+
* MIN_FARMS,
|
|
32
|
+
* US_STAKE_THRESHOLD,
|
|
33
|
+
* NON_US_STAKE_THRESHOLD,
|
|
34
|
+
* CAMPAIGN_DURATION_DAYS,
|
|
35
|
+
* MIN_INSTALLERS,
|
|
36
|
+
* US_STAKED_TRESHOLD_BIGINT,
|
|
37
|
+
* NON_US_STAKED_TRESHOLD_BIGINT,
|
|
38
|
+
* } from "@src/constants";
|
|
39
|
+
* ```
|
|
40
|
+
* - Region metadata: `regionMetadata` from `@glowlabs-org/utils/browser` feeds
|
|
41
|
+
* `/activation-config` responses.
|
|
42
|
+
* - Kickstarter endpoints live in `KickstarterRouter`.
|
|
43
|
+
*
|
|
44
|
+
* ## Activation Criteria
|
|
45
|
+
* A region activates when it satisfies all of:
|
|
46
|
+
* 1. Stake threshold met (≥ 20 000 GCTL for US, ≥ 200 000 GCTL otherwise).
|
|
47
|
+
* 2. At least 10 solar farms registered.
|
|
48
|
+
* 3. At least 1 certified installer.
|
|
49
|
+
*
|
|
50
|
+
* ## API Responses
|
|
51
|
+
* All numeric stake values are returned as strings (atomic units) to avoid
|
|
52
|
+
* precision loss. Dates are ISO 8601 strings. The router exposes typed helpers
|
|
53
|
+
* for the full dataset described above.
|
|
54
|
+
*/
|
|
55
|
+
|
|
3
56
|
import { generateSlug } from "src/utils/generate-slug";
|
|
4
57
|
import { regionMetadata } from "../region-metadata";
|
|
5
58
|
import type {
|
package/src/lib/types/index.ts
CHANGED
|
@@ -377,18 +377,14 @@ export interface RegionDetails extends RegionWithMetadata {
|
|
|
377
377
|
carbonCreditsPerWeek: number;
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
export interface
|
|
381
|
-
id: string;
|
|
382
|
-
regionId: number;
|
|
383
|
-
wallet: string;
|
|
380
|
+
export interface ActiveRegionSnapshot {
|
|
384
381
|
epoch: number;
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
actionSignatureData: unknown | null;
|
|
382
|
+
totals: {
|
|
383
|
+
gctlStaked: string;
|
|
384
|
+
pendingUnstake: string;
|
|
385
|
+
pendingRestakeOut: string;
|
|
386
|
+
pendingRestakeIn: string;
|
|
387
|
+
};
|
|
392
388
|
}
|
|
393
389
|
|
|
394
390
|
export interface ActiveRegionSummary {
|
|
@@ -403,7 +399,7 @@ export interface ActiveRegionSummary {
|
|
|
403
399
|
pendingUnstake: string;
|
|
404
400
|
pendingRestakeOut: string;
|
|
405
401
|
pendingRestakeIn: string;
|
|
406
|
-
|
|
402
|
+
snapshots: ActiveRegionSnapshot[];
|
|
407
403
|
}
|
|
408
404
|
|
|
409
405
|
export interface ActiveRegionsSummaryResponse {
|
|
@@ -703,6 +699,15 @@ export interface FarmRewardSplitsErrorResponse {
|
|
|
703
699
|
error: string;
|
|
704
700
|
}
|
|
705
701
|
|
|
702
|
+
export interface HoldersCountResponse {
|
|
703
|
+
holders: number;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export interface RetryFailedOperationResponse {
|
|
707
|
+
success?: boolean;
|
|
708
|
+
queued?: boolean;
|
|
709
|
+
}
|
|
710
|
+
|
|
706
711
|
// ---------------------------------------------------------------------------
|
|
707
712
|
// Barrel exports (convenience)
|
|
708
713
|
// ---------------------------------------------------------------------------
|