@glowlabs-org/utils 0.2.142 → 0.2.145

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.
@@ -10,3 +10,4 @@ export { RegionRouter } from "./lib/control-api/region-router";
10
10
  export { KickstarterRouter } from "./lib/control-api/kickstarter-router";
11
11
  export { WalletsRouter } from "./lib/control-api/wallets-router";
12
12
  export { FarmsRouter } from "./lib/control-api/farms-router";
13
+ export { configureSentry, type SentryClientLike } from "./utils/sentry";
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-Cxbn5Hap.js';
17
- export { C as ControlRouter, F as FarmsRouter, c 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, u as useForwarder, a as useOffchainFractions } from './farms-router-Cxbn5Hap.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-C_7Ys4An.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-C_7Ys4An.js';
18
18
 
19
19
  const GENESIS_TIMESTAMP = 1700352000;
20
20
 
@@ -1,4 +1,4 @@
1
- import type { RegionWithMetadata, ActivationConfig, CreateRegionPayload, ActivationEvent, RegionDetails, SponsoredFarm } from "../types";
1
+ import type { RegionWithMetadata, ActivationConfig, ActivationEvent, RegionDetails, SponsoredFarm } from "../types";
2
2
  export declare function RegionRouter(baseUrl: string): {
3
3
  readonly fetchRegions: (params?: {
4
4
  isActive?: boolean;
@@ -8,8 +8,6 @@ export declare function RegionRouter(baseUrl: string): {
8
8
  readonly fetchRegionByIdOrSlug: (idOrSlug: string) => Promise<RegionDetails>;
9
9
  readonly fetchRegionSolarFarms: (regionId: number) => Promise<SponsoredFarm[]>;
10
10
  readonly getRegionByCode: (code: string) => RegionWithMetadata | null;
11
- readonly createRegion: (payload: CreateRegionPayload) => Promise<void>;
12
11
  readonly regions: RegionWithMetadata[];
13
12
  readonly isLoading: boolean;
14
- readonly isCreatingRegion: boolean;
15
13
  };
@@ -0,0 +1,21 @@
1
+ export interface SentryBreadcrumb {
2
+ category: string;
3
+ message?: string;
4
+ level?: "error" | "warning" | "info" | "debug";
5
+ data?: Record<string, unknown>;
6
+ }
7
+ export interface SentryClientLike {
8
+ captureException: (error: unknown, context?: {
9
+ extra?: Record<string, unknown>;
10
+ }) => void;
11
+ addBreadcrumb?: (breadcrumb: SentryBreadcrumb) => void;
12
+ }
13
+ type SentryConfig = {
14
+ enabled?: boolean;
15
+ client?: SentryClientLike | null;
16
+ defaultContext?: Record<string, unknown>;
17
+ };
18
+ export declare function configureSentry(config: SentryConfig): void;
19
+ export declare function sentryAddBreadcrumb(breadcrumb: SentryBreadcrumb): void;
20
+ export declare function sentryCaptureException(error: unknown, extra?: Record<string, unknown>): void;
21
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glowlabs-org/utils",
3
- "version": "0.2.142",
3
+ "version": "0.2.145",
4
4
  "description": "A library containing all typechain types and addresses relating to the glow guarded launch",
5
5
  "keywords": [],
6
6
  "author": "",
package/src/browser.ts CHANGED
@@ -14,3 +14,4 @@ export * from "./constants/weights";
14
14
  export * from "./constants/urls";
15
15
  export * from "./utils/stake-control";
16
16
  export * from "./utils/transaction-utils";
17
+ export { configureSentry, type SentryClientLike } from "./utils/sentry";
package/src/index.ts CHANGED
@@ -13,3 +13,4 @@ export { RegionRouter } from "./lib/control-api/region-router";
13
13
  export { KickstarterRouter } from "./lib/control-api/kickstarter-router";
14
14
  export { WalletsRouter } from "./lib/control-api/wallets-router";
15
15
  export { FarmsRouter } from "./lib/control-api/farms-router";
16
+ export { configureSentry, type SentryClientLike } from "./utils/sentry";
@@ -20,6 +20,10 @@ import type {
20
20
  RestakeRequest,
21
21
  MigrationAmountResponse,
22
22
  } from "../types";
23
+ import {
24
+ sentryAddBreadcrumb,
25
+ sentryCaptureException,
26
+ } from "../../utils/sentry";
23
27
 
24
28
  export interface PayProtocolDepositUsingStakedControlRequest {
25
29
  wallet: string;
@@ -288,6 +292,16 @@ export function ControlRouter(baseUrl: string) {
288
292
  const stakeGctl = async (stakeRequest: StakeRequest): Promise<boolean> => {
289
293
  isStaking = true;
290
294
  try {
295
+ sentryAddBreadcrumb({
296
+ category: "control-api",
297
+ message: "POST /stake",
298
+ level: "info",
299
+ data: {
300
+ baseUrl,
301
+ wallet: stakeRequest.wallet,
302
+ regionId: stakeRequest.regionId,
303
+ },
304
+ });
291
305
  await request(`/stake`, {
292
306
  method: "POST",
293
307
  headers: { "Content-Type": "application/json" },
@@ -295,6 +309,14 @@ export function ControlRouter(baseUrl: string) {
295
309
  });
296
310
  return true;
297
311
  } catch (error) {
312
+ sentryCaptureException(error, {
313
+ action: "stakeGctl",
314
+ baseUrl,
315
+ wallet: stakeRequest.wallet,
316
+ regionId: stakeRequest.regionId,
317
+ amount: stakeRequest.amount,
318
+ deadline: stakeRequest.deadline,
319
+ });
298
320
  throw new Error(parseApiError(error));
299
321
  } finally {
300
322
  isStaking = false;
@@ -306,6 +328,16 @@ export function ControlRouter(baseUrl: string) {
306
328
  ): Promise<boolean> => {
307
329
  isUnstaking = true;
308
330
  try {
331
+ sentryAddBreadcrumb({
332
+ category: "control-api",
333
+ message: "POST /unstake",
334
+ level: "info",
335
+ data: {
336
+ baseUrl,
337
+ wallet: unstakeRequest.wallet,
338
+ regionId: unstakeRequest.regionId,
339
+ },
340
+ });
309
341
  await request(`/unstake`, {
310
342
  method: "POST",
311
343
  headers: { "Content-Type": "application/json" },
@@ -313,6 +345,14 @@ export function ControlRouter(baseUrl: string) {
313
345
  });
314
346
  return true;
315
347
  } catch (error) {
348
+ sentryCaptureException(error, {
349
+ action: "unstakeGctl",
350
+ baseUrl,
351
+ wallet: unstakeRequest.wallet,
352
+ regionId: unstakeRequest.regionId,
353
+ amount: unstakeRequest.amount,
354
+ deadline: unstakeRequest.deadline,
355
+ });
316
356
  throw new Error(parseApiError(error));
317
357
  } finally {
318
358
  isUnstaking = false;
@@ -324,6 +364,17 @@ export function ControlRouter(baseUrl: string) {
324
364
  ): Promise<boolean> => {
325
365
  isRestaking = true;
326
366
  try {
367
+ sentryAddBreadcrumb({
368
+ category: "control-api",
369
+ message: "POST /restake",
370
+ level: "info",
371
+ data: {
372
+ baseUrl,
373
+ wallet: restakeRequest.wallet,
374
+ fromZoneId: restakeRequest.fromZoneId,
375
+ toZoneId: restakeRequest.toZoneId,
376
+ },
377
+ });
327
378
  await request(`/restake`, {
328
379
  method: "POST",
329
380
  headers: { "Content-Type": "application/json" },
@@ -331,6 +382,15 @@ export function ControlRouter(baseUrl: string) {
331
382
  });
332
383
  return true;
333
384
  } catch (error) {
385
+ sentryCaptureException(error, {
386
+ action: "restakeGctl",
387
+ baseUrl,
388
+ wallet: restakeRequest.wallet,
389
+ fromZoneId: restakeRequest.fromZoneId,
390
+ toZoneId: restakeRequest.toZoneId,
391
+ amount: restakeRequest.amount,
392
+ deadline: restakeRequest.deadline,
393
+ });
334
394
  throw new Error(parseApiError(error));
335
395
  } finally {
336
396
  isRestaking = false;
@@ -342,12 +402,23 @@ export function ControlRouter(baseUrl: string) {
342
402
  ): Promise<boolean> => {
343
403
  isRetryingFailedOperation = true;
344
404
  try {
405
+ sentryAddBreadcrumb({
406
+ category: "control-api",
407
+ message: "POST /operations/failed/:id/retry",
408
+ level: "info",
409
+ data: { baseUrl, operationId },
410
+ });
345
411
  await request(`/operations/failed/${operationId}/retry`, {
346
412
  method: "POST",
347
413
  headers: { "Content-Type": "application/json" },
348
414
  });
349
415
  return true;
350
416
  } catch (error) {
417
+ sentryCaptureException(error, {
418
+ action: "retryFailedOperation",
419
+ baseUrl,
420
+ operationId,
421
+ });
351
422
  throw new Error(parseApiError(error));
352
423
  } finally {
353
424
  isRetryingFailedOperation = false;
@@ -359,6 +430,18 @@ export function ControlRouter(baseUrl: string) {
359
430
  ): Promise<PayProtocolDepositUsingStakedControlResponse> => {
360
431
  isPayingProtocolDepositUsingStakedControl = true;
361
432
  try {
433
+ sentryAddBreadcrumb({
434
+ category: "control-api",
435
+ message: "POST /pay-protocol-deposit-staked",
436
+ level: "info",
437
+ data: {
438
+ baseUrl,
439
+ wallet: paymentRequest.wallet,
440
+ regionId: paymentRequest.regionId,
441
+ applicationId: paymentRequest.applicationId,
442
+ amount: paymentRequest.amount,
443
+ },
444
+ });
362
445
  const response =
363
446
  await request<PayProtocolDepositUsingStakedControlResponse>(
364
447
  `/pay-protocol-deposit-staked`,
@@ -370,6 +453,14 @@ export function ControlRouter(baseUrl: string) {
370
453
  );
371
454
  return response;
372
455
  } catch (error) {
456
+ sentryCaptureException(error, {
457
+ action: "payProtocolDepositUsingStakedControl",
458
+ baseUrl,
459
+ wallet: paymentRequest.wallet,
460
+ regionId: paymentRequest.regionId,
461
+ applicationId: paymentRequest.applicationId,
462
+ amount: paymentRequest.amount,
463
+ });
373
464
  throw new Error(parseApiError(error));
374
465
  } finally {
375
466
  isPayingProtocolDepositUsingStakedControl = false;
@@ -381,6 +472,15 @@ export function ControlRouter(baseUrl: string) {
381
472
  ): Promise<MigrateUserResponse> => {
382
473
  isMigratingUser = true;
383
474
  try {
475
+ sentryAddBreadcrumb({
476
+ category: "control-api",
477
+ message: "POST /migrate-user",
478
+ level: "info",
479
+ data: {
480
+ baseUrl,
481
+ wallet: migrateRequest.wallet,
482
+ },
483
+ });
384
484
  const response = await request<MigrateUserResponse>(`/migrate-user`, {
385
485
  method: "POST",
386
486
  headers: { "Content-Type": "application/json" },
@@ -388,6 +488,12 @@ export function ControlRouter(baseUrl: string) {
388
488
  });
389
489
  return response;
390
490
  } catch (error) {
491
+ sentryCaptureException(error, {
492
+ action: "migrateUser",
493
+ baseUrl,
494
+ wallet: migrateRequest.wallet,
495
+ deadline: migrateRequest.deadline,
496
+ });
391
497
  throw new Error(parseApiError(error));
392
498
  } finally {
393
499
  isMigratingUser = false;
@@ -47,6 +47,10 @@ import type {
47
47
  MiningScoresBatchParams,
48
48
  MiningScoresBatchResponse,
49
49
  } from "../types";
50
+ import {
51
+ sentryAddBreadcrumb,
52
+ sentryCaptureException,
53
+ } from "../../utils/sentry";
50
54
 
51
55
  function parseApiError(error: unknown): string {
52
56
  if (!error) return "Unknown error";
@@ -128,6 +132,12 @@ export function FarmsRouter(baseUrl: string) {
128
132
  params: EstimateRewardScoreParams
129
133
  ): Promise<RewardScoreResponse> => {
130
134
  try {
135
+ sentryAddBreadcrumb({
136
+ category: "control-api",
137
+ message: "POST /farms/estimate-reward-score",
138
+ level: "info",
139
+ data: { baseUrl, regionId: params.regionId, userId: params.userId },
140
+ });
131
141
  const data = await request<
132
142
  RewardScoreResponse | EstimateRewardScoreErrorResponse
133
143
  >("/farms/estimate-reward-score", {
@@ -147,6 +157,13 @@ export function FarmsRouter(baseUrl: string) {
147
157
  // All fields are required in the success response based on the API spec
148
158
  return data as RewardScoreResponse;
149
159
  } catch (error) {
160
+ sentryCaptureException(error, {
161
+ action: "estimateRewardScore",
162
+ baseUrl,
163
+ userId: params.userId,
164
+ regionId: params.regionId,
165
+ paymentCurrency: params.paymentCurrency,
166
+ });
150
167
  throw new Error(parseApiError(error));
151
168
  }
152
169
  };
@@ -155,6 +172,12 @@ export function FarmsRouter(baseUrl: string) {
155
172
  params: EstimateRewardScoresBatchParams
156
173
  ): Promise<EstimateRewardScoresBatchResponse> => {
157
174
  try {
175
+ sentryAddBreadcrumb({
176
+ category: "control-api",
177
+ message: "POST /farms/estimate-reward-scores-batch",
178
+ level: "info",
179
+ data: { baseUrl },
180
+ });
158
181
  const data = await request<EstimateRewardScoresBatchResponse>(
159
182
  "/farms/estimate-reward-scores-batch",
160
183
  {
@@ -168,6 +191,11 @@ export function FarmsRouter(baseUrl: string) {
168
191
 
169
192
  return data;
170
193
  } catch (error) {
194
+ sentryCaptureException(error, {
195
+ action: "estimateRewardScoresBatch",
196
+ baseUrl,
197
+ farmsCount: params.farms?.length,
198
+ });
171
199
  throw new Error(parseApiError(error));
172
200
  }
173
201
  };
@@ -176,6 +204,12 @@ export function FarmsRouter(baseUrl: string) {
176
204
  params: MiningScoresBatchParams
177
205
  ): Promise<MiningScoresBatchResponse> => {
178
206
  try {
207
+ sentryAddBreadcrumb({
208
+ category: "control-api",
209
+ message: "POST /farms/mining-scores-batch",
210
+ level: "info",
211
+ data: { baseUrl },
212
+ });
179
213
  const data = await request<MiningScoresBatchResponse>(
180
214
  "/farms/mining-scores-batch",
181
215
  {
@@ -189,6 +223,11 @@ export function FarmsRouter(baseUrl: string) {
189
223
 
190
224
  return data;
191
225
  } catch (error) {
226
+ sentryCaptureException(error, {
227
+ action: "calculateMiningScoresBatch",
228
+ baseUrl,
229
+ farmsCount: params.farms?.length,
230
+ });
192
231
  throw new Error(parseApiError(error));
193
232
  }
194
233
  };
@@ -11,6 +11,10 @@ import type {
11
11
  KickstarterCommitmentsQuery,
12
12
  KickstarterCommitmentsResponse,
13
13
  } from "../types";
14
+ import {
15
+ sentryAddBreadcrumb,
16
+ sentryCaptureException,
17
+ } from "../../utils/sentry";
14
18
 
15
19
  function parseApiError(error: unknown): string {
16
20
  if (!error) return "Unknown error";
@@ -49,6 +53,16 @@ export function KickstarterRouter(baseUrl: string) {
49
53
  ): Promise<KickstarterCreateResponse> => {
50
54
  isCreatingKickstarter = true;
51
55
  try {
56
+ sentryAddBreadcrumb({
57
+ category: "control-api",
58
+ message: "POST /kickstarters",
59
+ level: "info",
60
+ data: {
61
+ baseUrl,
62
+ code: payload.code,
63
+ creatorWallet: payload.creatorWallet,
64
+ },
65
+ });
52
66
  const exists = Boolean(regionMetadata[payload.code]);
53
67
  if (!exists) {
54
68
  throw new Error(`Unknown region code: ${payload.code}`);
@@ -60,6 +74,14 @@ export function KickstarterRouter(baseUrl: string) {
60
74
  });
61
75
  return data;
62
76
  } catch (error) {
77
+ sentryCaptureException(error, {
78
+ action: "createKickstarter",
79
+ baseUrl,
80
+ code: payload.code,
81
+ creatorWallet: payload.creatorWallet,
82
+ title: payload.title,
83
+ regionName: payload.regionName,
84
+ });
63
85
  throw new Error(parseApiError(error));
64
86
  } finally {
65
87
  isCreatingKickstarter = false;
@@ -97,6 +119,12 @@ export function KickstarterRouter(baseUrl: string) {
97
119
  payload: CommitKickstarterPayload
98
120
  ): Promise<CommitKickstarterResponse> => {
99
121
  try {
122
+ sentryAddBreadcrumb({
123
+ category: "control-api",
124
+ message: "POST /kickstarters/commit/:id",
125
+ level: "info",
126
+ data: { baseUrl, kickstarterId },
127
+ });
100
128
  const data = await request<CommitKickstarterResponse>(
101
129
  `/kickstarters/commit/${encodeURIComponent(kickstarterId)}`,
102
130
  {
@@ -107,6 +135,13 @@ export function KickstarterRouter(baseUrl: string) {
107
135
  );
108
136
  return data;
109
137
  } catch (error) {
138
+ sentryCaptureException(error, {
139
+ action: "commitKickstarter",
140
+ baseUrl,
141
+ kickstarterId,
142
+ wallet: payload.wallet,
143
+ amount: payload.amount,
144
+ });
110
145
  throw new Error(parseApiError(error));
111
146
  }
112
147
  };
@@ -5,7 +5,6 @@ import { regionMetadata } from "../region-metadata";
5
5
  import type {
6
6
  RegionWithMetadata,
7
7
  ActivationConfig,
8
- CreateRegionPayload,
9
8
  ActivationEvent,
10
9
  RegionDetails,
11
10
  SponsoredFarm,
@@ -43,7 +42,6 @@ export function RegionRouter(baseUrl: string) {
43
42
  // -------------------------------------------------------------------------
44
43
  let cachedRegions: RegionWithMetadata[] = [];
45
44
  let isLoading = false;
46
- let isCreatingRegion = false;
47
45
 
48
46
  // -------------------------------------------------------------------------
49
47
  // Queries
@@ -121,26 +119,6 @@ export function RegionRouter(baseUrl: string) {
121
119
  }
122
120
  };
123
121
 
124
- // -------------------------------------------------------------------------
125
- // Mutations
126
- // -------------------------------------------------------------------------
127
- const createRegion = async (payload: CreateRegionPayload): Promise<void> => {
128
- isCreatingRegion = true;
129
- try {
130
- await request(`/regions/create`, {
131
- method: "POST",
132
- headers: { "Content-Type": "application/json" },
133
- body: JSON.stringify(payload),
134
- });
135
- // Refresh the local cache after successful creation
136
- await fetchRegions();
137
- } catch (error) {
138
- throw new Error(parseApiError(error));
139
- } finally {
140
- isCreatingRegion = false;
141
- }
142
- };
143
-
144
122
  // Kickstarter-related logic moved to kickstarter-router.ts
145
123
 
146
124
  // -------------------------------------------------------------------------
@@ -196,7 +174,6 @@ export function RegionRouter(baseUrl: string) {
196
174
  fetchRegionByIdOrSlug,
197
175
  fetchRegionSolarFarms,
198
176
  getRegionByCode,
199
- createRegion,
200
177
 
201
178
  // Cached data & flags
202
179
  get regions() {
@@ -205,8 +182,5 @@ export function RegionRouter(baseUrl: string) {
205
182
  get isLoading() {
206
183
  return isLoading;
207
184
  },
208
- get isCreatingRegion() {
209
- return isCreatingRegion;
210
- },
211
185
  } as const;
212
186
  }
@@ -8,6 +8,10 @@ import {
8
8
  parseEthersError,
9
9
  waitForEthersTransactionWithRetry,
10
10
  } from "../../utils/transaction-utils";
11
+ import {
12
+ sentryAddBreadcrumb,
13
+ sentryCaptureException,
14
+ } from "../../utils/sentry";
11
15
 
12
16
  export enum ForwarderError {
13
17
  CONTRACT_NOT_AVAILABLE = "Contract not available",
@@ -260,6 +264,23 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
260
264
  if (!tokenContract)
261
265
  throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
262
266
 
267
+ sentryAddBreadcrumb({
268
+ category: "forwarder",
269
+ message: "forwardTokens.start",
270
+ level: "info",
271
+ data: {
272
+ chainId: CHAIN_ID,
273
+ type: params.type,
274
+ amount: amount.toString(),
275
+ currency,
276
+ applicationId: params.applicationId,
277
+ farmId: params.farmId,
278
+ regionId: params.regionId,
279
+ kickstarterId: params.kickstarterId,
280
+ userAddress: params.userAddress,
281
+ },
282
+ });
283
+
263
284
  const owner = await signer.getAddress();
264
285
 
265
286
  // Construct the appropriate message for this forward type
@@ -292,6 +313,13 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
292
313
  );
293
314
  await waitForEthersTransactionWithRetry(signer, approveTx.hash);
294
315
  } catch (approveError) {
316
+ sentryCaptureException(approveError, {
317
+ action: "forwardTokens.approve",
318
+ chainId: CHAIN_ID,
319
+ spender: ADDRESSES.FORWARDER,
320
+ amount: MaxUint256.toString(),
321
+ currency,
322
+ });
295
323
  throw new Error(
296
324
  parseEthersError(approveError) || "Token approval failed"
297
325
  );
@@ -346,6 +374,18 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
346
374
  );
347
375
  }
348
376
  } catch (staticError) {
377
+ sentryCaptureException(staticError, {
378
+ action: "forwardTokens.staticCall",
379
+ chainId: CHAIN_ID,
380
+ function:
381
+ !isAuditFees && currency === "USDC"
382
+ ? "swapUSDCAndForwardUSDG"
383
+ : "forward",
384
+ tokenAddress,
385
+ amount: amount.toString(),
386
+ currency,
387
+ isAuditFees,
388
+ });
349
389
  throw new Error(parseEthersError(staticError));
350
390
  }
351
391
 
@@ -373,6 +413,18 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
373
413
 
374
414
  return tx.hash;
375
415
  } catch (txError: any) {
416
+ sentryCaptureException(txError, {
417
+ action: "forwardTokens",
418
+ chainId: CHAIN_ID,
419
+ type: params.type,
420
+ amount: params.amount.toString(),
421
+ currency: params.currency ?? "USDC",
422
+ applicationId: params.applicationId,
423
+ farmId: params.farmId,
424
+ regionId: params.regionId,
425
+ kickstarterId: params.kickstarterId,
426
+ userAddress: params.userAddress,
427
+ });
376
428
  throw new Error(parseEthersError(txError));
377
429
  } finally {
378
430
  setIsProcessing(false);