@glowlabs-org/utils 0.2.154 → 0.2.156

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.
Files changed (39) hide show
  1. package/README.md +175 -17
  2. package/dist/cjs/browser.d.ts +2 -0
  3. package/dist/cjs/browser.js +7 -1
  4. package/dist/cjs/browser.js.map +1 -1
  5. package/dist/cjs/{farms-router-DwbBMkUd.js → farms-router-DekpTBQj.js} +750 -11
  6. package/dist/cjs/farms-router-DekpTBQj.js.map +1 -0
  7. package/dist/cjs/index.d.ts +1 -0
  8. package/dist/cjs/index.js +2 -1
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/lib/abis/rewardKernelABI.d.ts +418 -0
  11. package/dist/cjs/lib/control-api/farms-router.d.ts +2 -1
  12. package/dist/cjs/lib/control-api/region-router.d.ts +2 -1
  13. package/dist/cjs/lib/control-api/wallets-router.d.ts +2 -2
  14. package/dist/cjs/lib/hooks/use-rewards-kernel.d.ts +45 -0
  15. package/dist/cjs/lib/types/index.d.ts +77 -1
  16. package/dist/esm/browser.d.ts +2 -0
  17. package/dist/esm/browser.js +2 -2
  18. package/dist/esm/{farms-router-C0g4hf2Z.js → farms-router-L56VPDNz.js} +749 -12
  19. package/dist/esm/farms-router-L56VPDNz.js.map +1 -0
  20. package/dist/esm/index.d.ts +1 -0
  21. package/dist/esm/index.js +2 -2
  22. package/dist/esm/lib/abis/rewardKernelABI.d.ts +418 -0
  23. package/dist/esm/lib/control-api/farms-router.d.ts +2 -1
  24. package/dist/esm/lib/control-api/region-router.d.ts +2 -1
  25. package/dist/esm/lib/control-api/wallets-router.d.ts +2 -2
  26. package/dist/esm/lib/hooks/use-rewards-kernel.d.ts +45 -0
  27. package/dist/esm/lib/types/index.d.ts +77 -1
  28. package/package.json +1 -1
  29. package/src/browser.ts +2 -0
  30. package/src/index.ts +1 -0
  31. package/src/lib/abis/rewardKernelABI.ts +264 -0
  32. package/src/lib/control-api/farms-router.ts +33 -0
  33. package/src/lib/control-api/region-router.ts +29 -0
  34. package/src/lib/control-api/wallets-router.ts +36 -2
  35. package/src/lib/hooks/README.md +295 -0
  36. package/src/lib/hooks/use-rewards-kernel.ts +547 -0
  37. package/src/lib/types/index.ts +91 -1
  38. package/dist/cjs/farms-router-DwbBMkUd.js.map +0 -1
  39. package/dist/esm/farms-router-C0g4hf2Z.js.map +0 -1
@@ -284,3 +284,298 @@ async function createAndBuyFraction() {
284
284
  ```
285
285
 
286
286
  This hook provides a complete interface for managing fractional token sales on the Glow protocol, with built-in error handling, gas estimation, and type safety.
287
+
288
+ ## useRewardsKernel
289
+
290
+ The `useRewardsKernel` hook provides functionality for claiming rewards from the Glow Foundation's Merkle-tree based reward distribution system. This contract enables secure, verifiable token distributions with support for both regular and guarded tokens.
291
+
292
+ ### Key Concepts
293
+
294
+ **1. Merkle-tree Based Distribution**
295
+
296
+ - Rewards are distributed using Merkle proofs to ensure only eligible users can claim
297
+ - Each distribution has a unique nonce and merkle root
298
+ - Users provide proof of their eligibility when claiming
299
+
300
+ **2. Finality Period**
301
+
302
+ - After a reward root is posted, there's a finality period before claims can begin
303
+ - During this period, the rejection multisig can reject problematic distributions
304
+ - Once finalized, rewards become claimable
305
+
306
+ **3. Guarded Tokens**
307
+
308
+ - Some tokens have transfer restrictions (only transferable between EOAs and allowlisted contracts)
309
+ - The contract uses a CounterfactualHolderFactory to handle these special tokens
310
+ - Users can choose to receive guarded tokens to a counterfactual wallet
311
+
312
+ **4. Security Model**
313
+
314
+ - Foundation multisig posts reward roots (admin function - not included in this hook)
315
+ - Rejection multisig can reject roots within finality period (admin function - not included)
316
+ - Hot wallet holds the actual tokens and must approve the contract
317
+ - No custodied funds - tokens remain with the hot wallet until claimed
318
+
319
+ ### Setup
320
+
321
+ ```typescript
322
+ import { useRewardsKernel } from "@glowlabs-org/utils";
323
+ import { createWalletClient, createPublicClient, http } from "viem";
324
+ import { mainnet } from "viem/chains";
325
+
326
+ // Initialize clients
327
+ const walletClient = createWalletClient({
328
+ chain: mainnet,
329
+ transport: http(),
330
+ });
331
+
332
+ const publicClient = createPublicClient({
333
+ chain: mainnet,
334
+ transport: http(),
335
+ });
336
+
337
+ const CHAIN_ID = 1; // Ethereum mainnet
338
+ const rewardsKernel = useRewardsKernel(walletClient, publicClient, CHAIN_ID);
339
+ ```
340
+
341
+ ### Core Features
342
+
343
+ #### 1. Claiming Rewards
344
+
345
+ ```typescript
346
+ import { ClaimPayoutParams } from "@glowlabs-org/utils";
347
+
348
+ const claimParams: ClaimPayoutParams = {
349
+ nonce: 1n, // The distribution nonce
350
+ proof: [
351
+ "0x1234567890abcdef...", // Merkle proof elements
352
+ "0xabcdef1234567890...",
353
+ ],
354
+ tokensAndAmounts: [
355
+ {
356
+ token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
357
+ amount: 1000000n, // 1 USDC (6 decimals)
358
+ },
359
+ {
360
+ token: "0xf4fbC617A5733EAAF9af08E1Ab816B103388d8B6", // GLW
361
+ amount: 1000000000000000000n, // 1 GLW (18 decimals)
362
+ },
363
+ ],
364
+ from: "0xHotWalletAddress...", // Address holding the tokens
365
+ to: "0xYourAddress...", // Where you want to receive tokens
366
+ isGuardedToken: [false, true], // USDC is not guarded, GLW is guarded
367
+ toCounterfactual: [false, false], // Send both to regular address
368
+ };
369
+
370
+ try {
371
+ const txHash = await rewardsKernel.claimPayout(claimParams);
372
+ console.log("Rewards claimed:", txHash);
373
+ } catch (error) {
374
+ console.error("Claim failed:", error.message);
375
+ }
376
+ ```
377
+
378
+ ### Data Retrieval
379
+
380
+ #### Check Reward Status
381
+
382
+ ```typescript
383
+ // Get reward metadata for a nonce
384
+ const rewardMeta = await rewardsKernel.getRewardMeta(1n);
385
+ console.log({
386
+ merkleRoot: rewardMeta.merkleRoot,
387
+ pushTimestamp: rewardMeta.pushTimestamp,
388
+ rejected: rewardMeta.rejected,
389
+ });
390
+
391
+ // Check if nonce is finalized and claimable
392
+ const isFinalized = await rewardsKernel.isFinalized(1n);
393
+ console.log("Can claim:", isFinalized);
394
+
395
+ // Check if user already claimed
396
+ const userAddress = "0xYourAddress...";
397
+ const hasClaimed = await rewardsKernel.isClaimed(userAddress, 1n);
398
+ console.log("Already claimed:", hasClaimed);
399
+ ```
400
+
401
+ #### Check Token Amounts
402
+
403
+ ```typescript
404
+ const nonce = 1n;
405
+ const usdcAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
406
+
407
+ // Get maximum claimable amount for a token
408
+ const maxReward = await rewardsKernel.getMaxReward(nonce, usdcAddress);
409
+ console.log("Max USDC claimable:", maxReward);
410
+
411
+ // Get amount already claimed
412
+ const amountClaimed = await rewardsKernel.getAmountClaimed(nonce, usdcAddress);
413
+ console.log("USDC already claimed:", amountClaimed);
414
+
415
+ // Calculate remaining claimable
416
+ const remaining = maxReward - amountClaimed;
417
+ console.log("USDC remaining:", remaining);
418
+ ```
419
+
420
+ ### Contract Configuration
421
+
422
+ ```typescript
423
+ // Get finality period (in seconds)
424
+ const finality = await rewardsKernel.getFinality();
425
+ console.log(`Finality period: ${finality} seconds`);
426
+
427
+ // Get next nonce that will be used
428
+ const nextNonce = await rewardsKernel.getNextPostNonce();
429
+ console.log("Next nonce:", nextNonce);
430
+
431
+ // Get multisig addresses
432
+ const foundationMultisig = await rewardsKernel.getFoundationMultisig();
433
+ const rejectionMultisig = await rewardsKernel.getRejectionMultisig();
434
+ console.log("Foundation:", foundationMultisig);
435
+ console.log("Rejection:", rejectionMultisig);
436
+
437
+ // Get counterfactual holder factory
438
+ const cfhFactory = await rewardsKernel.getCFHFactory();
439
+ console.log("CFH Factory:", cfhFactory);
440
+ ```
441
+
442
+ ### Gas Estimation
443
+
444
+ ```typescript
445
+ const ethPrice = 2000; // Current ETH price in USD
446
+
447
+ // Estimate gas for claiming
448
+ const claimCost = await rewardsKernel.estimateGasForClaimPayout(
449
+ claimParams,
450
+ ethPrice
451
+ );
452
+ console.log(`Claim cost: $${claimCost}`);
453
+ ```
454
+
455
+ ### Understanding the Merkle Proof
456
+
457
+ The merkle proof verifies your eligibility to claim specific amounts of tokens:
458
+
459
+ 1. **Leaf Construction**: Your claim data is hashed as `keccak256(abi.encode(userAddress, tokensAndAmountsHash))`
460
+ 2. **Proof Verification**: The proof elements allow reconstruction of the merkle root
461
+ 3. **On-chain Validation**: The contract verifies your proof against the stored root
462
+
463
+ ### Error Handling
464
+
465
+ ```typescript
466
+ import { RewardsKernelError } from "@glowlabs-org/utils";
467
+
468
+ try {
469
+ await rewardsKernel.claimPayout(params);
470
+ } catch (error) {
471
+ if (error.message === RewardsKernelError.ALREADY_CLAIMED) {
472
+ console.log("You've already claimed from this distribution");
473
+ } else if (error.message === RewardsKernelError.NOT_FINALIZED) {
474
+ console.log("Distribution not yet finalized, please wait");
475
+ } else if (error.message === RewardsKernelError.NONCE_REJECTED) {
476
+ console.log("This distribution was rejected");
477
+ }
478
+ // ... handle other errors
479
+ }
480
+ ```
481
+
482
+ Available error types:
483
+
484
+ - `CONTRACT_NOT_AVAILABLE`
485
+ - `SIGNER_NOT_AVAILABLE`
486
+ - `UNKNOWN_ERROR`
487
+ - `INVALID_PARAMETERS`
488
+ - `ALREADY_CLAIMED`
489
+ - `NOT_FINALIZED`
490
+ - `NONCE_REJECTED`
491
+
492
+ ### Best Practices
493
+
494
+ 1. **Always check claim status** before attempting to claim
495
+ 2. **Verify finalization** to avoid failed transactions
496
+ 3. **Handle guarded tokens properly** - understand which tokens need special handling
497
+ 4. **Validate merkle proofs** off-chain before submitting transactions
498
+ 5. **Monitor gas prices** for optimal claiming times
499
+
500
+ ### Example: Complete Claim Flow
501
+
502
+ ```typescript
503
+ async function claimRewards(nonce: bigint, proof: string[], claimData: any) {
504
+ const rewardsKernel = useRewardsKernel(walletClient, publicClient, CHAIN_ID);
505
+
506
+ try {
507
+ // 1. Check if nonce exists and is valid
508
+ const meta = await rewardsKernel.getRewardMeta(nonce);
509
+ if (meta.rejected) {
510
+ throw new Error("This distribution was rejected");
511
+ }
512
+
513
+ // 2. Check if finalized
514
+ const finalized = await rewardsKernel.isFinalized(nonce);
515
+ if (!finalized) {
516
+ const finalityPeriod = await rewardsKernel.getFinality();
517
+ const timeRemaining =
518
+ Number(meta.pushTimestamp) + Number(finalityPeriod) - Date.now() / 1000;
519
+ throw new Error(`Not finalized yet. Wait ${timeRemaining} seconds`);
520
+ }
521
+
522
+ // 3. Check if already claimed
523
+ const userAddress = await walletClient.account.address;
524
+ const claimed = await rewardsKernel.isClaimed(userAddress, nonce);
525
+ if (claimed) {
526
+ throw new Error("Already claimed from this distribution");
527
+ }
528
+
529
+ // 4. Verify amounts are still available
530
+ for (const tokenAmount of claimData.tokensAndAmounts) {
531
+ const maxReward = await rewardsKernel.getMaxReward(
532
+ nonce,
533
+ tokenAmount.token
534
+ );
535
+ const claimed = await rewardsKernel.getAmountClaimed(
536
+ nonce,
537
+ tokenAmount.token
538
+ );
539
+ const remaining = maxReward - claimed;
540
+
541
+ if (remaining < tokenAmount.amount) {
542
+ throw new Error(`Insufficient ${tokenAmount.token} remaining`);
543
+ }
544
+ }
545
+
546
+ // 5. Estimate gas
547
+ const gasEstimate = await rewardsKernel.estimateGasForClaimPayout(
548
+ claimData,
549
+ 2000 // current ETH price
550
+ );
551
+ console.log(`Estimated cost: $${gasEstimate}`);
552
+
553
+ // 6. Execute claim
554
+ const txHash = await rewardsKernel.claimPayout(claimData);
555
+ console.log("Success! Transaction:", txHash);
556
+ } catch (error) {
557
+ console.error("Claim failed:", error.message);
558
+ }
559
+ }
560
+ ```
561
+
562
+ ### Working with Guarded Tokens
563
+
564
+ Guarded tokens (like GLW) have transfer restrictions. Here's how to handle them:
565
+
566
+ ```typescript
567
+ // Option 1: Receive to counterfactual wallet
568
+ const claimToCounterfactual = {
569
+ ...claimParams,
570
+ toCounterfactual: [false, true], // GLW goes to counterfactual
571
+ };
572
+
573
+ // Option 2: Check if your address can receive guarded tokens
574
+ // (This would require checking with the token contract's allowlist)
575
+
576
+ // The counterfactual wallet address can be computed:
577
+ const cfhFactory = await rewardsKernel.getCFHFactory();
578
+ // The CFH factory will create/use a deterministic address for your wallet + token
579
+ ```
580
+
581
+ This hook provides a secure interface for claiming rewards from the Glow Foundation's distribution system, with full support for both regular and guarded tokens, comprehensive error handling, and gas estimation.