@glowlabs-org/utils 0.2.91 → 0.2.93
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 +675 -636
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/{farms-router-ClIWm9AQ.js → farms-router-C2sviclU.js} +71 -22
- package/dist/cjs/farms-router-C2sviclU.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/lib/control-api/control-router.d.ts +16 -0
- package/dist/cjs/lib/types/index.d.ts +14 -2
- package/dist/cjs/utils/stake-control.d.ts +33 -0
- package/dist/esm/browser.js +669 -633
- package/dist/esm/browser.js.map +1 -1
- package/dist/esm/{farms-router-DVSHNqsT.js → farms-router-oHFOyL2k.js} +69 -23
- package/dist/esm/farms-router-oHFOyL2k.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/lib/control-api/control-router.d.ts +16 -0
- package/dist/esm/lib/types/index.d.ts +14 -2
- package/dist/esm/utils/stake-control.d.ts +33 -0
- package/package.json +1 -1
- package/src/lib/control-api/control-router.ts +43 -0
- package/src/lib/hooks/use-forwarder.ts +23 -22
- package/src/lib/types/index.ts +16 -12
- package/src/utils/stake-control.ts +82 -1
- package/dist/cjs/farms-router-ClIWm9AQ.js.map +0 -1
- package/dist/esm/farms-router-DVSHNqsT.js.map +0 -1
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
import type { StakeRequest, RegionStake, WalletRegionStake, WalletRegionUnlocked, TransferDetails, GlwRegionRewardsResponse, MintedEventsResponse, StakeEventsResponse, FailedOperationsResponse, PendingTransfersResponse, PendingTransferType, RestakeRequest } from "../types";
|
|
2
|
+
export interface PayProtocolDepositUsingStakedControlRequest {
|
|
3
|
+
wallet: string;
|
|
4
|
+
regionId: number;
|
|
5
|
+
applicationId: string;
|
|
6
|
+
amount: string;
|
|
7
|
+
signature: string;
|
|
8
|
+
deadline: string;
|
|
9
|
+
nonce: string;
|
|
10
|
+
}
|
|
11
|
+
export interface PayProtocolDepositUsingStakedControlResponse {
|
|
12
|
+
success: true;
|
|
13
|
+
farmId: string;
|
|
14
|
+
applicationId: string;
|
|
15
|
+
}
|
|
2
16
|
export declare function ControlRouter(baseUrl: string): {
|
|
3
17
|
readonly fetchGctlBalance: (wallet: string) => Promise<string>;
|
|
4
18
|
readonly fetchGctlPrice: () => Promise<string>;
|
|
@@ -18,8 +32,10 @@ export declare function ControlRouter(baseUrl: string): {
|
|
|
18
32
|
readonly unstakeGctl: (unstakeRequest: StakeRequest) => Promise<boolean>;
|
|
19
33
|
readonly restakeGctl: (restakeRequest: RestakeRequest) => Promise<boolean>;
|
|
20
34
|
readonly retryFailedOperation: (operationId: string) => Promise<boolean>;
|
|
35
|
+
readonly payProtocolDepositUsingStakedControl: (paymentRequest: PayProtocolDepositUsingStakedControlRequest) => Promise<PayProtocolDepositUsingStakedControlResponse>;
|
|
21
36
|
readonly isStaking: boolean;
|
|
22
37
|
readonly isUnstaking: boolean;
|
|
23
38
|
readonly isRestaking: boolean;
|
|
24
39
|
readonly isRetryingFailedOperation: boolean;
|
|
40
|
+
readonly isPayingProtocolDepositUsingStakedControl: boolean;
|
|
25
41
|
};
|
|
@@ -34,8 +34,19 @@ export interface PendingTransfer {
|
|
|
34
34
|
regionId?: number;
|
|
35
35
|
kickstarterId?: string;
|
|
36
36
|
}
|
|
37
|
-
export declare const TRANSFER_TYPES:
|
|
38
|
-
|
|
37
|
+
export declare const TRANSFER_TYPES: {
|
|
38
|
+
readonly PayProtocolFeeAndMintGCTLAndStake: "PayProtocolFeeAndMintGCTLAndStake";
|
|
39
|
+
readonly PayProtocolFee: "PayProtocolFee";
|
|
40
|
+
readonly PayAuditFees: "PayAuditFees";
|
|
41
|
+
readonly CommitKickstarter: "CommitKickstarter";
|
|
42
|
+
readonly MintGCTLAndStake: "MintGCTLAndStake";
|
|
43
|
+
readonly MintGCTL: "MintGCTL";
|
|
44
|
+
readonly BuySolarFarm: "BuySolarFarm";
|
|
45
|
+
readonly SponsorProtocolFee: "SponsorProtocolFee";
|
|
46
|
+
readonly SponsorProtocolFeeAndMintGCTLAndStake: "SponsorProtocolFeeAndMintGCTLAndStake";
|
|
47
|
+
readonly PayProtocolDepositUsingStakedControl: "PayProtocolDepositUsingStakedControl";
|
|
48
|
+
};
|
|
49
|
+
export type PendingTransferType = (typeof TRANSFER_TYPES)[keyof typeof TRANSFER_TYPES];
|
|
39
50
|
export interface TransferDetails extends PendingTransfer {
|
|
40
51
|
blockNumber: string;
|
|
41
52
|
failureInfo?: {
|
|
@@ -190,6 +201,7 @@ export interface KickstarterDetails extends Kickstarter {
|
|
|
190
201
|
contributorsCount: number;
|
|
191
202
|
farmCount: number;
|
|
192
203
|
solarFarmApplications: SolarFarmApplication[];
|
|
204
|
+
sponsoredFarms: SponsoredFarm[];
|
|
193
205
|
}
|
|
194
206
|
export interface CommitKickstarterPayload {
|
|
195
207
|
wallet: string;
|
|
@@ -86,6 +86,21 @@ export declare const commitKickstarterEIP712Types: {
|
|
|
86
86
|
readonly type: "uint256";
|
|
87
87
|
}];
|
|
88
88
|
};
|
|
89
|
+
export declare const payProtocolDepositUsingStakedControlEIP712Types: {
|
|
90
|
+
readonly PayProtocolDepositUsingStakedControl: readonly [{
|
|
91
|
+
readonly name: "amount";
|
|
92
|
+
readonly type: "uint256";
|
|
93
|
+
}, {
|
|
94
|
+
readonly name: "applicationId";
|
|
95
|
+
readonly type: "string";
|
|
96
|
+
}, {
|
|
97
|
+
readonly name: "nonce";
|
|
98
|
+
readonly type: "uint256";
|
|
99
|
+
}, {
|
|
100
|
+
readonly name: "deadline";
|
|
101
|
+
readonly type: "uint256";
|
|
102
|
+
}];
|
|
103
|
+
};
|
|
89
104
|
export declare const stakeSignatureRequestSchema: z.ZodObject<{
|
|
90
105
|
wallet: z.ZodString;
|
|
91
106
|
signature: z.ZodString;
|
|
@@ -128,11 +143,20 @@ export declare const commitKickstarterSignatureRequestSchema: z.ZodObject<{
|
|
|
128
143
|
kickstarterId: z.ZodString;
|
|
129
144
|
deadline: z.ZodString;
|
|
130
145
|
}, z.core.$strip>;
|
|
146
|
+
export declare const payProtocolDepositUsingStakedControlSignatureRequestSchema: z.ZodObject<{
|
|
147
|
+
wallet: z.ZodString;
|
|
148
|
+
signature: z.ZodString;
|
|
149
|
+
nonce: z.ZodString;
|
|
150
|
+
amount: z.ZodString;
|
|
151
|
+
applicationId: z.ZodString;
|
|
152
|
+
deadline: z.ZodString;
|
|
153
|
+
}, z.core.$strip>;
|
|
131
154
|
export type StakeSignatureRequest = z.infer<typeof stakeSignatureRequestSchema>;
|
|
132
155
|
export type UnstakeUnlockSignatureRequest = z.infer<typeof unstakeUnlockSignatureRequestSchema>;
|
|
133
156
|
export type UnstakeMoveSignatureRequest = z.infer<typeof unstakeMoveSignatureRequestSchema>;
|
|
134
157
|
export type RestakeSignatureRequest = z.infer<typeof restakeSignatureRequestSchema>;
|
|
135
158
|
export type CommitKickstarterSignatureRequest = z.infer<typeof commitKickstarterSignatureRequestSchema>;
|
|
159
|
+
export type PayProtocolDepositUsingStakedControlSignatureRequest = z.infer<typeof payProtocolDepositUsingStakedControlSignatureRequestSchema>;
|
|
136
160
|
export type StakeMessage = {
|
|
137
161
|
nonce: bigint;
|
|
138
162
|
amount: bigint;
|
|
@@ -165,6 +189,12 @@ export type CommitKickstarterMessage = {
|
|
|
165
189
|
kickstarterId: string;
|
|
166
190
|
deadline: bigint;
|
|
167
191
|
};
|
|
192
|
+
export type PayProtocolDepositUsingStakedControlMessage = {
|
|
193
|
+
amount: bigint;
|
|
194
|
+
applicationId: string;
|
|
195
|
+
nonce: bigint;
|
|
196
|
+
deadline: bigint;
|
|
197
|
+
};
|
|
168
198
|
export type SignatureValidationReason = "deadline_expired" | "signature_failed" | "signer_mismatch" | null;
|
|
169
199
|
export type SignatureValidationResult = {
|
|
170
200
|
valid: boolean;
|
|
@@ -176,14 +206,17 @@ type UnstakeUnlockMessageInput = Pick<UnstakeUnlockSignatureRequest, "nonce" | "
|
|
|
176
206
|
type UnstakeMoveMessageInput = Pick<UnstakeMoveSignatureRequest, "nonce" | "amount" | "fromZoneId" | "toZoneId" | "deadline">;
|
|
177
207
|
type RestakeMessageInput = Pick<RestakeSignatureRequest, "nonce" | "amount" | "fromZoneId" | "toZoneId" | "deadline">;
|
|
178
208
|
type CommitKickstarterMessageInput = Pick<CommitKickstarterSignatureRequest, "nonce" | "amount" | "kickstarterId" | "deadline">;
|
|
209
|
+
type PayProtocolDepositUsingStakedControlMessageInput = Pick<PayProtocolDepositUsingStakedControlSignatureRequest, "amount" | "applicationId" | "nonce" | "deadline">;
|
|
179
210
|
export declare function buildStakeMessage(req: StakeMessageInput): StakeMessage;
|
|
180
211
|
export declare function buildUnstakeUnlockMessage(req: UnstakeUnlockMessageInput): UnstakeUnlockMessage;
|
|
181
212
|
export declare function buildUnstakeMoveMessage(req: UnstakeMoveMessageInput): UnstakeMoveMessage;
|
|
182
213
|
export declare function buildRestakeMessage(req: RestakeMessageInput): RestakeMessage;
|
|
183
214
|
export declare function buildCommitKickstarterMessage(req: CommitKickstarterMessageInput): CommitKickstarterMessage;
|
|
215
|
+
export declare function buildPayProtocolDepositUsingStakedControlMessage(req: PayProtocolDepositUsingStakedControlMessageInput): PayProtocolDepositUsingStakedControlMessage;
|
|
184
216
|
export declare function validateStakeSignature(input: StakeSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
185
217
|
export declare function validateUnstakeUnlockSignature(input: UnstakeUnlockSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
186
218
|
export declare function validateUnstakeMoveSignature(input: UnstakeMoveSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
187
219
|
export declare function validateRestakeSignature(input: RestakeSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
188
220
|
export declare function validateCommitKickstarterSignature(input: CommitKickstarterSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
221
|
+
export declare function validatePayProtocolDepositUsingStakedControlSignature(input: PayProtocolDepositUsingStakedControlSignatureRequest, domain?: ReturnType<typeof stakeControlEIP712Domain>): Promise<SignatureValidationResult>;
|
|
189
222
|
export {};
|
package/package.json
CHANGED
|
@@ -19,6 +19,22 @@ import type {
|
|
|
19
19
|
RestakeRequest,
|
|
20
20
|
} from "../types";
|
|
21
21
|
|
|
22
|
+
export interface PayProtocolDepositUsingStakedControlRequest {
|
|
23
|
+
wallet: string;
|
|
24
|
+
regionId: number;
|
|
25
|
+
applicationId: string;
|
|
26
|
+
amount: string;
|
|
27
|
+
signature: string;
|
|
28
|
+
deadline: string;
|
|
29
|
+
nonce: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PayProtocolDepositUsingStakedControlResponse {
|
|
33
|
+
success: true;
|
|
34
|
+
farmId: string;
|
|
35
|
+
applicationId: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
22
38
|
// --------------------------------------------------------------------------
|
|
23
39
|
|
|
24
40
|
/**
|
|
@@ -229,6 +245,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
229
245
|
let isUnstaking = false;
|
|
230
246
|
let isRestaking = false;
|
|
231
247
|
let isRetryingFailedOperation = false;
|
|
248
|
+
let isPayingProtocolDepositUsingStakedControl = false;
|
|
232
249
|
|
|
233
250
|
const stakeGctl = async (stakeRequest: StakeRequest): Promise<boolean> => {
|
|
234
251
|
isStaking = true;
|
|
@@ -299,6 +316,28 @@ export function ControlRouter(baseUrl: string) {
|
|
|
299
316
|
}
|
|
300
317
|
};
|
|
301
318
|
|
|
319
|
+
const payProtocolDepositUsingStakedControl = async (
|
|
320
|
+
paymentRequest: PayProtocolDepositUsingStakedControlRequest
|
|
321
|
+
): Promise<PayProtocolDepositUsingStakedControlResponse> => {
|
|
322
|
+
isPayingProtocolDepositUsingStakedControl = true;
|
|
323
|
+
try {
|
|
324
|
+
const response =
|
|
325
|
+
await request<PayProtocolDepositUsingStakedControlResponse>(
|
|
326
|
+
`/pay-protocol-deposit-staked`,
|
|
327
|
+
{
|
|
328
|
+
method: "POST",
|
|
329
|
+
headers: { "Content-Type": "application/json" },
|
|
330
|
+
body: JSON.stringify(paymentRequest),
|
|
331
|
+
}
|
|
332
|
+
);
|
|
333
|
+
return response;
|
|
334
|
+
} catch (error) {
|
|
335
|
+
throw new Error(parseApiError(error));
|
|
336
|
+
} finally {
|
|
337
|
+
isPayingProtocolDepositUsingStakedControl = false;
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
302
341
|
// --------------------------- Public API ----------------------------------
|
|
303
342
|
return {
|
|
304
343
|
// Queries
|
|
@@ -322,6 +361,7 @@ export function ControlRouter(baseUrl: string) {
|
|
|
322
361
|
unstakeGctl,
|
|
323
362
|
restakeGctl,
|
|
324
363
|
retryFailedOperation,
|
|
364
|
+
payProtocolDepositUsingStakedControl,
|
|
325
365
|
|
|
326
366
|
// Processing flags
|
|
327
367
|
get isStaking() {
|
|
@@ -336,5 +376,8 @@ export function ControlRouter(baseUrl: string) {
|
|
|
336
376
|
get isRetryingFailedOperation() {
|
|
337
377
|
return isRetryingFailedOperation;
|
|
338
378
|
},
|
|
379
|
+
get isPayingProtocolDepositUsingStakedControl() {
|
|
380
|
+
return isPayingProtocolDepositUsingStakedControl;
|
|
381
|
+
},
|
|
339
382
|
} as const;
|
|
340
383
|
}
|
|
@@ -3,7 +3,7 @@ import { FORWARDER_ABI } from "../abis/forwarderABI";
|
|
|
3
3
|
import { ERC20_ABI } from "../abis/erc20.abi";
|
|
4
4
|
import { getAddresses } from "../../constants/addresses";
|
|
5
5
|
import { formatEther } from "viem";
|
|
6
|
-
import { PendingTransferType } from "../types";
|
|
6
|
+
import { PendingTransferType, TRANSFER_TYPES } from "../types";
|
|
7
7
|
|
|
8
8
|
export enum ForwarderError {
|
|
9
9
|
CONTRACT_NOT_AVAILABLE = "Contract not available",
|
|
@@ -96,55 +96,55 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
96
96
|
} = params;
|
|
97
97
|
|
|
98
98
|
switch (type) {
|
|
99
|
-
case
|
|
99
|
+
case TRANSFER_TYPES.PayProtocolFeeAndMintGCTLAndStake:
|
|
100
100
|
if (!applicationId) {
|
|
101
101
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
102
102
|
}
|
|
103
103
|
return `PayProtocolFeeAndMintGCTLAndStake::${applicationId}`;
|
|
104
104
|
|
|
105
|
-
case
|
|
105
|
+
case TRANSFER_TYPES.PayProtocolFee:
|
|
106
106
|
if (!applicationId) {
|
|
107
107
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
108
108
|
}
|
|
109
109
|
return `PayProtocolFee::${applicationId}`;
|
|
110
110
|
|
|
111
|
-
case
|
|
111
|
+
case TRANSFER_TYPES.SponsorProtocolFee:
|
|
112
112
|
if (!applicationId) {
|
|
113
113
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
114
114
|
}
|
|
115
115
|
return `SponsorProtocolFee::${applicationId}`;
|
|
116
116
|
|
|
117
|
-
case
|
|
117
|
+
case TRANSFER_TYPES.SponsorProtocolFeeAndMintGCTLAndStake:
|
|
118
118
|
if (!applicationId) {
|
|
119
119
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
120
120
|
}
|
|
121
121
|
return `SponsorProtocolFeeAndMintGCTLAndStake::${applicationId}`;
|
|
122
122
|
|
|
123
|
-
case
|
|
123
|
+
case TRANSFER_TYPES.MintGCTLAndStake:
|
|
124
124
|
if (!regionId) {
|
|
125
125
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
126
126
|
}
|
|
127
127
|
return `MintGCTLAndStake::${regionId}`;
|
|
128
128
|
|
|
129
|
-
case
|
|
129
|
+
case TRANSFER_TYPES.MintGCTL:
|
|
130
130
|
if (!userAddress) {
|
|
131
131
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
132
132
|
}
|
|
133
133
|
return `MintGCTL::${userAddress}`;
|
|
134
134
|
|
|
135
|
-
case
|
|
135
|
+
case TRANSFER_TYPES.BuySolarFarm:
|
|
136
136
|
if (!farmId) {
|
|
137
137
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
138
138
|
}
|
|
139
139
|
return `BuySolarFarm::${farmId}`;
|
|
140
140
|
|
|
141
|
-
case
|
|
141
|
+
case TRANSFER_TYPES.PayAuditFees:
|
|
142
142
|
if (!applicationId) {
|
|
143
143
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
144
144
|
}
|
|
145
145
|
return `PayAuditFees::${applicationId}`;
|
|
146
146
|
|
|
147
|
-
case
|
|
147
|
+
case TRANSFER_TYPES.CommitKickstarter:
|
|
148
148
|
if (!kickstarterId) {
|
|
149
149
|
throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
|
|
150
150
|
}
|
|
@@ -288,13 +288,14 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
288
288
|
const message = constructForwardMessage(params);
|
|
289
289
|
|
|
290
290
|
// Special handling: PayAuditFees can ONLY be USDC, and must call forward()
|
|
291
|
-
const isAuditFees = params.type ===
|
|
291
|
+
const isAuditFees = params.type === TRANSFER_TYPES.PayAuditFees;
|
|
292
292
|
if (isAuditFees && currency !== "USDC") {
|
|
293
293
|
throw new Error("PayAuditFees only supports USDC");
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
// CommitKickstarter supports only USDC or USDG (GLW not allowed)
|
|
297
|
-
const isCommitKickstarter =
|
|
297
|
+
const isCommitKickstarter =
|
|
298
|
+
params.type === TRANSFER_TYPES.CommitKickstarter;
|
|
298
299
|
if (isCommitKickstarter && currency === "GLW") {
|
|
299
300
|
throw new Error("CommitKickstarter supports only USDC or USDG");
|
|
300
301
|
}
|
|
@@ -410,7 +411,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
410
411
|
return forwardTokens({
|
|
411
412
|
amount,
|
|
412
413
|
userAddress,
|
|
413
|
-
type:
|
|
414
|
+
type: TRANSFER_TYPES.PayProtocolFeeAndMintGCTLAndStake,
|
|
414
415
|
currency,
|
|
415
416
|
applicationId,
|
|
416
417
|
regionId,
|
|
@@ -436,7 +437,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
436
437
|
return forwardTokens({
|
|
437
438
|
amount,
|
|
438
439
|
userAddress,
|
|
439
|
-
type:
|
|
440
|
+
type: TRANSFER_TYPES.SponsorProtocolFeeAndMintGCTLAndStake,
|
|
440
441
|
currency,
|
|
441
442
|
applicationId,
|
|
442
443
|
});
|
|
@@ -456,7 +457,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
456
457
|
return forwardTokens({
|
|
457
458
|
amount,
|
|
458
459
|
userAddress,
|
|
459
|
-
type:
|
|
460
|
+
type: TRANSFER_TYPES.PayProtocolFee,
|
|
460
461
|
currency,
|
|
461
462
|
applicationId,
|
|
462
463
|
});
|
|
@@ -476,7 +477,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
476
477
|
return forwardTokens({
|
|
477
478
|
amount,
|
|
478
479
|
userAddress,
|
|
479
|
-
type:
|
|
480
|
+
type: TRANSFER_TYPES.SponsorProtocolFee,
|
|
480
481
|
currency,
|
|
481
482
|
applicationId,
|
|
482
483
|
});
|
|
@@ -503,7 +504,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
503
504
|
return forwardTokens({
|
|
504
505
|
amount,
|
|
505
506
|
userAddress,
|
|
506
|
-
type:
|
|
507
|
+
type: TRANSFER_TYPES.MintGCTLAndStake,
|
|
507
508
|
currency,
|
|
508
509
|
regionId,
|
|
509
510
|
});
|
|
@@ -529,7 +530,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
529
530
|
return forwardTokens({
|
|
530
531
|
amount,
|
|
531
532
|
userAddress,
|
|
532
|
-
type:
|
|
533
|
+
type: TRANSFER_TYPES.MintGCTL,
|
|
533
534
|
currency,
|
|
534
535
|
});
|
|
535
536
|
}
|
|
@@ -547,7 +548,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
547
548
|
return forwardTokens({
|
|
548
549
|
amount,
|
|
549
550
|
userAddress,
|
|
550
|
-
type:
|
|
551
|
+
type: TRANSFER_TYPES.PayAuditFees,
|
|
551
552
|
currency: "USDC",
|
|
552
553
|
applicationId,
|
|
553
554
|
});
|
|
@@ -567,7 +568,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
567
568
|
return forwardTokens({
|
|
568
569
|
amount,
|
|
569
570
|
userAddress,
|
|
570
|
-
type:
|
|
571
|
+
type: TRANSFER_TYPES.BuySolarFarm,
|
|
571
572
|
currency,
|
|
572
573
|
farmId,
|
|
573
574
|
});
|
|
@@ -591,7 +592,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
591
592
|
return forwardTokens({
|
|
592
593
|
amount,
|
|
593
594
|
userAddress,
|
|
594
|
-
type:
|
|
595
|
+
type: TRANSFER_TYPES.CommitKickstarter,
|
|
595
596
|
currency,
|
|
596
597
|
kickstarterId,
|
|
597
598
|
});
|
|
@@ -614,7 +615,7 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
|
|
|
614
615
|
throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
|
|
615
616
|
|
|
616
617
|
const { amount, currency = "USDC" } = params;
|
|
617
|
-
const isAuditFees = params.type ===
|
|
618
|
+
const isAuditFees = params.type === TRANSFER_TYPES.PayAuditFees;
|
|
618
619
|
if (isAuditFees && currency !== "USDC") {
|
|
619
620
|
throw new Error("PayAuditFees only supports USDC");
|
|
620
621
|
}
|
package/src/lib/types/index.ts
CHANGED
|
@@ -51,20 +51,23 @@ export interface PendingTransfer {
|
|
|
51
51
|
kickstarterId?: string;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export const TRANSFER_TYPES =
|
|
55
|
-
"PayProtocolFeeAndMintGCTLAndStake",
|
|
56
|
-
"PayProtocolFee",
|
|
57
|
-
"PayAuditFees",
|
|
58
|
-
"CommitKickstarter",
|
|
59
|
-
"MintGCTLAndStake",
|
|
60
|
-
"MintGCTL",
|
|
61
|
-
"BuySolarFarm",
|
|
62
|
-
"SponsorProtocolFee",
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
export const TRANSFER_TYPES = {
|
|
55
|
+
PayProtocolFeeAndMintGCTLAndStake: "PayProtocolFeeAndMintGCTLAndStake",
|
|
56
|
+
PayProtocolFee: "PayProtocolFee",
|
|
57
|
+
PayAuditFees: "PayAuditFees",
|
|
58
|
+
CommitKickstarter: "CommitKickstarter",
|
|
59
|
+
MintGCTLAndStake: "MintGCTLAndStake",
|
|
60
|
+
MintGCTL: "MintGCTL",
|
|
61
|
+
BuySolarFarm: "BuySolarFarm",
|
|
62
|
+
SponsorProtocolFee: "SponsorProtocolFee",
|
|
63
|
+
SponsorProtocolFeeAndMintGCTLAndStake:
|
|
64
|
+
"SponsorProtocolFeeAndMintGCTLAndStake",
|
|
65
|
+
PayProtocolDepositUsingStakedControl: "PayProtocolDepositUsingStakedControl",
|
|
66
|
+
} as const;
|
|
65
67
|
|
|
66
68
|
// Pending transfer type filter for listing endpoint
|
|
67
|
-
export type PendingTransferType =
|
|
69
|
+
export type PendingTransferType =
|
|
70
|
+
(typeof TRANSFER_TYPES)[keyof typeof TRANSFER_TYPES];
|
|
68
71
|
|
|
69
72
|
export interface TransferDetails extends PendingTransfer {
|
|
70
73
|
blockNumber: string;
|
|
@@ -251,6 +254,7 @@ export interface KickstarterDetails extends Kickstarter {
|
|
|
251
254
|
contributorsCount: number;
|
|
252
255
|
farmCount: number;
|
|
253
256
|
solarFarmApplications: SolarFarmApplication[];
|
|
257
|
+
sponsoredFarms: SponsoredFarm[];
|
|
254
258
|
}
|
|
255
259
|
|
|
256
260
|
export interface CommitKickstarterPayload {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TRANSFER_TYPES } from "src/browser";
|
|
2
|
+
import { verifyTypedData, type Hex, getAddress } from "viem";
|
|
2
3
|
import z from "zod";
|
|
3
4
|
|
|
4
5
|
export const stakeControlEIP712Domain = (chainId: number) => ({
|
|
@@ -57,6 +58,15 @@ export const commitKickstarterEIP712Types = {
|
|
|
57
58
|
],
|
|
58
59
|
} as const;
|
|
59
60
|
|
|
61
|
+
export const payProtocolDepositUsingStakedControlEIP712Types = {
|
|
62
|
+
PayProtocolDepositUsingStakedControl: [
|
|
63
|
+
{ name: "amount", type: "uint256" },
|
|
64
|
+
{ name: "applicationId", type: "string" },
|
|
65
|
+
{ name: "nonce", type: "uint256" },
|
|
66
|
+
{ name: "deadline", type: "uint256" },
|
|
67
|
+
],
|
|
68
|
+
} as const;
|
|
69
|
+
|
|
60
70
|
// Separate request schemas for clarity between stake and unstake
|
|
61
71
|
export const stakeSignatureRequestSchema = z.object({
|
|
62
72
|
wallet: z.string().regex(/^0x[a-fA-F0-9]{40}$/),
|
|
@@ -105,6 +115,16 @@ export const commitKickstarterSignatureRequestSchema = z.object({
|
|
|
105
115
|
deadline: z.string(),
|
|
106
116
|
});
|
|
107
117
|
|
|
118
|
+
export const payProtocolDepositUsingStakedControlSignatureRequestSchema =
|
|
119
|
+
z.object({
|
|
120
|
+
wallet: z.string().regex(/^0x[a-fA-F0-9]{40}$/),
|
|
121
|
+
signature: z.string().regex(/^0x[a-fA-F0-9]{130}$/),
|
|
122
|
+
nonce: z.string(),
|
|
123
|
+
amount: z.string(),
|
|
124
|
+
applicationId: z.string(),
|
|
125
|
+
deadline: z.string(),
|
|
126
|
+
});
|
|
127
|
+
|
|
108
128
|
export type StakeSignatureRequest = z.infer<typeof stakeSignatureRequestSchema>;
|
|
109
129
|
export type UnstakeUnlockSignatureRequest = z.infer<
|
|
110
130
|
typeof unstakeUnlockSignatureRequestSchema
|
|
@@ -118,6 +138,9 @@ export type RestakeSignatureRequest = z.infer<
|
|
|
118
138
|
export type CommitKickstarterSignatureRequest = z.infer<
|
|
119
139
|
typeof commitKickstarterSignatureRequestSchema
|
|
120
140
|
>;
|
|
141
|
+
export type PayProtocolDepositUsingStakedControlSignatureRequest = z.infer<
|
|
142
|
+
typeof payProtocolDepositUsingStakedControlSignatureRequestSchema
|
|
143
|
+
>;
|
|
121
144
|
|
|
122
145
|
export type StakeMessage = {
|
|
123
146
|
nonce: bigint;
|
|
@@ -156,6 +179,13 @@ export type CommitKickstarterMessage = {
|
|
|
156
179
|
deadline: bigint;
|
|
157
180
|
};
|
|
158
181
|
|
|
182
|
+
export type PayProtocolDepositUsingStakedControlMessage = {
|
|
183
|
+
amount: bigint;
|
|
184
|
+
applicationId: string;
|
|
185
|
+
nonce: bigint;
|
|
186
|
+
deadline: bigint;
|
|
187
|
+
};
|
|
188
|
+
|
|
159
189
|
export type SignatureValidationReason =
|
|
160
190
|
| "deadline_expired"
|
|
161
191
|
| "signature_failed"
|
|
@@ -196,6 +226,11 @@ type CommitKickstarterMessageInput = Pick<
|
|
|
196
226
|
"nonce" | "amount" | "kickstarterId" | "deadline"
|
|
197
227
|
>;
|
|
198
228
|
|
|
229
|
+
type PayProtocolDepositUsingStakedControlMessageInput = Pick<
|
|
230
|
+
PayProtocolDepositUsingStakedControlSignatureRequest,
|
|
231
|
+
"amount" | "applicationId" | "nonce" | "deadline"
|
|
232
|
+
>;
|
|
233
|
+
|
|
199
234
|
export function buildStakeMessage(req: StakeMessageInput): StakeMessage {
|
|
200
235
|
const nonce = BigInt(req.nonce);
|
|
201
236
|
const amount = BigInt(req.amount);
|
|
@@ -266,6 +301,20 @@ export function buildCommitKickstarterMessage(
|
|
|
266
301
|
return { nonce, amount, kickstarterId, deadline };
|
|
267
302
|
}
|
|
268
303
|
|
|
304
|
+
export function buildPayProtocolDepositUsingStakedControlMessage(
|
|
305
|
+
req: PayProtocolDepositUsingStakedControlMessageInput
|
|
306
|
+
): PayProtocolDepositUsingStakedControlMessage {
|
|
307
|
+
const amount = BigInt(req.amount);
|
|
308
|
+
const nonce = BigInt(req.nonce);
|
|
309
|
+
const deadline = BigInt(req.deadline);
|
|
310
|
+
const applicationId = req.applicationId;
|
|
311
|
+
if (amount < 0n) throw new Error("Amount must be non-negative");
|
|
312
|
+
if (nonce < 0n) throw new Error("Nonce must be non-negative");
|
|
313
|
+
if (deadline < 0n) throw new Error("Deadline must be non-negative");
|
|
314
|
+
if (!applicationId) throw new Error("applicationId must be non-empty");
|
|
315
|
+
return { amount, applicationId, nonce, deadline };
|
|
316
|
+
}
|
|
317
|
+
|
|
269
318
|
// Helper to validate the signature using viem
|
|
270
319
|
export async function validateStakeSignature(
|
|
271
320
|
input: StakeSignatureRequest,
|
|
@@ -428,3 +477,35 @@ export async function validateCommitKickstarterSignature(
|
|
|
428
477
|
return { valid: false, recovered: null, reason: "signature_failed" };
|
|
429
478
|
}
|
|
430
479
|
}
|
|
480
|
+
|
|
481
|
+
export async function validatePayProtocolDepositUsingStakedControlSignature(
|
|
482
|
+
input: PayProtocolDepositUsingStakedControlSignatureRequest,
|
|
483
|
+
domain: ReturnType<
|
|
484
|
+
typeof stakeControlEIP712Domain
|
|
485
|
+
> = stakeControlEIP712Domain(1)
|
|
486
|
+
): Promise<SignatureValidationResult> {
|
|
487
|
+
const message = buildPayProtocolDepositUsingStakedControlMessage({
|
|
488
|
+
amount: input.amount,
|
|
489
|
+
applicationId: input.applicationId,
|
|
490
|
+
nonce: input.nonce,
|
|
491
|
+
deadline: input.deadline,
|
|
492
|
+
});
|
|
493
|
+
if (isDeadlineExpired(message.deadline)) {
|
|
494
|
+
return { valid: false, recovered: null, reason: "deadline_expired" };
|
|
495
|
+
}
|
|
496
|
+
try {
|
|
497
|
+
const verified = await verifyTypedData({
|
|
498
|
+
address: getAddress(input.wallet as Hex),
|
|
499
|
+
domain,
|
|
500
|
+
types: payProtocolDepositUsingStakedControlEIP712Types,
|
|
501
|
+
primaryType: TRANSFER_TYPES.PayProtocolDepositUsingStakedControl,
|
|
502
|
+
message,
|
|
503
|
+
signature: input.signature as Hex,
|
|
504
|
+
});
|
|
505
|
+
return verified
|
|
506
|
+
? { valid: true, recovered: input.wallet, reason: null }
|
|
507
|
+
: { valid: false, recovered: null, reason: "signer_mismatch" };
|
|
508
|
+
} catch (_) {
|
|
509
|
+
return { valid: false, recovered: null, reason: "signature_failed" };
|
|
510
|
+
}
|
|
511
|
+
}
|