@turtleclub/hooks 0.3.1 → 0.4.0-beta.0

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/index.cjs CHANGED
@@ -31,7 +31,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  campaignsV2: () => campaigns_v2_exports,
34
+ chainSchema: () => chainSchema2,
34
35
  defaultQueryClient: () => defaultQueryClient,
36
+ getOpportunities: () => getOpportunities,
37
+ getOpportunityById: () => getOpportunityById,
38
+ incentiveSchema: () => incentiveSchema2,
39
+ lendingConfigSchema: () => lendingConfigSchema,
40
+ opportunitiesQueries: () => opportunitiesQueries,
41
+ opportunitySchema: () => opportunitySchema,
42
+ organizationSchema: () => organizationSchema2,
43
+ productSchema: () => productSchema,
44
+ queries: () => queries,
45
+ tokenSchema: () => tokenSchema2,
35
46
  useConfig: () => useConfig,
36
47
  useEarnCampaigns: () => useEarnCampaigns,
37
48
  useEarnDeals: () => useEarnDeals,
@@ -40,6 +51,8 @@ __export(index_exports, {
40
51
  useExists: () => useExists,
41
52
  useGeocheck: () => useGeocheck,
42
53
  useIndexerTvl: () => useIndexerTvl,
54
+ useOpportunities: () => useOpportunities,
55
+ useOpportunity: () => useOpportunity,
43
56
  useOrganizationDeals: () => useOrganizationDeals,
44
57
  useOrganizations: () => useOrganizations,
45
58
  useOrganizationsDeals: () => useOrganizationsDeals,
@@ -47,7 +60,8 @@ __export(index_exports, {
47
60
  usePartnerDeals: () => usePartnerDeals,
48
61
  usePrepareSignup: () => usePrepareSignup,
49
62
  useProjectTvl: () => useProjectTvl,
50
- useSignup: () => useSignup
63
+ useSignup: () => useSignup,
64
+ vaultConfigSchema: () => vaultConfigSchema
51
65
  });
52
66
  module.exports = __toCommonJS(index_exports);
53
67
 
@@ -4296,10 +4310,307 @@ function useUserCampaignPositions({
4296
4310
  invalidateUserPositions
4297
4311
  };
4298
4312
  }
4313
+
4314
+ // src/v2/index.ts
4315
+ var import_query_key_factory2 = require("@lukemorales/query-key-factory");
4316
+
4317
+ // src/v2/opportunities/queries.ts
4318
+ var import_query_key_factory = require("@lukemorales/query-key-factory");
4319
+
4320
+ // src/v2/lib/api-client.ts
4321
+ var API_BASE_URL = "https://api.turtle.xyz";
4322
+ var EARN_BASE_URL = "https://earn.turtle.xyz";
4323
+ var ApiError = class extends Error {
4324
+ constructor(message, status, response) {
4325
+ super(message);
4326
+ this.status = status;
4327
+ this.response = response;
4328
+ this.name = "ApiError";
4329
+ }
4330
+ };
4331
+ async function apiClient(endpoint, options) {
4332
+ const { debug, domain = "api", ...fetchOptions } = options ?? {};
4333
+ const baseUrl = domain === "earn" ? EARN_BASE_URL : API_BASE_URL;
4334
+ const url = `${baseUrl}${endpoint}`;
4335
+ if (debug) {
4336
+ console.log("[API Request]", {
4337
+ method: fetchOptions.method ?? "GET",
4338
+ url,
4339
+ headers: fetchOptions.headers,
4340
+ body: fetchOptions.body
4341
+ });
4342
+ }
4343
+ try {
4344
+ const response = await fetch(url, {
4345
+ headers: {
4346
+ "Content-Type": "application/json",
4347
+ ...fetchOptions.headers
4348
+ },
4349
+ ...fetchOptions
4350
+ });
4351
+ const data = await response.json();
4352
+ if (debug) {
4353
+ console.log("[API Response]", {
4354
+ status: response.status,
4355
+ ok: response.ok,
4356
+ data
4357
+ });
4358
+ }
4359
+ if (!response.ok) {
4360
+ throw new ApiError(
4361
+ `API error: ${response.status} ${response.statusText}`,
4362
+ response.status,
4363
+ data
4364
+ );
4365
+ }
4366
+ return data;
4367
+ } catch (error) {
4368
+ if (debug) {
4369
+ console.error("[API Error]", error);
4370
+ }
4371
+ if (error instanceof ApiError) {
4372
+ throw error;
4373
+ }
4374
+ throw new ApiError(
4375
+ error instanceof Error ? error.message : "Unknown error",
4376
+ 0,
4377
+ error
4378
+ );
4379
+ }
4380
+ }
4381
+
4382
+ // src/v2/schemas/shared.ts
4383
+ var import_zod13 = require("zod");
4384
+ var chainSchema2 = import_zod13.z.object({
4385
+ id: import_zod13.z.string(),
4386
+ name: import_zod13.z.string(),
4387
+ slug: import_zod13.z.string(),
4388
+ chainId: import_zod13.z.string(),
4389
+ logoUrl: import_zod13.z.string(),
4390
+ ecosystem: import_zod13.z.string(),
4391
+ status: import_zod13.z.string(),
4392
+ explorerUrl: import_zod13.z.string()
4393
+ });
4394
+ var tokenSchema2 = import_zod13.z.object({
4395
+ id: import_zod13.z.string(),
4396
+ name: import_zod13.z.string(),
4397
+ symbol: import_zod13.z.string(),
4398
+ address: import_zod13.z.string(),
4399
+ chain: chainSchema2,
4400
+ decimals: import_zod13.z.number(),
4401
+ logoUrl: import_zod13.z.string(),
4402
+ isNative: import_zod13.z.boolean()
4403
+ });
4404
+ var organizationSchema2 = import_zod13.z.object({
4405
+ id: import_zod13.z.string(),
4406
+ name: import_zod13.z.string(),
4407
+ description: import_zod13.z.string().optional().nullable(),
4408
+ landingUrl: import_zod13.z.string().optional().nullable(),
4409
+ iconUrl: import_zod13.z.string().optional().nullable(),
4410
+ organizationType: import_zod13.z.string().optional().nullable(),
4411
+ turtleRefCode: import_zod13.z.string().optional().nullable(),
4412
+ twitterHandle: import_zod13.z.string().optional().nullable(),
4413
+ status: import_zod13.z.string().optional().nullable(),
4414
+ featured: import_zod13.z.boolean().optional().nullable()
4415
+ });
4416
+ var productSchema = import_zod13.z.object({
4417
+ id: import_zod13.z.string(),
4418
+ name: import_zod13.z.string(),
4419
+ title: import_zod13.z.string().optional().nullable(),
4420
+ subtitle: import_zod13.z.string().optional().nullable(),
4421
+ description: import_zod13.z.string().optional().nullable(),
4422
+ logoUrl: import_zod13.z.string().optional().nullable(),
4423
+ productUrl: import_zod13.z.string().optional().nullable(),
4424
+ startedAt: import_zod13.z.string().optional().nullable(),
4425
+ status: import_zod13.z.string().optional().nullable(),
4426
+ productType: import_zod13.z.string().optional().nullable(),
4427
+ organization: organizationSchema2,
4428
+ createdAt: import_zod13.z.string().optional().nullable()
4429
+ });
4430
+ var vaultConfigSchema = import_zod13.z.object({
4431
+ id: import_zod13.z.string().uuid().optional(),
4432
+ infraProvider: organizationSchema2.optional().nullable(),
4433
+ curator: organizationSchema2.optional().nullable(),
4434
+ withdrawalCooldownSecs: import_zod13.z.number().int().min(0).optional().nullable(),
4435
+ withdrawalContractAddress: import_zod13.z.string().optional().nullable(),
4436
+ withdrawalDetails: import_zod13.z.any().optional().nullable(),
4437
+ depositUrl: import_zod13.z.string().optional().nullable(),
4438
+ providerMetadata: import_zod13.z.any().optional().nullable(),
4439
+ performanceFee: import_zod13.z.number().min(0).max(100).optional().nullable(),
4440
+ managementFee: import_zod13.z.number().min(0).max(100).optional().nullable(),
4441
+ createdAt: import_zod13.z.string().datetime().optional(),
4442
+ updatedAt: import_zod13.z.string().datetime().optional()
4443
+ });
4444
+ var lendingConfigSchema = import_zod13.z.object({
4445
+ id: import_zod13.z.string().uuid().optional(),
4446
+ protocol: import_zod13.z.object({ id: import_zod13.z.string() }),
4447
+ marketAddress: import_zod13.z.string().min(1, "Market address is required"),
4448
+ depositUrl: import_zod13.z.string().optional().nullable(),
4449
+ providerMetadata: import_zod13.z.any().optional().nullable(),
4450
+ createdAt: import_zod13.z.string().datetime().optional(),
4451
+ updatedAt: import_zod13.z.string().datetime().optional()
4452
+ });
4453
+ var incentiveSchema2 = import_zod13.z.object({
4454
+ id: import_zod13.z.string().uuid(),
4455
+ name: import_zod13.z.string(),
4456
+ description: import_zod13.z.string(),
4457
+ iconUrl: import_zod13.z.string(),
4458
+ rewardType: import_zod13.z.string(),
4459
+ rewardTypeName: import_zod13.z.string(),
4460
+ boostPct: import_zod13.z.number().nullable(),
4461
+ totalCapacity: import_zod13.z.number().nullable(),
4462
+ maxCapacityPerLP: import_zod13.z.number().nullable(),
4463
+ lockup: import_zod13.z.string().nullable(),
4464
+ minCommitment: import_zod13.z.number().nullable(),
4465
+ baseYieldTarget: import_zod13.z.number().nullable(),
4466
+ baseYieldSource: import_zod13.z.string().nullable(),
4467
+ incentiveYieldTarget: import_zod13.z.number().nullable(),
4468
+ fdvEstimate: import_zod13.z.number().nullable(),
4469
+ isIncentiveYieldGuaranteed: import_zod13.z.boolean().nullable(),
4470
+ tokenSupplyAllocation: import_zod13.z.number().nullable(),
4471
+ yield: import_zod13.z.number().nullable()
4472
+ });
4473
+ var opportunityTypeEnum = import_zod13.z.enum(["vault", "lending", "staking"]);
4474
+ var opportunityStatusEnum = import_zod13.z.enum(["active", "paused", "deprecated"]);
4475
+ var opportunitySchema = import_zod13.z.object({
4476
+ id: import_zod13.z.string().uuid().optional(),
4477
+ name: import_zod13.z.string(),
4478
+ shortName: import_zod13.z.string(),
4479
+ type: opportunityTypeEnum,
4480
+ description: import_zod13.z.string().optional().default(""),
4481
+ curator: import_zod13.z.string().optional().default(""),
4482
+ tvl: import_zod13.z.number().min(0, "TVL must be positive"),
4483
+ featured: import_zod13.z.boolean().optional().default(false),
4484
+ featuredOrder: import_zod13.z.number().int().optional().nullable(),
4485
+ originalConfig: import_zod13.z.any().optional().nullable(),
4486
+ exposures: import_zod13.z.array(import_zod13.z.string()).optional().default([]),
4487
+ status: opportunityStatusEnum.optional().default("active"),
4488
+ statusReason: import_zod13.z.string().optional().default(""),
4489
+ depositDisabled: import_zod13.z.boolean().optional().default(false),
4490
+ depositDisabledReason: import_zod13.z.string().optional().default(""),
4491
+ withdrawalDisabled: import_zod13.z.boolean().optional().default(false),
4492
+ withdrawalDisabledReason: import_zod13.z.string().optional().default(""),
4493
+ docsUrl: import_zod13.z.string().optional().nullable(),
4494
+ auditsUrl: import_zod13.z.string().optional().nullable(),
4495
+ createdAt: import_zod13.z.string().datetime().optional(),
4496
+ updatedAt: import_zod13.z.string().datetime().optional(),
4497
+ // Relationships
4498
+ depositTokens: import_zod13.z.array(tokenSchema2),
4499
+ baseTokens: import_zod13.z.union([import_zod13.z.null(), tokenSchema2]),
4500
+ receiptToken: import_zod13.z.union([import_zod13.z.null(), tokenSchema2]),
4501
+ incentives: import_zod13.z.array(incentiveSchema2),
4502
+ products: import_zod13.z.array(productSchema),
4503
+ vaultConfig: vaultConfigSchema.optional().nullable(),
4504
+ lendingConfig: lendingConfigSchema.optional().nullable(),
4505
+ // Will be deprecated
4506
+ token: tokenSchema2,
4507
+ exposure: import_zod13.z.array(import_zod13.z.string()),
4508
+ explorerUrl: import_zod13.z.string().nullable()
4509
+ });
4510
+
4511
+ // src/v2/opportunities/schema.ts
4512
+ var import_zod14 = require("zod");
4513
+ var opportunityFiltersSchema = import_zod14.z.object({
4514
+ tokenId: import_zod14.z.string().uuid().optional(),
4515
+ chain: import_zod14.z.string().optional(),
4516
+ productId: import_zod14.z.string().uuid().optional()
4517
+ });
4518
+ var opportunitiesResponseSchema = import_zod14.z.object({
4519
+ opportunities: import_zod14.z.array(opportunitySchema),
4520
+ total: import_zod14.z.number().optional()
4521
+ });
4522
+
4523
+ // src/v2/opportunities/api.ts
4524
+ async function getOpportunities(filters, options) {
4525
+ const params = new URLSearchParams();
4526
+ if (filters?.tokenId) params.append("tokenId", filters.tokenId);
4527
+ if (filters?.chain) params.append("chain", filters.chain);
4528
+ if (filters?.productId) params.append("productId", filters.productId);
4529
+ const queryString = params.toString();
4530
+ const endpoint = `/turtle/opportunities${queryString ? `?${queryString}` : ""}`;
4531
+ const data = await apiClient(endpoint, {
4532
+ method: "GET",
4533
+ debug: options?.debug
4534
+ });
4535
+ const result = opportunitiesResponseSchema.safeParse(data);
4536
+ if (result.success === false) {
4537
+ console.log("[ZOD ERROR]", result.error);
4538
+ throw new Error(`Failed to parse opportunities: ${result.error.message}`);
4539
+ }
4540
+ return result.data;
4541
+ }
4542
+ async function getOpportunityById(id, options) {
4543
+ const data = await apiClient(`/turtle/opportunities/${id}`, {
4544
+ method: "GET",
4545
+ debug: options?.debug
4546
+ });
4547
+ const result = opportunitySchema.safeParse(data);
4548
+ if (result.success === false) {
4549
+ console.log("[ZOD ERROR]", result.error);
4550
+ throw new Error(`Failed to parse opportunity: ${result.error.message}`);
4551
+ }
4552
+ return result.data;
4553
+ }
4554
+
4555
+ // src/v2/opportunities/queries.ts
4556
+ var opportunitiesQueries = (0, import_query_key_factory.createQueryKeys)("opportunities", {
4557
+ // Get all opportunities (no filters)
4558
+ all: {
4559
+ queryKey: null,
4560
+ queryFn: () => getOpportunities()
4561
+ },
4562
+ // Get opportunities with filters
4563
+ list: (filters) => ({
4564
+ queryKey: [{ filters }],
4565
+ queryFn: () => getOpportunities(filters)
4566
+ }),
4567
+ // Get single opportunity by ID
4568
+ byId: (id) => ({
4569
+ queryKey: [id],
4570
+ queryFn: () => getOpportunityById(id)
4571
+ })
4572
+ });
4573
+
4574
+ // src/v2/opportunities/hooks.ts
4575
+ var import_react_query19 = require("@tanstack/react-query");
4576
+
4577
+ // src/v2/lib/query-config.ts
4578
+ var queryDefaults = {
4579
+ staleTime: 5 * 60 * 1e3,
4580
+ // 5 minutes - data is fresh
4581
+ gcTime: 10 * 60 * 1e3,
4582
+ // 10 minutes - cache garbage collection (formerly cacheTime)
4583
+ retry: 1,
4584
+ // Retry failed requests once
4585
+ refetchOnWindowFocus: false
4586
+ // Don't refetch on tab focus
4587
+ };
4588
+
4589
+ // src/v2/opportunities/hooks.ts
4590
+ function useOpportunities(options) {
4591
+ return (0, import_react_query19.useQuery)({ ...opportunitiesQueries.all, ...queryDefaults });
4592
+ }
4593
+ function useOpportunity({ id, ...options }) {
4594
+ return (0, import_react_query19.useQuery)({ ...opportunitiesQueries.byId(id), ...queryDefaults });
4595
+ }
4596
+
4597
+ // src/v2/index.ts
4598
+ var queries = (0, import_query_key_factory2.mergeQueryKeys)(opportunitiesQueries);
4299
4599
  // Annotate the CommonJS export names for ESM import in node:
4300
4600
  0 && (module.exports = {
4301
4601
  campaignsV2,
4602
+ chainSchema,
4302
4603
  defaultQueryClient,
4604
+ getOpportunities,
4605
+ getOpportunityById,
4606
+ incentiveSchema,
4607
+ lendingConfigSchema,
4608
+ opportunitiesQueries,
4609
+ opportunitySchema,
4610
+ organizationSchema,
4611
+ productSchema,
4612
+ queries,
4613
+ tokenSchema,
4303
4614
  useConfig,
4304
4615
  useEarnCampaigns,
4305
4616
  useEarnDeals,
@@ -4308,6 +4619,8 @@ function useUserCampaignPositions({
4308
4619
  useExists,
4309
4620
  useGeocheck,
4310
4621
  useIndexerTvl,
4622
+ useOpportunities,
4623
+ useOpportunity,
4311
4624
  useOrganizationDeals,
4312
4625
  useOrganizations,
4313
4626
  useOrganizationsDeals,
@@ -4315,6 +4628,7 @@ function useUserCampaignPositions({
4315
4628
  usePartnerDeals,
4316
4629
  usePrepareSignup,
4317
4630
  useProjectTvl,
4318
- useSignup
4631
+ useSignup,
4632
+ vaultConfigSchema
4319
4633
  });
4320
4634
  //# sourceMappingURL=index.cjs.map