@glowlabs-org/utils 0.2.47 → 0.2.48
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.d.ts +1 -0
- package/dist/cjs/browser.js +12211 -4
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +95 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/control-api/control-router.d.ts +3 -3
- package/dist/cjs/lib/control-api/kickstarter-router.d.ts +9 -0
- package/dist/cjs/lib/control-api/region-router.d.ts +1 -6
- package/dist/cjs/lib/types/index.d.ts +30 -0
- package/dist/cjs/{region-router-1QcGCT_a.js → region-router-ihtk6PPi.js} +7 -66
- package/dist/cjs/region-router-ihtk6PPi.js.map +1 -0
- package/dist/cjs/utils/stake-control.d.ts +156 -0
- package/dist/esm/browser.d.ts +1 -0
- package/dist/esm/browser.js +12196 -2
- package/dist/esm/browser.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +96 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/control-api/control-router.d.ts +3 -3
- package/dist/esm/lib/control-api/kickstarter-router.d.ts +9 -0
- package/dist/esm/lib/control-api/region-router.d.ts +1 -6
- package/dist/esm/lib/types/index.d.ts +30 -0
- package/dist/esm/{region-router-DDMKweoS.js → region-router-BoyHO9Zp.js} +7 -66
- package/dist/esm/region-router-BoyHO9Zp.js.map +1 -0
- package/dist/esm/utils/stake-control.d.ts +156 -0
- package/package.json +6 -3
- package/src/browser.ts +1 -0
- package/src/index.ts +1 -0
- package/src/lib/control-api/control-router.ts +3 -10
- package/src/lib/control-api/kickstarter-router.ts +119 -0
- package/src/lib/control-api/region-router.ts +4 -75
- package/src/lib/types/index.ts +44 -6
- package/src/utils/stake-control.ts +343 -0
- package/dist/cjs/region-router-1QcGCT_a.js.map +0 -1
- package/dist/esm/region-router-DDMKweoS.js.map +0 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export declare const stakeControlEIP712Domain: {
|
|
3
|
+
readonly name: "ControlManager";
|
|
4
|
+
readonly version: "1";
|
|
5
|
+
readonly chainId: number;
|
|
6
|
+
readonly verifyingContract: "0x0000000000000000000000000000000000000000";
|
|
7
|
+
};
|
|
8
|
+
export declare const stakeEIP712Types: {
|
|
9
|
+
readonly Stake: readonly [{
|
|
10
|
+
readonly name: "nonce";
|
|
11
|
+
readonly type: "uint256";
|
|
12
|
+
}, {
|
|
13
|
+
readonly name: "amount";
|
|
14
|
+
readonly type: "uint256";
|
|
15
|
+
}, {
|
|
16
|
+
readonly name: "toZoneId";
|
|
17
|
+
readonly type: "uint256";
|
|
18
|
+
}, {
|
|
19
|
+
readonly name: "deadline";
|
|
20
|
+
readonly type: "uint256";
|
|
21
|
+
}];
|
|
22
|
+
};
|
|
23
|
+
export declare const unstakeUnlockEIP712Types: {
|
|
24
|
+
readonly Unstake: readonly [{
|
|
25
|
+
readonly name: "nonce";
|
|
26
|
+
readonly type: "uint256";
|
|
27
|
+
}, {
|
|
28
|
+
readonly name: "amount";
|
|
29
|
+
readonly type: "uint256";
|
|
30
|
+
}, {
|
|
31
|
+
readonly name: "fromZoneId";
|
|
32
|
+
readonly type: "uint256";
|
|
33
|
+
}, {
|
|
34
|
+
readonly name: "deadline";
|
|
35
|
+
readonly type: "uint256";
|
|
36
|
+
}];
|
|
37
|
+
};
|
|
38
|
+
export declare const unstakeMoveEIP712Types: {
|
|
39
|
+
readonly UnstakeMove: readonly [{
|
|
40
|
+
readonly name: "nonce";
|
|
41
|
+
readonly type: "uint256";
|
|
42
|
+
}, {
|
|
43
|
+
readonly name: "amount";
|
|
44
|
+
readonly type: "uint256";
|
|
45
|
+
}, {
|
|
46
|
+
readonly name: "fromZoneId";
|
|
47
|
+
readonly type: "uint256";
|
|
48
|
+
}, {
|
|
49
|
+
readonly name: "toZoneId";
|
|
50
|
+
readonly type: "uint256";
|
|
51
|
+
}, {
|
|
52
|
+
readonly name: "deadline";
|
|
53
|
+
readonly type: "uint256";
|
|
54
|
+
}];
|
|
55
|
+
};
|
|
56
|
+
export declare const restakeEIP712Types: {
|
|
57
|
+
readonly Restake: readonly [{
|
|
58
|
+
readonly name: "nonce";
|
|
59
|
+
readonly type: "uint256";
|
|
60
|
+
}, {
|
|
61
|
+
readonly name: "amount";
|
|
62
|
+
readonly type: "uint256";
|
|
63
|
+
}, {
|
|
64
|
+
readonly name: "fromZoneId";
|
|
65
|
+
readonly type: "uint256";
|
|
66
|
+
}, {
|
|
67
|
+
readonly name: "toZoneId";
|
|
68
|
+
readonly type: "uint256";
|
|
69
|
+
}, {
|
|
70
|
+
readonly name: "deadline";
|
|
71
|
+
readonly type: "uint256";
|
|
72
|
+
}];
|
|
73
|
+
};
|
|
74
|
+
export declare const stakeSignatureRequestSchema: z.ZodObject<{
|
|
75
|
+
wallet: z.ZodString;
|
|
76
|
+
signature: z.ZodString;
|
|
77
|
+
nonce: z.ZodString;
|
|
78
|
+
amount: z.ZodString;
|
|
79
|
+
toZoneId: z.ZodString;
|
|
80
|
+
deadline: z.ZodString;
|
|
81
|
+
}, z.core.$strip>;
|
|
82
|
+
export declare const unstakeUnlockSignatureRequestSchema: z.ZodObject<{
|
|
83
|
+
wallet: z.ZodString;
|
|
84
|
+
signature: z.ZodString;
|
|
85
|
+
nonce: z.ZodString;
|
|
86
|
+
amount: z.ZodString;
|
|
87
|
+
fromZoneId: z.ZodString;
|
|
88
|
+
deadline: z.ZodString;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
export declare const unstakeMoveSignatureRequestSchema: z.ZodObject<{
|
|
91
|
+
wallet: z.ZodString;
|
|
92
|
+
signature: z.ZodString;
|
|
93
|
+
nonce: z.ZodString;
|
|
94
|
+
amount: z.ZodString;
|
|
95
|
+
fromZoneId: z.ZodString;
|
|
96
|
+
toZoneId: z.ZodString;
|
|
97
|
+
deadline: z.ZodString;
|
|
98
|
+
}, z.core.$strip>;
|
|
99
|
+
export declare const restakeSignatureRequestSchema: z.ZodObject<{
|
|
100
|
+
wallet: z.ZodString;
|
|
101
|
+
signature: z.ZodString;
|
|
102
|
+
nonce: z.ZodString;
|
|
103
|
+
amount: z.ZodString;
|
|
104
|
+
fromZoneId: z.ZodString;
|
|
105
|
+
toZoneId: z.ZodString;
|
|
106
|
+
deadline: z.ZodString;
|
|
107
|
+
}, z.core.$strip>;
|
|
108
|
+
export type StakeSignatureRequest = z.infer<typeof stakeSignatureRequestSchema>;
|
|
109
|
+
export type UnstakeUnlockSignatureRequest = z.infer<typeof unstakeUnlockSignatureRequestSchema>;
|
|
110
|
+
export type UnstakeMoveSignatureRequest = z.infer<typeof unstakeMoveSignatureRequestSchema>;
|
|
111
|
+
export type RestakeSignatureRequest = z.infer<typeof restakeSignatureRequestSchema>;
|
|
112
|
+
export type StakeMessage = {
|
|
113
|
+
nonce: bigint;
|
|
114
|
+
amount: bigint;
|
|
115
|
+
toZoneId: bigint;
|
|
116
|
+
deadline: bigint;
|
|
117
|
+
};
|
|
118
|
+
export type UnstakeUnlockMessage = {
|
|
119
|
+
nonce: bigint;
|
|
120
|
+
amount: bigint;
|
|
121
|
+
fromZoneId: bigint;
|
|
122
|
+
deadline: bigint;
|
|
123
|
+
};
|
|
124
|
+
export type UnstakeMoveMessage = {
|
|
125
|
+
nonce: bigint;
|
|
126
|
+
amount: bigint;
|
|
127
|
+
fromZoneId: bigint;
|
|
128
|
+
toZoneId: bigint;
|
|
129
|
+
deadline: bigint;
|
|
130
|
+
};
|
|
131
|
+
export type RestakeMessage = {
|
|
132
|
+
nonce: bigint;
|
|
133
|
+
amount: bigint;
|
|
134
|
+
fromZoneId: bigint;
|
|
135
|
+
toZoneId: bigint;
|
|
136
|
+
deadline: bigint;
|
|
137
|
+
};
|
|
138
|
+
export type SignatureValidationReason = "deadline_expired" | "signature_failed" | "signer_mismatch" | null;
|
|
139
|
+
export type SignatureValidationResult = {
|
|
140
|
+
valid: boolean;
|
|
141
|
+
recovered: string | null;
|
|
142
|
+
reason: SignatureValidationReason;
|
|
143
|
+
};
|
|
144
|
+
type StakeMessageInput = Pick<StakeSignatureRequest, "nonce" | "amount" | "toZoneId" | "deadline">;
|
|
145
|
+
type UnstakeUnlockMessageInput = Pick<UnstakeUnlockSignatureRequest, "nonce" | "amount" | "fromZoneId" | "deadline">;
|
|
146
|
+
type UnstakeMoveMessageInput = Pick<UnstakeMoveSignatureRequest, "nonce" | "amount" | "fromZoneId" | "toZoneId" | "deadline">;
|
|
147
|
+
type RestakeMessageInput = Pick<RestakeSignatureRequest, "nonce" | "amount" | "fromZoneId" | "toZoneId" | "deadline">;
|
|
148
|
+
export declare function buildStakeMessage(req: StakeMessageInput): StakeMessage;
|
|
149
|
+
export declare function buildUnstakeUnlockMessage(req: UnstakeUnlockMessageInput): UnstakeUnlockMessage;
|
|
150
|
+
export declare function buildUnstakeMoveMessage(req: UnstakeMoveMessageInput): UnstakeMoveMessage;
|
|
151
|
+
export declare function buildRestakeMessage(req: RestakeMessageInput): RestakeMessage;
|
|
152
|
+
export declare function validateStakeSignature(input: StakeSignatureRequest, domain?: typeof stakeControlEIP712Domain): Promise<SignatureValidationResult>;
|
|
153
|
+
export declare function validateUnstakeUnlockSignature(input: UnstakeUnlockSignatureRequest, domain?: typeof stakeControlEIP712Domain): Promise<SignatureValidationResult>;
|
|
154
|
+
export declare function validateUnstakeMoveSignature(input: UnstakeMoveSignatureRequest, domain?: typeof stakeControlEIP712Domain): Promise<SignatureValidationResult>;
|
|
155
|
+
export declare function validateRestakeSignature(input: RestakeSignatureRequest, domain?: typeof stakeControlEIP712Domain): Promise<SignatureValidationResult>;
|
|
156
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glowlabs-org/utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.48",
|
|
4
4
|
"description": "A library containing all typechain types and addresses relating to the glow guarded launch",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"node": ">=16"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
+
"decimal.js": "^10.4.3",
|
|
44
45
|
"ethers": "6.x.x",
|
|
45
46
|
"merkletreejs": "^0.3.11",
|
|
46
|
-
"viem": "^2.19.7"
|
|
47
|
-
"decimal.js": "^10.4.3"
|
|
47
|
+
"viem": "^2.19.7"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@rollup/plugin-commonjs": "^26.0.1",
|
|
@@ -61,6 +61,9 @@
|
|
|
61
61
|
"typescript": "^5.5.4",
|
|
62
62
|
"viem": "^2.7.16"
|
|
63
63
|
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"zod": "^4.0.17"
|
|
66
|
+
},
|
|
64
67
|
"scripts": {
|
|
65
68
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
66
69
|
"build": "rollup -c",
|
package/src/browser.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -9,3 +9,4 @@ export {
|
|
|
9
9
|
export { useForwarder } from "./lib/hooks/use-forwarder";
|
|
10
10
|
export { ControlRouter } from "./lib/control-api/control-router";
|
|
11
11
|
export { RegionRouter } from "./lib/control-api/region-router";
|
|
12
|
+
export { KickstarterRouter } from "./lib/control-api/kickstarter-router";
|
|
@@ -114,6 +114,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
114
114
|
const data = await request<{ transfers: PendingTransfer[] }>(
|
|
115
115
|
`/transfers/pending${buildPaginationQuery(page, limit)}`
|
|
116
116
|
);
|
|
117
|
+
|
|
117
118
|
return data.transfers ?? [];
|
|
118
119
|
} catch (error) {
|
|
119
120
|
throw new Error(parseApiError(error));
|
|
@@ -192,14 +193,9 @@ export function ControlRouter(baseUrl: string) {
|
|
|
192
193
|
let isUnstaking = false;
|
|
193
194
|
let isRetryingFailedOperation = false;
|
|
194
195
|
|
|
195
|
-
const stakeGctl = async (
|
|
196
|
-
wallet: string,
|
|
197
|
-
regionId: number,
|
|
198
|
-
amount: string
|
|
199
|
-
): Promise<boolean> => {
|
|
196
|
+
const stakeGctl = async (stakeRequest: StakeRequest): Promise<boolean> => {
|
|
200
197
|
isStaking = true;
|
|
201
198
|
try {
|
|
202
|
-
const stakeRequest: StakeRequest = { wallet, regionId, amount };
|
|
203
199
|
await request(`/stake`, {
|
|
204
200
|
method: "POST",
|
|
205
201
|
headers: { "Content-Type": "application/json" },
|
|
@@ -214,13 +210,10 @@ export function ControlRouter(baseUrl: string) {
|
|
|
214
210
|
};
|
|
215
211
|
|
|
216
212
|
const unstakeGctl = async (
|
|
217
|
-
|
|
218
|
-
regionId: number,
|
|
219
|
-
amount: string
|
|
213
|
+
unstakeRequest: StakeRequest
|
|
220
214
|
): Promise<boolean> => {
|
|
221
215
|
isUnstaking = true;
|
|
222
216
|
try {
|
|
223
|
-
const unstakeRequest: StakeRequest = { wallet, regionId, amount };
|
|
224
217
|
await request(`/unstake`, {
|
|
225
218
|
method: "POST",
|
|
226
219
|
headers: { "Content-Type": "application/json" },
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { regionMetadata } from "../region-metadata";
|
|
4
|
+
import type {
|
|
5
|
+
Kickstarter,
|
|
6
|
+
CreateKickstarterPayload,
|
|
7
|
+
KickstarterCreateResponse,
|
|
8
|
+
CommitKickstarterPayload,
|
|
9
|
+
CommitKickstarterResponse,
|
|
10
|
+
} from "../types";
|
|
11
|
+
|
|
12
|
+
function parseApiError(error: unknown): string {
|
|
13
|
+
if (!error) return "Unknown error";
|
|
14
|
+
if (error instanceof Error) return error.message;
|
|
15
|
+
const possible: any = error;
|
|
16
|
+
return possible?.error?.message ?? possible?.message ?? "Unknown error";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function KickstarterRouter(baseUrl: string) {
|
|
20
|
+
if (!baseUrl) throw new Error("CONTROL API base URL is not set");
|
|
21
|
+
|
|
22
|
+
const request = async <T>(path: string, init?: RequestInit): Promise<T> => {
|
|
23
|
+
const res = await fetch(`${baseUrl}${path}`, init);
|
|
24
|
+
if (!res.ok) {
|
|
25
|
+
const errData = await res.json().catch(() => ({}));
|
|
26
|
+
throw new Error(errData?.error || `Request to ${path} failed`);
|
|
27
|
+
}
|
|
28
|
+
return (await res.json()) as T;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
let isCreatingKickstarter = false;
|
|
32
|
+
|
|
33
|
+
const fetchKickstarters = async (): Promise<Kickstarter[]> => {
|
|
34
|
+
try {
|
|
35
|
+
const data = await request<{ kickstarters: Kickstarter[] }>(
|
|
36
|
+
`/kickstarters`
|
|
37
|
+
);
|
|
38
|
+
return data.kickstarters ?? [];
|
|
39
|
+
} catch (error) {
|
|
40
|
+
throw new Error(parseApiError(error));
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const createKickstarter = async (
|
|
45
|
+
payload: CreateKickstarterPayload
|
|
46
|
+
): Promise<KickstarterCreateResponse> => {
|
|
47
|
+
isCreatingKickstarter = true;
|
|
48
|
+
try {
|
|
49
|
+
const exists = Boolean(regionMetadata[payload.code]);
|
|
50
|
+
if (!exists) {
|
|
51
|
+
throw new Error(`Unknown region code: ${payload.code}`);
|
|
52
|
+
}
|
|
53
|
+
const data = await request<KickstarterCreateResponse>(`/kickstarters`, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: { "Content-Type": "application/json" },
|
|
56
|
+
body: JSON.stringify(payload),
|
|
57
|
+
});
|
|
58
|
+
return data;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new Error(parseApiError(error));
|
|
61
|
+
} finally {
|
|
62
|
+
isCreatingKickstarter = false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const fetchKickstarter = async (idOrSlug: string): Promise<Kickstarter> => {
|
|
67
|
+
try {
|
|
68
|
+
const data = await request<{ kickstarter: Kickstarter }>(
|
|
69
|
+
`/kickstarters/${encodeURIComponent(idOrSlug)}`
|
|
70
|
+
);
|
|
71
|
+
return data.kickstarter;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
throw new Error(parseApiError(error));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const fetchKickstartersByWallet = async (
|
|
78
|
+
wallet: string
|
|
79
|
+
): Promise<Kickstarter[]> => {
|
|
80
|
+
try {
|
|
81
|
+
const data = await request<{ kickstarters: Kickstarter[] }>(
|
|
82
|
+
`/kickstarters/by-wallet/${encodeURIComponent(wallet)}`
|
|
83
|
+
);
|
|
84
|
+
return data.kickstarters ?? [];
|
|
85
|
+
} catch (error) {
|
|
86
|
+
throw new Error(parseApiError(error));
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const commitKickstarter = async (
|
|
91
|
+
kickstarterId: string,
|
|
92
|
+
payload: CommitKickstarterPayload
|
|
93
|
+
): Promise<CommitKickstarterResponse> => {
|
|
94
|
+
try {
|
|
95
|
+
const data = await request<CommitKickstarterResponse>(
|
|
96
|
+
`/kickstarters/commit/${encodeURIComponent(kickstarterId)}`,
|
|
97
|
+
{
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "Content-Type": "application/json" },
|
|
100
|
+
body: JSON.stringify(payload),
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
return data;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error(parseApiError(error));
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
fetchKickstarters,
|
|
111
|
+
fetchKickstarter,
|
|
112
|
+
fetchKickstartersByWallet,
|
|
113
|
+
commitKickstarter,
|
|
114
|
+
createKickstarter,
|
|
115
|
+
get isCreatingKickstarter() {
|
|
116
|
+
return isCreatingKickstarter;
|
|
117
|
+
},
|
|
118
|
+
} as const;
|
|
119
|
+
}
|
|
@@ -6,10 +6,7 @@ import type {
|
|
|
6
6
|
RegionWithMetadata,
|
|
7
7
|
ActivationConfig,
|
|
8
8
|
CreateRegionPayload,
|
|
9
|
-
CreateKickstarterPayload,
|
|
10
|
-
Kickstarter,
|
|
11
9
|
ActivationEvent,
|
|
12
|
-
KickstarterCreateResponse,
|
|
13
10
|
RegionVcr,
|
|
14
11
|
SponsoredFarm,
|
|
15
12
|
} from "../types";
|
|
@@ -47,7 +44,6 @@ export function RegionRouter(baseUrl: string) {
|
|
|
47
44
|
let cachedRegions: RegionWithMetadata[] = [];
|
|
48
45
|
let isLoading = false;
|
|
49
46
|
let isCreatingRegion = false;
|
|
50
|
-
let isCreatingKickstarter = false;
|
|
51
47
|
|
|
52
48
|
// -------------------------------------------------------------------------
|
|
53
49
|
// Queries
|
|
@@ -112,17 +108,6 @@ export function RegionRouter(baseUrl: string) {
|
|
|
112
108
|
}
|
|
113
109
|
};
|
|
114
110
|
|
|
115
|
-
const fetchKickstarters = async (): Promise<Kickstarter[]> => {
|
|
116
|
-
try {
|
|
117
|
-
const data = await request<{ kickstarters: Kickstarter[] }>(
|
|
118
|
-
`/regions/kickstarters`
|
|
119
|
-
);
|
|
120
|
-
return data.kickstarters ?? [];
|
|
121
|
-
} catch (error) {
|
|
122
|
-
throw new Error(parseApiError(error));
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
111
|
const fetchRegionSolarFarms = async (
|
|
127
112
|
regionId: number
|
|
128
113
|
): Promise<SponsoredFarm[]> => {
|
|
@@ -156,56 +141,7 @@ export function RegionRouter(baseUrl: string) {
|
|
|
156
141
|
}
|
|
157
142
|
};
|
|
158
143
|
|
|
159
|
-
|
|
160
|
-
payload: CreateKickstarterPayload
|
|
161
|
-
): Promise<KickstarterCreateResponse> => {
|
|
162
|
-
isCreatingKickstarter = true;
|
|
163
|
-
try {
|
|
164
|
-
const exists = Boolean(regionMetadata[payload.code]);
|
|
165
|
-
if (!exists) {
|
|
166
|
-
throw new Error(`Unknown region code: ${payload.code}`);
|
|
167
|
-
}
|
|
168
|
-
const data = await request<KickstarterCreateResponse>(
|
|
169
|
-
`/regions/kickstarters`,
|
|
170
|
-
{
|
|
171
|
-
method: "POST",
|
|
172
|
-
headers: { "Content-Type": "application/json" },
|
|
173
|
-
body: JSON.stringify(payload),
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
// A new region may have been created; refresh regions cache
|
|
177
|
-
await fetchRegions();
|
|
178
|
-
return data;
|
|
179
|
-
} catch (error) {
|
|
180
|
-
throw new Error(parseApiError(error));
|
|
181
|
-
} finally {
|
|
182
|
-
isCreatingKickstarter = false;
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const fetchKickstarter = async (idOrSlug: string): Promise<Kickstarter> => {
|
|
187
|
-
try {
|
|
188
|
-
const data = await request<{ kickstarter: Kickstarter }>(
|
|
189
|
-
`/regions/kickstarters/${encodeURIComponent(idOrSlug)}`
|
|
190
|
-
);
|
|
191
|
-
return data.kickstarter;
|
|
192
|
-
} catch (error) {
|
|
193
|
-
throw new Error(parseApiError(error));
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
const fetchKickstartersByWallet = async (
|
|
198
|
-
wallet: string
|
|
199
|
-
): Promise<Kickstarter[]> => {
|
|
200
|
-
try {
|
|
201
|
-
const data = await request<{ kickstarters: Kickstarter[] }>(
|
|
202
|
-
`/regions/kickstarters/by-wallet/${encodeURIComponent(wallet)}`
|
|
203
|
-
);
|
|
204
|
-
return data.kickstarters ?? [];
|
|
205
|
-
} catch (error) {
|
|
206
|
-
throw new Error(parseApiError(error));
|
|
207
|
-
}
|
|
208
|
-
};
|
|
144
|
+
// Kickstarter-related logic moved to kickstarter-router.ts
|
|
209
145
|
|
|
210
146
|
// -------------------------------------------------------------------------
|
|
211
147
|
// Helpers (derived)
|
|
@@ -239,10 +175,10 @@ export function RegionRouter(baseUrl: string) {
|
|
|
239
175
|
isUs: metadata.isUs,
|
|
240
176
|
isActive: false,
|
|
241
177
|
stake: "0",
|
|
242
|
-
stakeThreshold: metadata.isUs ? "20000000000" : "
|
|
178
|
+
stakeThreshold: metadata.isUs ? "20000000000" : "200000000000",
|
|
243
179
|
solarPanelsQuantity: 0,
|
|
244
|
-
solarFarmThreshold:
|
|
245
|
-
installerThreshold:
|
|
180
|
+
solarFarmThreshold: 10,
|
|
181
|
+
installerThreshold: 1,
|
|
246
182
|
stakeProgress: 0,
|
|
247
183
|
solarFarmCount: 0,
|
|
248
184
|
solarFarmProgress: 0,
|
|
@@ -260,13 +196,9 @@ export function RegionRouter(baseUrl: string) {
|
|
|
260
196
|
fetchActivationConfig,
|
|
261
197
|
fetchActivationEvents,
|
|
262
198
|
fetchRegionByIdOrSlug,
|
|
263
|
-
fetchKickstarters,
|
|
264
|
-
fetchKickstarter,
|
|
265
|
-
fetchKickstartersByWallet,
|
|
266
199
|
fetchRegionSolarFarms,
|
|
267
200
|
getRegionByCode,
|
|
268
201
|
createRegion,
|
|
269
|
-
createKickstarter,
|
|
270
202
|
|
|
271
203
|
// Cached data & flags
|
|
272
204
|
get regions() {
|
|
@@ -278,8 +210,5 @@ export function RegionRouter(baseUrl: string) {
|
|
|
278
210
|
get isCreatingRegion() {
|
|
279
211
|
return isCreatingRegion;
|
|
280
212
|
},
|
|
281
|
-
get isCreatingKickstarter() {
|
|
282
|
-
return isCreatingKickstarter;
|
|
283
|
-
},
|
|
284
213
|
} as const;
|
|
285
214
|
}
|
package/src/lib/types/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export interface PendingTransfer {
|
|
|
34
34
|
applicationId?: string;
|
|
35
35
|
farmId?: string;
|
|
36
36
|
regionId?: number;
|
|
37
|
+
kickstarterId?: string;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
export interface TransferDetails extends PendingTransfer {
|
|
@@ -79,6 +80,9 @@ export interface StakeRequest {
|
|
|
79
80
|
wallet: string;
|
|
80
81
|
regionId: number;
|
|
81
82
|
amount: string; // Amount in atomic units (10^6 = 1 GCTL)
|
|
83
|
+
signature: string; // 0x-prefixed 65-byte hex signature
|
|
84
|
+
deadline: string; // unix timestamp (as string)
|
|
85
|
+
nonce: string; // stringified integer
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
export interface RegionStake {
|
|
@@ -114,14 +118,14 @@ export interface RegionWithMetadata extends Region {
|
|
|
114
118
|
isActive: boolean;
|
|
115
119
|
stake: string; // current GCTL stake (atomic units)
|
|
116
120
|
stakeThreshold: string; // threshold required to activate
|
|
117
|
-
stakeProgress: number; //
|
|
121
|
+
stakeProgress: number; // stake / stakeThreshold (may exceed 1)
|
|
118
122
|
solarFarmCount: number;
|
|
119
123
|
solarPanelsQuantity: number;
|
|
120
|
-
solarFarmThreshold: number; //
|
|
121
|
-
solarFarmProgress: number; //
|
|
124
|
+
solarFarmThreshold: number; // current minimum required (from constants)
|
|
125
|
+
solarFarmProgress: number; // solarFarmCount / solarFarmThreshold (may exceed 1)
|
|
122
126
|
installerCount: number;
|
|
123
|
-
installerThreshold: number; //
|
|
124
|
-
installerProgress: number; //
|
|
127
|
+
installerThreshold: number; // current minimum required (from constants)
|
|
128
|
+
installerProgress: number; // installerCount / installerThreshold (may exceed 1)
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
export interface ActivationConfig {
|
|
@@ -186,7 +190,7 @@ export interface Kickstarter {
|
|
|
186
190
|
cancelledAt?: string; // ISO 8601
|
|
187
191
|
expiredAt?: string; // ISO 8601
|
|
188
192
|
deadline: string; // ISO 8601
|
|
189
|
-
stakeTargetGctl: string; //
|
|
193
|
+
stakeTargetGctl: string; // atomic units (GCTL scaled by 10^6)
|
|
190
194
|
requiredFarmCount: number;
|
|
191
195
|
requiredInstallerCount: number;
|
|
192
196
|
stakeContributed: boolean;
|
|
@@ -197,6 +201,19 @@ export interface Kickstarter {
|
|
|
197
201
|
kickoffStakeEventId?: string;
|
|
198
202
|
}
|
|
199
203
|
|
|
204
|
+
export interface CommitKickstarterPayload {
|
|
205
|
+
wallet: string; // 0x-prefixed 40-char hex
|
|
206
|
+
amount: string; // atomic GCTL, must equal stakeTargetGctl/KICKSTARTER_STAKE_PERCENTAGE
|
|
207
|
+
nonce: string; // uint256 as string
|
|
208
|
+
deadline: string; // unix seconds as string
|
|
209
|
+
signature: string; // 0x-prefixed 65-byte hex
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface CommitKickstarterResponse {
|
|
213
|
+
success: true;
|
|
214
|
+
regionId: number;
|
|
215
|
+
}
|
|
216
|
+
|
|
200
217
|
export interface ActivationEvent {
|
|
201
218
|
id: string;
|
|
202
219
|
regionId: number;
|
|
@@ -249,6 +266,27 @@ export interface RegionVcr {
|
|
|
249
266
|
carbonCreditsPerWeek: number;
|
|
250
267
|
}
|
|
251
268
|
|
|
269
|
+
// ----------------------------- API Responses --------------------------------
|
|
270
|
+
export interface RegionsResponse {
|
|
271
|
+
regions: RegionWithMetadata[];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface RegionResponse {
|
|
275
|
+
region: RegionVcr;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface ActivationEventsResponse {
|
|
279
|
+
events: ActivationEvent[];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface RegionSolarFarmsResponse {
|
|
283
|
+
sponsoredFarms: SponsoredFarm[];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface FetchRegionsParams {
|
|
287
|
+
isActive?: boolean;
|
|
288
|
+
}
|
|
289
|
+
|
|
252
290
|
// ---------------------------------------------------------------------------
|
|
253
291
|
// Barrel exports (convenience)
|
|
254
292
|
// ---------------------------------------------------------------------------
|