From 7014ae7262f53c4fff5ed0265cafe56df886e2d2 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 10 Dec 2024 23:27:33 -0300 Subject: [PATCH 01/44] add sepolia river token address --- src/contracts.ts | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ wagmi.config.ts | 3 ++ 2 files changed, 81 insertions(+) diff --git a/src/contracts.ts b/src/contracts.ts index f79fa7d..3dcdd0a 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -875,6 +875,7 @@ export const rewardsDistributionConfig = { * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenAbi = [ { @@ -1563,17 +1564,20 @@ export const riverTokenAbi = [ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenAddress = { 1: '0x53319181e003E7f86fB79f794649a2aB680Db244', 8453: '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920', 84532: '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0', + 11155111: '0x53319181e003E7f86fB79f794649a2aB680Db244', } as const /** * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenConfig = { address: riverTokenAddress, @@ -2525,6 +2529,7 @@ export const useWatchRewardsDistributionWithdrawEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverToken = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2537,6 +2542,7 @@ export const useReadRiverToken = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenClockMode = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2550,6 +2556,7 @@ export const useReadRiverTokenClockMode = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDomainSeparator = /*#__PURE__*/ createUseReadContract({ @@ -2564,6 +2571,7 @@ export const useReadRiverTokenDomainSeparator = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenAllowance = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2577,6 +2585,7 @@ export const useReadRiverTokenAllowance = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenBalanceOf = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2590,6 +2599,7 @@ export const useReadRiverTokenBalanceOf = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenBridge = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2603,6 +2613,7 @@ export const useReadRiverTokenBridge = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenCheckpoints = /*#__PURE__*/ createUseReadContract( { @@ -2618,6 +2629,7 @@ export const useReadRiverTokenCheckpoints = /*#__PURE__*/ createUseReadContract( * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenClock = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2631,6 +2643,7 @@ export const useReadRiverTokenClock = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDecimals = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2644,6 +2657,7 @@ export const useReadRiverTokenDecimals = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDelegates = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2657,6 +2671,7 @@ export const useReadRiverTokenDelegates = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenEip712Domain = /*#__PURE__*/ createUseReadContract({ @@ -2671,6 +2686,7 @@ export const useReadRiverTokenEip712Domain = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegationTimeForDelegator = /*#__PURE__*/ createUseReadContract({ @@ -2685,6 +2701,7 @@ export const useReadRiverTokenGetDelegationTimeForDelegator = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegators = /*#__PURE__*/ createUseReadContract({ @@ -2699,6 +2716,7 @@ export const useReadRiverTokenGetDelegators = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegatorsByDelegatee = /*#__PURE__*/ createUseReadContract({ @@ -2713,6 +2731,7 @@ export const useReadRiverTokenGetDelegatorsByDelegatee = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetPastTotalSupply = /*#__PURE__*/ createUseReadContract({ @@ -2727,6 +2746,7 @@ export const useReadRiverTokenGetPastTotalSupply = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetPastVotes = /*#__PURE__*/ createUseReadContract({ @@ -2741,6 +2761,7 @@ export const useReadRiverTokenGetPastVotes = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetVotes = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2754,6 +2775,7 @@ export const useReadRiverTokenGetVotes = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenIsLockEnabled = /*#__PURE__*/ createUseReadContract({ @@ -2768,6 +2790,7 @@ export const useReadRiverTokenIsLockEnabled = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenL1Token = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2781,6 +2804,7 @@ export const useReadRiverTokenL1Token = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenL2Bridge = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2794,6 +2818,7 @@ export const useReadRiverTokenL2Bridge = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenLockCooldown = /*#__PURE__*/ createUseReadContract({ @@ -2808,6 +2833,7 @@ export const useReadRiverTokenLockCooldown = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenName = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2821,6 +2847,7 @@ export const useReadRiverTokenName = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenNonces = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2834,6 +2861,7 @@ export const useReadRiverTokenNonces = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenNumCheckpoints = /*#__PURE__*/ createUseReadContract({ @@ -2848,6 +2876,7 @@ export const useReadRiverTokenNumCheckpoints = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenOwner = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2861,6 +2890,7 @@ export const useReadRiverTokenOwner = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenRemoteToken = /*#__PURE__*/ createUseReadContract( { @@ -2876,6 +2906,7 @@ export const useReadRiverTokenRemoteToken = /*#__PURE__*/ createUseReadContract( * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenSupportsInterface = /*#__PURE__*/ createUseReadContract({ @@ -2890,6 +2921,7 @@ export const useReadRiverTokenSupportsInterface = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenSymbol = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2903,6 +2935,7 @@ export const useReadRiverTokenSymbol = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenTotalSupply = /*#__PURE__*/ createUseReadContract( { @@ -2918,6 +2951,7 @@ export const useReadRiverTokenTotalSupply = /*#__PURE__*/ createUseReadContract( * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenVersion = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2931,6 +2965,7 @@ export const useReadRiverTokenVersion = /*#__PURE__*/ createUseReadContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverToken = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -2943,6 +2978,7 @@ export const useWriteRiverToken = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenIntrospectionInit = /*#__PURE__*/ createUseWriteContract({ @@ -2957,6 +2993,7 @@ export const useWriteRiverTokenIntrospectionInit = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenLockFacetInit = /*#__PURE__*/ createUseWriteContract({ @@ -2971,6 +3008,7 @@ export const useWriteRiverTokenLockFacetInit = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenApprove = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -2984,6 +3022,7 @@ export const useWriteRiverTokenApprove = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenBurn = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -2997,6 +3036,7 @@ export const useWriteRiverTokenBurn = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDelegate = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3010,6 +3050,7 @@ export const useWriteRiverTokenDelegate = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDelegateBySig = /*#__PURE__*/ createUseWriteContract({ @@ -3024,6 +3065,7 @@ export const useWriteRiverTokenDelegateBySig = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDisableLock = /*#__PURE__*/ createUseWriteContract({ @@ -3038,6 +3080,7 @@ export const useWriteRiverTokenDisableLock = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenEnableLock = /*#__PURE__*/ createUseWriteContract({ @@ -3052,6 +3095,7 @@ export const useWriteRiverTokenEnableLock = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenMint = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3065,6 +3109,7 @@ export const useWriteRiverTokenMint = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenPermit = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3078,6 +3123,7 @@ export const useWriteRiverTokenPermit = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenRenounceOwnership = /*#__PURE__*/ createUseWriteContract({ @@ -3092,6 +3138,7 @@ export const useWriteRiverTokenRenounceOwnership = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenSetLockCooldown = /*#__PURE__*/ createUseWriteContract({ @@ -3106,6 +3153,7 @@ export const useWriteRiverTokenSetLockCooldown = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransfer = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3119,6 +3167,7 @@ export const useWriteRiverTokenTransfer = /*#__PURE__*/ createUseWriteContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransferFrom = /*#__PURE__*/ createUseWriteContract({ @@ -3133,6 +3182,7 @@ export const useWriteRiverTokenTransferFrom = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransferOwnership = /*#__PURE__*/ createUseWriteContract({ @@ -3147,6 +3197,7 @@ export const useWriteRiverTokenTransferOwnership = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverToken = /*#__PURE__*/ createUseSimulateContract({ abi: riverTokenAbi, @@ -3159,6 +3210,7 @@ export const useSimulateRiverToken = /*#__PURE__*/ createUseSimulateContract({ * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenIntrospectionInit = /*#__PURE__*/ createUseSimulateContract({ @@ -3173,6 +3225,7 @@ export const useSimulateRiverTokenIntrospectionInit = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenLockFacetInit = /*#__PURE__*/ createUseSimulateContract({ @@ -3187,6 +3240,7 @@ export const useSimulateRiverTokenLockFacetInit = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenApprove = /*#__PURE__*/ createUseSimulateContract({ @@ -3201,6 +3255,7 @@ export const useSimulateRiverTokenApprove = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenBurn = /*#__PURE__*/ createUseSimulateContract({ @@ -3215,6 +3270,7 @@ export const useSimulateRiverTokenBurn = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDelegate = /*#__PURE__*/ createUseSimulateContract({ @@ -3229,6 +3285,7 @@ export const useSimulateRiverTokenDelegate = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDelegateBySig = /*#__PURE__*/ createUseSimulateContract({ @@ -3243,6 +3300,7 @@ export const useSimulateRiverTokenDelegateBySig = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDisableLock = /*#__PURE__*/ createUseSimulateContract({ @@ -3257,6 +3315,7 @@ export const useSimulateRiverTokenDisableLock = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenEnableLock = /*#__PURE__*/ createUseSimulateContract({ @@ -3271,6 +3330,7 @@ export const useSimulateRiverTokenEnableLock = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenMint = /*#__PURE__*/ createUseSimulateContract({ @@ -3285,6 +3345,7 @@ export const useSimulateRiverTokenMint = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenPermit = /*#__PURE__*/ createUseSimulateContract({ @@ -3299,6 +3360,7 @@ export const useSimulateRiverTokenPermit = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenRenounceOwnership = /*#__PURE__*/ createUseSimulateContract({ @@ -3313,6 +3375,7 @@ export const useSimulateRiverTokenRenounceOwnership = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenSetLockCooldown = /*#__PURE__*/ createUseSimulateContract({ @@ -3327,6 +3390,7 @@ export const useSimulateRiverTokenSetLockCooldown = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransfer = /*#__PURE__*/ createUseSimulateContract({ @@ -3341,6 +3405,7 @@ export const useSimulateRiverTokenTransfer = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransferFrom = /*#__PURE__*/ createUseSimulateContract({ @@ -3355,6 +3420,7 @@ export const useSimulateRiverTokenTransferFrom = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransferOwnership = /*#__PURE__*/ createUseSimulateContract({ @@ -3369,6 +3435,7 @@ export const useSimulateRiverTokenTransferOwnership = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3382,6 +3449,7 @@ export const useWatchRiverTokenEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3396,6 +3464,7 @@ export const useWatchRiverTokenApprovalEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenDelegateChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3410,6 +3479,7 @@ export const useWatchRiverTokenDelegateChangedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenDelegateVotesChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3424,6 +3494,7 @@ export const useWatchRiverTokenDelegateVotesChangedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenEip712DomainChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3438,6 +3509,7 @@ export const useWatchRiverTokenEip712DomainChangedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInitializedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3452,6 +3524,7 @@ export const useWatchRiverTokenInitializedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInterfaceAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3466,6 +3539,7 @@ export const useWatchRiverTokenInterfaceAddedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInterfaceRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3480,6 +3554,7 @@ export const useWatchRiverTokenInterfaceRemovedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenLockUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3494,6 +3569,7 @@ export const useWatchRiverTokenLockUpdatedEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenOwnershipTransferredEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3508,6 +3584,7 @@ export const useWatchRiverTokenOwnershipTransferredEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenTokenThresholdSetEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3522,6 +3599,7 @@ export const useWatchRiverTokenTokenThresholdSetEvent = * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenTransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ diff --git a/wagmi.config.ts b/wagmi.config.ts index 2c7e5c4..69d0887 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -1345,6 +1345,8 @@ const riverTokenAbi = [ ] as const const mainnetRiverTokenAddress = '0x53319181e003E7f86fB79f794649a2aB680Db244' satisfies Address +const sepoliaRiverTokenAddress = '0x53319181e003E7f86fB79f794649a2aB680Db244' satisfies Address + const baseRiverTokenAddress = '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920' satisfies Address const baseGammaSepoliaTokenAddress = '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0' satisfies Address @@ -1355,6 +1357,7 @@ export default defineConfig({ name: 'RiverToken', address: { [mainnet.id]: mainnetRiverTokenAddress, + [sepolia.id]: sepoliaRiverTokenAddress, [base.id]: baseRiverTokenAddress, [baseSepolia.id]: baseGammaSepoliaTokenAddress, }, From a4a6c8df086f6269e18ab94116033cd03872b5f1 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 10 Dec 2024 23:54:57 -0300 Subject: [PATCH 02/44] """redelegate""" --- src/components/delegate/delegate-section.tsx | 53 ++++++++++++++++++- src/components/delegate/redelegate-button.tsx | 51 ++++++++++++++++++ src/components/delegate/redelegate-dialog.tsx | 33 ++++++++++++ src/components/ui/dialog.tsx | 6 +-- src/components/ui/label.tsx | 4 +- 5 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 src/components/delegate/redelegate-button.tsx create mode 100644 src/components/delegate/redelegate-dialog.tsx diff --git a/src/components/delegate/delegate-section.tsx b/src/components/delegate/delegate-section.tsx index b9b3524..2a7f8c6 100644 --- a/src/components/delegate/delegate-section.tsx +++ b/src/components/delegate/delegate-section.tsx @@ -1,10 +1,30 @@ +import { useRedelegate } from '@/lib/hooks/use-redelegate' import { cn } from '@/lib/utils' +import type { Address } from 'viem' +import { Button } from '../ui/button' +import { Dialog, DialogTrigger } from '../ui/dialog' import { Typography } from '../ui/typography' import { WalletInfo } from '../wallet-info' import { AuthorizeClaimerForm } from './authorize-claimer-form' import { DelegateForm } from './delegate-form' +import { RedelegateButton } from './redelegate-button' +import { RedelegateDialogContent } from './redelegate-dialog' + +const fakeDeposits = Array.from({ length: 4 }, (_, i) => ({ + id: BigInt(i), + delegatee: ('0x' + i.toString(16).padStart(40, '0')) as Address, +})) satisfies { id: bigint; delegatee: Address }[] + +const fakeSingleDeposit = [ + { + id: 1n, + delegatee: '0x1234567890' as Address, + }, +] export const DelegateSection = () => { + const { deposits } = useRedelegate() + return (
{ - +
+ + {!deposits || deposits.length === 0 ? null : ( + <> +
+
+
+

OR

+
+
+

+ You can also redelegate to a previous delegatee +

+ {deposits.length === 1 ? ( + + ) : ( + + + + + + + )} +
+ + )} +
diff --git a/src/components/delegate/redelegate-button.tsx b/src/components/delegate/redelegate-button.tsx new file mode 100644 index 0000000..38401e5 --- /dev/null +++ b/src/components/delegate/redelegate-button.tsx @@ -0,0 +1,51 @@ +import { useRedelegate } from '@/lib/hooks/use-redelegate' +import { formatAddress } from '@/lib/utils' +import { Check } from 'lucide-react' +import { useEffect } from 'react' +import type { Address } from 'viem' +import { Button } from '../ui/button' +import { useToast } from '../ui/use-toast' + +export const RedelegateButton = ({ + depositId, + delegatedAddress, + variant = 'primary', + showAddress, +}: { + depositId: bigint + delegatedAddress: Address + variant?: 'primary' | 'secondary' + showAddress?: boolean +}) => { + const { toast } = useToast() + const { isTxConfirmed, isPending, isTxPending, writeRedelegate } = useRedelegate() + + useEffect(() => { + if (isTxConfirmed && delegatedAddress) { + toast({ + title: `You've redelegated your RVR balance to ${formatAddress(delegatedAddress)}.`, + }) + } + }, [delegatedAddress, isTxConfirmed, toast]) + + return ( + + ) +} diff --git a/src/components/delegate/redelegate-dialog.tsx b/src/components/delegate/redelegate-dialog.tsx new file mode 100644 index 0000000..2e2daa0 --- /dev/null +++ b/src/components/delegate/redelegate-dialog.tsx @@ -0,0 +1,33 @@ +import { formatAddress } from '@/lib/utils' +import type { Address } from 'viem' +import { DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/dialog' +import { RedelegateButton } from './redelegate-button' + +export const RedelegateDialogContent = ({ + deposits, +}: { + deposits: { id: bigint; delegatee: Address }[] +}) => { + return ( + + + Redelegate + + Select the address you want to redelegate to. +
+ {deposits.map((deposit) => ( +
+ + {formatAddress(deposit.delegatee)} + + +
+ ))} +
+
+ ) +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 8240868..41a3f1b 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -36,14 +36,14 @@ const DialogContent = React.forwardRef< {children} - + Close @@ -70,7 +70,7 @@ const DialogTitle = React.forwardRef< >(({ className, ...props }, ref) => ( )) diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx index 4b12914..659a6ff 100644 --- a/src/components/ui/label.tsx +++ b/src/components/ui/label.tsx @@ -4,8 +4,8 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" -const labelVariants = cva( - "text-sm text-white font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +export const labelVariants = cva( + 'text-sm text-white font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', ) const Label = React.forwardRef< From 7f1f794adf8cbe347f756233840d36264004307d Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 12 Dec 2024 23:09:40 -0300 Subject: [PATCH 03/44] remove river token mainnet --- src/contracts.ts | 156 ----------------------------------------------- wagmi.config.ts | 5 -- 2 files changed, 161 deletions(-) diff --git a/src/contracts.ts b/src/contracts.ts index 3dcdd0a..248cbfa 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -872,10 +872,8 @@ export const rewardsDistributionConfig = { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenAbi = [ { @@ -1561,23 +1559,17 @@ export const riverTokenAbi = [ ] as const /** - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenAddress = { - 1: '0x53319181e003E7f86fB79f794649a2aB680Db244', 8453: '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920', 84532: '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0', - 11155111: '0x53319181e003E7f86fB79f794649a2aB680Db244', } as const /** - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const riverTokenConfig = { address: riverTokenAddress, @@ -2526,10 +2518,8 @@ export const useWatchRewardsDistributionWithdrawEvent = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverToken = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2539,10 +2529,8 @@ export const useReadRiverToken = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"CLOCK_MODE"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenClockMode = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2553,10 +2541,8 @@ export const useReadRiverTokenClockMode = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"DOMAIN_SEPARATOR"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDomainSeparator = /*#__PURE__*/ createUseReadContract({ @@ -2568,10 +2554,8 @@ export const useReadRiverTokenDomainSeparator = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"allowance"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenAllowance = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2582,10 +2566,8 @@ export const useReadRiverTokenAllowance = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"balanceOf"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenBalanceOf = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2596,10 +2578,8 @@ export const useReadRiverTokenBalanceOf = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"bridge"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenBridge = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2610,10 +2590,8 @@ export const useReadRiverTokenBridge = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"checkpoints"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenCheckpoints = /*#__PURE__*/ createUseReadContract( { @@ -2626,10 +2604,8 @@ export const useReadRiverTokenCheckpoints = /*#__PURE__*/ createUseReadContract( /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"clock"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenClock = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2640,10 +2616,8 @@ export const useReadRiverTokenClock = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"decimals"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDecimals = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2654,10 +2628,8 @@ export const useReadRiverTokenDecimals = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"delegates"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenDelegates = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2668,10 +2640,8 @@ export const useReadRiverTokenDelegates = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"eip712Domain"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenEip712Domain = /*#__PURE__*/ createUseReadContract({ @@ -2683,10 +2653,8 @@ export const useReadRiverTokenEip712Domain = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getDelegationTimeForDelegator"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegationTimeForDelegator = /*#__PURE__*/ createUseReadContract({ @@ -2698,10 +2666,8 @@ export const useReadRiverTokenGetDelegationTimeForDelegator = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getDelegators"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegators = /*#__PURE__*/ createUseReadContract({ @@ -2713,10 +2679,8 @@ export const useReadRiverTokenGetDelegators = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getDelegatorsByDelegatee"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetDelegatorsByDelegatee = /*#__PURE__*/ createUseReadContract({ @@ -2728,10 +2692,8 @@ export const useReadRiverTokenGetDelegatorsByDelegatee = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getPastTotalSupply"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetPastTotalSupply = /*#__PURE__*/ createUseReadContract({ @@ -2743,10 +2705,8 @@ export const useReadRiverTokenGetPastTotalSupply = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getPastVotes"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetPastVotes = /*#__PURE__*/ createUseReadContract({ @@ -2758,10 +2718,8 @@ export const useReadRiverTokenGetPastVotes = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"getVotes"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenGetVotes = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2772,10 +2730,8 @@ export const useReadRiverTokenGetVotes = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"isLockEnabled"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenIsLockEnabled = /*#__PURE__*/ createUseReadContract({ @@ -2787,10 +2743,8 @@ export const useReadRiverTokenIsLockEnabled = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"l1Token"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenL1Token = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2801,10 +2755,8 @@ export const useReadRiverTokenL1Token = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"l2Bridge"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenL2Bridge = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2815,10 +2767,8 @@ export const useReadRiverTokenL2Bridge = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"lockCooldown"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenLockCooldown = /*#__PURE__*/ createUseReadContract({ @@ -2830,10 +2780,8 @@ export const useReadRiverTokenLockCooldown = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"name"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenName = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2844,10 +2792,8 @@ export const useReadRiverTokenName = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"nonces"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenNonces = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2858,10 +2804,8 @@ export const useReadRiverTokenNonces = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"numCheckpoints"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenNumCheckpoints = /*#__PURE__*/ createUseReadContract({ @@ -2873,10 +2817,8 @@ export const useReadRiverTokenNumCheckpoints = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"owner"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenOwner = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2887,10 +2829,8 @@ export const useReadRiverTokenOwner = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"remoteToken"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenRemoteToken = /*#__PURE__*/ createUseReadContract( { @@ -2903,10 +2843,8 @@ export const useReadRiverTokenRemoteToken = /*#__PURE__*/ createUseReadContract( /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"supportsInterface"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenSupportsInterface = /*#__PURE__*/ createUseReadContract({ @@ -2918,10 +2856,8 @@ export const useReadRiverTokenSupportsInterface = /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"symbol"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenSymbol = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2932,10 +2868,8 @@ export const useReadRiverTokenSymbol = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"totalSupply"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenTotalSupply = /*#__PURE__*/ createUseReadContract( { @@ -2948,10 +2882,8 @@ export const useReadRiverTokenTotalSupply = /*#__PURE__*/ createUseReadContract( /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"version"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useReadRiverTokenVersion = /*#__PURE__*/ createUseReadContract({ abi: riverTokenAbi, @@ -2962,10 +2894,8 @@ export const useReadRiverTokenVersion = /*#__PURE__*/ createUseReadContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverToken = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -2975,10 +2905,8 @@ export const useWriteRiverToken = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"__Introspection_init"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenIntrospectionInit = /*#__PURE__*/ createUseWriteContract({ @@ -2990,10 +2918,8 @@ export const useWriteRiverTokenIntrospectionInit = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"__LockFacet_init"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenLockFacetInit = /*#__PURE__*/ createUseWriteContract({ @@ -3005,10 +2931,8 @@ export const useWriteRiverTokenLockFacetInit = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"approve"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenApprove = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3019,10 +2943,8 @@ export const useWriteRiverTokenApprove = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"burn"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenBurn = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3033,10 +2955,8 @@ export const useWriteRiverTokenBurn = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"delegate"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDelegate = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3047,10 +2967,8 @@ export const useWriteRiverTokenDelegate = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"delegateBySig"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDelegateBySig = /*#__PURE__*/ createUseWriteContract({ @@ -3062,10 +2980,8 @@ export const useWriteRiverTokenDelegateBySig = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"disableLock"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenDisableLock = /*#__PURE__*/ createUseWriteContract({ @@ -3077,10 +2993,8 @@ export const useWriteRiverTokenDisableLock = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"enableLock"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenEnableLock = /*#__PURE__*/ createUseWriteContract({ @@ -3092,10 +3006,8 @@ export const useWriteRiverTokenEnableLock = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"mint"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenMint = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3106,10 +3018,8 @@ export const useWriteRiverTokenMint = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"permit"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenPermit = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3120,10 +3030,8 @@ export const useWriteRiverTokenPermit = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"renounceOwnership"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenRenounceOwnership = /*#__PURE__*/ createUseWriteContract({ @@ -3135,10 +3043,8 @@ export const useWriteRiverTokenRenounceOwnership = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"setLockCooldown"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenSetLockCooldown = /*#__PURE__*/ createUseWriteContract({ @@ -3150,10 +3056,8 @@ export const useWriteRiverTokenSetLockCooldown = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transfer"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransfer = /*#__PURE__*/ createUseWriteContract({ abi: riverTokenAbi, @@ -3164,10 +3068,8 @@ export const useWriteRiverTokenTransfer = /*#__PURE__*/ createUseWriteContract({ /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transferFrom"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransferFrom = /*#__PURE__*/ createUseWriteContract({ @@ -3179,10 +3081,8 @@ export const useWriteRiverTokenTransferFrom = /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transferOwnership"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWriteRiverTokenTransferOwnership = /*#__PURE__*/ createUseWriteContract({ @@ -3194,10 +3094,8 @@ export const useWriteRiverTokenTransferOwnership = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverToken = /*#__PURE__*/ createUseSimulateContract({ abi: riverTokenAbi, @@ -3207,10 +3105,8 @@ export const useSimulateRiverToken = /*#__PURE__*/ createUseSimulateContract({ /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"__Introspection_init"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenIntrospectionInit = /*#__PURE__*/ createUseSimulateContract({ @@ -3222,10 +3118,8 @@ export const useSimulateRiverTokenIntrospectionInit = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"__LockFacet_init"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenLockFacetInit = /*#__PURE__*/ createUseSimulateContract({ @@ -3237,10 +3131,8 @@ export const useSimulateRiverTokenLockFacetInit = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"approve"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenApprove = /*#__PURE__*/ createUseSimulateContract({ @@ -3252,10 +3144,8 @@ export const useSimulateRiverTokenApprove = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"burn"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenBurn = /*#__PURE__*/ createUseSimulateContract({ @@ -3267,10 +3157,8 @@ export const useSimulateRiverTokenBurn = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"delegate"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDelegate = /*#__PURE__*/ createUseSimulateContract({ @@ -3282,10 +3170,8 @@ export const useSimulateRiverTokenDelegate = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"delegateBySig"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDelegateBySig = /*#__PURE__*/ createUseSimulateContract({ @@ -3297,10 +3183,8 @@ export const useSimulateRiverTokenDelegateBySig = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"disableLock"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenDisableLock = /*#__PURE__*/ createUseSimulateContract({ @@ -3312,10 +3196,8 @@ export const useSimulateRiverTokenDisableLock = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"enableLock"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenEnableLock = /*#__PURE__*/ createUseSimulateContract({ @@ -3327,10 +3209,8 @@ export const useSimulateRiverTokenEnableLock = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"mint"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenMint = /*#__PURE__*/ createUseSimulateContract({ @@ -3342,10 +3222,8 @@ export const useSimulateRiverTokenMint = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"permit"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenPermit = /*#__PURE__*/ createUseSimulateContract({ @@ -3357,10 +3235,8 @@ export const useSimulateRiverTokenPermit = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"renounceOwnership"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenRenounceOwnership = /*#__PURE__*/ createUseSimulateContract({ @@ -3372,10 +3248,8 @@ export const useSimulateRiverTokenRenounceOwnership = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"setLockCooldown"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenSetLockCooldown = /*#__PURE__*/ createUseSimulateContract({ @@ -3387,10 +3261,8 @@ export const useSimulateRiverTokenSetLockCooldown = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transfer"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransfer = /*#__PURE__*/ createUseSimulateContract({ @@ -3402,10 +3274,8 @@ export const useSimulateRiverTokenTransfer = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transferFrom"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransferFrom = /*#__PURE__*/ createUseSimulateContract({ @@ -3417,10 +3287,8 @@ export const useSimulateRiverTokenTransferFrom = /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverTokenAbi}__ and `functionName` set to `"transferOwnership"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useSimulateRiverTokenTransferOwnership = /*#__PURE__*/ createUseSimulateContract({ @@ -3432,10 +3300,8 @@ export const useSimulateRiverTokenTransferOwnership = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3446,10 +3312,8 @@ export const useWatchRiverTokenEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"Approval"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3461,10 +3325,8 @@ export const useWatchRiverTokenApprovalEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"DelegateChanged"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenDelegateChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3476,10 +3338,8 @@ export const useWatchRiverTokenDelegateChangedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"DelegateVotesChanged"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenDelegateVotesChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3491,10 +3351,8 @@ export const useWatchRiverTokenDelegateVotesChangedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"EIP712DomainChanged"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenEip712DomainChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3506,10 +3364,8 @@ export const useWatchRiverTokenEip712DomainChangedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"Initialized"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInitializedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3521,10 +3377,8 @@ export const useWatchRiverTokenInitializedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"InterfaceAdded"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInterfaceAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3536,10 +3390,8 @@ export const useWatchRiverTokenInterfaceAddedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"InterfaceRemoved"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenInterfaceRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3551,10 +3403,8 @@ export const useWatchRiverTokenInterfaceRemovedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"LockUpdated"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenLockUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3566,10 +3416,8 @@ export const useWatchRiverTokenLockUpdatedEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"OwnershipTransferred"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenOwnershipTransferredEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3581,10 +3429,8 @@ export const useWatchRiverTokenOwnershipTransferredEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"TokenThresholdSet"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenTokenThresholdSetEvent = /*#__PURE__*/ createUseWatchContractEvent({ @@ -3596,10 +3442,8 @@ export const useWatchRiverTokenTokenThresholdSetEvent = /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverTokenAbi}__ and `eventName` set to `"Transfer"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x53319181e003E7f86fB79f794649a2aB680Db244) */ export const useWatchRiverTokenTransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ diff --git a/wagmi.config.ts b/wagmi.config.ts index 69d0887..738580d 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -1344,9 +1344,6 @@ const riverTokenAbi = [ }, ] as const -const mainnetRiverTokenAddress = '0x53319181e003E7f86fB79f794649a2aB680Db244' satisfies Address -const sepoliaRiverTokenAddress = '0x53319181e003E7f86fB79f794649a2aB680Db244' satisfies Address - const baseRiverTokenAddress = '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920' satisfies Address const baseGammaSepoliaTokenAddress = '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0' satisfies Address @@ -1356,8 +1353,6 @@ export default defineConfig({ { name: 'RiverToken', address: { - [mainnet.id]: mainnetRiverTokenAddress, - [sepolia.id]: sepoliaRiverTokenAddress, [base.id]: baseRiverTokenAddress, [baseSepolia.id]: baseGammaSepoliaTokenAddress, }, From 2758cb8462b978a18d8fefc07aabb35fd13191a3 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Sat, 14 Dec 2024 00:00:31 -0300 Subject: [PATCH 04/44] node operator contracts --- src/contracts.ts | 757 +++++++++++++++++++++++++++++++++++++++++++++++ wagmi.config.ts | 229 ++++++++++++++ 2 files changed, 986 insertions(+) diff --git a/src/contracts.ts b/src/contracts.ts index 248cbfa..3b1685e 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -92,6 +92,367 @@ export const authorizerConfig = { abi: authorizerAbi, } as const +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// NodeOperator +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const nodeOperatorAbi = [ + { type: 'error', inputs: [], name: 'ApprovalCallerNotOwnerNorApproved' }, + { type: 'error', inputs: [], name: 'ApprovalQueryForNonexistentToken' }, + { type: 'error', inputs: [], name: 'BalanceQueryForZeroAddress' }, + { type: 'error', inputs: [], name: 'Initializable_InInitializingState' }, + { type: 'error', inputs: [], name: 'Initializable_NotInInitializingState' }, + { type: 'error', inputs: [], name: 'Introspection_AlreadySupported' }, + { type: 'error', inputs: [], name: 'Introspection_NotSupported' }, + { type: 'error', inputs: [], name: 'MintERC2309QuantityExceedsLimit' }, + { type: 'error', inputs: [], name: 'MintToZeroAddress' }, + { type: 'error', inputs: [], name: 'MintZeroQuantity' }, + { + type: 'error', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'NodeOperator__AlreadyDelegated', + }, + { type: 'error', inputs: [], name: 'NodeOperator__AlreadyRegistered' }, + { type: 'error', inputs: [], name: 'NodeOperator__ClaimAddressNotChanged' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidAddress' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidCommissionRate' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidOperator' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidSpace' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidStakeRequirement' }, + { type: 'error', inputs: [], name: 'NodeOperator__InvalidStatusTransition' }, + { type: 'error', inputs: [], name: 'NodeOperator__NotClaimer' }, + { type: 'error', inputs: [], name: 'NodeOperator__NotEnoughStake' }, + { type: 'error', inputs: [], name: 'NodeOperator__NotRegistered' }, + { type: 'error', inputs: [], name: 'NodeOperator__NotTransferable' }, + { type: 'error', inputs: [], name: 'NodeOperator__StatusNotChanged' }, + { + type: 'error', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'Ownable__NotOwner', + }, + { type: 'error', inputs: [], name: 'Ownable__ZeroAddress' }, + { type: 'error', inputs: [], name: 'OwnerQueryForNonexistentToken' }, + { type: 'error', inputs: [], name: 'OwnershipNotInitializedForExtraData' }, + { type: 'error', inputs: [], name: 'TransferCallerNotOwnerNorApproved' }, + { type: 'error', inputs: [], name: 'TransferFromIncorrectOwner' }, + { type: 'error', inputs: [], name: 'TransferToNonERC721ReceiverImplementer' }, + { type: 'error', inputs: [], name: 'TransferToZeroAddress' }, + { type: 'error', inputs: [], name: 'URIQueryForNonexistentToken' }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'approved', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Approval', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ApprovalForAll', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'fromTokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'toTokenId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + ], + name: 'ConsecutiveTransfer', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'version', + internalType: 'uint32', + type: 'uint32', + indexed: false, + }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'interfaceId', + internalType: 'bytes4', + type: 'bytes4', + indexed: true, + }, + ], + name: 'InterfaceAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'interfaceId', + internalType: 'bytes4', + type: 'bytes4', + indexed: true, + }, + ], + name: 'InterfaceRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'claimAddress', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OperatorClaimAddressChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'commission', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'OperatorCommissionChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OperatorRegistered', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newStatus', + internalType: 'enum NodeOperatorStatus', + type: 'uint8', + indexed: true, + }, + ], + name: 'OperatorStatusChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'tokenId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: '__NodeOperator_init', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'getClaimAddressForOperator', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'getCommissionRate', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'getOperatorStatus', + outputs: [ + { name: '', internalType: 'enum NodeOperatorStatus', type: 'uint8' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getOperators', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'isOperator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'claimer', internalType: 'address', type: 'address' }], + name: 'registerOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'claimer', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'setClaimAddressForOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'rateBps', internalType: 'uint256', type: 'uint256' }], + name: 'setCommissionRate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'operator', internalType: 'address', type: 'address' }, + { + name: 'newStatus', + internalType: 'enum NodeOperatorStatus', + type: 'uint8', + }, + ], + name: 'setOperatorStatus', + outputs: [], + stateMutability: 'nonpayable', + }, +] as const + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const nodeOperatorAddress = { + 8453: '0x7c0422b31401C936172C897802CF0373B35B7698', + 84532: '0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F', +} as const + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const nodeOperatorConfig = { + address: nodeOperatorAddress, + abi: nodeOperatorAbi, +} as const + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // RewardsDistribution ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1716,6 +2077,402 @@ export const useWatchAuthorizerAuthorizedClaimerRemovedEvent = eventName: 'AuthorizedClaimerRemoved', }) +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperator = /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetClaimAddressForOperator = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getClaimAddressForOperator', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetCommissionRate = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getCommissionRate', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetOperatorStatus = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getOperatorStatus', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperators"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetOperators = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getOperators', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"isOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorIsOperator = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'isOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperator = /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorNodeOperatorInit = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: '__NodeOperator_init', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorRegisterOperator = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'registerOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetClaimAddressForOperator = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setClaimAddressForOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetCommissionRate = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setCommissionRate', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetOperatorStatus = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setOperatorStatus', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperator = /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorNodeOperatorInit = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: '__NodeOperator_init', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorRegisterOperator = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'registerOperator', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetClaimAddressForOperator = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setClaimAddressForOperator', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetCommissionRate = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setCommissionRate', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetOperatorStatus = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setOperatorStatus', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Approval"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorApprovalEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Approval', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ApprovalForAll"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorApprovalForAllEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'ApprovalForAll', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ConsecutiveTransfer"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorConsecutiveTransferEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'ConsecutiveTransfer', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Initialized"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInitializedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Initialized', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceAdded"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInterfaceAddedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'InterfaceAdded', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceRemoved"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInterfaceRemovedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'InterfaceRemoved', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorClaimAddressChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorClaimAddressChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorClaimAddressChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorCommissionChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorCommissionChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorCommissionChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorRegistered"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorRegisteredEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorRegistered', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorStatusChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorStatusChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorStatusChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OwnershipTransferred"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOwnershipTransferredEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OwnershipTransferred', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Transfer"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorTransferEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Transfer', + }) + /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ * diff --git a/wagmi.config.ts b/wagmi.config.ts index 738580d..6ee7f5c 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -1344,6 +1344,227 @@ const riverTokenAbi = [ }, ] as const +const nodeOperatorAbi = [ + { inputs: [], name: 'ApprovalCallerNotOwnerNorApproved', type: 'error' }, + { inputs: [], name: 'ApprovalQueryForNonexistentToken', type: 'error' }, + { inputs: [], name: 'BalanceQueryForZeroAddress', type: 'error' }, + { inputs: [], name: 'Initializable_InInitializingState', type: 'error' }, + { inputs: [], name: 'Initializable_NotInInitializingState', type: 'error' }, + { inputs: [], name: 'Introspection_AlreadySupported', type: 'error' }, + { inputs: [], name: 'Introspection_NotSupported', type: 'error' }, + { inputs: [], name: 'MintERC2309QuantityExceedsLimit', type: 'error' }, + { inputs: [], name: 'MintToZeroAddress', type: 'error' }, + { inputs: [], name: 'MintZeroQuantity', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'operator', type: 'address' }], + name: 'NodeOperator__AlreadyDelegated', + type: 'error', + }, + { inputs: [], name: 'NodeOperator__AlreadyRegistered', type: 'error' }, + { inputs: [], name: 'NodeOperator__ClaimAddressNotChanged', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidAddress', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidCommissionRate', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidOperator', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidSpace', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidStakeRequirement', type: 'error' }, + { inputs: [], name: 'NodeOperator__InvalidStatusTransition', type: 'error' }, + { inputs: [], name: 'NodeOperator__NotClaimer', type: 'error' }, + { inputs: [], name: 'NodeOperator__NotEnoughStake', type: 'error' }, + { inputs: [], name: 'NodeOperator__NotRegistered', type: 'error' }, + { inputs: [], name: 'NodeOperator__NotTransferable', type: 'error' }, + { inputs: [], name: 'NodeOperator__StatusNotChanged', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'Ownable__NotOwner', + type: 'error', + }, + { inputs: [], name: 'Ownable__ZeroAddress', type: 'error' }, + { inputs: [], name: 'OwnerQueryForNonexistentToken', type: 'error' }, + { inputs: [], name: 'OwnershipNotInitializedForExtraData', type: 'error' }, + { inputs: [], name: 'TransferCallerNotOwnerNorApproved', type: 'error' }, + { inputs: [], name: 'TransferFromIncorrectOwner', type: 'error' }, + { inputs: [], name: 'TransferToNonERC721ReceiverImplementer', type: 'error' }, + { inputs: [], name: 'TransferToZeroAddress', type: 'error' }, + { inputs: [], name: 'URIQueryForNonexistentToken', type: 'error' }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'approved', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'owner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'operator', type: 'address' }, + { indexed: false, internalType: 'bool', name: 'approved', type: 'bool' }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'uint256', name: 'fromTokenId', type: 'uint256' }, + { indexed: false, internalType: 'uint256', name: 'toTokenId', type: 'uint256' }, + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'ConsecutiveTransfer', + type: 'event', + }, + { + anonymous: false, + inputs: [{ indexed: false, internalType: 'uint32', name: 'version', type: 'uint32' }], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [{ indexed: true, internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'InterfaceAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [{ indexed: true, internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'InterfaceRemoved', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'operator', type: 'address' }, + { indexed: true, internalType: 'address', name: 'claimAddress', type: 'address' }, + ], + name: 'OperatorClaimAddressChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'operator', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'commission', type: 'uint256' }, + ], + name: 'OperatorCommissionChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [{ indexed: true, internalType: 'address', name: 'operator', type: 'address' }], + name: 'OperatorRegistered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'operator', type: 'address' }, + { indexed: true, internalType: 'enum NodeOperatorStatus', name: 'newStatus', type: 'uint8' }, + ], + name: 'OperatorStatusChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'previousOwner', type: 'address' }, + { indexed: true, internalType: 'address', name: 'newOwner', type: 'address' }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: 'address', name: 'from', type: 'address' }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { indexed: true, internalType: 'uint256', name: 'tokenId', type: 'uint256' }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [], + name: '__NodeOperator_init', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator', type: 'address' }], + name: 'getClaimAddressForOperator', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator', type: 'address' }], + name: 'getCommissionRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator', type: 'address' }], + name: 'getOperatorStatus', + outputs: [{ internalType: 'enum NodeOperatorStatus', name: '', type: 'uint8' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getOperators', + outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'operator', type: 'address' }], + name: 'isOperator', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'claimer', type: 'address' }], + name: 'registerOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'claimer', type: 'address' }, + { internalType: 'address', name: 'operator', type: 'address' }, + ], + name: 'setClaimAddressForOperator', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'rateBps', type: 'uint256' }], + name: 'setCommissionRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'operator', type: 'address' }, + { internalType: 'enum NodeOperatorStatus', name: 'newStatus', type: 'uint8' }, + ], + name: 'setOperatorStatus', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const + const baseRiverTokenAddress = '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920' satisfies Address const baseGammaSepoliaTokenAddress = '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0' satisfies Address @@ -1366,6 +1587,14 @@ export default defineConfig({ }, abi: rewardDistributionAbi, }, + { + name: 'NodeOperator', + address: { + [base.id]: omega.address as Address, + [baseSepolia.id]: gamma.address as Address, + }, + abi: nodeOperatorAbi, + }, ], plugins: [ etherscan({ From 713f75135a19d501793396c5f26bf4d82a358677 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 16 Dec 2024 15:46:28 -0300 Subject: [PATCH 05/44] dump --- src/app/(requires-wallet)/stake/layout.tsx | 32 ++++ src/app/(requires-wallet)/stake/page.tsx | 70 ++++++++ src/app/status/node-status.tsx | 2 +- src/components/delegate/delegate-section.tsx | 2 +- src/components/max-button.tsx | 33 ++++ src/components/stake/increase-stake.tsx | 156 ++++++++++++++++++ src/components/stake/initiate-withdraw.tsx | 75 +++++++++ src/components/stake/node-card.tsx | 117 +++++++++++++ src/components/stake/stake-to-operator.tsx | 135 +++++++++++++++ src/components/stake/total-supply.tsx | 45 +++++ src/components/stake/withdraw.tsx | 79 +++++++++ src/components/stake/your-account.tsx | 67 ++++++++ src/components/stake/your-rewards.tsx | 63 +++++++ src/components/status/gradient-ring.tsx | 2 +- .../status/node-animation-scene.tsx | 2 +- src/components/status/node-status-pill.tsx | 2 +- src/components/status/node-tooltips.tsx | 4 +- src/components/switch-to-base.tsx | 25 +++ src/components/ui/button.tsx | 7 +- src/components/ui/card.tsx | 2 +- src/components/ui/dialog.tsx | 16 +- src/data/requests.ts | 55 +++++- src/lib/hooks/use-claim.ts | 5 + src/lib/hooks/use-increase-stake.ts | 47 ++++++ src/lib/hooks/use-initiate-withdraw.ts | 21 +++ src/lib/hooks/use-node-data.ts | 116 ++++++++----- src/lib/hooks/use-stake.ts | 43 +++++ src/lib/hooks/use-withdraw.ts | 22 +++ 28 files changed, 1184 insertions(+), 61 deletions(-) create mode 100644 src/app/(requires-wallet)/stake/layout.tsx create mode 100644 src/app/(requires-wallet)/stake/page.tsx create mode 100644 src/components/max-button.tsx create mode 100644 src/components/stake/increase-stake.tsx create mode 100644 src/components/stake/initiate-withdraw.tsx create mode 100644 src/components/stake/node-card.tsx create mode 100644 src/components/stake/stake-to-operator.tsx create mode 100644 src/components/stake/total-supply.tsx create mode 100644 src/components/stake/withdraw.tsx create mode 100644 src/components/stake/your-account.tsx create mode 100644 src/components/stake/your-rewards.tsx create mode 100644 src/components/switch-to-base.tsx create mode 100644 src/lib/hooks/use-increase-stake.ts create mode 100644 src/lib/hooks/use-initiate-withdraw.ts create mode 100644 src/lib/hooks/use-stake.ts create mode 100644 src/lib/hooks/use-withdraw.ts diff --git a/src/app/(requires-wallet)/stake/layout.tsx b/src/app/(requires-wallet)/stake/layout.tsx new file mode 100644 index 0000000..1bbf05f --- /dev/null +++ b/src/app/(requires-wallet)/stake/layout.tsx @@ -0,0 +1,32 @@ +import { sharedMetadata } from '@/constants/metadata' +import { Metadata } from 'next' + +const metadataTitle = 'Stake - River Protocol' +const metadataDescription = 'Stake your tokens and earn rewards' + +export const metadata: Metadata = { + title: metadataTitle, + description: metadataDescription, + openGraph: { + ...sharedMetadata.openGraph, + url: 'https://river.build/stake', + title: metadataTitle, + description: metadataDescription, + images: [ + { + url: '/og-image-stake.jpg', + alt: metadataTitle, + }, + ], + }, + twitter: { + ...sharedMetadata.twitter, + description: metadataDescription, + }, +} + +const StakeLayout = ({ children }: { children: React.ReactNode }) => { + return <>{children} +} + +export default StakeLayout diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx new file mode 100644 index 0000000..e833a5d --- /dev/null +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -0,0 +1,70 @@ +import { NodeCard } from '@/components/stake/node-card' +import { TotalSupplyCard } from '@/components/stake/total-supply' +import { YourAccountCard } from '@/components/stake/your-account' +import { YourRewardsCard } from '@/components/stake/your-rewards' +import { SwitchToBase } from '@/components/switch-to-base' +import { getStakeableNodes } from '@/data/requests' +import { formatStackableNodeData } from '@/lib/hooks/use-node-data' +import { cn } from '@/lib/utils' + +const totalSupplyData = [ + { name: 'Staked', value: 4345345333, color: 'green' }, + { name: 'Unstaked', value: 1035345, color: 'gray' }, +] + +const rewardsClaimedData = [ + { name: 'Claimed', value: 1035345, color: 'hsl(var(--chart-3))' }, + { name: 'Unclaimed', value: 4345345333 - 1035345, color: 'hsl(var(--muted))' }, +] + +const colors = [ + '#1DDCF2', + '#AFDD79', + '#FED83D', + '#C740F2', + '#9558FA', + '#FEA56F', + '#FF60B2', + '#FEA56F', + '#DBDE54', +] + +const StakePage = async () => { + // Get data from SSR + // live data probably doesnt make sense here. + const initialData = await getStakeableNodes().catch(() => undefined) + const operators = formatStackableNodeData(initialData) + + return ( +
+
+ + + +
+ + +
+
+

All Operators

+

+ To distribute power on the network, please delegate to top performing operators. +

+
+ {/* TODO: this page wont be live fetching node data - right? */} + {operators.map((operator) => ( + + ))} +
+
+
+
+ ) +} + +export default StakePage diff --git a/src/app/status/node-status.tsx b/src/app/status/node-status.tsx index bf175cf..871482a 100644 --- a/src/app/status/node-status.tsx +++ b/src/app/status/node-status.tsx @@ -5,7 +5,7 @@ import { NodeStatusSchema } from '@/data/requests' import { useNodeData } from '@/lib/hooks/use-node-data' export const NodeStatus = ({ initialData }: { initialData?: NodeStatusSchema }) => { - const nodes = useNodeData({ initialData }) + const nodes = useNodeData({ initialData, liveQuery: true }) return ( <> {nodes.map((node) => ( diff --git a/src/components/delegate/delegate-section.tsx b/src/components/delegate/delegate-section.tsx index 2a7f8c6..9c11820 100644 --- a/src/components/delegate/delegate-section.tsx +++ b/src/components/delegate/delegate-section.tsx @@ -69,7 +69,7 @@ export const DelegateSection = () => { showAddress /> ) : ( - + diff --git a/src/components/max-button.tsx b/src/components/max-button.tsx new file mode 100644 index 0000000..a238bab --- /dev/null +++ b/src/components/max-button.tsx @@ -0,0 +1,33 @@ +import { motion, useAnimate } from 'framer-motion' + +export const MaxButton = ({ onClick }: { onClick: () => void }) => { + const [scope, animate] = useAnimate() + + return ( + { + animate( + [ + [scope.current, { scale: 0.85 }], + [scope.current, { scale: 1 }], + ], + { + defaultTransition: { ease: 'easeOut' }, + duration: 0.1, + }, + ) + onClick() + }} + > + MAX + + ) +} diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx new file mode 100644 index 0000000..eadfb8f --- /dev/null +++ b/src/components/stake/increase-stake.tsx @@ -0,0 +1,156 @@ +import { Button } from '@/components/ui/button' +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form' +import { Input } from '@/components/ui/input' +import { useReadRiverTokenBalanceOf } from '@/contracts' +import { useIncreaseStake } from '@/lib/hooks/use-increase-stake' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { zodResolver } from '@hookform/resolvers/zod' +import type { DialogContentProps } from '@radix-ui/react-dialog' +import { useCallback, useEffect, useMemo } from 'react' +import { useForm } from 'react-hook-form' +import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' +import * as z from 'zod' +import { MaxButton } from '../max-button' +import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' +import { Skeleton } from '../ui/skeleton' +import { Typography } from '../ui/typography' +import { NodeCard } from './node-card' + +type IncreaseStakeFormProps = { + node: StackableNodeData + depositId: bigint // TODO: how should we archicture around this? + onStakeFinish?: (amount: number) => void +} + +export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseStakeFormProps) { + const { address } = useAccount() + const { data: balance } = useReadRiverTokenBalanceOf({ + args: [address!], + query: { enabled: !!address }, + }) + const avaliableBalance = balance || 0n + const formSchema = useMemo( + () => + z.object({ + amount: z + .number() + .refine((val) => Number(val) > 0, { + message: 'Amount must be a positive number', + }) + .refine((val) => val <= avaliableBalance, { + message: 'Amount can not be greater than available balance', + }), + }), + [avaliableBalance], + ) + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + amount: 0, + }, + }) + + const { + isStakingStateLoading, + stakingState, + increaseStake, + isPending, + isTxPending, + isTxConfirmed, + } = useIncreaseStake() + const isStaking = isPending || isTxPending + + useEffect(() => { + if (isTxConfirmed) { + onStakeFinish?.(form.getValues('amount')) + form.reset() + } + }, [isTxConfirmed, onStakeFinish, form]) + + const handleSetMax = useCallback(() => { + form.setValue('amount', Number(avaliableBalance)) + }, [avaliableBalance, form]) + + return ( +
+ + increaseStake({ + args: [depositId, BigInt(values.amount)], + }), + )} + className="space-y-6 py-4" + > +
+ Currently Staked: + {isStakingStateLoading ? ( + + ) : ( + + {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + + )} +
+
+ Stake to: + +
+ + ( + +
+ Enter amount + +
+ + + + + + Available Balance {formatUnits(avaliableBalance, 18)} RVR + +
+ )} + /> + + + + + ) +} + +export const IncreaseStakeDialogContent = ({ + node, + depositId, + onStakeFinish, + ...rest +}: IncreaseStakeFormProps & DialogContentProps) => { + return ( + + + Increase Stake + + + + ) +} diff --git a/src/components/stake/initiate-withdraw.tsx b/src/components/stake/initiate-withdraw.tsx new file mode 100644 index 0000000..deaa8da --- /dev/null +++ b/src/components/stake/initiate-withdraw.tsx @@ -0,0 +1,75 @@ +'use client' +import { Button } from '@/components/ui/button' +import { useReadRiverTokenBalanceOf } from '@/contracts' +import { useInitiateWithdraw } from '@/lib/hooks/use-initiate-withdraw' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { useStake } from '@/lib/hooks/use-stake' +import type { DialogContentProps } from '@radix-ui/react-dialog' +import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' +import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' +import { Skeleton } from '../ui/skeleton' +import { Typography } from '../ui/typography' +import { NodeCard } from './node-card' + +type InitiateWithdrawFormProps = { + node: StackableNodeData + depositId: bigint // TODO: how should we archicture around this? + onStakeFinish?: (amount: number) => void +} + +export function InitiateWithdrawForm({ node }: InitiateWithdrawFormProps) { + const { address } = useAccount() + const { data: balance } = useReadRiverTokenBalanceOf({ + args: [address!], + query: { enabled: !!address }, + }) + const avaliableBalance = balance || 0n + const { isStakingStateLoading, stakingState } = useStake() + const { initiateWithdraw, isPending, isTxPending, isTxConfirmed } = useInitiateWithdraw() + const isWithdrawing = isPending || isTxPending + + return ( +
+
+ Currently Staked: + {isStakingStateLoading ? ( + + ) : ( + + {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + + )} +
+
+ Currently delegated to: + +
+ + + Initiating withdraw will take 3 days lock up period, after which you can withdraw the tokens + to your wallet. + + + +
+ ) +} + +export const InitiateWithdrawDialogContent = ({ + node, + depositId, + onStakeFinish, + ...rest +}: InitiateWithdrawFormProps & DialogContentProps) => { + return ( + + + Initiate Withdraw + + + + ) +} diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx new file mode 100644 index 0000000..8d4cd2b --- /dev/null +++ b/src/components/stake/node-card.tsx @@ -0,0 +1,117 @@ +'use client' + +import { Button } from '@/components/ui/button' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { cn, formatUptime } from '@/lib/utils' +import { MoreVertical } from 'lucide-react' +import { Dialog, DialogTrigger } from '../ui/dialog' +import { Typography } from '../ui/typography' +import { IncreaseStakeDialogContent } from './increase-stake' +import { StakeDialogContent } from './stake-to-operator' +import { WithdrawDialogContent } from './withdraw' + +export interface NodeCardProps { + node: StackableNodeData + onMenuClick?: () => void + className?: string + showButton?: boolean +} + +type Status = 'stakeable' | 'staked' | 'locked' | 'can-withdraw' + +export function NodeCard({ node, onMenuClick, className, showButton }: NodeCardProps) { + const estimatedApr = 10 // TODO: + const withdrawalTime = '10 days' // TODO: + const amountStaked = false // TODO: + const name = new URL(node.data.record.url).hostname + const status = 'stakeable' as Status // TODO: + return ( +
+ {/* Header */} +
+
+ + {name} + +
+ +
+ + {node.data.http20.elapsed} HTTP/2 + + {node.data.grpc.elapsed} gRPC + + } + /> + + + + // + {estimatedApr}% + // + // + //

APR may vary and depends on delegation amount or total period reward.

+ //
+ // + } + /> + {amountStaked && {amountStaked} RVR} />} +
+ + {/* Bottom Row */} + {showButton ? ( +
+ {status === 'stakeable' && ( + + + + + + + )} + {status === 'staked' && ( + + + + + + + )} + {status === 'locked' && } + {status === 'can-withdraw' && ( + + + + + + + )} + {onMenuClick && ( + + )} +
+ ) : null} +
+ ) +} + +const InfoRow = ({ label, value }: { label: React.ReactNode; value: React.ReactNode }) => { + return ( +
+ + {label} + + + {value} + +
+ ) +} diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx new file mode 100644 index 0000000..6cbf5b2 --- /dev/null +++ b/src/components/stake/stake-to-operator.tsx @@ -0,0 +1,135 @@ +import { Button } from '@/components/ui/button' +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form' +import { Input } from '@/components/ui/input' +import { useReadRiverTokenBalanceOf } from '@/contracts' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { useStake } from '@/lib/hooks/use-stake' +import { zodResolver } from '@hookform/resolvers/zod' +import type { DialogContentProps } from '@radix-ui/react-dialog' +import { useCallback, useEffect, useMemo } from 'react' +import { useForm } from 'react-hook-form' +import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' +import * as z from 'zod' +import { MaxButton } from '../max-button' +import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' +import { NodeCard } from './node-card' + +type StakeFormProps = { + node: StackableNodeData + onStakeFinish?: (amount: number) => void +} + +export function StakeForm({ node, onStakeFinish }: StakeFormProps) { + const { address } = useAccount() + const { data: balance } = useReadRiverTokenBalanceOf({ + args: [address!], + query: { enabled: !!address }, + }) + const avaliableBalance = balance || 0n + const formSchema = useMemo( + () => + z.object({ + amount: z + .number() + .refine((val) => Number(val) > 0, { + message: 'Amount must be a positive number', + }) + .refine((val) => val <= avaliableBalance, { + message: 'Amount can not be greater than available balance', + }), + }), + [avaliableBalance], + ) + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + amount: 0, + }, + }) + + const { stake, isPending, isTxPending, isTxConfirmed } = useStake() + const isStaking = isPending || isTxPending + + useEffect(() => { + if (isTxConfirmed) { + onStakeFinish?.(form.getValues('amount')) + form.reset() + } + }, [isTxConfirmed, onStakeFinish, form]) + + const handleSetMax = useCallback(() => { + form.setValue('amount', Number(avaliableBalance)) + }, [avaliableBalance, form]) + + return ( +
+ + stake({ + args: [BigInt(values.amount), node.data.record.operator, address!], + }), + )} + className="space-y-6 py-4" + > +
+ Stake to: + +
+ + ( + +
+ Enter amount + +
+ + + + + + Available Balance {formatUnits(avaliableBalance, 18)} RVR + +
+ )} + /> + + + + + ) +} + +export const StakeDialogContent = ({ + node, + onStakeFinish, + ...rest +}: StakeFormProps & DialogContentProps) => { + return ( + + + Stake to Operator + + + + ) +} diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx new file mode 100644 index 0000000..ec0ab23 --- /dev/null +++ b/src/components/stake/total-supply.tsx @@ -0,0 +1,45 @@ +'use client'; +import { useAccount } from 'wagmi' +import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' +import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' + +export const TotalSupplyCard = () => { + const { isConnected } = useAccount() + + return ( + + + Total Supply + + +
+ {/* TODO: Add chart */} +
+
Staked
+
4,345,345,333 RVR
+
+
+ +
+ {/* TODO: Add chart */} +
+
Rewards Claimed
+
1,035,345 RVR
+
+
+ + + +
+
4.3%
+
Estimated APR*
+
+
+ +

APR may vary and depends on delegation amount or total period reward.

+
+
+
+
+ ) +} diff --git a/src/components/stake/withdraw.tsx b/src/components/stake/withdraw.tsx new file mode 100644 index 0000000..a80f56d --- /dev/null +++ b/src/components/stake/withdraw.tsx @@ -0,0 +1,79 @@ +'use client' +import { Button } from '@/components/ui/button' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { useWithdraw } from '@/lib/hooks/use-withdraw' +import type { DialogContentProps } from '@radix-ui/react-dialog' +import { formatUnits } from 'viem' +import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' +import { Skeleton } from '../ui/skeleton' +import { Typography } from '../ui/typography' +import { NodeCard } from './node-card' + +type WithdrawFormProps = { + node: StackableNodeData + depositId: bigint // TODO: how should we archicture around this? + onStakeFinish?: (amount: number) => void +} + +export function WithdrawForm({ node, depositId }: WithdrawFormProps) { + const { + withdraw, + isPending, + isTxPending, + isTxConfirmed, + amountToWithdraw, + isAmountToWithdrawLoading, + } = useWithdraw(depositId) + const isWithdrawing = isPending || isTxPending + + return ( +
+
+
+ Currently delegated to: + +
+ + Amount to withdraw: + {isAmountToWithdrawLoading ? ( + + ) : ( + + {formatUnits(amountToWithdraw ?? 0n, 18)} RVR + + )} +
+ + + Initiating withdraw will take 3 days lock up period, after which you can withdraw the tokens + to your wallet. + + + +
+ ) +} + +export const WithdrawDialogContent = ({ + node, + depositId, + onStakeFinish, + ...rest +}: WithdrawFormProps & DialogContentProps) => { + return ( + + + Withdraw + + + + ) +} diff --git a/src/components/stake/your-account.tsx b/src/components/stake/your-account.tsx new file mode 100644 index 0000000..c660151 --- /dev/null +++ b/src/components/stake/your-account.tsx @@ -0,0 +1,67 @@ +'use client' + +import { useReadRiverTokenBalanceOf } from '@/contracts' +import { useStake } from '@/lib/hooks/use-stake' +import { useEffect, useRef } from 'react' +import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' +import { Button } from '../ui/button' +import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' +import { Skeleton } from '../ui/skeleton' + +export const YourAccountCard = () => { + const { isConnected, address } = useAccount() + const { data: balance, isLoading: isBalanceLoading } = useReadRiverTokenBalanceOf({ + args: [address!], + query: { enabled: isConnected && !!address }, + }) + const { stakingState, isStakingStateLoading } = useStake() + const allOperatorsListRef = useRef(null) + + useEffect(() => { + // not getting the from the parent with useRef + // because we dont want the parent to be a client component + allOperatorsListRef.current = document.getElementById('all-operators') + console.log(allOperatorsListRef.current) + }, []) + + return ( + + + Your Account + + +
+ Wallet Balance + + {!isConnected && '-'} + {isConnected && isBalanceLoading ? ( + + ) : ( + {formatUnits(balance ?? 0n, 18)} + )} + +
+
+ Staked + + {!isConnected && '-'} + {isConnected && isStakingStateLoading ? ( + + ) : ( + {formatUnits(stakingState?.totalStaked ?? 0n, 18)} + )} + +
+ +
+
+ ) +} diff --git a/src/components/stake/your-rewards.tsx b/src/components/stake/your-rewards.tsx new file mode 100644 index 0000000..bc00495 --- /dev/null +++ b/src/components/stake/your-rewards.tsx @@ -0,0 +1,63 @@ +'use client' + +import { useClaim } from '@/lib/hooks/use-claim' +import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' +import { Button } from '../ui/button' +import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' +import { Skeleton } from '../ui/skeleton' + +export const YourRewardsCard = () => { + const { isConnected, address } = useAccount() + const { + isPending, + claimableBalance, + isTxConfirmed, + isLoadingClaimableBalance, + isTxPending, + claimReward, + } = useClaim() + return ( + + + Your Rewards + + +
+ + {isConnected ? ( + isLoadingClaimableBalance ? ( + + ) : ( + formatUnits(claimableBalance ?? 0n, 18) + ) + ) : ( + '-' + )} + +
+ +
+
+ ) +} diff --git a/src/components/status/gradient-ring.tsx b/src/components/status/gradient-ring.tsx index 10c6116..cd4d215 100644 --- a/src/components/status/gradient-ring.tsx +++ b/src/components/status/gradient-ring.tsx @@ -49,7 +49,7 @@ export const GradientRing = (props: Props) => { ), vertexColors: Array.from({ length: numPoints }).map((_, i) => new Color(0xffffff)), bufferColors: Array.from({ length: numPoints * 3 }).map((_, i) => 0), - } as const), + }) as const, ) const sortedColors = useMemo(() => nodes.map((n) => new Color(n.color)), [nodes]) diff --git a/src/components/status/node-animation-scene.tsx b/src/components/status/node-animation-scene.tsx index c12dbc9..577f695 100644 --- a/src/components/status/node-animation-scene.tsx +++ b/src/components/status/node-animation-scene.tsx @@ -57,7 +57,7 @@ const GlobeScene = (props: { const { canvas, relevantPoints } = useGlobeTexture(noise, mapSize) const globeRef = useRef(null) - const nodeConnections = useNodeData() + const nodeConnections = useNodeData({ liveQuery: true }) const nodes = useMemo(() => { return nodeConnections.map((n, index) => ({ diff --git a/src/components/status/node-status-pill.tsx b/src/components/status/node-status-pill.tsx index 89aaca3..dca80ba 100644 --- a/src/components/status/node-status-pill.tsx +++ b/src/components/status/node-status-pill.tsx @@ -111,7 +111,7 @@ export const NodeStatusPill = ({ nodeData }: { nodeData: NodeData }) => {
diff --git a/src/components/status/node-tooltips.tsx b/src/components/status/node-tooltips.tsx index a936d96..f9b84f3 100644 --- a/src/components/status/node-tooltips.tsx +++ b/src/components/status/node-tooltips.tsx @@ -57,7 +57,7 @@ const NodeTooltip = forwardRef(({ nodeDa ref={ref} className="flex min-w-full select-none flex-col gap-0.5 rounded-md border border-gray-30 bg-[#222026] px-2.5 py-1.5 shadow-sm" > - + {formatUrl(nodeData.nodeUrl)} @@ -65,7 +65,7 @@ const NodeTooltip = forwardRef(({ nodeDa {nodeData.data.grpc.elapsed} gRPC {nodeData.data.http20.elapsed} HTTP/2 - + Uptime{' '} {formatUptime(new Date(nodeData.data.grpc.start_time))} diff --git a/src/components/switch-to-base.tsx b/src/components/switch-to-base.tsx new file mode 100644 index 0000000..507b1d0 --- /dev/null +++ b/src/components/switch-to-base.tsx @@ -0,0 +1,25 @@ +'use client' +import { base, baseSepolia } from 'viem/chains' +import { useAccount, useSwitchChain } from 'wagmi' +import { Button } from './ui/button' +import { Typography } from './ui/typography' + +export const SwitchToBase = () => { + const { chainId, isConnected } = useAccount() + const isBase = chainId === base.id || chainId === baseSepolia.id + const { switchChain } = useSwitchChain() + return ( + <> + {isConnected && !isBase && ( +
+ + You can only stake on the Base chain. Please switch to Base. + + +
+ )} + + ) +} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 3f294bb..621c121 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -43,8 +43,9 @@ const bgClassName = cva( { variants: { variant: { - primary: 'bg-gray-10 text-gray-90 group-disabled:bg-white/10 group-disabled:text-white/20', - secondary: 'bg-gray-60 text-gray-10 transition-all group-hover:bg-gray-30 group-disabled:bg-gray-30 group-disabled:text-gray-20', + primary: 'bg-gray-10 text-gray-90 group-disabled:bg-white/10 group-disabled:text-white/20', + secondary: + 'bg-gray-60 text-gray-10 transition-all group-hover:bg-gray-30 group-disabled:bg-gray-30 group-disabled:text-gray-20', }, }, defaultVariants: { @@ -77,7 +78,7 @@ const Button = React.forwardRef( )} {/* */} - + {isLoading && } {children} diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index f46ea24..9011c5e 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -46,7 +46,7 @@ const Card = React.forwardRef< onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > -
{children}
+
{children}
) }, diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 41a3f1b..8a5b051 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -19,7 +19,7 @@ const DialogOverlay = React.forwardRef< - {children} - - + + Close + {children} )) diff --git a/src/data/requests.ts b/src/data/requests.ts index 06942a5..29e458a 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -1,4 +1,6 @@ -import { isAddress } from 'viem' +import { nodeOperatorAbi, nodeOperatorAddress } from '@/contracts' +import { createPublicClient, formatUnits, http, isAddress, type Address } from 'viem' +import { base } from 'viem/chains' import { z } from 'zod' // TODO: [HNT-6333] The main node should be decided by making a read call from the RiverRegistry in RiverChain @@ -52,6 +54,8 @@ export const getNodeData = async () => { const zodAddress = z.string().refine(isAddress) export type NodeStatusSchema = z.infer +export type NodeData = Awaited>['nodes'][number] + export const nodeStatusSchema = z.object({ nodes: z.array( z.object({ @@ -126,3 +130,52 @@ export const nodeStatusSchema = z.object({ query_time: z.string(), elapsed: z.string(), }) + +export type StackableNode = Awaited>[number] + +// wip 🏗️ +export const getStakeableNodes = async () => { + // todo: change depending on chain + const client = createPublicClient({ + chain: base, + transport: http(), + }) + const nodeData = await getNodeData() + const operators = nodeData.nodes.map((node) => node.record.operator) + // get all operators + const uniqueOperators = Array.from(new Set(operators)) // Get unique operators + + // get all comission rates + const comissionRates = await Promise.all( + uniqueOperators.map((operator) => + client.readContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress[base.id], + functionName: 'getCommissionRate', + args: [operator], + }), + ), + ) + + // Create a hashmap from unique operator address to commission rate + const operatorCommissionMap = uniqueOperators.reduce>( + (map, operator, index) => { + map[operator] = comissionRates[index] + return map + }, + {}, + ) + + // calculate APR for each operator + const calculateApr = (comissionRate: bigint) => { + return Number(comissionRate) / 10000 // todo: calculate APR + } + // skip - check depositIds (? - think we cant do this here) + // sort by APR + + return nodeData.nodes.map((node) => { + const commissionRate = operatorCommissionMap[node.record.operator] + const estimatedApr = calculateApr(commissionRate) + return { ...node, commissionRatePercentage: formatUnits(commissionRate, 3), estimatedApr } + }) +} diff --git a/src/lib/hooks/use-claim.ts b/src/lib/hooks/use-claim.ts index d5128f8..1e1ecba 100644 --- a/src/lib/hooks/use-claim.ts +++ b/src/lib/hooks/use-claim.ts @@ -1,3 +1,5 @@ +'use client' + import { toast } from '@/components/ui/use-toast' import { useReadRewardsDistributionCurrentReward, @@ -15,6 +17,9 @@ export const useClaim = () => { const confetti = useMemo(() => new Confetti(), []) const { queryKey: riverBalanceQueryKey } = useReadRiverTokenBalanceOf({ args: [address!], + query: { + enabled: !!address, + }, }) const { data: claimableBalance, diff --git a/src/lib/hooks/use-increase-stake.ts b/src/lib/hooks/use-increase-stake.ts new file mode 100644 index 0000000..db5060c --- /dev/null +++ b/src/lib/hooks/use-increase-stake.ts @@ -0,0 +1,47 @@ +'use client' +import { + useReadRewardsDistributionStakingState, + useWriteRewardsDistributionIncreaseStake, +} from '@/contracts' +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useAccount, useWaitForTransactionReceipt } from 'wagmi' + +export const useIncreaseStake = () => { + const { address } = useAccount() + const qc = useQueryClient() + + const { + writeContract: increaseStake, + data: hash, + isPending, + } = useWriteRewardsDistributionIncreaseStake() + const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ + hash: hash, + }) + + const { + queryKey: stakingStateQueryKey, + data: stakingState, + isLoading: isStakingStateLoading, + } = useReadRewardsDistributionStakingState({ + query: { + enabled: !!address, + }, + }) + + useEffect(() => { + if (isTxConfirmed) { + qc.invalidateQueries({ queryKey: [stakingStateQueryKey] }) + } + }, [isTxConfirmed]) + + return { + increaseStake, + isPending, + isTxPending, + isTxConfirmed, + stakingState, + isStakingStateLoading, + } +} diff --git a/src/lib/hooks/use-initiate-withdraw.ts b/src/lib/hooks/use-initiate-withdraw.ts new file mode 100644 index 0000000..a9e9c40 --- /dev/null +++ b/src/lib/hooks/use-initiate-withdraw.ts @@ -0,0 +1,21 @@ +'use client' +import { useWriteRewardsDistributionInitiateWithdraw } from '@/contracts' +import { useWaitForTransactionReceipt } from 'wagmi' + +export const useInitiateWithdraw = () => { + const { + writeContract: initiateWithdraw, + data: hash, + isPending, + } = useWriteRewardsDistributionInitiateWithdraw() + const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ + hash: hash, + }) + + return { + initiateWithdraw, + isPending, + isTxPending, + isTxConfirmed, + } +} diff --git a/src/lib/hooks/use-node-data.ts b/src/lib/hooks/use-node-data.ts index b87ab43..614c31f 100644 --- a/src/lib/hooks/use-node-data.ts +++ b/src/lib/hooks/use-node-data.ts @@ -1,54 +1,82 @@ import { SECOND_MS } from '@/constants/time-ms' +import { NodeStatusSchema, getNodeData, type StackableNode } from '@/data/requests' import { useQuery } from '@tanstack/react-query' import { useMemo } from 'react' -import { Color } from 'three' -import { NodeStatusSchema, getNodeData } from '@/data/requests' const colors = [ - '#1DDCF2', - '#AFDD79', - '#FED83D', - '#C740F2', - '#9558FA', - '#FEA56F', - '#FF60B2', - '#FEA56F', - '#DBDE54', + '#1DDCF2', + '#AFDD79', + '#FED83D', + '#C740F2', + '#9558FA', + '#FEA56F', + '#FF60B2', + '#FEA56F', + '#DBDE54', ] export type NodeData = ReturnType[0] -export const useNodeData = ({ initialData }: { initialData?: NodeStatusSchema} = {}) => { - const { data } = useQuery({ - queryKey: ['nodeStatus'], - queryFn: getNodeData, - refetchInterval: 30 * SECOND_MS, - initialData, - }) - - const nodeConnections = useMemo(() => { - const operators = new Set() - return ( - data?.nodes.map((n, i) => { - operators.add(n.record.operator) - const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) - return { - id: n.record.url, - index: i, - nodeUrl: n.record.url, - statusText: n.record.status_text, - status: n.record.status, - operator: n.record.operator, - operatorIndex, - data: n, - color: new Color( - colors[Math.floor((i * colors.length) / data.nodes.length) % colors.length], - ), - operatorColor: new Color(colors[(3 + operatorIndex) % colors.length]), - } - }) ?? [] - ) - }, [data?.nodes]) - - return nodeConnections +export const useNodeData = ({ + initialData, + liveQuery, +}: { initialData?: NodeStatusSchema; liveQuery?: boolean } = {}) => { + const { data } = useQuery({ + queryKey: ['nodeStatus'], + queryFn: getNodeData, + refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, + initialData, + }) + + const nodeConnections = useMemo(() => { + return formatNodeData(data) + }, [data]) + + return nodeConnections +} + +export const formatNodeData = (data: NodeStatusSchema | undefined) => { + if (!data) return [] + const operators = new Set() + return data.nodes.map((n, i) => { + operators.add(n.record.operator) + const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) + return { + id: n.record.url, + index: i, + nodeUrl: n.record.url, + statusText: n.record.status_text, + status: n.record.status, + operator: n.record.operator, + operatorIndex, + data: n, + color: colors[Math.floor((i * colors.length) / data.nodes.length) % colors.length], + operatorColor: colors[(3 + operatorIndex) % colors.length], + // TODO: add user stacked amount - use it to sort in the UI + } + }) +} + +export type StackableNodeData = ReturnType[number] + +export const formatStackableNodeData = (data: StackableNode[] | undefined) => { + if (!data) return [] + const operators = new Set() + return data.map((n, i) => { + operators.add(n.record.operator) + const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) + return { + id: n.record.url, + index: i, + nodeUrl: n.record.url, + statusText: n.record.status_text, + status: n.record.status, + operator: n.record.operator, + operatorIndex, + data: n, + color: colors[Math.floor((i * colors.length) / data.length) % colors.length], + operatorColor: colors[(3 + operatorIndex) % colors.length], + // TODO: add user stacked amount - use it to sort in the UI + } + }) } diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts new file mode 100644 index 0000000..0a526ce --- /dev/null +++ b/src/lib/hooks/use-stake.ts @@ -0,0 +1,43 @@ +'use client' +import { + useReadRewardsDistributionStakingState, + useWriteRewardsDistributionStake, +} from '@/contracts' +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useAccount, useWaitForTransactionReceipt } from 'wagmi' + +export const useStake = () => { + const { address } = useAccount() + const qc = useQueryClient() + + const { writeContract: stake, data: hash, isPending } = useWriteRewardsDistributionStake() + const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ + hash: hash, + }) + + const { + queryKey: stakingStateQueryKey, + data: stakingState, + isLoading: isStakingStateLoading, + } = useReadRewardsDistributionStakingState({ + query: { + enabled: !!address, + }, + }) + + useEffect(() => { + if (isTxConfirmed) { + qc.invalidateQueries({ queryKey: [stakingStateQueryKey] }) + } + }, [isTxConfirmed]) + + return { + stake, + isPending, + isTxPending, + isTxConfirmed, + stakingState, + isStakingStateLoading, + } +} diff --git a/src/lib/hooks/use-withdraw.ts b/src/lib/hooks/use-withdraw.ts new file mode 100644 index 0000000..f0be44f --- /dev/null +++ b/src/lib/hooks/use-withdraw.ts @@ -0,0 +1,22 @@ +'use client' +import { useWriteRewardsDistributionWithdraw } from '@/contracts' +import { useWaitForTransactionReceipt } from 'wagmi' + +export const useWithdraw = (depositId: bigint) => { + const { writeContract: withdraw, data: hash, isPending } = useWriteRewardsDistributionWithdraw() + const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ + hash: hash, + }) + // TODO: add query to get the amount of tokens to withdraw using the depositId + const amountToWithdraw = 42069n + const isAmountToWithdrawLoading = false + + return { + withdraw, + isPending, + isTxPending, + isTxConfirmed, + amountToWithdraw, + isAmountToWithdrawLoading, + } +} From 92cbf68888713c642be1f9f590948201741fe147 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 16 Dec 2024 18:37:19 -0300 Subject: [PATCH 06/44] dark color-scheme --- src/app/layout.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 7f4e06a..55bb428 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -58,6 +58,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo + From b0db5b1b671148fd606f0fb8b5e96290554542e8 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 16 Dec 2024 19:12:58 -0300 Subject: [PATCH 07/44] redelegate modal --- src/app/(requires-wallet)/stake/page.tsx | 2 +- src/components/delegate/redelegate-button.tsx | 11 +- src/components/stake/node-card.tsx | 46 ++++- src/components/stake/redelegate.tsx | 174 ++++++++++++++++++ src/components/ui/dialog.tsx | 5 +- 5 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 src/components/stake/redelegate.tsx diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index e833a5d..33cfed5 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -58,7 +58,7 @@ const StakePage = async () => {
{/* TODO: this page wont be live fetching node data - right? */} {operators.map((operator) => ( - + ))}
diff --git a/src/components/delegate/redelegate-button.tsx b/src/components/delegate/redelegate-button.tsx index 38401e5..b0203ea 100644 --- a/src/components/delegate/redelegate-button.tsx +++ b/src/components/delegate/redelegate-button.tsx @@ -11,11 +11,15 @@ export const RedelegateButton = ({ delegatedAddress, variant = 'primary', showAddress, + className, + onRedelegateFinish, }: { depositId: bigint - delegatedAddress: Address + delegatedAddress: Address | undefined variant?: 'primary' | 'secondary' showAddress?: boolean + className?: string + onRedelegateFinish?: () => void }) => { const { toast } = useToast() const { isTxConfirmed, isPending, isTxPending, writeRedelegate } = useRedelegate() @@ -25,6 +29,7 @@ export const RedelegateButton = ({ toast({ title: `You've redelegated your RVR balance to ${formatAddress(delegatedAddress)}.`, }) + onRedelegateFinish?.() } }, [delegatedAddress, isTxConfirmed, toast]) @@ -32,18 +37,20 @@ export const RedelegateButton = ({ diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx index 8d4cd2b..2cd3f39 100644 --- a/src/components/stake/node-card.tsx +++ b/src/components/stake/node-card.tsx @@ -6,27 +6,42 @@ import { cn, formatUptime } from '@/lib/utils' import { MoreVertical } from 'lucide-react' import { Dialog, DialogTrigger } from '../ui/dialog' import { Typography } from '../ui/typography' -import { IncreaseStakeDialogContent } from './increase-stake' +import { RedelegateDialog, RedelegateDialogContent, RedelegateProvider } from './redelegate' import { StakeDialogContent } from './stake-to-operator' import { WithdrawDialogContent } from './withdraw' export interface NodeCardProps { node: StackableNodeData + allNodes?: StackableNodeData[] onMenuClick?: () => void className?: string showButton?: boolean + onSelect?: () => void + ringColor?: string } type Status = 'stakeable' | 'staked' | 'locked' | 'can-withdraw' -export function NodeCard({ node, onMenuClick, className, showButton }: NodeCardProps) { +export function NodeCard({ + node, + onMenuClick, + className, + showButton, + allNodes, + onSelect, + ringColor, +}: NodeCardProps) { const estimatedApr = 10 // TODO: const withdrawalTime = '10 days' // TODO: const amountStaked = false // TODO: const name = new URL(node.data.record.url).hostname const status = 'stakeable' as Status // TODO: + return ( -
+
{/* Header */}
@@ -65,6 +80,13 @@ export function NodeCard({ node, onMenuClick, className, showButton }: NodeCardP
{/* Bottom Row */} + {onSelect && ( +
+ +
+ )} {showButton ? (
{status === 'stakeable' && ( @@ -76,12 +98,18 @@ export function NodeCard({ node, onMenuClick, className, showButton }: NodeCardP
)} {status === 'staked' && ( - - - - - - + + + + + + + + )} {status === 'locked' && } {status === 'can-withdraw' && ( diff --git a/src/components/stake/redelegate.tsx b/src/components/stake/redelegate.tsx new file mode 100644 index 0000000..03bd792 --- /dev/null +++ b/src/components/stake/redelegate.tsx @@ -0,0 +1,174 @@ +import { Button } from '@/components/ui/button' +import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { cn } from '@/lib/utils' +import { Dialog, type DialogContentProps, type DialogProps } from '@radix-ui/react-dialog' +import { ArrowLeft } from 'lucide-react' +import { createContext, useContext, useState } from 'react' +import { RedelegateButton } from '../delegate/redelegate-button' +import { DialogContent, DialogHeader, DialogTitle, closeStyle } from '../ui/dialog' +import { Typography } from '../ui/typography' +import { NodeCard } from './node-card' + +type RedelegateFormProps = { + currentNode: StackableNodeData + availableNodes: StackableNodeData[] + depositId: bigint + onRedelegateFinish?: () => void +} + +export const RedelegateDialogContent = ({ + currentNode, + availableNodes, + depositId, + onRedelegateFinish, + ...rest +}: RedelegateFormProps & DialogContentProps) => { + const { + onOpenChange, + selectedOperator, + showOperatorSelect, + setSelectedOperator, + setShowOperatorSelect, + } = useContext(RedelegateContext) + + // TODO: animate height x.x + return ( + + {showOperatorSelect && ( + + )} + + + {showOperatorSelect ? 'Select a new operator' : 'Redelegate'} + + {showOperatorSelect && ( + + To distribute power on the network, please delegate to top performing operators. + + )} + + + {!showOperatorSelect && ( +
+
+ Currently delegated to: + +
+
+ Redelegate to: + +
+ { + onRedelegateFinish?.() + setSelectedOperator(undefined) + onOpenChange(false) + }} + /> +
+ )} + {showOperatorSelect && ( +
+
+ {availableNodes + .filter((node) => node.data.record.operator !== currentNode.data.record.operator) + .map((node) => ( + { + setSelectedOperator(node) + setShowOperatorSelect(false) + }} + className={cn( + 'cursor-pointer transition-all hover:opacity-85', + selectedOperator?.id === node.id ? 'ring-2 ring-white' : '', + )} + ringColor={ + selectedOperator?.id === node.id ? selectedOperator.color : 'transparent' + } + /> + ))} +
+ {/* scroll bottom fade out gradient */} +
+
+
+
+ )} + + ) +} + +const RedelegateContext = createContext<{ + onOpenChange: (open: boolean) => void + selectedOperator: StackableNodeData | undefined + setSelectedOperator: (operator: StackableNodeData | undefined) => void + showOperatorSelect: boolean + setShowOperatorSelect: (show: boolean) => void + open: boolean +}>({ + onOpenChange: () => {}, + selectedOperator: undefined, + setSelectedOperator: () => {}, + showOperatorSelect: false, + setShowOperatorSelect: () => {}, + open: false, +}) + +export const RedelegateProvider = ({ children }: { children: React.ReactNode }) => { + const [showRedelegate, setShowRedelegate] = useState(false) + const [showOperatorSelect, setShowOperatorSelect] = useState(false) + const [selectedOperator, setSelectedOperator] = useState() + + return ( + { + setShowOperatorSelect((state) => (open ? false : state)) + setShowRedelegate(open) + setSelectedOperator(undefined) + }, + selectedOperator, + showOperatorSelect, + setSelectedOperator, + setShowOperatorSelect, + open: showRedelegate, + }} + > + {children} + + ) +} + +export const RedelegateDialog = ({ + children, + ...rest +}: { children: React.ReactNode } & DialogProps) => { + const { open, onOpenChange } = useContext(RedelegateContext) + return ( + + {children} + + ) +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 8a5b051..75eb5d8 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -12,6 +12,9 @@ const DialogPortal = DialogPrimitive.Portal const DialogClose = DialogPrimitive.Close +export const closeStyle = + 'rounded-sm opacity-70 ring-offset-gray-30 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-neutral-100 data-[state=open]:text-neutral-500 dark:ring-offset-neutral-950 dark:focus:ring-neutral-300 dark:data-[state=open]:bg-neutral-800 dark:data-[state=open]:text-neutral-400' + const DialogOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -47,7 +50,7 @@ const DialogContent = React.forwardRef< )} {...props} > - + Close From 97402b608faf14939384d22f71445c7f8301674f Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 16 Dec 2024 23:32:47 -0300 Subject: [PATCH 08/44] join deposits <> node data --- src/app/(requires-wallet)/stake/page.tsx | 38 +------- src/components/delegate/redelegate-button.tsx | 2 +- src/components/stake/all-operators.tsx | 91 +++++++++++++++++++ src/components/stake/node-card.tsx | 11 ++- src/data/requests.ts | 1 - 5 files changed, 105 insertions(+), 38 deletions(-) create mode 100644 src/components/stake/all-operators.tsx diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index 33cfed5..4f48462 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -1,4 +1,4 @@ -import { NodeCard } from '@/components/stake/node-card' +import { AllOperators } from '@/components/stake/all-operators' import { TotalSupplyCard } from '@/components/stake/total-supply' import { YourAccountCard } from '@/components/stake/your-account' import { YourRewardsCard } from '@/components/stake/your-rewards' @@ -7,27 +7,8 @@ import { getStakeableNodes } from '@/data/requests' import { formatStackableNodeData } from '@/lib/hooks/use-node-data' import { cn } from '@/lib/utils' -const totalSupplyData = [ - { name: 'Staked', value: 4345345333, color: 'green' }, - { name: 'Unstaked', value: 1035345, color: 'gray' }, -] - -const rewardsClaimedData = [ - { name: 'Claimed', value: 1035345, color: 'hsl(var(--chart-3))' }, - { name: 'Unclaimed', value: 4345345333 - 1035345, color: 'hsl(var(--muted))' }, -] - -const colors = [ - '#1DDCF2', - '#AFDD79', - '#FED83D', - '#C740F2', - '#9558FA', - '#FEA56F', - '#FF60B2', - '#FEA56F', - '#DBDE54', -] +// keep in cache for 1 minute +export const revalidate = 60 const StakePage = async () => { // Get data from SSR @@ -50,18 +31,7 @@ const StakePage = async () => {
-
-

All Operators

-

- To distribute power on the network, please delegate to top performing operators. -

-
- {/* TODO: this page wont be live fetching node data - right? */} - {operators.map((operator) => ( - - ))} -
-
+ ) diff --git a/src/components/delegate/redelegate-button.tsx b/src/components/delegate/redelegate-button.tsx index b0203ea..44cf6ac 100644 --- a/src/components/delegate/redelegate-button.tsx +++ b/src/components/delegate/redelegate-button.tsx @@ -31,7 +31,7 @@ export const RedelegateButton = ({ }) onRedelegateFinish?.() } - }, [delegatedAddress, isTxConfirmed, toast]) + }, [delegatedAddress, isTxConfirmed, onRedelegateFinish, toast]) return ( + Connect Wallet + {isConnected ? ( + + ) : ( + Connect Wallet to Stake + )} ) diff --git a/src/components/stake/your-rewards.tsx b/src/components/stake/your-rewards.tsx index bc00495..4eef028 100644 --- a/src/components/stake/your-rewards.tsx +++ b/src/components/stake/your-rewards.tsx @@ -5,6 +5,7 @@ import { formatUnits } from 'viem' import { useAccount } from 'wagmi' import { Button } from '../ui/button' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' +import { ConnectWalletButton } from '../ui/connect-wallet-button' import { Skeleton } from '../ui/skeleton' export const YourRewardsCard = () => { @@ -18,45 +19,49 @@ export const YourRewardsCard = () => { claimReward, } = useClaim() return ( - + Your Rewards
- - {isConnected ? ( - isLoadingClaimableBalance ? ( - - ) : ( - formatUnits(claimableBalance ?? 0n, 18) - ) + {isConnected ? ( + isLoadingClaimableBalance ? ( + ) : ( - '-' - )} - + {formatUnits(claimableBalance ?? 0n, 18)} RVR + ) + ) : ( + - + )}
- + {isConnected ? ( + + ) : ( + + Connect Wallet to Claim Rewards + + )}
) diff --git a/src/components/ui/connect-wallet-button.tsx b/src/components/ui/connect-wallet-button.tsx new file mode 100644 index 0000000..7ac4d94 --- /dev/null +++ b/src/components/ui/connect-wallet-button.tsx @@ -0,0 +1,19 @@ +'use client' + +import { useAppKit } from '@reown/appkit/react' +import { Button } from '../ui/button' + +export const ConnectWalletButton = ({ + children, + className, +}: { + children: React.ReactNode + className?: string +}) => { + const { open } = useAppKit() + return ( + + ) +} diff --git a/src/components/wallet-connect.tsx b/src/components/wallet-connect.tsx deleted file mode 100644 index cdae4ed..0000000 --- a/src/components/wallet-connect.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' -import { projectId, wagmiConfig } from '@/lib/wagmi' -import { ReactNode, useState } from 'react' - -import { createWeb3Modal } from '@web3modal/wagmi/react' - -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' - -import { State, WagmiProvider } from 'wagmi' - -if (!projectId) throw new Error('Project ID is not defined') - -// Create modal -createWeb3Modal({ - wagmiConfig, - projectId, - enableAnalytics: true, // Optional - defaults to your Cloud configuration - enableOnramp: true, // Optional - false as default -}) - -const ONE_MINUTE = 1000 * 60 - -export function WalletConnectProvider({ - children, - initialState, -}: { - children: ReactNode - initialState?: State -}) { - const [queryClient] = useState( - () => new QueryClient({ defaultOptions: { queries: { staleTime: ONE_MINUTE } } }), - ) - - return ( - - {children} - - ) -} diff --git a/src/lib/context/wagmi-provider.tsx b/src/lib/context/wagmi-provider.tsx deleted file mode 100644 index 7f3614a..0000000 --- a/src/lib/context/wagmi-provider.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client' -import { projectId, wagmiConfig } from '@/lib/wagmi' -import { ReactNode } from 'react' - -import { createWeb3Modal } from '@web3modal/wagmi/react' - -import { State, WagmiProvider } from 'wagmi' - -if (!projectId) throw new Error('Project ID is not defined') - -// Create modal -createWeb3Modal({ - wagmiConfig, - projectId, - enableAnalytics: true, // Optional - defaults to your Cloud configuration - enableOnramp: true, // Optional - false as default -}) - -export function WalletConnectProvider({ - children, - initialState, -}: { - children: ReactNode - initialState?: State -}) { - return ( - - {children} - - ) -} diff --git a/src/lib/context/wallet-connect-provider.tsx b/src/lib/context/wallet-connect-provider.tsx new file mode 100644 index 0000000..9d3479f --- /dev/null +++ b/src/lib/context/wallet-connect-provider.tsx @@ -0,0 +1,45 @@ +'use client' +import { projectId, wagmiAdapter } from '@/lib/wagmi' +import { base, baseSepolia } from '@reown/appkit/networks' +import { createAppKit } from '@reown/appkit/react' +import { ReactNode } from 'react' + +import { State, WagmiProvider } from 'wagmi' + +if (!projectId) throw new Error('Project ID is not defined') + +const metadata = { + name: 'River', + description: 'River', + url: 'https://river.build', // origin must match your domain & subdomain + icons: ['https://www.river.build/favicon/dark/apple-icon.png'], +} + +createAppKit({ + adapters: [wagmiAdapter], + defaultNetwork: process.env.NODE_ENV === 'production' ? base : baseSepolia, + networks: process.env.NODE_ENV === 'production' ? [base] : [base, baseSepolia], + metadata: metadata, + projectId, + features: { + onramp: false, + socials: false, + email: false, + swaps: false, + analytics: true, + }, +}) + +export function WalletConnectProvider({ + children, + initialState, +}: { + children: ReactNode + initialState?: State +}) { + return ( + + {children} + + ) +} diff --git a/src/lib/wagmi.ts b/src/lib/wagmi.ts index 354d62e..53f3d87 100644 --- a/src/lib/wagmi.ts +++ b/src/lib/wagmi.ts @@ -1,28 +1,18 @@ -import { defaultWagmiConfig } from '@web3modal/wagmi/react/config' +import { WagmiAdapter } from '@reown/appkit-adapter-wagmi' +import { base, baseSepolia } from '@reown/appkit/networks' import { cookieStorage, createStorage } from 'wagmi' -import { base, baseSepolia, mainnet, sepolia } from 'wagmi/chains' - export const projectId = process.env.NEXT_PUBLIC_PROJECT_ID if (!projectId) { throw new Error('WalletConnect Project ID is not defined') } -const metadata = { - name: 'River Delegate', - description: 'Delegate your RVR tokens to a claimer', - url: 'https://river.build', // origin must match your domain & subdomain - icons: ['https://www.river.build/favicon/dark/apple-icon.png'], -} - -// Create wagmiConfig -export const wagmiConfig = defaultWagmiConfig({ - chains: [mainnet, base, sepolia, baseSepolia], +export const wagmiAdapter = new WagmiAdapter({ + networks: process.env.NODE_ENV === 'production' ? [base] : [base, baseSepolia], projectId, - metadata, ssr: true, - storage: createStorage({ - storage: cookieStorage, - }), + storage: createStorage({ + storage: cookieStorage, + }), }) From d97ce2ec1a8175dcd8ef55dd76ef3b576c2febb9 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 17 Dec 2024 15:45:32 -0300 Subject: [PATCH 12/44] get total staked & invalidate when increase --- src/components/stake/increase-stake.tsx | 10 +++++----- src/components/stake/total-supply.tsx | 14 +++++++++++--- src/components/stake/your-account.tsx | 19 +++++++++++++------ src/lib/hooks/use-increase-stake.ts | 24 ++++++++++++++++-------- 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx index eadfb8f..1f912cb 100644 --- a/src/components/stake/increase-stake.tsx +++ b/src/components/stake/increase-stake.tsx @@ -61,13 +61,13 @@ export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseSt }) const { - isStakingStateLoading, - stakingState, + isCurrentDepositLoading, + currentDeposit, increaseStake, isPending, isTxPending, isTxConfirmed, - } = useIncreaseStake() + } = useIncreaseStake(depositId) const isStaking = isPending || isTxPending useEffect(() => { @@ -93,11 +93,11 @@ export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseSt >
Currently Staked: - {isStakingStateLoading ? ( + {isCurrentDepositLoading ? ( ) : ( - {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + {formatUnits(currentDeposit?.amount ?? 0n, 18)} RVR )}
diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index ebe0626..51db99d 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,10 +1,12 @@ 'use client' -import { useAccount } from 'wagmi' +import { useStake } from '@/lib/hooks/use-stake' +import { formatUnits } from 'viem' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' +import { Skeleton } from '../ui/skeleton' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' export const TotalSupplyCard = () => { - const { isConnected } = useAccount() + const { isStakingStateLoading, stakingState } = useStake() return ( @@ -16,7 +18,13 @@ export const TotalSupplyCard = () => { {/* TODO: Add chart */}
Staked
-
4,345,345,333 (mock data) RVR
+
+ {isStakingStateLoading ? ( + + ) : ( + {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + )} +
diff --git a/src/components/stake/your-account.tsx b/src/components/stake/your-account.tsx index 00abcf0..a0257a3 100644 --- a/src/components/stake/your-account.tsx +++ b/src/components/stake/your-account.tsx @@ -1,7 +1,9 @@ 'use client' -import { useReadRiverTokenBalanceOf } from '@/contracts' -import { useStake } from '@/lib/hooks/use-stake' +import { + useReadRewardsDistributionStakedByDepositor, + useReadRiverTokenBalanceOf, +} from '@/contracts' import { useEffect, useRef } from 'react' import { formatUnits } from 'viem' import { useAccount } from 'wagmi' @@ -16,14 +18,19 @@ export const YourAccountCard = () => { args: [address!], query: { enabled: isConnected && !!address }, }) - const { stakingState, isStakingStateLoading } = useStake() + + const { data: stakedByUser, isLoading: isStakedByUserLoading } = + useReadRewardsDistributionStakedByDepositor({ + args: [address!], + query: { enabled: isConnected && !!address }, + }) + const allOperatorsListRef = useRef(null) useEffect(() => { // not getting the from the parent with useRef // because we dont want the parent to be a client component allOperatorsListRef.current = document.getElementById('all-operators') - console.log(allOperatorsListRef.current) }, []) return ( @@ -47,10 +54,10 @@ export const YourAccountCard = () => {
Staked {isConnected ? ( - isStakingStateLoading ? ( + isStakedByUserLoading ? ( ) : ( - {formatUnits(stakingState?.totalStaked ?? 0n, 18)} + {formatUnits(stakedByUser ?? 0n, 18)} RVR ) ) : ( - diff --git a/src/lib/hooks/use-increase-stake.ts b/src/lib/hooks/use-increase-stake.ts index 46a1757..cc00810 100644 --- a/src/lib/hooks/use-increase-stake.ts +++ b/src/lib/hooks/use-increase-stake.ts @@ -1,5 +1,6 @@ 'use client' import { + useReadRewardsDistributionDepositById, useReadRewardsDistributionStakingState, useWriteRewardsDistributionIncreaseStake, } from '@/contracts' @@ -7,7 +8,7 @@ import { useQueryClient } from '@tanstack/react-query' import { useEffect } from 'react' import { useAccount, useWaitForTransactionReceipt } from 'wagmi' -export const useIncreaseStake = () => { +export const useIncreaseStake = (depositId: bigint) => { const { address } = useAccount() const qc = useQueryClient() @@ -21,10 +22,16 @@ export const useIncreaseStake = () => { }) const { - queryKey: stakingStateQueryKey, - data: stakingState, - isLoading: isStakingStateLoading, - } = useReadRewardsDistributionStakingState({ + queryKey: currentDepositQueryKey, + data: currentDeposit, + isLoading: isCurrentDepositLoading, + } = useReadRewardsDistributionDepositById({ + args: [depositId], + query: { + enabled: !!address, + }, + }) + const { queryKey: stakingStateQueryKey } = useReadRewardsDistributionStakingState({ query: { enabled: !!address, }, @@ -32,16 +39,17 @@ export const useIncreaseStake = () => { useEffect(() => { if (isTxConfirmed) { + qc.invalidateQueries({ queryKey: [currentDepositQueryKey] }) qc.invalidateQueries({ queryKey: [stakingStateQueryKey] }) } - }, [isTxConfirmed, qc, stakingStateQueryKey]) + }, [isTxConfirmed, qc, currentDepositQueryKey, stakingStateQueryKey]) return { increaseStake, isPending, isTxPending, isTxConfirmed, - stakingState, - isStakingStateLoading, + currentDeposit, + isCurrentDepositLoading, } } From f771470b0d18612e4f05a8e23a295a2deaf46a97 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 17 Dec 2024 16:18:29 -0300 Subject: [PATCH 13/44] polishes --- src/components/stake/all-operators.tsx | 13 ++++++++----- src/components/stake/node-card.tsx | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/components/stake/all-operators.tsx b/src/components/stake/all-operators.tsx index 76e3e74..f9ca3fb 100644 --- a/src/components/stake/all-operators.tsx +++ b/src/components/stake/all-operators.tsx @@ -7,16 +7,19 @@ import { } from '@/contracts' import type { StackableNodeData } from '@/lib/hooks/use-node-data' import { useAccount, useReadContracts } from 'wagmi' +import { Typography } from '../ui/typography' import { NodeCard } from './node-card' export const AllOperators = ({ operators }: { operators: StackableNodeData[] }) => { const { data: operatorsWithDeposits } = useStackableNodeData(operators) return ( -
-

All Operators

-

- To distribute power on the network, please delegate to top performing operators. -

+
+
+

All Operators

+ + To distribute power on the network, please delegate to top performing operators. + +
{/* TODO: this page wont be live fetching node data - right? */} {operatorsWithDeposits.map((operator) => ( diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx index a11b3ab..9339e02 100644 --- a/src/components/stake/node-card.tsx +++ b/src/components/stake/node-card.tsx @@ -51,7 +51,7 @@ export function NodeCard({ > {/* Header */}
-
+
{name} @@ -71,7 +71,7 @@ export function NodeCard({ // From 3dc79f077525d756e698ac50ab3dc6809df832fa Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 17 Dec 2024 16:22:04 -0300 Subject: [PATCH 14/44] fix build (??) --- src/components/ui/3d-card.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/ui/3d-card.tsx b/src/components/ui/3d-card.tsx index 984323d..dbd68da 100644 --- a/src/components/ui/3d-card.tsx +++ b/src/components/ui/3d-card.tsx @@ -104,7 +104,7 @@ export const CardBody = ({ return (
*]:[transform-style:preserve-3d]', + 'h-96 w-96 [transform-style:preserve-3d] [&>*]:[transform-style:preserve-3d]', className, )} > @@ -151,11 +151,14 @@ export const CardItem = ({ ref.current.style.transform = `translateX(0px) translateY(0px) translateZ(0px) rotateX(0deg) rotateY(0deg) rotateZ(0deg)` } } - - return ( - - {children} - + return React.createElement( + Tag, + { + ref, + className: cn('w-fit transition duration-200 ease-linear', className), + ...rest, + }, + children, ) } From 443f720ce00fe5bec83adaf406c3a7e5c59e6fc9 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 17 Dec 2024 21:04:47 -0300 Subject: [PATCH 15/44] estimated apr --- src/app/(requires-wallet)/stake/page.tsx | 17 +++++-- src/components/stake/node-card.tsx | 6 +-- src/components/stake/total-supply.tsx | 23 +++++---- src/data/requests.ts | 60 ++++++++++++++++-------- src/lib/hooks/use-stake.ts | 6 +-- src/lib/utils/formatPrecisionNumber.ts | 4 ++ 6 files changed, 76 insertions(+), 40 deletions(-) create mode 100644 src/lib/utils/formatPrecisionNumber.ts diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index 4f48462..bf8c6cc 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -6,15 +6,26 @@ import { SwitchToBase } from '@/components/switch-to-base' import { getStakeableNodes } from '@/data/requests' import { formatStackableNodeData } from '@/lib/hooks/use-node-data' import { cn } from '@/lib/utils' +import { wagmiAdapter } from '@/lib/wagmi' +import { headers } from 'next/headers' +import { baseSepolia } from 'viem/chains' +import { cookieToInitialState } from 'wagmi' // keep in cache for 1 minute export const revalidate = 60 +const getSsrChainId = () => { + return cookieToInitialState(wagmiAdapter.wagmiConfig, headers().get('cookie'))?.chainId +} + const StakePage = async () => { // Get data from SSR // live data probably doesnt make sense here. - const initialData = await getStakeableNodes().catch(() => undefined) - const operators = formatStackableNodeData(initialData) + const chainId = getSsrChainId() + const initialData = await getStakeableNodes(chainId === baseSepolia.id ? 'gamma' : 'omega').catch( + () => undefined, + ) + const operators = formatStackableNodeData(initialData?.nodes) return (
{
- +
diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx index 9339e02..441b926 100644 --- a/src/components/stake/node-card.tsx +++ b/src/components/stake/node-card.tsx @@ -3,6 +3,7 @@ import { Button } from '@/components/ui/button' import type { StackableNodeData } from '@/lib/hooks/use-node-data' import { cn, formatUptime } from '@/lib/utils' +import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' import { MoreVertical } from 'lucide-react' import { useMemo } from 'react' import { Dialog, DialogTrigger } from '../ui/dialog' @@ -33,7 +34,6 @@ export function NodeCard({ onSelect, ringColor, }: NodeCardProps) { - const estimatedApr = 10 // TODO: const withdrawalTime = '10 days' // TODO: const amountStaked = false // TODO: const name = new URL(node.data.record.url).hostname @@ -69,13 +69,13 @@ export function NodeCard({ } /> - + // - {estimatedApr}% + {formatPrecisionNumber(node.data.estimatedApr, 2)}% // // //

APR may vary and depends on delegation amount or total period reward.

diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index 51db99d..b9a980b 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,11 +1,16 @@ 'use client' import { useStake } from '@/lib/hooks/use-stake' +import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' import { formatUnits } from 'viem' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { Skeleton } from '../ui/skeleton' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' -export const TotalSupplyCard = () => { +export const TotalSupplyCard = ({ + networkEstimatedApy, +}: { + networkEstimatedApy: number | undefined +}) => { const { isStakingStateLoading, stakingState } = useStake() return ( @@ -28,18 +33,16 @@ export const TotalSupplyCard = () => {
-
- {/* TODO: Add chart */} -
-
Rewards Claimed
-
1,035,345 RVR (mock data)
-
-
-
-
4.3% (mock data)
+
+ {!networkEstimatedApy ? ( + + ) : ( + {formatPrecisionNumber(networkEstimatedApy, 2)}% + )} +
Estimated APR*
diff --git a/src/data/requests.ts b/src/data/requests.ts index c0a488a..5b609c3 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -1,6 +1,11 @@ -import { nodeOperatorAbi, nodeOperatorAddress } from '@/contracts' +import { + nodeOperatorAbi, + nodeOperatorAddress, + rewardsDistributionAbi, + rewardsDistributionAddress, +} from '@/contracts' import { createPublicClient, formatUnits, http, isAddress, type Address } from 'viem' -import { base } from 'viem/chains' +import { base, baseSepolia } from 'viem/chains' import { z } from 'zod' // TODO: [HNT-6333] The main node should be decided by making a read call from the RiverRegistry in RiverChain @@ -131,16 +136,35 @@ export const nodeStatusSchema = z.object({ elapsed: z.string(), }) -export type StackableNode = Awaited>[number] +export type StackableNode = Awaited>['nodes'][number] -// wip 🏗️ -export const getStakeableNodes = async () => { - // todo: change depending on chain +const estimatedApyOfNetwork = (rewardRate: bigint, totalStaked: bigint) => { + const rewardRatePerToken = Number(formatUnits(rewardRate, 18)) + const staked = Number(formatUnits(totalStaked, 18)) + const apy = (rewardRatePerToken / staked) * 24 * 365 * 100 + return apy +} + +const operatorApr = (commissionRate: bigint, networkApr: number) => { + const commInBps = Number(formatUnits(commissionRate, 3)) + const apr = networkApr * (1 - commInBps / 10000) + return apr +} + +export const getStakeableNodes = async (env: 'omega' | 'gamma') => { + const chain = env === 'omega' ? base : baseSepolia + const chainId = chain.id const client = createPublicClient({ - chain: base, + chain, transport: http(), }) - const nodeData = await getNodeData() + const stakingState = await client.readContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress[chainId], + functionName: 'stakingState', + }) + const networkApy = estimatedApyOfNetwork(stakingState.rewardRate, stakingState.totalStaked) + const nodeData = await getNodeData() // TODO: getNodeData isnt getting from the correct chain if we're on gamma const operators = nodeData.nodes.map((node) => node.record.operator) // get all operators const uniqueOperators = Array.from(new Set(operators)) // Get unique operators @@ -150,7 +174,7 @@ export const getStakeableNodes = async () => { uniqueOperators.map((operator) => client.readContract({ abi: nodeOperatorAbi, - address: nodeOperatorAddress[base.id], + address: nodeOperatorAddress[chainId], functionName: 'getCommissionRate', args: [operator], }), @@ -166,15 +190,13 @@ export const getStakeableNodes = async () => { {}, ) - // calculate APR for each operator - const calculateApr = (comissionRate: bigint) => { - return Number(comissionRate) / 10000 // todo: calculate APR + return { + nodes: nodeData.nodes.map((node) => { + const commissionRate = operatorCommissionMap[node.record.operator] + const estimatedApr = operatorApr(commissionRate, networkApy) + console.log('comission', commissionRate) + return { ...node, estimatedApr, commissionRate: formatUnits(commissionRate, 3) } + }), + networkEstimatedApy: networkApy, } - // sort by APR - - return nodeData.nodes.map((node) => { - const commissionRate = operatorCommissionMap[node.record.operator] - const estimatedApr = calculateApr(commissionRate) - return { ...node, commissionRatePercentage: formatUnits(commissionRate, 3), estimatedApr } - }) } diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts index 907223d..8449ab2 100644 --- a/src/lib/hooks/use-stake.ts +++ b/src/lib/hooks/use-stake.ts @@ -20,11 +20,7 @@ export const useStake = () => { queryKey: stakingStateQueryKey, data: stakingState, isLoading: isStakingStateLoading, - } = useReadRewardsDistributionStakingState({ - query: { - enabled: !!address, - }, - }) + } = useReadRewardsDistributionStakingState() useEffect(() => { if (isTxConfirmed) { diff --git a/src/lib/utils/formatPrecisionNumber.ts b/src/lib/utils/formatPrecisionNumber.ts new file mode 100644 index 0000000..417f767 --- /dev/null +++ b/src/lib/utils/formatPrecisionNumber.ts @@ -0,0 +1,4 @@ +export const formatPrecisionNumber = (value: number, decimals: number) => { + const formatted = value.toPrecision(decimals + 1) + return formatted.replace(/\e[+-]?\d+/, '') +} From f3520bec8c33c7a455a2da7107ed674fa077a95c Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 00:20:03 -0300 Subject: [PATCH 16/44] update lucide react --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e684c1c..771c2f9 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "graphql": "^16.8.1", "graphql-request": "^6.1.0", "js-confetti": "^0.12.0", - "lucide-react": "^0.236.0", + "lucide-react": "^0.352.0", "mini-svg-data-uri": "^1.4.4", "mixpanel-browser": "^2.45.0", "next": "^14.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34499d9..cd84bac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,8 +129,8 @@ importers: specifier: ^0.12.0 version: 0.12.0 lucide-react: - specifier: ^0.236.0 - version: 0.236.0(react@18.3.1) + specifier: ^0.352.0 + version: 0.352.0(react@18.3.1) mini-svg-data-uri: specifier: ^1.4.4 version: 1.4.4 @@ -6779,8 +6779,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-react@0.236.0: - resolution: {integrity: sha512-himeKF7nVgOQ1BNcyBgk41E4/rcbmI6Zw8Q4o57nlynsFvIBA/DMacFpzKYdcyBReUj8jf08xTnCGyn/niLvwQ==} + lucide-react@0.352.0: + resolution: {integrity: sha512-GKzcxx6H6PT9onMPN9zxyD4KNqgHDoVaY+ad14vhTzBdXFm3FQZhH5XeP8sHJRhLk9imHHta/8DZe55kd/KerQ==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 @@ -18543,7 +18543,7 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@0.236.0(react@18.3.1): + lucide-react@0.352.0(react@18.3.1): dependencies: react: 18.3.1 From 50e9e7fcacca9a92e49a838f14e7e6a15eda4622 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 00:56:28 -0300 Subject: [PATCH 17/44] withdraw timer + dropdown menu to redelegate/withdraw + tooltip --- src/components/stake/initiate-withdraw.tsx | 2 +- src/components/stake/node-card.tsx | 134 +++++++++++++++------ src/components/stake/redelegate.tsx | 23 +++- src/components/stake/stake-to-operator.tsx | 2 +- src/components/stake/total-supply.tsx | 7 +- src/components/stake/withdraw.tsx | 4 +- src/components/ui/dialog.tsx | 10 +- src/components/ui/dropdown-menu.tsx | 22 ++-- src/data/requests.ts | 1 - src/lib/hooks/use-withdraw-timer.ts | 36 ++++++ src/lib/hooks/use-withdraw.ts | 53 ++++++-- 11 files changed, 226 insertions(+), 68 deletions(-) create mode 100644 src/lib/hooks/use-withdraw-timer.ts diff --git a/src/components/stake/initiate-withdraw.tsx b/src/components/stake/initiate-withdraw.tsx index deaa8da..b3168ae 100644 --- a/src/components/stake/initiate-withdraw.tsx +++ b/src/components/stake/initiate-withdraw.tsx @@ -65,7 +65,7 @@ export const InitiateWithdrawDialogContent = ({ ...rest }: InitiateWithdrawFormProps & DialogContentProps) => { return ( - + Initiate Withdraw diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx index 441b926..eb02f6d 100644 --- a/src/components/stake/node-card.tsx +++ b/src/components/stake/node-card.tsx @@ -2,13 +2,23 @@ import { Button } from '@/components/ui/button' import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { useWithdraw } from '@/lib/hooks/use-withdraw' +import { useWithdrawTimer } from '@/lib/hooks/use-withdraw-timer' import { cn, formatUptime } from '@/lib/utils' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' -import { MoreVertical } from 'lucide-react' -import { useMemo } from 'react' +import { ArrowRightLeftIcon, EllipsisVertical, LogOutIcon } from 'lucide-react' +import { useMemo, useState } from 'react' import { Dialog, DialogTrigger } from '../ui/dialog' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '../ui/dropdown-menu' +import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' import { Typography } from '../ui/typography' import type { StackableNodeDataWithDeposits } from './all-operators' +import { IncreaseStakeDialogContent } from './increase-stake' import { RedelegateDialog, RedelegateDialogContent, RedelegateProvider } from './redelegate' import { StakeDialogContent } from './stake-to-operator' import { WithdrawDialogContent } from './withdraw' @@ -16,7 +26,6 @@ import { WithdrawDialogContent } from './withdraw' export interface NodeCardProps { node: StackableNodeDataWithDeposits allNodes?: StackableNodeData[] - onMenuClick?: () => void className?: string showButton?: boolean onSelect?: () => void @@ -27,22 +36,28 @@ type Status = 'stakeable' | 'staked' | 'locked' | 'can-withdraw' export function NodeCard({ node, - onMenuClick, className, showButton, allNodes, onSelect, ringColor, }: NodeCardProps) { - const withdrawalTime = '10 days' // TODO: - const amountStaked = false // TODO: const name = new URL(node.data.record.url).hostname + const { lockCooldown } = useWithdraw(node.deposits?.depositId) + const withdrawTimer = useWithdrawTimer(lockCooldown) + + const [openRedelegate, setOpenRedelegate] = useState(false) + const [openWithdraw, setOpenWithdraw] = useState(false) + const status = useMemo(() => { if (!node.deposits) return 'stakeable' - if (node.deposits.pendingWithdrawal > 0n) return 'can-withdraw' // TODO: can withdraw status - // TODO: locked status + if (node.deposits.pendingWithdrawal > 0n) { + // If there's a pending withdrawal, check if we have a timer + return withdrawTimer ? 'locked' : 'can-withdraw' + } if (node.deposits.amount > 0n) return 'staked' - }, [node.deposits]) as Status + return 'stakeable' + }, [node.deposits, withdrawTimer]) satisfies Status return (
- // - {formatPrecisionNumber(node.data.estimatedApr, 2)}% - // - // - //

APR may vary and depends on delegation amount or total period reward.

- //
- // + + + {formatPrecisionNumber(node.data.estimatedApr, 2)}% + + + APR may vary and depends on delegation amount or total period reward. + + } /> - {amountStaked && {amountStaked} RVR} />} + {/* TODO: unsure if we need to format this to 18 decimals - test later */} + {node.deposits?.amount && ( + {node.deposits.amount} RVR} /> + )}
{/* Bottom Row */} @@ -95,7 +113,7 @@ export function NodeCard({
)} {showButton ? ( -
+
{status === 'stakeable' && ( @@ -104,36 +122,76 @@ export function NodeCard({ )} - {status === 'staked' && ( - - + {status === 'staked' && node.deposits?.depositId && ( + <> + - + - - - + +
+ + + + + + setOpenRedelegate(true)} + asChild + > +
+ + Redelegate +
+
+ setOpenWithdraw(true)} asChild> +
+ + Withdraw +
+
+
+
+ )} - {status === 'locked' && } - {status === 'can-withdraw' && ( + {status === 'locked' && ( + + )} + {status === 'can-withdraw' && node.deposits?.depositId && ( - + )} - {onMenuClick && ( - - )} ) : null} + + + + + + + + + + ) } diff --git a/src/components/stake/redelegate.tsx b/src/components/stake/redelegate.tsx index 03bd792..d1cb9e7 100644 --- a/src/components/stake/redelegate.tsx +++ b/src/components/stake/redelegate.tsx @@ -33,7 +33,7 @@ export const RedelegateDialogContent = ({ // TODO: animate height x.x return ( - + {showOperatorSelect && ( @@ -69,7 +69,7 @@ export const WithdrawDialogContent = ({ ...rest }: WithdrawFormProps & DialogContentProps) => { return ( - + Withdraw diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 75eb5d8..29ebdd0 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -32,11 +32,17 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName const DialogContent = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( + React.ComponentPropsWithoutRef & { disableInteractOutside?: boolean } +>(({ className, children, disableInteractOutside, ...props }, ref) => ( { + if (disableInteractOutside) { + e.preventDefault() + e.stopPropagation() + } + }} ref={ref} className={cn( 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]', diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx index b6cd0e9..26b5224 100644 --- a/src/components/ui/dropdown-menu.tsx +++ b/src/components/ui/dropdown-menu.tsx @@ -1,3 +1,5 @@ +'use client' + import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' import { Check, ChevronRight, Circle } from 'lucide-react' import * as React from 'react' @@ -25,14 +27,14 @@ const DropdownMenuSubTrigger = React.forwardRef< {children} - + )) DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName @@ -44,7 +46,7 @@ const DropdownMenuSubContent = React.forwardRef< svg]:size-4 [&>svg]:shrink-0', inset && 'pl-8', className, )} @@ -95,7 +101,7 @@ const DropdownMenuCheckboxItem = React.forwardRef< (({ className, ...props }, ref) => ( )) diff --git a/src/data/requests.ts b/src/data/requests.ts index 5b609c3..a72bddc 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -194,7 +194,6 @@ export const getStakeableNodes = async (env: 'omega' | 'gamma') => { nodes: nodeData.nodes.map((node) => { const commissionRate = operatorCommissionMap[node.record.operator] const estimatedApr = operatorApr(commissionRate, networkApy) - console.log('comission', commissionRate) return { ...node, estimatedApr, commissionRate: formatUnits(commissionRate, 3) } }), networkEstimatedApy: networkApy, diff --git a/src/lib/hooks/use-withdraw-timer.ts b/src/lib/hooks/use-withdraw-timer.ts new file mode 100644 index 0000000..7a50b88 --- /dev/null +++ b/src/lib/hooks/use-withdraw-timer.ts @@ -0,0 +1,36 @@ +'use client' +import { useEffect, useState } from 'react' + +export const useWithdrawTimer = (unlockTimestamp: bigint | undefined) => { + const [timeRemaining, setTimeRemaining] = useState(null) + + useEffect(() => { + if (!unlockTimestamp) return + + const updateTimer = () => { + const now = new Date() + const unlockTime = new Date(Number(unlockTimestamp)) + const remaining = unlockTime.getTime() - now.getTime() + + if (remaining <= 0) { + setTimeRemaining(null) + return + } + + const days = Math.floor(remaining / (1000 * 60 * 60 * 24)) + const hours = Math.floor((remaining % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)) + + setTimeRemaining( + days > 0 ? `${days}d ${hours}h` : hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`, + ) + } + + updateTimer() + const interval = setInterval(updateTimer, 60000) // Update every minute + + return () => clearInterval(interval) + }, [unlockTimestamp]) + + return timeRemaining +} diff --git a/src/lib/hooks/use-withdraw.ts b/src/lib/hooks/use-withdraw.ts index f0be44f..14be716 100644 --- a/src/lib/hooks/use-withdraw.ts +++ b/src/lib/hooks/use-withdraw.ts @@ -1,15 +1,52 @@ 'use client' -import { useWriteRewardsDistributionWithdraw } from '@/contracts' -import { useWaitForTransactionReceipt } from 'wagmi' +import { + useReadRewardsDistributionDepositById, + useReadRiverTokenLockCooldown, + useWriteRewardsDistributionWithdraw, +} from '@/contracts' +import { useQueryClient } from '@tanstack/react-query' +import { useCallback, useEffect } from 'react' +import { useAccount, useWaitForTransactionReceipt } from 'wagmi' -export const useWithdraw = (depositId: bigint) => { - const { writeContract: withdraw, data: hash, isPending } = useWriteRewardsDistributionWithdraw() +export const useWithdraw = (depositId: bigint | undefined) => { + const { address } = useAccount() + const qc = useQueryClient() + const { data: lockCooldown, isLoading: isLockCooldownLoading } = useReadRiverTokenLockCooldown({ + args: [address!], + query: { + enabled: !!address, + }, + }) + + const { writeContract, data: hash, isPending } = useWriteRewardsDistributionWithdraw() const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ hash: hash, }) - // TODO: add query to get the amount of tokens to withdraw using the depositId - const amountToWithdraw = 42069n - const isAmountToWithdrawLoading = false + + const { + data: deposit, + isLoading: isAmountToWithdrawLoading, + queryKey: depositQueryKey, + } = useReadRewardsDistributionDepositById({ + args: [depositId!], + query: { + enabled: !!depositId, + }, + }) + const amountToWithdraw = deposit?.amount + + const withdraw = useCallback(() => { + if (!address) return + writeContract({ + args: [depositId!], + }) + }, [address, depositId, writeContract]) + + useEffect(() => { + if (isTxConfirmed) { + qc.invalidateQueries({ queryKey: depositQueryKey }) + } + }, [isTxConfirmed]) return { withdraw, @@ -18,5 +55,7 @@ export const useWithdraw = (depositId: bigint) => { isTxConfirmed, amountToWithdraw, isAmountToWithdrawLoading, + lockCooldown, + isLockCooldownLoading, } } From f46181eed1daf1261727a09b01cee1f2a9d5598d Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 21:40:28 -0300 Subject: [PATCH 18/44] HNT-6333 - get nodes from river registry --- src/app/status/page.tsx | 2 +- src/contracts.ts | 4062 +++++++++++++++++++++++++++------------ src/data/requests.ts | 60 +- src/lib/riverChain.ts | 32 + wagmi.config.ts | 1425 ++++++++++++++ 5 files changed, 4355 insertions(+), 1226 deletions(-) create mode 100644 src/lib/riverChain.ts diff --git a/src/app/status/page.tsx b/src/app/status/page.tsx index b435652..989883a 100644 --- a/src/app/status/page.tsx +++ b/src/app/status/page.tsx @@ -19,7 +19,7 @@ const NodeAnimation = loadDynamic( ) const StatusPage = async () => { - const initialData = await getNodeData().catch(() => undefined) + const initialData = await getNodeData('omega').catch(() => undefined) return (
diff --git a/src/contracts.ts b/src/contracts.ts index 3b1685e..23b1c19 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -1229,222 +1229,628 @@ export const rewardsDistributionConfig = { } as const ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// RiverToken +// RiverRegistry ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) - */ -export const riverTokenAbi = [ + +*/ +export const riverRegistryAbi = [ { type: 'constructor', inputs: [ - { name: '_bridge', internalType: 'address', type: 'address' }, - { name: '_remoteToken', internalType: 'address', type: 'address' }, + { + name: 'approvedOperators', + internalType: 'address[]', + type: 'address[]', + }, ], stateMutability: 'nonpayable', }, - { type: 'error', inputs: [], name: 'CheckpointUnorderedInsertion' }, - { type: 'error', inputs: [], name: 'ECDSAInvalidSignature' }, - { - type: 'error', - inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], - name: 'ECDSAInvalidSignatureLength', - }, - { - type: 'error', - inputs: [{ name: 's', internalType: 'bytes32', type: 'bytes32' }], - name: 'ECDSAInvalidSignatureS', - }, { - type: 'error', + type: 'function', inputs: [ - { name: 'increasedSupply', internalType: 'uint256', type: 'uint256' }, - { name: 'cap', internalType: 'uint256', type: 'uint256' }, + { + name: 'initialOperators', + internalType: 'address[]', + type: 'address[]', + }, ], - name: 'ERC20ExceededSafeSupply', + name: '__OperatorRegistry_init', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'spender', internalType: 'address', type: 'address' }, - { name: 'allowance', internalType: 'uint256', type: 'uint256' }, - { name: 'needed', internalType: 'uint256', type: 'uint256' }, + { name: 'configManagers', internalType: 'address[]', type: 'address[]' }, ], - name: 'ERC20InsufficientAllowance', + name: '__RiverConfig_init', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'sender', internalType: 'address', type: 'address' }, - { name: 'balance', internalType: 'uint256', type: 'uint256' }, - { name: 'needed', internalType: 'uint256', type: 'uint256' }, + { name: 'streamId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + { + name: 'genesisMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { name: 'genesisMiniblock', internalType: 'bytes', type: 'bytes' }, ], - name: 'ERC20InsufficientBalance', - }, - { - type: 'error', - inputs: [{ name: 'approver', internalType: 'address', type: 'address' }], - name: 'ERC20InvalidApprover', - }, - { - type: 'error', - inputs: [{ name: 'receiver', internalType: 'address', type: 'address' }], - name: 'ERC20InvalidReceiver', + name: 'allocateStream', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], - name: 'ERC20InvalidSender', + type: 'function', + inputs: [{ name: 'manager', internalType: 'address', type: 'address' }], + name: 'approveConfigurationManager', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [{ name: 'spender', internalType: 'address', type: 'address' }], - name: 'ERC20InvalidSpender', + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'approveOperator', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [{ name: 'deadline', internalType: 'uint256', type: 'uint256' }], - name: 'ERC2612ExpiredSignature', + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'configurationExists', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'signer', internalType: 'address', type: 'address' }, - { name: 'owner', internalType: 'address', type: 'address' }, - ], - name: 'ERC2612InvalidSigner', + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'deleteConfiguration', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, - { name: 'clock', internalType: 'uint48', type: 'uint48' }, + { name: 'key', internalType: 'bytes32', type: 'bytes32' }, + { name: 'blockNumber', internalType: 'uint64', type: 'uint64' }, ], - name: 'ERC5805FutureLookup', + name: 'deleteConfigurationOnBlock', + outputs: [], + stateMutability: 'nonpayable', }, - { type: 'error', inputs: [], name: 'ERC6372InconsistentClock' }, - { type: 'error', inputs: [], name: 'Initializable_InInitializingState' }, - { type: 'error', inputs: [], name: 'Initializable_NotInInitializingState' }, - { type: 'error', inputs: [], name: 'Introspection_AlreadySupported' }, - { type: 'error', inputs: [], name: 'Introspection_NotSupported' }, { - type: 'error', - inputs: [ - { name: 'account', internalType: 'address', type: 'address' }, - { name: 'currentNonce', internalType: 'uint256', type: 'uint256' }, + type: 'function', + inputs: [], + name: 'getAllConfiguration', + outputs: [ + { + name: '', + internalType: 'struct Setting[]', + type: 'tuple[]', + components: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32' }, + { name: 'blockNumber', internalType: 'uint64', type: 'uint64' }, + { name: 'value', internalType: 'bytes', type: 'bytes' }, + ], + }, ], - name: 'InvalidAccountNonce', - }, - { type: 'error', inputs: [], name: 'InvalidShortString' }, - { type: 'error', inputs: [], name: 'LockNotAuthorized' }, - { - type: 'error', - inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], - name: 'OwnableInvalidOwner', + stateMutability: 'view', }, { - type: 'error', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'OwnableUnauthorizedAccount', + type: 'function', + inputs: [], + name: 'getAllNodeAddresses', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', }, - { type: 'error', inputs: [], name: 'River__DelegateeSameAsCurrent' }, - { type: 'error', inputs: [], name: 'River__TransferLockEnabled' }, { - type: 'error', - inputs: [ - { name: 'bits', internalType: 'uint8', type: 'uint8' }, - { name: 'value', internalType: 'uint256', type: 'uint256' }, + type: 'function', + inputs: [], + name: 'getAllNodes', + outputs: [ + { + name: '', + internalType: 'struct Node[]', + type: 'tuple[]', + components: [ + { name: 'status', internalType: 'enum NodeStatus', type: 'uint8' }, + { name: 'url', internalType: 'string', type: 'string' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + }, ], - name: 'SafeCastOverflowedUintDowncast', + stateMutability: 'view', }, { - type: 'error', - inputs: [{ name: 'str', internalType: 'string', type: 'string' }], - name: 'StringTooLong', + type: 'function', + inputs: [], + name: 'getAllOperators', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [{ name: 'expiry', internalType: 'uint256', type: 'uint256' }], - name: 'VotesExpiredSignature', + type: 'function', + inputs: [], + name: 'getAllStreamIds', + outputs: [{ name: '', internalType: 'bytes32[]', type: 'bytes32[]' }], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, - inputs: [ + type: 'function', + inputs: [], + name: 'getAllStreams', + outputs: [ { - name: 'owner', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct StreamWithId[]', + type: 'tuple[]', + components: [ + { name: 'id', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'stream', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'key', internalType: 'bytes32', type: 'bytes32' }], + name: 'getConfiguration', + outputs: [ { - name: 'spender', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct Setting[]', + type: 'tuple[]', + components: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32' }, + { name: 'blockNumber', internalType: 'uint64', type: 'uint64' }, + { name: 'value', internalType: 'bytes', type: 'bytes' }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'getNode', + outputs: [ { - name: 'value', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: '', + internalType: 'struct Node', + type: 'tuple', + components: [ + { name: 'status', internalType: 'enum NodeStatus', type: 'uint8' }, + { name: 'url', internalType: 'string', type: 'string' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], }, ], - name: 'Approval', + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [], + name: 'getNodeCount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ + { name: 'start', internalType: 'uint256', type: 'uint256' }, + { name: 'stop', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPaginatedStreams', + outputs: [ { - name: 'delegator', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct StreamWithId[]', + type: 'tuple[]', + components: [ + { name: 'id', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'stream', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + ], }, + { name: '', internalType: 'bool', type: 'bool' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'streamId', internalType: 'bytes32', type: 'bytes32' }], + name: 'getStream', + outputs: [ { - name: 'fromDelegate', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { name: 'lastMiniblockNum', internalType: 'uint64', type: 'uint64' }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'i', internalType: 'uint256', type: 'uint256' }], + name: 'getStreamByIndex', + outputs: [ { - name: 'toDelegate', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct StreamWithId', + type: 'tuple', + components: [ + { name: 'id', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'stream', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + ], }, ], - name: 'DelegateChanged', + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [], + name: 'getStreamCount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'getStreamCountOnNode', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'streamId', internalType: 'bytes32', type: 'bytes32' }], + name: 'getStreamWithGenesis', + outputs: [ + { + name: '', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { name: 'lastMiniblockNum', internalType: 'uint64', type: 'uint64' }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + { name: '', internalType: 'bytes32', type: 'bytes32' }, + { name: '', internalType: 'bytes', type: 'bytes' }, + ], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ + { name: 'streamIds', internalType: 'bytes32[]', type: 'bytes32[]' }, + ], + name: 'getStreams', + outputs: [ + { name: 'foundCount', internalType: 'uint256', type: 'uint256' }, { - name: 'delegate', + name: '', + internalType: 'struct StreamWithId[]', + type: 'tuple[]', + components: [ + { name: 'id', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'stream', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'getStreamsOnNode', + outputs: [ + { + name: '', + internalType: 'struct StreamWithId[]', + type: 'tuple[]', + components: [ + { name: 'id', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'stream', + internalType: 'struct Stream', + type: 'tuple', + components: [ + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + }, + { name: 'reserved0', internalType: 'uint64', type: 'uint64' }, + { name: 'flags', internalType: 'uint64', type: 'uint64' }, + { name: 'nodes', internalType: 'address[]', type: 'address[]' }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'manager', internalType: 'address', type: 'address' }], + name: 'isConfigurationManager', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'isOperator', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'streamId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + ], + name: 'placeStreamOnNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'url', internalType: 'string', type: 'string' }, + { name: 'status', internalType: 'enum NodeStatus', type: 'uint8' }, + ], + name: 'registerNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'manager', internalType: 'address', type: 'address' }], + name: 'removeConfigurationManager', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'nodeAddress', internalType: 'address', type: 'address' }], + name: 'removeNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'operator', internalType: 'address', type: 'address' }], + name: 'removeOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'streamId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + ], + name: 'removeStreamFromNode', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32' }, + { name: 'blockNumber', internalType: 'uint64', type: 'uint64' }, + { name: 'value', internalType: 'bytes', type: 'bytes' }, + ], + name: 'setConfiguration', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'streamId', internalType: 'bytes32', type: 'bytes32' }, + { name: 'prevMiniBlockHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'lastMiniblockHash', internalType: 'bytes32', type: 'bytes32' }, + { name: 'lastMiniblockNum', internalType: 'uint64', type: 'uint64' }, + { name: 'isSealed', internalType: 'bool', type: 'bool' }, + ], + name: 'setStreamLastMiniblock', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { + name: 'miniblocks', + internalType: 'struct SetMiniblock[]', + type: 'tuple[]', + components: [ + { name: 'streamId', internalType: 'bytes32', type: 'bytes32' }, + { + name: 'prevMiniBlockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + }, + { name: 'lastMiniblockNum', internalType: 'uint64', type: 'uint64' }, + { name: 'isSealed', internalType: 'bool', type: 'bool' }, + ], + }, + ], + name: 'setStreamLastMiniblockBatch', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'status', internalType: 'enum NodeStatus', type: 'uint8' }, + ], + name: 'updateNodeStatus', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'nodeAddress', internalType: 'address', type: 'address' }, + { name: 'url', internalType: 'string', type: 'string' }, + ], + name: 'updateNodeUrl', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'key', internalType: 'bytes32', type: 'bytes32', indexed: false }, + { name: 'block', internalType: 'uint64', type: 'uint64', indexed: false }, + { name: 'value', internalType: 'bytes', type: 'bytes', indexed: false }, + { name: 'deleted', internalType: 'bool', type: 'bool', indexed: false }, + ], + name: 'ConfigurationChanged', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'manager', internalType: 'address', type: 'address', indexed: true, }, + ], + name: 'ConfigurationManagerAdded', + }, + { + type: 'event', + anonymous: false, + inputs: [ { - name: 'previousVotes', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'newVotes', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'manager', + internalType: 'address', + type: 'address', + indexed: true, }, ], - name: 'DelegateVotesChanged', + name: 'ConfigurationManagerRemoved', }, - { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, { type: 'event', anonymous: false, @@ -1489,1787 +1895,3057 @@ export const riverTokenAbi = [ anonymous: false, inputs: [ { - name: 'caller', + name: 'nodeAddress', internalType: 'address', type: 'address', indexed: true, }, - { name: 'enabled', internalType: 'bool', type: 'bool', indexed: true }, { - name: 'cooldown', - internalType: 'uint256', - type: 'uint256', + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'url', internalType: 'string', type: 'string', indexed: false }, + { + name: 'status', + internalType: 'enum NodeStatus', + type: 'uint8', indexed: false, }, ], - name: 'LockUpdated', + name: 'NodeAdded', }, { type: 'event', anonymous: false, inputs: [ { - name: 'previousOwner', + name: 'nodeAddress', internalType: 'address', type: 'address', indexed: true, }, + ], + name: 'NodeRemoved', + }, + { + type: 'event', + anonymous: false, + inputs: [ { - name: 'newOwner', + name: 'nodeAddress', internalType: 'address', type: 'address', indexed: true, }, + { + name: 'status', + internalType: 'enum NodeStatus', + type: 'uint8', + indexed: false, + }, ], - name: 'OwnershipTransferred', + name: 'NodeStatusUpdated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'threshold', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'nodeAddress', + internalType: 'address', + type: 'address', + indexed: true, }, + { name: 'url', internalType: 'string', type: 'string', indexed: false }, ], - name: 'TokenThresholdSet', + name: 'NodeUrlUpdated', }, { type: 'event', anonymous: false, inputs: [ - { name: 'from', internalType: 'address', type: 'address', indexed: true }, - { name: 'to', internalType: 'address', type: 'address', indexed: true }, { - name: 'value', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'operatorAddress', + internalType: 'address', + type: 'address', + indexed: true, }, ], - name: 'Transfer', + name: 'OperatorAdded', }, { - type: 'function', - inputs: [], - name: 'CLOCK_MODE', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'pure', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'operatorAddress', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OperatorRemoved', }, { - type: 'function', - inputs: [], - name: 'DOMAIN_SEPARATOR', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], - stateMutability: 'view', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', }, { - type: 'function', - inputs: [], - name: '__Introspection_init', - outputs: [], - stateMutability: 'nonpayable', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'streamId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'nodes', + internalType: 'address[]', + type: 'address[]', + indexed: false, + }, + { + name: 'genesisMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'genesisMiniblock', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, + ], + name: 'StreamAllocated', }, { - type: 'function', - inputs: [{ name: 'cooldown', internalType: 'uint256', type: 'uint256' }], - name: '__LockFacet_init', - outputs: [], - stateMutability: 'nonpayable', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'streamId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + indexed: false, + }, + { + name: 'reason', + internalType: 'string', + type: 'string', + indexed: false, + }, + ], + name: 'StreamLastMiniblockUpdateFailed', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'owner', internalType: 'address', type: 'address' }, - { name: 'spender', internalType: 'address', type: 'address' }, + { + name: 'streamId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'lastMiniblockHash', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'lastMiniblockNum', + internalType: 'uint64', + type: 'uint64', + indexed: false, + }, + { name: 'isSealed', internalType: 'bool', type: 'bool', indexed: false }, ], - name: 'allowance', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'StreamLastMiniblockUpdated', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'spender', internalType: 'address', type: 'address' }, - { name: 'value', internalType: 'uint256', type: 'uint256' }, + { + name: 'streamId', + internalType: 'bytes32', + type: 'bytes32', + indexed: false, + }, + { + name: 'nodeAddress', + internalType: 'address', + type: 'address', + indexed: false, + }, + { name: 'isAdded', internalType: 'bool', type: 'bool', indexed: false }, ], - name: 'approve', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'nonpayable', + name: 'StreamPlacementUpdated', }, + { type: 'error', inputs: [], name: 'Initializable_InInitializingState' }, + { type: 'error', inputs: [], name: 'Initializable_NotInInitializingState' }, + { type: 'error', inputs: [], name: 'Introspection_AlreadySupported' }, + { type: 'error', inputs: [], name: 'Introspection_NotSupported' }, { - type: 'function', + type: 'error', inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'balanceOf', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'bridge', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + name: 'Ownable__NotOwner', }, + { type: 'error', inputs: [], name: 'Ownable__ZeroAddress' }, +] as const + +/** + +*/ +export const riverRegistryAddress = { + 550: '0x1298c03Fde548dc433a452573E36A713b38A0404', + 6524490: '0xf18E98D36A6bd1aDb52F776aCc191E69B491c070', +} as const + +/** + +*/ +export const riverRegistryConfig = { + address: riverRegistryAddress, + abi: riverRegistryAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// RiverToken +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + */ +export const riverTokenAbi = [ { - type: 'function', + type: 'constructor', inputs: [ - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: '_bridge', internalType: 'address', type: 'address' }, + { name: '_remoteToken', internalType: 'address', type: 'address' }, ], - name: 'burn', - outputs: [], stateMutability: 'nonpayable', }, + { type: 'error', inputs: [], name: 'CheckpointUnorderedInsertion' }, + { type: 'error', inputs: [], name: 'ECDSAInvalidSignature' }, { - type: 'function', - inputs: [ - { name: 'account', internalType: 'address', type: 'address' }, - { name: 'pos', internalType: 'uint32', type: 'uint32' }, - ], - name: 'checkpoints', - outputs: [ - { - name: '', - internalType: 'struct Checkpoints.Checkpoint208', - type: 'tuple', - components: [ - { name: '_key', internalType: 'uint48', type: 'uint48' }, - { name: '_value', internalType: 'uint208', type: 'uint208' }, - ], - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'clock', - outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'ECDSAInvalidSignatureLength', }, { - type: 'function', - inputs: [], - name: 'decimals', - outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 's', internalType: 'bytes32', type: 'bytes32' }], + name: 'ECDSAInvalidSignatureS', }, { - type: 'function', - inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], - name: 'delegate', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [ + { name: 'increasedSupply', internalType: 'uint256', type: 'uint256' }, + { name: 'cap', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ERC20ExceededSafeSupply', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'delegatee', internalType: 'address', type: 'address' }, - { name: 'nonce', internalType: 'uint256', type: 'uint256' }, - { name: 'expiry', internalType: 'uint256', type: 'uint256' }, - { name: 'v', internalType: 'uint8', type: 'uint8' }, - { name: 'r', internalType: 'bytes32', type: 'bytes32' }, - { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'allowance', internalType: 'uint256', type: 'uint256' }, + { name: 'needed', internalType: 'uint256', type: 'uint256' }, ], - name: 'delegateBySig', - outputs: [], - stateMutability: 'nonpayable', + name: 'ERC20InsufficientAllowance', }, { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'delegates', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [ + { name: 'sender', internalType: 'address', type: 'address' }, + { name: 'balance', internalType: 'uint256', type: 'uint256' }, + { name: 'needed', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ERC20InsufficientBalance', }, { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'disableLock', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'approver', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidApprover', }, { - type: 'function', - inputs: [], - name: 'eip712Domain', - outputs: [ - { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'version', internalType: 'string', type: 'string' }, - { name: 'chainId', internalType: 'uint256', type: 'uint256' }, - { name: 'verifyingContract', internalType: 'address', type: 'address' }, - { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, - { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, - ], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'receiver', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidReceiver', }, { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'enableLock', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'sender', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidSender', }, { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'getDelegationTimeForDelegator', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'spender', internalType: 'address', type: 'address' }], + name: 'ERC20InvalidSpender', }, { - type: 'function', - inputs: [], - name: 'getDelegators', - outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'deadline', internalType: 'uint256', type: 'uint256' }], + name: 'ERC2612ExpiredSignature', }, { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'getDelegatorsByDelegatee', - outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], - stateMutability: 'view', + type: 'error', + inputs: [ + { name: 'signer', internalType: 'address', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, + ], + name: 'ERC2612InvalidSigner', }, { - type: 'function', - inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], - name: 'getPastTotalSupply', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', + type: 'error', inputs: [ - { name: 'account', internalType: 'address', type: 'address' }, { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + { name: 'clock', internalType: 'uint48', type: 'uint48' }, ], - name: 'getPastVotes', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'getVotes', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'isLockEnabled', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'l1Token', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'l2Bridge', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'lockCooldown', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'ERC5805FutureLookup', }, + { type: 'error', inputs: [], name: 'ERC6372InconsistentClock' }, + { type: 'error', inputs: [], name: 'Initializable_InInitializingState' }, + { type: 'error', inputs: [], name: 'Initializable_NotInInitializingState' }, + { type: 'error', inputs: [], name: 'Introspection_AlreadySupported' }, + { type: 'error', inputs: [], name: 'Introspection_NotSupported' }, { - type: 'function', + type: 'error', inputs: [ - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'currentNonce', internalType: 'uint256', type: 'uint256' }, ], - name: 'mint', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [], - name: 'name', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'view', + name: 'InvalidAccountNonce', }, + { type: 'error', inputs: [], name: 'InvalidShortString' }, + { type: 'error', inputs: [], name: 'LockNotAuthorized' }, { - type: 'function', + type: 'error', inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], - name: 'nonces', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'OwnableInvalidOwner', }, { - type: 'function', + type: 'error', inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'numCheckpoints', - outputs: [{ name: '', internalType: 'uint32', type: 'uint32' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'owner', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + name: 'OwnableUnauthorizedAccount', }, + { type: 'error', inputs: [], name: 'River__DelegateeSameAsCurrent' }, + { type: 'error', inputs: [], name: 'River__TransferLockEnabled' }, { - type: 'function', + type: 'error', inputs: [ - { name: 'owner', internalType: 'address', type: 'address' }, - { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'bits', internalType: 'uint8', type: 'uint8' }, { name: 'value', internalType: 'uint256', type: 'uint256' }, - { name: 'deadline', internalType: 'uint256', type: 'uint256' }, - { name: 'v', internalType: 'uint8', type: 'uint8' }, - { name: 'r', internalType: 'bytes32', type: 'bytes32' }, - { name: 's', internalType: 'bytes32', type: 'bytes32' }, ], - name: 'permit', - outputs: [], - stateMutability: 'nonpayable', + name: 'SafeCastOverflowedUintDowncast', }, { - type: 'function', - inputs: [], - name: 'remoteToken', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'str', internalType: 'string', type: 'string' }], + name: 'StringTooLong', }, { - type: 'function', - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'expiry', internalType: 'uint256', type: 'uint256' }], + name: 'VotesExpiredSignature', }, { - type: 'function', - inputs: [{ name: 'cooldown', internalType: 'uint256', type: 'uint256' }], - name: 'setLockCooldown', - outputs: [], - stateMutability: 'nonpayable', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'spender', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Approval', }, { - type: 'function', - inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], - name: 'supportsInterface', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'fromDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'toDelegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'DelegateChanged', }, { - type: 'function', - inputs: [], - name: 'symbol', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'view', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'delegate', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'previousVotes', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newVotes', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'DelegateVotesChanged', }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, { - type: 'function', - inputs: [], - name: 'totalSupply', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'version', + internalType: 'uint32', + type: 'uint32', + indexed: false, + }, + ], + name: 'Initialized', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'value', internalType: 'uint256', type: 'uint256' }, + { + name: 'interfaceId', + internalType: 'bytes4', + type: 'bytes4', + indexed: true, + }, ], - name: 'transfer', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'nonpayable', + name: 'InterfaceAdded', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'value', internalType: 'uint256', type: 'uint256' }, + { + name: 'interfaceId', + internalType: 'bytes4', + type: 'bytes4', + indexed: true, + }, ], - name: 'transferFrom', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'nonpayable', + name: 'InterfaceRemoved', }, { - type: 'function', - inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], - name: 'transferOwnership', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'caller', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'enabled', internalType: 'bool', type: 'bool', indexed: true }, + { + name: 'cooldown', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'LockUpdated', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'OwnershipTransferred', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'threshold', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'TokenThresholdSet', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'value', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'Transfer', + }, + { + type: 'function', + inputs: [], + name: 'CLOCK_MODE', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [], + name: 'DOMAIN_SEPARATOR', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: '__Introspection_init', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'cooldown', internalType: 'uint256', type: 'uint256' }], + name: '__LockFacet_init', outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + ], + name: 'allowance', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'approve', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, { type: 'function', inputs: [], - name: 'version', - outputs: [{ name: '', internalType: 'string', type: 'string' }], + name: 'bridge', + outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, -] as const + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burn', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'pos', internalType: 'uint32', type: 'uint32' }, + ], + name: 'checkpoints', + outputs: [ + { + name: '', + internalType: 'struct Checkpoints.Checkpoint208', + type: 'tuple', + components: [ + { name: '_key', internalType: 'uint48', type: 'uint48' }, + { name: '_value', internalType: 'uint208', type: 'uint208' }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'clock', + outputs: [{ name: '', internalType: 'uint48', type: 'uint48' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'decimals', + outputs: [{ name: '', internalType: 'uint8', type: 'uint8' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'delegatee', internalType: 'address', type: 'address' }], + name: 'delegate', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'delegatee', internalType: 'address', type: 'address' }, + { name: 'nonce', internalType: 'uint256', type: 'uint256' }, + { name: 'expiry', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'delegateBySig', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'delegates', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'disableLock', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'eip712Domain', + outputs: [ + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'enableLock', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getDelegationTimeForDelegator', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getDelegators', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getDelegatorsByDelegatee', + outputs: [{ name: '', internalType: 'address[]', type: 'address[]' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'timepoint', internalType: 'uint256', type: 'uint256' }], + name: 'getPastTotalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'timepoint', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getPastVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'getVotes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'isLockEnabled', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'l1Token', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'l2Bridge', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'lockCooldown', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'name', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'nonces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'numCheckpoints', + outputs: [{ name: '', internalType: 'uint32', type: 'uint32' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'owner', internalType: 'address', type: 'address' }, + { name: 'spender', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'permit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'remoteToken', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'cooldown', internalType: 'uint256', type: 'uint256' }], + name: 'setLockCooldown', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'interfaceId', internalType: 'bytes4', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'symbol', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transfer', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'value', internalType: 'uint256', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'version', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, +] as const + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + */ +export const riverTokenAddress = { + 8453: '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920', + 84532: '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0', +} as const + +/** + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + */ +export const riverTokenConfig = { + address: riverTokenAddress, + abi: riverTokenAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// React +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link authorizerAbi}__ + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useReadAuthorizer = /*#__PURE__*/ createUseReadContract({ + abi: authorizerAbi, + address: authorizerAddress, +}) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"getAuthorizedClaimer"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useReadAuthorizerGetAuthorizedClaimer = + /*#__PURE__*/ createUseReadContract({ + abi: authorizerAbi, + address: authorizerAddress, + functionName: 'getAuthorizedClaimer', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWriteAuthorizer = /*#__PURE__*/ createUseWriteContract({ + abi: authorizerAbi, + address: authorizerAddress, +}) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"authorizeClaimer"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWriteAuthorizerAuthorizeClaimer = + /*#__PURE__*/ createUseWriteContract({ + abi: authorizerAbi, + address: authorizerAddress, + functionName: 'authorizeClaimer', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"removeAuthorizedClaimer"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWriteAuthorizerRemoveAuthorizedClaimer = + /*#__PURE__*/ createUseWriteContract({ + abi: authorizerAbi, + address: authorizerAddress, + functionName: 'removeAuthorizedClaimer', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useSimulateAuthorizer = /*#__PURE__*/ createUseSimulateContract({ + abi: authorizerAbi, + address: authorizerAddress, +}) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"authorizeClaimer"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useSimulateAuthorizerAuthorizeClaimer = + /*#__PURE__*/ createUseSimulateContract({ + abi: authorizerAbi, + address: authorizerAddress, + functionName: 'authorizeClaimer', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"removeAuthorizedClaimer"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useSimulateAuthorizerRemoveAuthorizedClaimer = + /*#__PURE__*/ createUseSimulateContract({ + abi: authorizerAbi, + address: authorizerAddress, + functionName: 'removeAuthorizedClaimer', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWatchAuthorizerEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: authorizerAbi, + address: authorizerAddress, + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ and `eventName` set to `"AuthorizedClaimerChanged"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWatchAuthorizerAuthorizedClaimerChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: authorizerAbi, + address: authorizerAddress, + eventName: 'AuthorizedClaimerChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ and `eventName` set to `"AuthorizedClaimerRemoved"` + * + * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) + * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + */ +export const useWatchAuthorizerAuthorizedClaimerRemovedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: authorizerAbi, + address: authorizerAddress, + eventName: 'AuthorizedClaimerRemoved', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperator = /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetClaimAddressForOperator = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getClaimAddressForOperator', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetCommissionRate = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getCommissionRate', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetOperatorStatus = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getOperatorStatus', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperators"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorGetOperators = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'getOperators', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"isOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadNodeOperatorIsOperator = + /*#__PURE__*/ createUseReadContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'isOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperator = /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorNodeOperatorInit = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: '__NodeOperator_init', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorRegisterOperator = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'registerOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetClaimAddressForOperator = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setClaimAddressForOperator', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetCommissionRate = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setCommissionRate', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteNodeOperatorSetOperatorStatus = + /*#__PURE__*/ createUseWriteContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setOperatorStatus', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperator = /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, +}) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorNodeOperatorInit = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: '__NodeOperator_init', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorRegisterOperator = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'registerOperator', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetClaimAddressForOperator = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setClaimAddressForOperator', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetCommissionRate = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setCommissionRate', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateNodeOperatorSetOperatorStatus = + /*#__PURE__*/ createUseSimulateContract({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + functionName: 'setOperatorStatus', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Approval"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorApprovalEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Approval', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ApprovalForAll"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorApprovalForAllEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'ApprovalForAll', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ConsecutiveTransfer"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorConsecutiveTransferEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'ConsecutiveTransfer', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Initialized"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInitializedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Initialized', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceAdded"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInterfaceAddedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'InterfaceAdded', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceRemoved"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorInterfaceRemovedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'InterfaceRemoved', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorClaimAddressChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorClaimAddressChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorClaimAddressChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorCommissionChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorCommissionChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorCommissionChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorRegistered"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorRegisteredEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorRegistered', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorStatusChanged"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOperatorStatusChangedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OperatorStatusChanged', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OwnershipTransferred"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorOwnershipTransferredEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'OwnershipTransferred', + }) + +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Transfer"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchNodeOperatorTransferEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: nodeOperatorAbi, + address: nodeOperatorAddress, + eventName: 'Transfer', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistribution = /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, +}) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentReward"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionCurrentReward = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'currentReward', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentRewardPerTokenAccumulated"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionCurrentRewardPerTokenAccumulated = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'currentRewardPerTokenAccumulated', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentSpaceDelegationReward"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionCurrentSpaceDelegationReward = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'currentSpaceDelegationReward', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"delegationProxyById"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionDelegationProxyById = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'delegationProxyById', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"depositById"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionDepositById = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'depositById', + }) /** - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"getDepositsByDepositor"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const riverTokenAddress = { - 8453: '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920', - 84532: '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0', -} as const +export const useReadRewardsDistributionGetDepositsByDepositor = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'getDepositsByDepositor', + }) /** - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"implementation"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const riverTokenConfig = { - address: riverTokenAddress, - abi: riverTokenAbi, -} as const +export const useReadRewardsDistributionImplementation = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'implementation', + }) -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// React -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"isRewardNotifier"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionIsRewardNotifier = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'isRewardNotifier', + }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link authorizerAbi}__ + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"lastTimeRewardDistributed"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadAuthorizer = /*#__PURE__*/ createUseReadContract({ - abi: authorizerAbi, - address: authorizerAddress, -}) +export const useReadRewardsDistributionLastTimeRewardDistributed = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'lastTimeRewardDistributed', + }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"getAuthorizedClaimer"` + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakedByDepositor"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadAuthorizerGetAuthorizedClaimer = +export const useReadRewardsDistributionStakedByDepositor = /*#__PURE__*/ createUseReadContract({ - abi: authorizerAbi, - address: authorizerAddress, - functionName: 'getAuthorizedClaimer', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stakedByDepositor', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakingState"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteAuthorizer = /*#__PURE__*/ createUseWriteContract({ - abi: authorizerAbi, - address: authorizerAddress, -}) +export const useReadRewardsDistributionStakingState = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stakingState', + }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"authorizeClaimer"` + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"treasureByBeneficiary"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteAuthorizerAuthorizeClaimer = +export const useReadRewardsDistributionTreasureByBeneficiary = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'treasureByBeneficiary', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistribution = /*#__PURE__*/ createUseWriteContract( + { abi: rewardsDistributionAbi, address: rewardsDistributionAddress }, +) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"__RewardsDistribution_init"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionRewardsDistributionInit = /*#__PURE__*/ createUseWriteContract({ - abi: authorizerAbi, - address: authorizerAddress, - functionName: 'authorizeClaimer', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: '__RewardsDistribution_init', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"removeAuthorizedClaimer"` + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"changeBeneficiary"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteAuthorizerRemoveAuthorizedClaimer = +export const useWriteRewardsDistributionChangeBeneficiary = /*#__PURE__*/ createUseWriteContract({ - abi: authorizerAbi, - address: authorizerAddress, - functionName: 'removeAuthorizedClaimer', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'changeBeneficiary', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"claimReward"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionClaimReward = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'claimReward', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"increaseStake"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionIncreaseStake = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'increaseStake', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"initiateWithdraw"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionInitiateWithdraw = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'initiateWithdraw', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"notifyRewardAmount"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionNotifyRewardAmount = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'notifyRewardAmount', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"permitAndStake"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionPermitAndStake = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'permitAndStake', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"redelegate"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionRedelegate = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'redelegate', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionSetRewardNotifier = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'setRewardNotifier', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stake"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionStake = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stake', + }) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakeOnBehalf"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateAuthorizer = /*#__PURE__*/ createUseSimulateContract({ - abi: authorizerAbi, - address: authorizerAddress, -}) +export const useWriteRewardsDistributionStakeOnBehalf = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stakeOnBehalf', + }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"authorizeClaimer"` + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"upgradeDelegationProxy"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateAuthorizerAuthorizeClaimer = - /*#__PURE__*/ createUseSimulateContract({ - abi: authorizerAbi, - address: authorizerAddress, - functionName: 'authorizeClaimer', +export const useWriteRewardsDistributionUpgradeDelegationProxy = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'upgradeDelegationProxy', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link authorizerAbi}__ and `functionName` set to `"removeAuthorizedClaimer"` + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"withdraw"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateAuthorizerRemoveAuthorizedClaimer = - /*#__PURE__*/ createUseSimulateContract({ - abi: authorizerAbi, - address: authorizerAddress, - functionName: 'removeAuthorizedClaimer', +export const useWriteRewardsDistributionWithdraw = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'withdraw', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchAuthorizerEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: authorizerAbi, - address: authorizerAddress, +export const useSimulateRewardsDistribution = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ and `eventName` set to `"AuthorizedClaimerChanged"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"__RewardsDistribution_init"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchAuthorizerAuthorizedClaimerChangedEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: authorizerAbi, - address: authorizerAddress, - eventName: 'AuthorizedClaimerChanged', +export const useSimulateRewardsDistributionRewardsDistributionInit = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: '__RewardsDistribution_init', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link authorizerAbi}__ and `eventName` set to `"AuthorizedClaimerRemoved"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"changeBeneficiary"` * - * - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x0bEe55b52d01C4D5d4D0cfcE1d6e0baE6722db05) - * - [__View Contract on Sepolia Etherscan__](https://sepolia.etherscan.io/address/0x2f5E8F6Fb7EcF63d13C13B698d1e0B3EA4Ef604B) + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchAuthorizerAuthorizedClaimerRemovedEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: authorizerAbi, - address: authorizerAddress, - eventName: 'AuthorizedClaimerRemoved', +export const useSimulateRewardsDistributionChangeBeneficiary = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'changeBeneficiary', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"claimReward"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperator = /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, -}) +export const useSimulateRewardsDistributionClaimReward = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'claimReward', + }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getClaimAddressForOperator"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"increaseStake"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperatorGetClaimAddressForOperator = - /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'getClaimAddressForOperator', +export const useSimulateRewardsDistributionIncreaseStake = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'increaseStake', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getCommissionRate"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"initiateWithdraw"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperatorGetCommissionRate = - /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'getCommissionRate', +export const useSimulateRewardsDistributionInitiateWithdraw = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'initiateWithdraw', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperatorStatus"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"notifyRewardAmount"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperatorGetOperatorStatus = - /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'getOperatorStatus', +export const useSimulateRewardsDistributionNotifyRewardAmount = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'notifyRewardAmount', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"getOperators"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"permitAndStake"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperatorGetOperators = - /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'getOperators', +export const useSimulateRewardsDistributionPermitAndStake = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'permitAndStake', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"isOperator"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"redelegate"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadNodeOperatorIsOperator = - /*#__PURE__*/ createUseReadContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'isOperator', +export const useSimulateRewardsDistributionRedelegate = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'redelegate', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperator = /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, -}) +export const useSimulateRewardsDistributionSetRewardNotifier = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'setRewardNotifier', + }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stake"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperatorNodeOperatorInit = - /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: '__NodeOperator_init', +export const useSimulateRewardsDistributionStake = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stake', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakeOnBehalf"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperatorRegisterOperator = - /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'registerOperator', +export const useSimulateRewardsDistributionStakeOnBehalf = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'stakeOnBehalf', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"upgradeDelegationProxy"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperatorSetClaimAddressForOperator = - /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setClaimAddressForOperator', +export const useSimulateRewardsDistributionUpgradeDelegationProxy = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'upgradeDelegationProxy', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"withdraw"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperatorSetCommissionRate = - /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setCommissionRate', +export const useSimulateRewardsDistributionWithdraw = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'withdraw', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWriteNodeOperatorSetOperatorStatus = - /*#__PURE__*/ createUseWriteContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setOperatorStatus', +export const useWatchRewardsDistributionEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ChangeBeneficiary"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperator = /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, -}) +export const useWatchRewardsDistributionChangeBeneficiaryEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'ChangeBeneficiary', + }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"__NodeOperator_init"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ClaimReward"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperatorNodeOperatorInit = - /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: '__NodeOperator_init', +export const useWatchRewardsDistributionClaimRewardEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'ClaimReward', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"registerOperator"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ClaimerSet"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperatorRegisterOperator = - /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'registerOperator', +export const useWatchRewardsDistributionClaimerSetEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'ClaimerSet', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setClaimAddressForOperator"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationProxyDeployed"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperatorSetClaimAddressForOperator = - /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setClaimAddressForOperator', +export const useWatchRewardsDistributionDelegationProxyDeployedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'DelegationProxyDeployed', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setCommissionRate"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationRemoved"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperatorSetCommissionRate = - /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setCommissionRate', +export const useWatchRewardsDistributionDelegationRemovedEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'DelegationRemoved', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link nodeOperatorAbi}__ and `functionName` set to `"setOperatorStatus"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationSet"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useSimulateNodeOperatorSetOperatorStatus = - /*#__PURE__*/ createUseSimulateContract({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - functionName: 'setOperatorStatus', +export const useWatchRewardsDistributionDelegationSetEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'DelegationSet', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"IncreaseStake"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorEvent = +export const useWatchRewardsDistributionIncreaseStakeEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'IncreaseStake', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Approval"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Initialized"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorApprovalEvent = +export const useWatchRewardsDistributionInitializedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'Approval', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'Initialized', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ApprovalForAll"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InitiateWithdraw"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorApprovalForAllEvent = +export const useWatchRewardsDistributionInitiateWithdrawEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'ApprovalForAll', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'InitiateWithdraw', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"ConsecutiveTransfer"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InterfaceAdded"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorConsecutiveTransferEvent = +export const useWatchRewardsDistributionInterfaceAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'ConsecutiveTransfer', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'InterfaceAdded', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Initialized"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InterfaceRemoved"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorInitializedEvent = +export const useWatchRewardsDistributionInterfaceRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'Initialized', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'InterfaceRemoved', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceAdded"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"NotifyRewardAmount"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorInterfaceAddedEvent = +export const useWatchRewardsDistributionNotifyRewardAmountEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'InterfaceAdded', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'NotifyRewardAmount', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"InterfaceRemoved"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"OwnershipTransferred"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorInterfaceRemovedEvent = +export const useWatchRewardsDistributionOwnershipTransferredEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'InterfaceRemoved', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'OwnershipTransferred', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorClaimAddressChanged"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Redelegate"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorOperatorClaimAddressChangedEvent = +export const useWatchRewardsDistributionRedelegateEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'OperatorClaimAddressChanged', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'Redelegate', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorCommissionChanged"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"RewardNotifierSet"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorOperatorCommissionChangedEvent = +export const useWatchRewardsDistributionRewardNotifierSetEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'OperatorCommissionChanged', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'RewardNotifierSet', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorRegistered"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"RewardsDistributionInitialized"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorOperatorRegisteredEvent = +export const useWatchRewardsDistributionRewardsDistributionInitializedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'OperatorRegistered', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'RewardsDistributionInitialized', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OperatorStatusChanged"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"SpaceRewardsSwept"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorOperatorStatusChangedEvent = +export const useWatchRewardsDistributionSpaceRewardsSweptEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'OperatorStatusChanged', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'SpaceRewardsSwept', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"OwnershipTransferred"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Stake"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorOwnershipTransferredEvent = +export const useWatchRewardsDistributionStakeEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'OwnershipTransferred', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'Stake', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link nodeOperatorAbi}__ and `eventName` set to `"Transfer"` + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Upgraded"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useWatchNodeOperatorTransferEvent = +export const useWatchRewardsDistributionUpgradedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: nodeOperatorAbi, - address: nodeOperatorAddress, - eventName: 'Transfer', + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'Upgraded', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Withdraw"` * * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) */ -export const useReadRewardsDistribution = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, +export const useWatchRewardsDistributionWithdrawEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'Withdraw', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ + */ +export const useReadRiverRegistry = /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentReward"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"configurationExists"` */ -export const useReadRewardsDistributionCurrentReward = +export const useReadRiverRegistryConfigurationExists = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'currentReward', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'configurationExists', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllConfiguration"` + */ +export const useReadRiverRegistryGetAllConfiguration = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllConfiguration', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllNodeAddresses"` + */ +export const useReadRiverRegistryGetAllNodeAddresses = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllNodeAddresses', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllNodes"` + */ +export const useReadRiverRegistryGetAllNodes = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllNodes', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllOperators"` + */ +export const useReadRiverRegistryGetAllOperators = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllOperators', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllStreamIds"` + */ +export const useReadRiverRegistryGetAllStreamIds = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllStreamIds', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getAllStreams"` + */ +export const useReadRiverRegistryGetAllStreams = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getAllStreams', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getConfiguration"` + */ +export const useReadRiverRegistryGetConfiguration = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getConfiguration', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getNode"` + */ +export const useReadRiverRegistryGetNode = /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getNode', +}) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getNodeCount"` + */ +export const useReadRiverRegistryGetNodeCount = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getNodeCount', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getPaginatedStreams"` + */ +export const useReadRiverRegistryGetPaginatedStreams = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getPaginatedStreams', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStream"` + */ +export const useReadRiverRegistryGetStream = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStream', + }) + +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreamByIndex"` + */ +export const useReadRiverRegistryGetStreamByIndex = + /*#__PURE__*/ createUseReadContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreamByIndex', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentRewardPerTokenAccumulated"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreamCount"` */ -export const useReadRewardsDistributionCurrentRewardPerTokenAccumulated = +export const useReadRiverRegistryGetStreamCount = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'currentRewardPerTokenAccumulated', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreamCount', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"currentSpaceDelegationReward"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreamCountOnNode"` */ -export const useReadRewardsDistributionCurrentSpaceDelegationReward = +export const useReadRiverRegistryGetStreamCountOnNode = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'currentSpaceDelegationReward', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreamCountOnNode', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"delegationProxyById"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreamWithGenesis"` */ -export const useReadRewardsDistributionDelegationProxyById = +export const useReadRiverRegistryGetStreamWithGenesis = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'delegationProxyById', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreamWithGenesis', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"depositById"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreams"` */ -export const useReadRewardsDistributionDepositById = +export const useReadRiverRegistryGetStreams = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'depositById', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreams', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"getDepositsByDepositor"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"getStreamsOnNode"` */ -export const useReadRewardsDistributionGetDepositsByDepositor = +export const useReadRiverRegistryGetStreamsOnNode = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'getDepositsByDepositor', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'getStreamsOnNode', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"implementation"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"isConfigurationManager"` */ -export const useReadRewardsDistributionImplementation = +export const useReadRiverRegistryIsConfigurationManager = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'implementation', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'isConfigurationManager', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"isRewardNotifier"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useReadContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"isOperator"` */ -export const useReadRewardsDistributionIsRewardNotifier = +export const useReadRiverRegistryIsOperator = /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'isRewardNotifier', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'isOperator', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"lastTimeRewardDistributed"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ */ -export const useReadRewardsDistributionLastTimeRewardDistributed = - /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'lastTimeRewardDistributed', +export const useWriteRiverRegistry = /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, +}) + +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"__OperatorRegistry_init"` + */ +export const useWriteRiverRegistryOperatorRegistryInit = + /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: '__OperatorRegistry_init', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakedByDepositor"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"__RiverConfig_init"` */ -export const useReadRewardsDistributionStakedByDepositor = - /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stakedByDepositor', +export const useWriteRiverRegistryRiverConfigInit = + /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: '__RiverConfig_init', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakingState"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"allocateStream"` */ -export const useReadRewardsDistributionStakingState = - /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stakingState', +export const useWriteRiverRegistryAllocateStream = + /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'allocateStream', }) /** - * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"treasureByBeneficiary"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"approveConfigurationManager"` */ -export const useReadRewardsDistributionTreasureByBeneficiary = - /*#__PURE__*/ createUseReadContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'treasureByBeneficiary', +export const useWriteRiverRegistryApproveConfigurationManager = + /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'approveConfigurationManager', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"approveOperator"` */ -export const useWriteRewardsDistribution = /*#__PURE__*/ createUseWriteContract( - { abi: rewardsDistributionAbi, address: rewardsDistributionAddress }, -) +export const useWriteRiverRegistryApproveOperator = + /*#__PURE__*/ createUseWriteContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'approveOperator', + }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"__RewardsDistribution_init"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"deleteConfiguration"` */ -export const useWriteRewardsDistributionRewardsDistributionInit = +export const useWriteRiverRegistryDeleteConfiguration = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: '__RewardsDistribution_init', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'deleteConfiguration', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"changeBeneficiary"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"deleteConfigurationOnBlock"` */ -export const useWriteRewardsDistributionChangeBeneficiary = +export const useWriteRiverRegistryDeleteConfigurationOnBlock = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'changeBeneficiary', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'deleteConfigurationOnBlock', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"claimReward"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"placeStreamOnNode"` */ -export const useWriteRewardsDistributionClaimReward = +export const useWriteRiverRegistryPlaceStreamOnNode = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'claimReward', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'placeStreamOnNode', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"increaseStake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"registerNode"` */ -export const useWriteRewardsDistributionIncreaseStake = +export const useWriteRiverRegistryRegisterNode = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'increaseStake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'registerNode', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"initiateWithdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeConfigurationManager"` */ -export const useWriteRewardsDistributionInitiateWithdraw = +export const useWriteRiverRegistryRemoveConfigurationManager = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'initiateWithdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeConfigurationManager', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"notifyRewardAmount"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeNode"` */ -export const useWriteRewardsDistributionNotifyRewardAmount = +export const useWriteRiverRegistryRemoveNode = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'notifyRewardAmount', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeNode', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"permitAndStake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeOperator"` */ -export const useWriteRewardsDistributionPermitAndStake = +export const useWriteRiverRegistryRemoveOperator = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'permitAndStake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeOperator', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"redelegate"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeStreamFromNode"` */ -export const useWriteRewardsDistributionRedelegate = +export const useWriteRiverRegistryRemoveStreamFromNode = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'redelegate', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeStreamFromNode', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setConfiguration"` */ -export const useWriteRewardsDistributionSetRewardNotifier = +export const useWriteRiverRegistrySetConfiguration = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'setRewardNotifier', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setConfiguration', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setStreamLastMiniblock"` */ -export const useWriteRewardsDistributionStake = +export const useWriteRiverRegistrySetStreamLastMiniblock = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setStreamLastMiniblock', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakeOnBehalf"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setStreamLastMiniblockBatch"` */ -export const useWriteRewardsDistributionStakeOnBehalf = +export const useWriteRiverRegistrySetStreamLastMiniblockBatch = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stakeOnBehalf', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setStreamLastMiniblockBatch', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"upgradeDelegationProxy"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"updateNodeStatus"` */ -export const useWriteRewardsDistributionUpgradeDelegationProxy = +export const useWriteRiverRegistryUpdateNodeStatus = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'upgradeDelegationProxy', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'updateNodeStatus', }) /** - * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"withdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"updateNodeUrl"` */ -export const useWriteRewardsDistributionWithdraw = +export const useWriteRiverRegistryUpdateNodeUrl = /*#__PURE__*/ createUseWriteContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'withdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'updateNodeUrl', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ */ -export const useSimulateRewardsDistribution = +export const useSimulateRiverRegistry = /*#__PURE__*/ createUseSimulateContract( + { abi: riverRegistryAbi, address: riverRegistryAddress }, +) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"__OperatorRegistry_init"` + */ +export const useSimulateRiverRegistryOperatorRegistryInit = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: '__OperatorRegistry_init', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"__RewardsDistribution_init"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"__RiverConfig_init"` */ -export const useSimulateRewardsDistributionRewardsDistributionInit = +export const useSimulateRiverRegistryRiverConfigInit = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: '__RewardsDistribution_init', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: '__RiverConfig_init', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"changeBeneficiary"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"allocateStream"` */ -export const useSimulateRewardsDistributionChangeBeneficiary = +export const useSimulateRiverRegistryAllocateStream = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'changeBeneficiary', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'allocateStream', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"claimReward"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"approveConfigurationManager"` */ -export const useSimulateRewardsDistributionClaimReward = +export const useSimulateRiverRegistryApproveConfigurationManager = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'claimReward', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'approveConfigurationManager', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"increaseStake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"approveOperator"` + */ +export const useSimulateRiverRegistryApproveOperator = + /*#__PURE__*/ createUseSimulateContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'approveOperator', + }) + +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"deleteConfiguration"` */ -export const useSimulateRewardsDistributionIncreaseStake = +export const useSimulateRiverRegistryDeleteConfiguration = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'increaseStake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'deleteConfiguration', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"initiateWithdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"deleteConfigurationOnBlock"` */ -export const useSimulateRewardsDistributionInitiateWithdraw = +export const useSimulateRiverRegistryDeleteConfigurationOnBlock = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'initiateWithdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'deleteConfigurationOnBlock', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"notifyRewardAmount"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"placeStreamOnNode"` */ -export const useSimulateRewardsDistributionNotifyRewardAmount = +export const useSimulateRiverRegistryPlaceStreamOnNode = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'notifyRewardAmount', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'placeStreamOnNode', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"permitAndStake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"registerNode"` */ -export const useSimulateRewardsDistributionPermitAndStake = +export const useSimulateRiverRegistryRegisterNode = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'permitAndStake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'registerNode', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"redelegate"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeConfigurationManager"` */ -export const useSimulateRewardsDistributionRedelegate = +export const useSimulateRiverRegistryRemoveConfigurationManager = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'redelegate', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeConfigurationManager', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeNode"` */ -export const useSimulateRewardsDistributionSetRewardNotifier = +export const useSimulateRiverRegistryRemoveNode = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'setRewardNotifier', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeNode', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeOperator"` */ -export const useSimulateRewardsDistributionStake = +export const useSimulateRiverRegistryRemoveOperator = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeOperator', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"stakeOnBehalf"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"removeStreamFromNode"` */ -export const useSimulateRewardsDistributionStakeOnBehalf = +export const useSimulateRiverRegistryRemoveStreamFromNode = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'stakeOnBehalf', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'removeStreamFromNode', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"upgradeDelegationProxy"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setConfiguration"` */ -export const useSimulateRewardsDistributionUpgradeDelegationProxy = +export const useSimulateRiverRegistrySetConfiguration = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'upgradeDelegationProxy', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setConfiguration', }) /** - * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"withdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setStreamLastMiniblock"` */ -export const useSimulateRewardsDistributionWithdraw = +export const useSimulateRiverRegistrySetStreamLastMiniblock = /*#__PURE__*/ createUseSimulateContract({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - functionName: 'withdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setStreamLastMiniblock', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"setStreamLastMiniblockBatch"` */ -export const useWatchRewardsDistributionEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, +export const useSimulateRiverRegistrySetStreamLastMiniblockBatch = + /*#__PURE__*/ createUseSimulateContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'setStreamLastMiniblockBatch', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ChangeBeneficiary"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"updateNodeStatus"` */ -export const useWatchRewardsDistributionChangeBeneficiaryEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'ChangeBeneficiary', +export const useSimulateRiverRegistryUpdateNodeStatus = + /*#__PURE__*/ createUseSimulateContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'updateNodeStatus', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ClaimReward"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link riverRegistryAbi}__ and `functionName` set to `"updateNodeUrl"` */ -export const useWatchRewardsDistributionClaimRewardEvent = - /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'ClaimReward', +export const useSimulateRiverRegistryUpdateNodeUrl = + /*#__PURE__*/ createUseSimulateContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress, + functionName: 'updateNodeUrl', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"ClaimerSet"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ */ -export const useWatchRewardsDistributionClaimerSetEvent = +export const useWatchRiverRegistryEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'ClaimerSet', + abi: riverRegistryAbi, + address: riverRegistryAddress, }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationProxyDeployed"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"ConfigurationChanged"` */ -export const useWatchRewardsDistributionDelegationProxyDeployedEvent = +export const useWatchRiverRegistryConfigurationChangedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'DelegationProxyDeployed', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'ConfigurationChanged', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationRemoved"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"ConfigurationManagerAdded"` */ -export const useWatchRewardsDistributionDelegationRemovedEvent = +export const useWatchRiverRegistryConfigurationManagerAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'DelegationRemoved', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'ConfigurationManagerAdded', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"DelegationSet"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"ConfigurationManagerRemoved"` */ -export const useWatchRewardsDistributionDelegationSetEvent = +export const useWatchRiverRegistryConfigurationManagerRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'DelegationSet', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'ConfigurationManagerRemoved', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"IncreaseStake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"Initialized"` */ -export const useWatchRewardsDistributionIncreaseStakeEvent = +export const useWatchRiverRegistryInitializedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'IncreaseStake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'Initialized', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Initialized"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"InterfaceAdded"` */ -export const useWatchRewardsDistributionInitializedEvent = +export const useWatchRiverRegistryInterfaceAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'Initialized', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'InterfaceAdded', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InitiateWithdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"InterfaceRemoved"` */ -export const useWatchRewardsDistributionInitiateWithdrawEvent = +export const useWatchRiverRegistryInterfaceRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'InitiateWithdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'InterfaceRemoved', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InterfaceAdded"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"NodeAdded"` */ -export const useWatchRewardsDistributionInterfaceAddedEvent = +export const useWatchRiverRegistryNodeAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'InterfaceAdded', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'NodeAdded', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"InterfaceRemoved"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"NodeRemoved"` */ -export const useWatchRewardsDistributionInterfaceRemovedEvent = +export const useWatchRiverRegistryNodeRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'InterfaceRemoved', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'NodeRemoved', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"NotifyRewardAmount"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"NodeStatusUpdated"` */ -export const useWatchRewardsDistributionNotifyRewardAmountEvent = +export const useWatchRiverRegistryNodeStatusUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'NotifyRewardAmount', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'NodeStatusUpdated', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"OwnershipTransferred"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"NodeUrlUpdated"` */ -export const useWatchRewardsDistributionOwnershipTransferredEvent = +export const useWatchRiverRegistryNodeUrlUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'OwnershipTransferred', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'NodeUrlUpdated', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Redelegate"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"OperatorAdded"` */ -export const useWatchRewardsDistributionRedelegateEvent = +export const useWatchRiverRegistryOperatorAddedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'Redelegate', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'OperatorAdded', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"RewardNotifierSet"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"OperatorRemoved"` */ -export const useWatchRewardsDistributionRewardNotifierSetEvent = +export const useWatchRiverRegistryOperatorRemovedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'RewardNotifierSet', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'OperatorRemoved', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"RewardsDistributionInitialized"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"OwnershipTransferred"` */ -export const useWatchRewardsDistributionRewardsDistributionInitializedEvent = +export const useWatchRiverRegistryOwnershipTransferredEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'RewardsDistributionInitialized', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'OwnershipTransferred', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"SpaceRewardsSwept"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"StreamAllocated"` */ -export const useWatchRewardsDistributionSpaceRewardsSweptEvent = +export const useWatchRiverRegistryStreamAllocatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'SpaceRewardsSwept', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'StreamAllocated', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Stake"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"StreamLastMiniblockUpdateFailed"` */ -export const useWatchRewardsDistributionStakeEvent = +export const useWatchRiverRegistryStreamLastMiniblockUpdateFailedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'Stake', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'StreamLastMiniblockUpdateFailed', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Upgraded"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"StreamLastMiniblockUpdated"` */ -export const useWatchRewardsDistributionUpgradedEvent = +export const useWatchRiverRegistryStreamLastMiniblockUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'Upgraded', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'StreamLastMiniblockUpdated', }) /** - * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Withdraw"` - * - * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) - * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link riverRegistryAbi}__ and `eventName` set to `"StreamPlacementUpdated"` */ -export const useWatchRewardsDistributionWithdrawEvent = +export const useWatchRiverRegistryStreamPlacementUpdatedEvent = /*#__PURE__*/ createUseWatchContractEvent({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress, - eventName: 'Withdraw', + abi: riverRegistryAbi, + address: riverRegistryAddress, + eventName: 'StreamPlacementUpdated', }) /** diff --git a/src/data/requests.ts b/src/data/requests.ts index a72bddc..691fea2 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -3,45 +3,45 @@ import { nodeOperatorAddress, rewardsDistributionAbi, rewardsDistributionAddress, + riverRegistryAbi, + riverRegistryAddress, } from '@/contracts' +import { river, riverGamma } from '@/lib/riverChain' import { createPublicClient, formatUnits, http, isAddress, type Address } from 'viem' import { base, baseSepolia } from 'viem/chains' import { z } from 'zod' -// TODO: [HNT-6333] The main node should be decided by making a read call from the RiverRegistry in RiverChain -// instead of picking a random node from the hardcoded list. -const nodes = [ - 'https://framework-1.nodes.towns-u4.com', - 'https://framework-2.nodes.towns-u4.com', - 'https://framework-3.nodes.towns-u4.com', - 'https://haneda-1.nodes.towns-u4.com', - 'https://haneda-2.nodes.towns-u4.com', - 'https://hnt-labs-1.staking.production.figment.io', - 'https://hnt-labs-2.staking.production.figment.io', - 'https://hnt-labs-3.staking.production.figment.io', - 'https://ohare-1.staking.production.figment.io', - 'https://ohare-2.staking.production.figment.io', - 'https://ohare-3.staking.production.figment.io', -] - -const getRandomNode = (nodes: string[]) => { - return nodes[Math.floor(Math.random() * nodes.length)] +const getRandomNode = async (env: 'gamma' | 'omega') => { + const chain = env === 'gamma' ? riverGamma : river + const chainId = chain.id + const riverClient = createPublicClient({ + chain, + transport: http(), + }) + const nodes = await riverClient.readContract({ + abi: riverRegistryAbi, + address: riverRegistryAddress[chainId], + functionName: 'getAllNodes', + }) + const operationalNodes = nodes.filter((node) => node.status === 2) + const randomNode = operationalNodes[Math.floor(Math.random() * operationalNodes.length)] + return { node: randomNode, length: operationalNodes.length } } -export const getNodeData = async () => { - const maxRetries = nodes.length +export const getNodeData = async (env: 'gamma' | 'omega') => { + console.log('getting node data') let attempts = 0 let lastError let lastNode - let randomNode = getRandomNode(nodes) + let { node: randomNode, length: maxRetries } = await getRandomNode(env) while (attempts < maxRetries) { while (randomNode === lastNode) { - randomNode = getRandomNode(nodes) + randomNode = await getRandomNode(env).then(({ node }) => node) } try { - const res = await fetch(`${randomNode}/debug/multi/json`) - if (!res.ok) throw new Error(`${randomNode} failed with status: ${res.status}`) + const res = await fetch(`${randomNode.url}/debug/multi/json`) + if (!res.ok) throw new Error(`${randomNode.url} failed with status: ${res.status}`) return res.json() as Promise } catch (error) { attempts++ @@ -151,8 +151,8 @@ const operatorApr = (commissionRate: bigint, networkApr: number) => { return apr } -export const getStakeableNodes = async (env: 'omega' | 'gamma') => { - const chain = env === 'omega' ? base : baseSepolia +export const getStakeableNodes = async (env: 'gamma' | 'omega') => { + const chain = env === 'gamma' ? baseSepolia : base const chainId = chain.id const client = createPublicClient({ chain, @@ -164,12 +164,10 @@ export const getStakeableNodes = async (env: 'omega' | 'gamma') => { functionName: 'stakingState', }) const networkApy = estimatedApyOfNetwork(stakingState.rewardRate, stakingState.totalStaked) - const nodeData = await getNodeData() // TODO: getNodeData isnt getting from the correct chain if we're on gamma + const nodeData = await getNodeData(env) const operators = nodeData.nodes.map((node) => node.record.operator) - // get all operators - const uniqueOperators = Array.from(new Set(operators)) // Get unique operators + const uniqueOperators = Array.from(new Set(operators)) - // get all comission rates const comissionRates = await Promise.all( uniqueOperators.map((operator) => client.readContract({ @@ -180,8 +178,6 @@ export const getStakeableNodes = async (env: 'omega' | 'gamma') => { }), ), ) - - // Create a hashmap from unique operator address to commission rate const operatorCommissionMap = uniqueOperators.reduce>( (map, operator, index) => { map[operator] = comissionRates[index] diff --git a/src/lib/riverChain.ts b/src/lib/riverChain.ts new file mode 100644 index 0000000..ccf2b5f --- /dev/null +++ b/src/lib/riverChain.ts @@ -0,0 +1,32 @@ +import { defineChain } from 'viem' + +export const riverGamma = defineChain({ + id: 6524490, + name: 'River Gamma', + nativeCurrency: { + name: 'Ether', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://devnet.rpc.river.build'], + }, + }, + testnet: true, +}) + +export const river = defineChain({ + id: 550, + name: 'River', + nativeCurrency: { + name: 'Ether', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: { + default: { + http: ['https://mainnet.rpc.river.build'], + }, + }, +}) diff --git a/wagmi.config.ts b/wagmi.config.ts index 6ee7f5c..d0427b8 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -1,3 +1,4 @@ +import { river, riverGamma } from '@/lib/riverChain' import gamma from '@river-build/generated/deployments/gamma/base/addresses/baseRegistry.json' with { type: 'json' } import omega from '@river-build/generated/deployments/omega/base/addresses/baseRegistry.json' with { type: @@ -1565,6 +1566,1422 @@ const nodeOperatorAbi = [ }, ] as const +export const riverRegistryAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'approvedOperators', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: '__OperatorRegistry_init', + inputs: [ + { + name: 'initialOperators', + type: 'address[]', + internalType: 'address[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: '__RiverConfig_init', + inputs: [ + { + name: 'configManagers', + type: 'address[]', + internalType: 'address[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'allocateStream', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + { + name: 'genesisMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'genesisMiniblock', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'approveConfigurationManager', + inputs: [ + { + name: 'manager', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'approveOperator', + inputs: [ + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'configurationExists', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'deleteConfiguration', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'deleteConfigurationOnBlock', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'blockNumber', + type: 'uint64', + internalType: 'uint64', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAllConfiguration', + inputs: [], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct Setting[]', + components: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'blockNumber', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'value', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllNodeAddresses', + inputs: [], + outputs: [ + { + name: '', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllNodes', + inputs: [], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct Node[]', + components: [ + { + name: 'status', + type: 'uint8', + internalType: 'enum NodeStatus', + }, + { + name: 'url', + type: 'string', + internalType: 'string', + }, + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllOperators', + inputs: [], + outputs: [ + { + name: '', + type: 'address[]', + internalType: 'address[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllStreamIds', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32[]', + internalType: 'bytes32[]', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAllStreams', + inputs: [], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct StreamWithId[]', + components: [ + { + name: 'id', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'stream', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getConfiguration', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct Setting[]', + components: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'blockNumber', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'value', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getNode', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Node', + components: [ + { + name: 'status', + type: 'uint8', + internalType: 'enum NodeStatus', + }, + { + name: 'url', + type: 'string', + internalType: 'string', + }, + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getNodeCount', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getPaginatedStreams', + inputs: [ + { + name: 'start', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'stop', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct StreamWithId[]', + components: [ + { + name: 'id', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'stream', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + }, + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStream', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreamByIndex', + inputs: [ + { + name: 'i', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct StreamWithId', + components: [ + { + name: 'id', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'stream', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreamCount', + inputs: [], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreamCountOnNode', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreamWithGenesis', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: '', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreams', + inputs: [ + { + name: 'streamIds', + type: 'bytes32[]', + internalType: 'bytes32[]', + }, + ], + outputs: [ + { + name: 'foundCount', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'tuple[]', + internalType: 'struct StreamWithId[]', + components: [ + { + name: 'id', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'stream', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getStreamsOnNode', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'tuple[]', + internalType: 'struct StreamWithId[]', + components: [ + { + name: 'id', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'stream', + type: 'tuple', + internalType: 'struct Stream', + components: [ + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'reserved0', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'flags', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'nodes', + type: 'address[]', + internalType: 'address[]', + }, + ], + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isConfigurationManager', + inputs: [ + { + name: 'manager', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'isOperator', + inputs: [ + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'placeStreamOnNode', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'registerNode', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + { + name: 'url', + type: 'string', + internalType: 'string', + }, + { + name: 'status', + type: 'uint8', + internalType: 'enum NodeStatus', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeConfigurationManager', + inputs: [ + { + name: 'manager', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeNode', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeOperator', + inputs: [ + { + name: 'operator', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'removeStreamFromNode', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setConfiguration', + inputs: [ + { + name: 'key', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'blockNumber', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'value', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setStreamLastMiniblock', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'prevMiniBlockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'isSealed', + type: 'bool', + internalType: 'bool', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'setStreamLastMiniblockBatch', + inputs: [ + { + name: 'miniblocks', + type: 'tuple[]', + internalType: 'struct SetMiniblock[]', + components: [ + { + name: 'streamId', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'prevMiniBlockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + internalType: 'uint64', + }, + { + name: 'isSealed', + type: 'bool', + internalType: 'bool', + }, + ], + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updateNodeStatus', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + { + name: 'status', + type: 'uint8', + internalType: 'enum NodeStatus', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updateNodeUrl', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + internalType: 'address', + }, + { + name: 'url', + type: 'string', + internalType: 'string', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'ConfigurationChanged', + inputs: [ + { + name: 'key', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'block', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'value', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + { + name: 'deleted', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigurationManagerAdded', + inputs: [ + { + name: 'manager', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ConfigurationManagerRemoved', + inputs: [ + { + name: 'manager', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Initialized', + inputs: [ + { + name: 'version', + type: 'uint32', + indexed: false, + internalType: 'uint32', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InterfaceAdded', + inputs: [ + { + name: 'interfaceId', + type: 'bytes4', + indexed: true, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'InterfaceRemoved', + inputs: [ + { + name: 'interfaceId', + type: 'bytes4', + indexed: true, + internalType: 'bytes4', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NodeAdded', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'operator', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'url', + type: 'string', + indexed: false, + internalType: 'string', + }, + { + name: 'status', + type: 'uint8', + indexed: false, + internalType: 'enum NodeStatus', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NodeRemoved', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NodeStatusUpdated', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'status', + type: 'uint8', + indexed: false, + internalType: 'enum NodeStatus', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'NodeUrlUpdated', + inputs: [ + { + name: 'nodeAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'url', + type: 'string', + indexed: false, + internalType: 'string', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OperatorAdded', + inputs: [ + { + name: 'operatorAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OperatorRemoved', + inputs: [ + { + name: 'operatorAddress', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'previousOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'StreamAllocated', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'nodes', + type: 'address[]', + indexed: false, + internalType: 'address[]', + }, + { + name: 'genesisMiniblockHash', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'genesisMiniblock', + type: 'bytes', + indexed: false, + internalType: 'bytes', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'StreamLastMiniblockUpdateFailed', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'lastMiniblockHash', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'reason', + type: 'string', + indexed: false, + internalType: 'string', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'StreamLastMiniblockUpdated', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'lastMiniblockHash', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'lastMiniblockNum', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + { + name: 'isSealed', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'StreamPlacementUpdated', + inputs: [ + { + name: 'streamId', + type: 'bytes32', + indexed: false, + internalType: 'bytes32', + }, + { + name: 'nodeAddress', + type: 'address', + indexed: false, + internalType: 'address', + }, + { + name: 'isAdded', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'Initializable_InInitializingState', + inputs: [], + }, + { + type: 'error', + name: 'Initializable_NotInInitializingState', + inputs: [], + }, + { + type: 'error', + name: 'Introspection_AlreadySupported', + inputs: [], + }, + { + type: 'error', + name: 'Introspection_NotSupported', + inputs: [], + }, + { + type: 'error', + name: 'Ownable__NotOwner', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'Ownable__ZeroAddress', + inputs: [], + }, +] as const + const baseRiverTokenAddress = '0x91930fd11ABAa5241241d3B07c02A8d0B5ac1920' satisfies Address const baseGammaSepoliaTokenAddress = '0x24e3123E1b30E041E2df26Da9d6140c5B07Fe4F0' satisfies Address @@ -1595,6 +3012,14 @@ export default defineConfig({ }, abi: nodeOperatorAbi, }, + { + name: 'RiverRegistry', + address: { + [river.id]: '0x1298c03Fde548dc433a452573E36A713b38A0404', + [riverGamma.id]: '0xf18E98D36A6bd1aDb52F776aCc191E69B491c070', + }, + abi: riverRegistryAbi, + }, ], plugins: [ etherscan({ From 97a79f7f86ff7ff49d874973f12ad8f2aceccc9f Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 21:41:59 -0300 Subject: [PATCH 19/44] move getSsrChainId to utils --- src/app/(requires-wallet)/stake/page.tsx | 12 +++--------- src/app/utils.ts | 7 +++++++ 2 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 src/app/utils.ts diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index bf8c6cc..8d8c689 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -1,3 +1,4 @@ +import { getSsrChainId } from '@/app/utils' import { AllOperators } from '@/components/stake/all-operators' import { TotalSupplyCard } from '@/components/stake/total-supply' import { YourAccountCard } from '@/components/stake/your-account' @@ -6,21 +7,14 @@ import { SwitchToBase } from '@/components/switch-to-base' import { getStakeableNodes } from '@/data/requests' import { formatStackableNodeData } from '@/lib/hooks/use-node-data' import { cn } from '@/lib/utils' -import { wagmiAdapter } from '@/lib/wagmi' -import { headers } from 'next/headers' import { baseSepolia } from 'viem/chains' -import { cookieToInitialState } from 'wagmi' // keep in cache for 1 minute export const revalidate = 60 -const getSsrChainId = () => { - return cookieToInitialState(wagmiAdapter.wagmiConfig, headers().get('cookie'))?.chainId -} - +// Get data from SSR +// live data probably doesnt make sense here. const StakePage = async () => { - // Get data from SSR - // live data probably doesnt make sense here. const chainId = getSsrChainId() const initialData = await getStakeableNodes(chainId === baseSepolia.id ? 'gamma' : 'omega').catch( () => undefined, diff --git a/src/app/utils.ts b/src/app/utils.ts new file mode 100644 index 0000000..ffee4a2 --- /dev/null +++ b/src/app/utils.ts @@ -0,0 +1,7 @@ +import { wagmiAdapter } from '@/lib/wagmi' +import { headers } from 'next/headers' +import { cookieToInitialState } from 'wagmi' + +export const getSsrChainId = () => { + return cookieToInitialState(wagmiAdapter.wagmiConfig, headers().get('cookie'))?.chainId +} From af6e26555c8a13d0da5b67e61bc91b765c4ce13e Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 22:58:54 -0300 Subject: [PATCH 20/44] pie chart --- src/components/pie-chart.tsx | 36 +++++++++++++++++++++++++++ src/components/stake/total-supply.tsx | 29 +++++++++++++-------- 2 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 src/components/pie-chart.tsx diff --git a/src/components/pie-chart.tsx b/src/components/pie-chart.tsx new file mode 100644 index 0000000..f64e824 --- /dev/null +++ b/src/components/pie-chart.tsx @@ -0,0 +1,36 @@ +import type { SVGProps } from 'react' + +export const PieChart = ( + props: { + percentage: number + gradient: 'red' | 'blue' + } & SVGProps, +) => { + const percentage = Math.min(Math.max(props.percentage, 0), 99.99) + return ( + + + + + + + + + + + + + + + 50 ? 1 : 0} 1 + ${50 + 45 * Math.cos((percentage / 100) * 2 * Math.PI - Math.PI / 2)} + ${50 + 45 * Math.sin((percentage / 100) * 2 * Math.PI - Math.PI / 2)} + Z`} + fill={`url(#pieGradient-${props.gradient})`} + /> + + ) +} diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index 05de1e9..129daee 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,10 +1,14 @@ 'use client' +import { useReadRiverTokenTotalSupply } from '@/contracts' import { useStake } from '@/lib/hooks/use-stake' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' +import { useMemo } from 'react' import { formatUnits } from 'viem' +import { PieChart } from '../pie-chart' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { Skeleton } from '../ui/skeleton' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' +import { Typography } from '../ui/typography' export const TotalSupplyCard = ({ networkEstimatedApy, @@ -12,6 +16,11 @@ export const TotalSupplyCard = ({ networkEstimatedApy: number | undefined }) => { const { isStakingStateLoading, stakingState } = useStake() + const { data: totalSupply } = useReadRiverTokenTotalSupply() + const stakedPercentage = useMemo(() => { + if (!stakingState?.totalStaked || !totalSupply) return 0 + return Math.round((Number(stakingState.totalStaked) / Number(totalSupply)) * 100) + }, [stakingState, totalSupply]) return ( @@ -19,17 +28,15 @@ export const TotalSupplyCard = ({ Total Supply -
- {/* TODO: Add chart */} -
-
Staked
-
- {isStakingStateLoading ? ( - - ) : ( - {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR - )} -
+
+ + Staked +
+ {isStakingStateLoading ? ( + + ) : ( + {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + )}
From 08f1f52a12e41026b4c4288a62ab3a796a0494f8 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 18 Dec 2024 23:03:27 -0300 Subject: [PATCH 21/44] fix build --- src/lib/hooks/use-node-data.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/hooks/use-node-data.ts b/src/lib/hooks/use-node-data.ts index 614c31f..329396e 100644 --- a/src/lib/hooks/use-node-data.ts +++ b/src/lib/hooks/use-node-data.ts @@ -2,6 +2,8 @@ import { SECOND_MS } from '@/constants/time-ms' import { NodeStatusSchema, getNodeData, type StackableNode } from '@/data/requests' import { useQuery } from '@tanstack/react-query' import { useMemo } from 'react' +import { baseSepolia } from 'viem/chains' +import { useAccount } from 'wagmi' const colors = [ '#1DDCF2', @@ -21,9 +23,11 @@ export const useNodeData = ({ initialData, liveQuery, }: { initialData?: NodeStatusSchema; liveQuery?: boolean } = {}) => { + const { chainId } = useAccount() + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' const { data } = useQuery({ queryKey: ['nodeStatus'], - queryFn: getNodeData, + queryFn: () => getNodeData(env), refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, initialData, }) From d827c595f508938f21c5093dae993006bfd0e8c5 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 19 Dec 2024 02:43:12 -0300 Subject: [PATCH 22/44] use vercel_env instead of node_env to block networks --- src/lib/context/wallet-connect-provider.tsx | 4 ++-- src/lib/wagmi.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/context/wallet-connect-provider.tsx b/src/lib/context/wallet-connect-provider.tsx index 9d3479f..d77c658 100644 --- a/src/lib/context/wallet-connect-provider.tsx +++ b/src/lib/context/wallet-connect-provider.tsx @@ -17,8 +17,8 @@ const metadata = { createAppKit({ adapters: [wagmiAdapter], - defaultNetwork: process.env.NODE_ENV === 'production' ? base : baseSepolia, - networks: process.env.NODE_ENV === 'production' ? [base] : [base, baseSepolia], + defaultNetwork: process.env.VERCEL_ENV === 'production' ? base : baseSepolia, + networks: process.env.VERCEL_ENV === 'production' ? [base] : [base, baseSepolia], metadata: metadata, projectId, features: { diff --git a/src/lib/wagmi.ts b/src/lib/wagmi.ts index 53f3d87..7a324fe 100644 --- a/src/lib/wagmi.ts +++ b/src/lib/wagmi.ts @@ -9,7 +9,7 @@ if (!projectId) { } export const wagmiAdapter = new WagmiAdapter({ - networks: process.env.NODE_ENV === 'production' ? [base] : [base, baseSepolia], + networks: process.env.VERCEL_ENV === 'production' ? [base] : [base, baseSepolia], projectId, ssr: true, storage: createStorage({ From fa64a6fc0929a0e063a49150dd25082f0bb4cb9b Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 19 Dec 2024 02:47:28 -0300 Subject: [PATCH 23/44] force dynamic --- src/app/(requires-wallet)/stake/page.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index 8d8c689..572800e 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -9,8 +9,9 @@ import { formatStackableNodeData } from '@/lib/hooks/use-node-data' import { cn } from '@/lib/utils' import { baseSepolia } from 'viem/chains' -// keep in cache for 1 minute -export const revalidate = 60 +// TODO: add cache later +// export const revalidate = 60 +export const dynamic = 'force-dynamic' // Get data from SSR // live data probably doesnt make sense here. From 8fd6c399627e17ca39dbd0c9aa2936dff990af0a Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 19 Dec 2024 03:09:30 -0300 Subject: [PATCH 24/44] hydrate data from ssr, use live data in client --- src/app/(requires-wallet)/stake/page.tsx | 8 ++----- src/components/stake/all-operators.tsx | 28 +++++++++++++++------- src/components/stake/total-supply.tsx | 7 ++++-- src/data/requests.ts | 2 ++ src/lib/hooks/use-node-data.ts | 30 ++++++++++++++++++++++-- 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index 572800e..e195074 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -5,7 +5,6 @@ import { YourAccountCard } from '@/components/stake/your-account' import { YourRewardsCard } from '@/components/stake/your-rewards' import { SwitchToBase } from '@/components/switch-to-base' import { getStakeableNodes } from '@/data/requests' -import { formatStackableNodeData } from '@/lib/hooks/use-node-data' import { cn } from '@/lib/utils' import { baseSepolia } from 'viem/chains' @@ -13,14 +12,11 @@ import { baseSepolia } from 'viem/chains' // export const revalidate = 60 export const dynamic = 'force-dynamic' -// Get data from SSR -// live data probably doesnt make sense here. const StakePage = async () => { const chainId = getSsrChainId() const initialData = await getStakeableNodes(chainId === baseSepolia.id ? 'gamma' : 'omega').catch( () => undefined, ) - const operators = formatStackableNodeData(initialData?.nodes) return (
{
- +
- +
) diff --git a/src/components/stake/all-operators.tsx b/src/components/stake/all-operators.tsx index f9ca3fb..1700481 100644 --- a/src/components/stake/all-operators.tsx +++ b/src/components/stake/all-operators.tsx @@ -5,13 +5,22 @@ import { rewardsDistributionAddress, useReadRewardsDistributionGetDepositsByDepositor, } from '@/contracts' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import type { StakeableNodesResponse } from '@/data/requests' +import { + formatStackableNodeData, + useStakeableNodes, + type StackableNodeData, +} from '@/lib/hooks/use-node-data' import { useAccount, useReadContracts } from 'wagmi' import { Typography } from '../ui/typography' import { NodeCard } from './node-card' -export const AllOperators = ({ operators }: { operators: StackableNodeData[] }) => { - const { data: operatorsWithDeposits } = useStackableNodeData(operators) +export const AllOperators = ({ + initialData, +}: { + initialData: StakeableNodesResponse | undefined +}) => { + const { data: operatorsWithDeposits } = useOperatorsWithDeposits(initialData) return (
@@ -21,9 +30,8 @@ export const AllOperators = ({ operators }: { operators: StackableNodeData[] })
- {/* TODO: this page wont be live fetching node data - right? */} {operatorsWithDeposits.map((operator) => ( - + ))}
@@ -44,8 +52,12 @@ export type StackableNodeDataWithDeposits = StackableNodeData & { deposits?: Deposit } -const useStackableNodeData = (initialData: StackableNodeData[]) => { +const useOperatorsWithDeposits = (initialData: StakeableNodesResponse | undefined) => { const { address, isConnected, chainId } = useAccount() + const { operators: _operators } = useStakeableNodes({ + initialData, + liveQuery: true, + }) const { data: allDepositIds } = useReadRewardsDistributionGetDepositsByDepositor({ args: [address!], query: { enabled: isConnected }, @@ -79,7 +91,7 @@ const useStackableNodeData = (initialData: StackableNodeData[]) => { ) : {} - const stackableNodes = initialData.map((node) => { + const stackableNodes = _operators.map((node) => { const nodeDeposits = operators?.[node.operator] return { ...node, @@ -89,6 +101,6 @@ const useStackableNodeData = (initialData: StackableNodeData[]) => { // TODO: sort by staked & total deposit amount (?) return { - data: isConnected ? stackableNodes : initialData, + data: isConnected ? stackableNodes : formatStackableNodeData(initialData?.nodes), } } diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index 129daee..d56727c 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,5 +1,7 @@ 'use client' import { useReadRiverTokenTotalSupply } from '@/contracts' +import type { StakeableNodesResponse } from '@/data/requests' +import { useStakeableNodes } from '@/lib/hooks/use-node-data' import { useStake } from '@/lib/hooks/use-stake' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' import { useMemo } from 'react' @@ -11,12 +13,13 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' import { Typography } from '../ui/typography' export const TotalSupplyCard = ({ - networkEstimatedApy, + initialData, }: { - networkEstimatedApy: number | undefined + initialData: StakeableNodesResponse | undefined }) => { const { isStakingStateLoading, stakingState } = useStake() const { data: totalSupply } = useReadRiverTokenTotalSupply() + const { networkEstimatedApy } = useStakeableNodes({ initialData, liveQuery: true }) const stakedPercentage = useMemo(() => { if (!stakingState?.totalStaked || !totalSupply) return 0 return Math.round((Number(stakingState.totalStaked) / Number(totalSupply)) * 100) diff --git a/src/data/requests.ts b/src/data/requests.ts index 691fea2..e281b15 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -151,6 +151,8 @@ const operatorApr = (commissionRate: bigint, networkApr: number) => { return apr } +export type StakeableNodesResponse = Awaited> + export const getStakeableNodes = async (env: 'gamma' | 'omega') => { const chain = env === 'gamma' ? baseSepolia : base const chainId = chain.id diff --git a/src/lib/hooks/use-node-data.ts b/src/lib/hooks/use-node-data.ts index 329396e..9217037 100644 --- a/src/lib/hooks/use-node-data.ts +++ b/src/lib/hooks/use-node-data.ts @@ -1,5 +1,11 @@ import { SECOND_MS } from '@/constants/time-ms' -import { NodeStatusSchema, getNodeData, type StackableNode } from '@/data/requests' +import { + NodeStatusSchema, + getNodeData, + getStakeableNodes, + type StackableNode, + type StakeableNodesResponse, +} from '@/data/requests' import { useQuery } from '@tanstack/react-query' import { useMemo } from 'react' import { baseSepolia } from 'viem/chains' @@ -26,7 +32,7 @@ export const useNodeData = ({ const { chainId } = useAccount() const env = chainId === baseSepolia.id ? 'gamma' : 'omega' const { data } = useQuery({ - queryKey: ['nodeStatus'], + queryKey: ['nodeStatus', env], queryFn: () => getNodeData(env), refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, initialData, @@ -39,6 +45,26 @@ export const useNodeData = ({ return nodeConnections } +export const useStakeableNodes = ({ + initialData, + liveQuery, +}: { initialData?: StakeableNodesResponse; liveQuery?: boolean } = {}) => { + const { chainId } = useAccount() + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' + const { data } = useQuery({ + queryKey: ['stakeableNodes', env], + queryFn: () => getStakeableNodes(env), + initialData, + refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, + }) + + const operators = useMemo(() => { + return formatStackableNodeData(data?.nodes) + }, [data]) + + return { operators, networkEstimatedApy: data?.networkEstimatedApy } +} + export const formatNodeData = (data: NodeStatusSchema | undefined) => { if (!data) return [] const operators = new Set() From 85a500dca42885dbff145ae538de661ec0605399 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 6 Jan 2025 15:47:49 -0300 Subject: [PATCH 25/44] fix: commision, apr, apy values --- src/components/stake/node-card.tsx | 2 +- src/data/requests.ts | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx index eb02f6d..d4b3671 100644 --- a/src/components/stake/node-card.tsx +++ b/src/components/stake/node-card.tsx @@ -84,7 +84,7 @@ export function NodeCard({ } /> - + >['nodes'][number] const estimatedApyOfNetwork = (rewardRate: bigint, totalStaked: bigint) => { - const rewardRatePerToken = Number(formatUnits(rewardRate, 18)) - const staked = Number(formatUnits(totalStaked, 18)) - const apy = (rewardRatePerToken / staked) * 24 * 365 * 100 + const apy = (Number(rewardRate) / Number(totalStaked) / 1e36) * (365 * 24 * 60 * 60) return apy } const operatorApr = (commissionRate: bigint, networkApr: number) => { - const commInBps = Number(formatUnits(commissionRate, 3)) - const apr = networkApr * (1 - commInBps / 10000) + const commInBps = Number(commissionRate) + const apr = networkApr * (1 - commInBps / 10_000) return apr } @@ -170,7 +168,7 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { const operators = nodeData.nodes.map((node) => node.record.operator) const uniqueOperators = Array.from(new Set(operators)) - const comissionRates = await Promise.all( + const commissionRates = await Promise.all( uniqueOperators.map((operator) => client.readContract({ abi: nodeOperatorAbi, @@ -182,7 +180,7 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { ) const operatorCommissionMap = uniqueOperators.reduce>( (map, operator, index) => { - map[operator] = comissionRates[index] + map[operator] = commissionRates[index] return map }, {}, @@ -190,9 +188,9 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { return { nodes: nodeData.nodes.map((node) => { - const commissionRate = operatorCommissionMap[node.record.operator] - const estimatedApr = operatorApr(commissionRate, networkApy) - return { ...node, estimatedApr, commissionRate: formatUnits(commissionRate, 3) } + const commissionRateInBps = operatorCommissionMap[node.record.operator] + const estimatedApr = operatorApr(commissionRateInBps, networkApy) + return { ...node, estimatedApr, commissionPercentage: Number(commissionRateInBps) / 100 } }), networkEstimatedApy: networkApy, } From d6e0f2ac319527206c91c5104fec866f24ff9709 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 6 Jan 2025 16:25:01 -0300 Subject: [PATCH 26/44] add cache time to viem public client unsure why this fixes, but the data wasnt in sync (server <> client mismatch) --- src/app/(requires-wallet)/stake/page.tsx | 5 ++--- src/data/requests.ts | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index e195074..d160bcb 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -14,9 +14,8 @@ export const dynamic = 'force-dynamic' const StakePage = async () => { const chainId = getSsrChainId() - const initialData = await getStakeableNodes(chainId === baseSepolia.id ? 'gamma' : 'omega').catch( - () => undefined, - ) + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' + const initialData = await getStakeableNodes(env).catch(() => undefined) return (
{ } export const getNodeData = async (env: 'gamma' | 'omega') => { - console.log('getting node data') let attempts = 0 let lastError let lastNode @@ -156,6 +156,7 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { const chainId = chain.id const client = createPublicClient({ chain, + cacheTime: 30 * SECOND_MS, transport: http(), }) const stakingState = await client.readContract({ @@ -185,7 +186,6 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { }, {}, ) - return { nodes: nodeData.nodes.map((node) => { const commissionRateInBps = operatorCommissionMap[node.record.operator] From 86df64ac40c29bb5c1fba95b8e87c067ca0fc202 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 6 Jan 2025 18:28:29 -0300 Subject: [PATCH 27/44] chore: update river token total suppy to use mainnet value --- src/components/stake/total-supply.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index d56727c..c442b46 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,5 +1,4 @@ 'use client' -import { useReadRiverTokenTotalSupply } from '@/contracts' import type { StakeableNodesResponse } from '@/data/requests' import { useStakeableNodes } from '@/lib/hooks/use-node-data' import { useStake } from '@/lib/hooks/use-stake' @@ -12,18 +11,22 @@ import { Skeleton } from '../ui/skeleton' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' import { Typography } from '../ui/typography' +const RIVER_TOKEN_TOTAL_SUPPLY = 10000000000000000000000000000n + export const TotalSupplyCard = ({ initialData, }: { initialData: StakeableNodesResponse | undefined }) => { const { isStakingStateLoading, stakingState } = useStake() - const { data: totalSupply } = useReadRiverTokenTotalSupply() + const { networkEstimatedApy } = useStakeableNodes({ initialData, liveQuery: true }) const stakedPercentage = useMemo(() => { - if (!stakingState?.totalStaked || !totalSupply) return 0 - return Math.round((Number(stakingState.totalStaked) / Number(totalSupply)) * 100) - }, [stakingState, totalSupply]) + if (!stakingState?.totalStaked) return 0 + const totalStaked = Number(stakingState.totalStaked) + const percentage = (totalStaked / Number(RIVER_TOKEN_TOTAL_SUPPLY)) * 100 + return percentage + }, [stakingState]) return ( From f573761bdafed6ed6e2760e57807d18a7f6bff2a Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 7 Jan 2025 00:47:12 -0300 Subject: [PATCH 28/44] feat: show wallet button in header if its in `/stake` --- src/app/(requires-wallet)/layout.tsx | 20 ++------- src/app/layout.tsx | 26 ++++++++---- src/app/status/layout.tsx | 5 +-- src/components/header/index.tsx | 62 ++++++++++++++++++++++------ 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/app/(requires-wallet)/layout.tsx b/src/app/(requires-wallet)/layout.tsx index 865ea4b..3a4e75d 100644 --- a/src/app/(requires-wallet)/layout.tsx +++ b/src/app/(requires-wallet)/layout.tsx @@ -1,23 +1,11 @@ -import { wagmiAdapter } from '@/lib/wagmi' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' - import { FooterDivider } from '@/components/footer/footer-divider' -import { TanstackQueryProvider } from '@/lib/context/tanstack-query-provider' -import { WalletConnectProvider } from '@/lib/context/wallet-connect-provider' -import { headers } from 'next/headers' -import { cookieToInitialState } from 'wagmi' const WalletLayout = ({ children }: { children: React.ReactNode }) => { - const initialState = cookieToInitialState(wagmiAdapter.wagmiConfig, headers().get('cookie')) - return ( - - - {children} - - - - + <> + {children} + + ) } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9d3ae07..90aa2e7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -9,6 +9,9 @@ import { client } from '@/gql/client' import { siteDataQuery } from '@/gql/query' import { TooltipProvider } from '@/components/ui/tooltip' +import { TanstackQueryProvider } from '@/lib/context/tanstack-query-provider' +import { WalletConnectProvider } from '@/lib/context/wallet-connect-provider' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { GeistSans } from 'geist/font/sans' import { Metadata } from 'next' import localFont from 'next/font/local' @@ -63,15 +66,20 @@ export default async function RootLayout({ children }: { children: React.ReactNo - -
-
- {children} -
- - -
-
+ + + +
+
+ {children} +
+ + +
+
+
+ +
) diff --git a/src/app/status/layout.tsx b/src/app/status/layout.tsx index 9bcfc9c..3f70127 100644 --- a/src/app/status/layout.tsx +++ b/src/app/status/layout.tsx @@ -1,6 +1,5 @@ import { FooterDivider } from '@/components/footer/footer-divider' import { sharedMetadata } from '@/constants/metadata' -import { TanstackQueryProvider } from '@/lib/context/tanstack-query-provider' import { Metadata } from 'next' const metadataTitle = 'River Node Network Status' @@ -29,10 +28,10 @@ export const metadata: Metadata = { const StatusLayout = async ({ children }: { children: React.ReactNode }) => { return ( - + <> {children} - + ) } diff --git a/src/components/header/index.tsx b/src/components/header/index.tsx index a0f54b8..a5450be 100644 --- a/src/components/header/index.tsx +++ b/src/components/header/index.tsx @@ -3,9 +3,13 @@ import Logo from '@/components/icons/Logo' import { links } from '@/constants/links' import { SiteDataQuery } from '@/gql/graphql' import useWindowSize from '@/lib/hooks/use-window-size' -import { cn } from '@/lib/utils' +import { cn, formatAddress } from '@/lib/utils' import useAppStore from '@/stores/app.store' +import { useAppKit } from '@reown/appkit/react' +import { ChevronDown } from 'lucide-react' import Link from 'next/link' +import { usePathname } from 'next/navigation' +import { useAccount } from 'wagmi' import { Blog } from '../icons/Blog' import { Github } from '../icons/Github' import { Towns } from '../icons/Towns' @@ -17,6 +21,8 @@ import Developers from './developers' import Governance from './governance' import MobileDropownMenu from './mobile-dropdown-menu' +const ROUTE_WITH_WALLET_BUTTON = ['/stake'] + type HeaderProps = { cms: SiteDataQuery withNetworkStatusBanner?: boolean @@ -25,6 +31,8 @@ type HeaderProps = { export default function Header({ cms, withNetworkStatusBanner }: HeaderProps) { const { isMobile } = useWindowSize() const { isMobileMenuOpen, setIsMobileMenuOpen } = useAppStore() + const pathname = usePathname() + const isWalletButtonRoute = ROUTE_WITH_WALLET_BUTTON.includes(pathname) return (
@@ -47,18 +55,24 @@ export default function Header({ cms, withNetworkStatusBanner }: HeaderProps) {
- - - - - - - - - - - - + {isWalletButtonRoute ? ( + + ) : ( + <> + + + + + + + + + + + + + + )}
{isMobileMenuOpen &&
} {isMobile && ( @@ -74,3 +88,25 @@ export default function Header({ cms, withNetworkStatusBanner }: HeaderProps) { ) } + +const WalletButton = () => { + const { isConnected, address } = useAccount() + const { open } = useAppKit() + + return ( + + ) +} From 5de3121215372f437adb7668ce8da31651ecee7e Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 8 Jan 2025 02:15:11 -0300 Subject: [PATCH 29/44] providers component --- src/app/layout.tsx | 28 ++++++++++------------------ src/app/providers.tsx | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 src/app/providers.tsx diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 90aa2e7..3dbc8d8 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -8,13 +8,10 @@ import { sharedMetadata } from '@/constants/metadata' import { client } from '@/gql/client' import { siteDataQuery } from '@/gql/query' -import { TooltipProvider } from '@/components/ui/tooltip' -import { TanstackQueryProvider } from '@/lib/context/tanstack-query-provider' -import { WalletConnectProvider } from '@/lib/context/wallet-connect-provider' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' import { GeistSans } from 'geist/font/sans' import { Metadata } from 'next' import localFont from 'next/font/local' +import { Providers } from './providers' // Font files can be colocated inside of `pages` const menloFont = localFont({ src: '../lib/fonts/Menlo-Regular.woff', variable: '--font-menlo' }) @@ -66,20 +63,15 @@ export default async function RootLayout({ children }: { children: React.ReactNo - - - -
-
- {children} -
- - -
-
-
- -
+ +
+
+ {children} +
+ + +
+
) diff --git a/src/app/providers.tsx b/src/app/providers.tsx new file mode 100644 index 0000000..ac2a244 --- /dev/null +++ b/src/app/providers.tsx @@ -0,0 +1,19 @@ +'use client' + +import { TooltipProvider } from '@/components/ui/tooltip' +import { TanstackQueryProvider } from '@/lib/context/tanstack-query-provider' +import { WalletConnectProvider } from '@/lib/context/wallet-connect-provider' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + + {children} + + + + + ) +} From ef67453169e8e4823389ac9ce18d2e1cfc188479 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 8 Jan 2025 02:30:50 -0300 Subject: [PATCH 30/44] better naming about NodeData --- src/app/status/node-status.tsx | 8 +- src/app/status/page.tsx | 4 +- src/components/status/gradient-ring.tsx | 20 ++-- .../status/node-animation-scene.tsx | 10 +- src/components/status/node-status-pill.tsx | 6 +- src/components/status/node-tooltips.tsx | 50 ++++---- src/data/requests.ts | 12 +- src/lib/hooks/use-node-data.ts | 112 ------------------ src/lib/hooks/use-river-nodes.ts | 61 ++++++++++ 9 files changed, 117 insertions(+), 166 deletions(-) delete mode 100644 src/lib/hooks/use-node-data.ts create mode 100644 src/lib/hooks/use-river-nodes.ts diff --git a/src/app/status/node-status.tsx b/src/app/status/node-status.tsx index 871482a..a477244 100644 --- a/src/app/status/node-status.tsx +++ b/src/app/status/node-status.tsx @@ -1,11 +1,11 @@ 'use client' import { NodeStatusPill } from '@/components/status/node-status-pill' -import { NodeStatusSchema } from '@/data/requests' -import { useNodeData } from '@/lib/hooks/use-node-data' +import type { NodeData } from '@/data/requests' +import { useRiverNodes } from '@/lib/hooks/use-river-nodes' -export const NodeStatus = ({ initialData }: { initialData?: NodeStatusSchema }) => { - const nodes = useNodeData({ initialData, liveQuery: true }) +export const NodeStatus = ({ initialData }: { initialData?: NodeData[] }) => { + const nodes = useRiverNodes({ initialData, liveQuery: true }) return ( <> {nodes.map((node) => ( diff --git a/src/app/status/page.tsx b/src/app/status/page.tsx index 989883a..7f52fe1 100644 --- a/src/app/status/page.tsx +++ b/src/app/status/page.tsx @@ -1,5 +1,5 @@ import { Typography } from '@/components/ui/typography' -import { getNodeData } from '@/data/requests' +import { getRiverNodes } from '@/data/requests' import { Loader2 } from 'lucide-react' import loadDynamic from 'next/dynamic' import { NodeStatus } from './node-status' @@ -19,7 +19,7 @@ const NodeAnimation = loadDynamic( ) const StatusPage = async () => { - const initialData = await getNodeData('omega').catch(() => undefined) + const initialData = await getRiverNodes('omega').catch(() => undefined) return (
diff --git a/src/components/status/gradient-ring.tsx b/src/components/status/gradient-ring.tsx index 1b445b0..1155224 100644 --- a/src/components/status/gradient-ring.tsx +++ b/src/components/status/gradient-ring.tsx @@ -1,4 +1,4 @@ -import { NodeData } from '@/lib/hooks/use-node-data' +import { NodeDataWithStatus } from '@/lib/hooks/use-river-nodes' import { Billboard, Line, LineProps, RoundedBox } from '@react-three/drei' import { Object3DProps, useFrame } from '@react-three/fiber' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' @@ -6,11 +6,11 @@ import { Color, Object3D, Vector3 } from 'three' import { Line2, LineSegments2 } from 'three-stdlib' type Props = { - nodes: NodeData[] + nodes: NodeDataWithStatus[] radius: number animating: boolean - onNodeHover: (node: NodeData | null) => void - connectedNode?: NodeData + onNodeHover: (node: NodeDataWithStatus | null) => void + connectedNode?: NodeDataWithStatus } & Object3DProps type NodeRef = { @@ -166,17 +166,17 @@ export const GradientRing = (props: Props) => { updateAnimation() }, [updateAnimation]) - const [hoveredNode, setHoveredNode] = useState(null) + const [hoveredNode, setHoveredNode] = useState(null) useEffect(() => { props.onNodeHover(hoveredNode) }, [hoveredNode, props]) - const onNodeHover = useCallback((node: NodeData) => { + const onNodeHover = useCallback((node: NodeDataWithStatus) => { setHoveredNode(node) }, []) - const onNodeLeave = useCallback((node: NodeData) => { + const onNodeLeave = useCallback((node: NodeDataWithStatus) => { setHoveredNode((n) => (n === node ? null : n)) }, []) @@ -205,10 +205,10 @@ export const GradientRing = (props: Props) => { } const CircleNode = (props: { - node: NodeData + node: NodeDataWithStatus nodePosition: NodeRef - onHover: (node: NodeData) => void - onLeave: (node: NodeData) => void + onHover: (node: NodeDataWithStatus) => void + onLeave: (node: NodeDataWithStatus) => void selected?: boolean }) => { const { node, nodePosition } = props diff --git a/src/components/status/node-animation-scene.tsx b/src/components/status/node-animation-scene.tsx index 647bcb6..b1e5ceb 100644 --- a/src/components/status/node-animation-scene.tsx +++ b/src/components/status/node-animation-scene.tsx @@ -1,7 +1,7 @@ 'use client' import { useGlobeTexture } from '@/lib/hooks/use-globe-texture' -import { NodeData, useNodeData } from '@/lib/hooks/use-node-data' +import { NodeDataWithStatus, useRiverNodes } from '@/lib/hooks/use-river-nodes' import { createNoise } from '@/lib/utils' import { animated, useSpring } from '@react-spring/three' import { PerspectiveCamera } from '@react-three/drei' @@ -22,9 +22,9 @@ export const NodeAnimationScene = () => { const containerRef = useRef(null) - const [hoveredNode, setHoveredNode] = useState(null) + const [hoveredNode, setHoveredNode] = useState(null) - const onNodeHover = useCallback((node: NodeData | null) => { + const onNodeHover = useCallback((node: NodeDataWithStatus | null) => { setHoveredNode(node) }, []) @@ -50,14 +50,14 @@ export const NodeAnimationScene = () => { const GlobeScene = (props: { noise: ReturnType mapSize: [number, number] - onNodeHover: (node: NodeData | null) => void + onNodeHover: (node: NodeDataWithStatus | null) => void onHover: (hovered: boolean) => void }) => { const { mapSize, noise } = props const { canvas, relevantPoints } = useGlobeTexture(noise, mapSize) const globeRef = useRef(null) - const nodeConnections = useNodeData({ liveQuery: true }) + const nodeConnections = useRiverNodes({ liveQuery: true }) const nodes = useMemo(() => { return nodeConnections.map((n, index) => ({ diff --git a/src/components/status/node-status-pill.tsx b/src/components/status/node-status-pill.tsx index dca80ba..4469ef4 100644 --- a/src/components/status/node-status-pill.tsx +++ b/src/components/status/node-status-pill.tsx @@ -1,4 +1,4 @@ -import { NodeData } from '@/lib/hooks/use-node-data' +import { NodeDataWithStatus } from '@/lib/hooks/use-river-nodes' import { cn, formatUptime, formatUrl } from '@/lib/utils' import { Circle } from 'lucide-react' import { useMemo } from 'react' @@ -15,7 +15,7 @@ type Status = { className: string } -const getResponseStatus = (nodeData: NodeData) => { +const getResponseStatus = (nodeData: NodeDataWithStatus) => { if (nodeData.status !== 2) { return undefined } @@ -84,7 +84,7 @@ const NodeStatus: Status[] = [ }, ] -export const NodeStatusPill = ({ nodeData }: { nodeData: NodeData }) => { +export const NodeStatusPill = ({ nodeData }: { nodeData: NodeDataWithStatus }) => { const nodeStatusFromContract = NodeStatus[nodeData.data.record.status] const responseStatus = getResponseStatus(nodeData) // if node is operational, but has a non-OK response, it's down diff --git a/src/components/status/node-tooltips.tsx b/src/components/status/node-tooltips.tsx index f9b84f3..7d96658 100644 --- a/src/components/status/node-tooltips.tsx +++ b/src/components/status/node-tooltips.tsx @@ -1,10 +1,10 @@ -import { NodeData } from '@/lib/hooks/use-node-data' +import { NodeDataWithStatus } from '@/lib/hooks/use-river-nodes' import { formatUptime, formatUrl } from '@/lib/utils' import { AnimatePresence, motion } from 'framer-motion' import React, { forwardRef, useEffect, useRef } from 'react' type Props = { - hoveredNode: NodeData | null + hoveredNode: NodeDataWithStatus | null containerRef: React.RefObject } @@ -50,27 +50,29 @@ export const NodeTooltips = (props: Props) => { ) } -const NodeTooltip = forwardRef(({ nodeData }, ref) => { - // TODO: Move colors to tailwind config - return ( -
- - {formatUrl(nodeData.nodeUrl)} - - - Health - {nodeData.data.grpc.elapsed} gRPC - {nodeData.data.http20.elapsed} HTTP/2 - - - Uptime{' '} - {formatUptime(new Date(nodeData.data.grpc.start_time))} - -
- ) -}) +const NodeTooltip = forwardRef( + ({ nodeData }, ref) => { + // TODO: Move colors to tailwind config + return ( +
+ + {formatUrl(nodeData.nodeUrl)} + + + Health + {nodeData.data.grpc.elapsed} gRPC + {nodeData.data.http20.elapsed} HTTP/2 + + + Uptime{' '} + {formatUptime(new Date(nodeData.data.grpc.start_time))} + +
+ ) + }, +) NodeTooltip.displayName = 'NodeTooltips' diff --git a/src/data/requests.ts b/src/data/requests.ts index 5dae3f6..99b7e71 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -29,7 +29,7 @@ const getRandomNode = async (env: 'gamma' | 'omega') => { return { node: randomNode, length: operationalNodes.length } } -export const getNodeData = async (env: 'gamma' | 'omega') => { +export const getRiverNodes = async (env: 'gamma' | 'omega') => { let attempts = 0 let lastError let lastNode @@ -42,7 +42,8 @@ export const getNodeData = async (env: 'gamma' | 'omega') => { try { const res = await fetch(`${randomNode.url}/debug/multi/json`) if (!res.ok) throw new Error(`${randomNode.url} failed with status: ${res.status}`) - return res.json() as Promise + const data = (await res.json()) as NodeStatusSchema + return data.nodes } catch (error) { attempts++ lastError = error @@ -59,7 +60,7 @@ export const getNodeData = async (env: 'gamma' | 'omega') => { const zodAddress = z.string().refine(isAddress) export type NodeStatusSchema = z.infer -export type NodeData = Awaited>['nodes'][number] +export type NodeData = Awaited>[number] export const nodeStatusSchema = z.object({ nodes: z.array( @@ -165,9 +166,8 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { functionName: 'stakingState', }) const networkApy = estimatedApyOfNetwork(stakingState.rewardRate, stakingState.totalStaked) - const nodeData = await getNodeData(env) - const operators = nodeData.nodes.map((node) => node.record.operator) - const uniqueOperators = Array.from(new Set(operators)) + const nodes = await getRiverNodes(env) + const uniqueOperators = Array.from(new Set(nodes.map((node) => node.record.operator))) const commissionRates = await Promise.all( uniqueOperators.map((operator) => diff --git a/src/lib/hooks/use-node-data.ts b/src/lib/hooks/use-node-data.ts deleted file mode 100644 index 9217037..0000000 --- a/src/lib/hooks/use-node-data.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { SECOND_MS } from '@/constants/time-ms' -import { - NodeStatusSchema, - getNodeData, - getStakeableNodes, - type StackableNode, - type StakeableNodesResponse, -} from '@/data/requests' -import { useQuery } from '@tanstack/react-query' -import { useMemo } from 'react' -import { baseSepolia } from 'viem/chains' -import { useAccount } from 'wagmi' - -const colors = [ - '#1DDCF2', - '#AFDD79', - '#FED83D', - '#C740F2', - '#9558FA', - '#FEA56F', - '#FF60B2', - '#FEA56F', - '#DBDE54', -] - -export type NodeData = ReturnType[0] - -export const useNodeData = ({ - initialData, - liveQuery, -}: { initialData?: NodeStatusSchema; liveQuery?: boolean } = {}) => { - const { chainId } = useAccount() - const env = chainId === baseSepolia.id ? 'gamma' : 'omega' - const { data } = useQuery({ - queryKey: ['nodeStatus', env], - queryFn: () => getNodeData(env), - refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, - initialData, - }) - - const nodeConnections = useMemo(() => { - return formatNodeData(data) - }, [data]) - - return nodeConnections -} - -export const useStakeableNodes = ({ - initialData, - liveQuery, -}: { initialData?: StakeableNodesResponse; liveQuery?: boolean } = {}) => { - const { chainId } = useAccount() - const env = chainId === baseSepolia.id ? 'gamma' : 'omega' - const { data } = useQuery({ - queryKey: ['stakeableNodes', env], - queryFn: () => getStakeableNodes(env), - initialData, - refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, - }) - - const operators = useMemo(() => { - return formatStackableNodeData(data?.nodes) - }, [data]) - - return { operators, networkEstimatedApy: data?.networkEstimatedApy } -} - -export const formatNodeData = (data: NodeStatusSchema | undefined) => { - if (!data) return [] - const operators = new Set() - return data.nodes.map((n, i) => { - operators.add(n.record.operator) - const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) - return { - id: n.record.url, - index: i, - nodeUrl: n.record.url, - statusText: n.record.status_text, - status: n.record.status, - operator: n.record.operator, - operatorIndex, - data: n, - color: colors[Math.floor((i * colors.length) / data.nodes.length) % colors.length], - operatorColor: colors[(3 + operatorIndex) % colors.length], - // TODO: add user stacked amount - use it to sort in the UI - } - }) -} - -export type StackableNodeData = ReturnType[number] - -export const formatStackableNodeData = (data: StackableNode[] | undefined) => { - if (!data) return [] - const operators = new Set() - return data.map((n, i) => { - operators.add(n.record.operator) - const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) - return { - id: n.record.url, - index: i, - nodeUrl: n.record.url, - statusText: n.record.status_text, - status: n.record.status, - operator: n.record.operator, - operatorIndex, - data: n, - color: colors[Math.floor((i * colors.length) / data.length) % colors.length], - operatorColor: colors[(3 + operatorIndex) % colors.length], - // TODO: add user stacked amount - use it to sort in the UI - } - }) -} diff --git a/src/lib/hooks/use-river-nodes.ts b/src/lib/hooks/use-river-nodes.ts new file mode 100644 index 0000000..9431446 --- /dev/null +++ b/src/lib/hooks/use-river-nodes.ts @@ -0,0 +1,61 @@ +import { SECOND_MS } from '@/constants/time-ms' +import { NodeData as RawNodeData, getRiverNodes } from '@/data/requests' +import { useQuery } from '@tanstack/react-query' +import { useMemo } from 'react' +import { baseSepolia } from 'viem/chains' +import { useAccount } from 'wagmi' + +const colors = [ + '#1DDCF2', + '#AFDD79', + '#FED83D', + '#C740F2', + '#9558FA', + '#FEA56F', + '#FF60B2', + '#FEA56F', + '#DBDE54', +] + +export type NodeDataWithStatus = ReturnType[0] + +export const useRiverNodes = ({ + initialData, + liveQuery, +}: { initialData?: RawNodeData[]; liveQuery?: boolean } = {}) => { + const { chainId } = useAccount() + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' + const { data } = useQuery({ + queryKey: ['nodeStatus', env], + queryFn: () => getRiverNodes(env), + refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, + initialData: initialData, + }) + + const nodeConnections = useMemo(() => { + return formatNodeData(data) + }, [data]) + + return nodeConnections +} + +export const formatNodeData = (nodes: RawNodeData[] | undefined) => { + if (!nodes) return [] + const operators = new Set() + return nodes.map((n, i) => { + operators.add(n.record.operator) + const operatorIndex = Array.from(operators.values()).indexOf(n.record.operator) + return { + id: n.record.url, + index: i, + nodeUrl: n.record.url, + statusText: n.record.status_text, + status: n.record.status, + operator: n.record.operator, + operatorIndex, + data: n, + color: colors[Math.floor((i * colors.length) / nodes.length) % colors.length], + operatorColor: colors[(3 + operatorIndex) % colors.length], + } + }) +} From f9afb062685c17296dab8335bacbf0c89430d90e Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Wed, 8 Jan 2025 22:46:12 -0300 Subject: [PATCH 31/44] UI to stake to operators, not individual nodes --- src/app/(requires-wallet)/stake/page.tsx | 4 +- src/components/delegate/delegate-section.tsx | 35 +- src/components/delegate/redelegate-button.tsx | 14 +- src/components/delegate/redelegate-dialog.tsx | 39 +- src/components/stake/all-operators.tsx | 97 +- src/components/stake/increase-stake.tsx | 59 +- src/components/stake/initiate-withdraw.tsx | 81 +- src/components/stake/node-card.tsx | 210 --- src/components/stake/operator-card.tsx | 318 +++++ src/components/stake/redelegate.tsx | 89 +- src/components/stake/stake-to-operator.tsx | 41 +- src/components/stake/total-supply.tsx | 13 +- src/components/stake/withdraw.tsx | 36 +- src/components/stake/your-account.tsx | 8 +- src/components/wallet-info.tsx | 14 +- src/constants/fake.ts | 1137 +++++++++++++++++ src/constants/hostname-to-operator.ts | 10 + src/data/requests.ts | 91 +- src/lib/hooks/use-increase-stake.ts | 9 +- src/lib/hooks/use-initiate-withdraw.ts | 8 +- src/lib/hooks/use-river-nodes.ts | 4 +- src/lib/hooks/use-stake.ts | 7 +- src/lib/hooks/use-stakeable-operators.ts | 104 ++ src/lib/hooks/use-withdraw.ts | 8 +- 24 files changed, 1948 insertions(+), 488 deletions(-) delete mode 100644 src/components/stake/node-card.tsx create mode 100644 src/components/stake/operator-card.tsx create mode 100644 src/constants/fake.ts create mode 100644 src/constants/hostname-to-operator.ts create mode 100644 src/lib/hooks/use-stakeable-operators.ts diff --git a/src/app/(requires-wallet)/stake/page.tsx b/src/app/(requires-wallet)/stake/page.tsx index d160bcb..477534f 100644 --- a/src/app/(requires-wallet)/stake/page.tsx +++ b/src/app/(requires-wallet)/stake/page.tsx @@ -4,7 +4,7 @@ import { TotalSupplyCard } from '@/components/stake/total-supply' import { YourAccountCard } from '@/components/stake/your-account' import { YourRewardsCard } from '@/components/stake/your-rewards' import { SwitchToBase } from '@/components/switch-to-base' -import { getStakeableNodes } from '@/data/requests' +import { getStakeableOperators } from '@/data/requests' import { cn } from '@/lib/utils' import { baseSepolia } from 'viem/chains' @@ -15,7 +15,7 @@ export const dynamic = 'force-dynamic' const StakePage = async () => { const chainId = getSsrChainId() const env = chainId === baseSepolia.id ? 'gamma' : 'omega' - const initialData = await getStakeableNodes(env).catch(() => undefined) + const initialData = await getStakeableOperators(env).catch(() => undefined) return (
({ - id: BigInt(i), - delegatee: ('0x' + i.toString(16).padStart(40, '0')) as Address, -})) satisfies { id: bigint; delegatee: Address }[] - -const fakeSingleDeposit = [ - { - id: 1n, - delegatee: '0x1234567890' as Address, - }, -] +// const fakeDeposits = FAKE_OPERATORS.map((operator) => ({ +// id: 1n, +// delegatee: operator.address, +// })) satisfies { id: bigint; delegatee: Address }[] export const DelegateSection = () => { const { deposits } = useRedelegate() + const router = useRouter() + const searchParams = useSearchParams() + + const handleOpenChange = (open: boolean) => { + const params = new URLSearchParams(searchParams) + if (open) { + params.set('redelegate', 'true') + } else { + params.delete('redelegate') + } + router.replace(`/delegate?${params.toString()}`) + } + + const open = searchParams.get('redelegate') === 'true' + return (
{ depositId={deposits[0].id} delegatedAddress={deposits[0].delegatee} variant="secondary" - showAddress /> ) : ( - + diff --git a/src/components/delegate/redelegate-button.tsx b/src/components/delegate/redelegate-button.tsx index 44cf6ac..8afc013 100644 --- a/src/components/delegate/redelegate-button.tsx +++ b/src/components/delegate/redelegate-button.tsx @@ -1,7 +1,8 @@ import { useRedelegate } from '@/lib/hooks/use-redelegate' +import { useOperatorsWithDeposits } from '@/lib/hooks/use-stakeable-operators' import { formatAddress } from '@/lib/utils' import { Check } from 'lucide-react' -import { useEffect } from 'react' +import { useEffect, useMemo } from 'react' import type { Address } from 'viem' import { Button } from '../ui/button' import { useToast } from '../ui/use-toast' @@ -10,19 +11,22 @@ export const RedelegateButton = ({ depositId, delegatedAddress, variant = 'primary', - showAddress, className, onRedelegateFinish, }: { depositId: bigint delegatedAddress: Address | undefined variant?: 'primary' | 'secondary' - showAddress?: boolean className?: string onRedelegateFinish?: () => void }) => { const { toast } = useToast() const { isTxConfirmed, isPending, isTxPending, writeRedelegate } = useRedelegate() + const { data: operators } = useOperatorsWithDeposits() + const lookup = useMemo( + () => Object.fromEntries(operators.map((operator) => [operator.address, operator])), + [operators], + ) useEffect(() => { if (isTxConfirmed && delegatedAddress) { @@ -50,8 +54,8 @@ export const RedelegateButton = ({ ? 'Redelegated' : isPending || isTxPending ? 'Redelegating...' - : showAddress && !!delegatedAddress - ? `Redelegate to ${formatAddress(delegatedAddress)}` + : delegatedAddress && lookup[delegatedAddress]?.name + ? `Redelegate to ${lookup[delegatedAddress].name}` : 'Redelegate'} ) diff --git a/src/components/delegate/redelegate-dialog.tsx b/src/components/delegate/redelegate-dialog.tsx index 2e2daa0..3553c46 100644 --- a/src/components/delegate/redelegate-dialog.tsx +++ b/src/components/delegate/redelegate-dialog.tsx @@ -1,5 +1,8 @@ -import { formatAddress } from '@/lib/utils' +import type { StackableOperator } from '@/data/requests' +import { useOperatorsWithDeposits } from '@/lib/hooks/use-stakeable-operators' +import { useMemo } from 'react' import type { Address } from 'viem' +import { OperatorCard } from '../stake/operator-card' import { DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../ui/dialog' import { RedelegateButton } from './redelegate-button' @@ -8,24 +11,36 @@ export const RedelegateDialogContent = ({ }: { deposits: { id: bigint; delegatee: Address }[] }) => { + const { data: operators } = useOperatorsWithDeposits() + const operatorsWithDeposits: Record = useMemo(() => { + // const withDeposits = FAKE_OPERATORS + const withDeposits = operators.filter((operator) => 'deposits' in operator) + + const fromOperatorAddress = Object.fromEntries( + withDeposits.map((operator) => [operator.address, operator]), + ) + return fromOperatorAddress + }, [operators]) + return ( Redelegate - Select the address you want to redelegate to. + Select the operator you want to redelegate to.
{deposits.map((deposit) => ( -
- - {formatAddress(deposit.delegatee)} - - -
+ + } + /> ))}
diff --git a/src/components/stake/all-operators.tsx b/src/components/stake/all-operators.tsx index 1700481..5d94b03 100644 --- a/src/components/stake/all-operators.tsx +++ b/src/components/stake/all-operators.tsx @@ -1,26 +1,20 @@ 'use client' +import type { StakeableOperatorsResponse } from '@/data/requests' import { - rewardsDistributionAbi, - rewardsDistributionAddress, - useReadRewardsDistributionGetDepositsByDepositor, -} from '@/contracts' -import type { StakeableNodesResponse } from '@/data/requests' -import { - formatStackableNodeData, - useStakeableNodes, - type StackableNodeData, -} from '@/lib/hooks/use-node-data' -import { useAccount, useReadContracts } from 'wagmi' + useOperatorsWithDeposits, + type OperatorWithDeposits, +} from '@/lib/hooks/use-stakeable-operators' import { Typography } from '../ui/typography' -import { NodeCard } from './node-card' +import { OperatorCard } from './operator-card' export const AllOperators = ({ initialData, }: { - initialData: StakeableNodesResponse | undefined + initialData: StakeableOperatorsResponse | undefined }) => { const { data: operatorsWithDeposits } = useOperatorsWithDeposits(initialData) + return (
@@ -30,77 +24,16 @@ export const AllOperators = ({
- {operatorsWithDeposits.map((operator) => ( - + {operatorsWithDeposits.map((operator: OperatorWithDeposits) => ( + ))}
) } - -type Deposit = { - depositId: bigint - amount: bigint - owner: `0x${string}` - commissionEarningPower: bigint - delegatee: `0x${string}` - pendingWithdrawal: bigint - beneficiary: `0x${string}` -} - -export type StackableNodeDataWithDeposits = StackableNodeData & { - deposits?: Deposit -} - -const useOperatorsWithDeposits = (initialData: StakeableNodesResponse | undefined) => { - const { address, isConnected, chainId } = useAccount() - const { operators: _operators } = useStakeableNodes({ - initialData, - liveQuery: true, - }) - const { data: allDepositIds } = useReadRewardsDistributionGetDepositsByDepositor({ - args: [address!], - query: { enabled: isConnected }, - }) - - const depositsQueries = useReadContracts({ - contracts: (allDepositIds || []).map( - (id) => - ({ - abi: rewardsDistributionAbi, - address: rewardsDistributionAddress[chainId as keyof typeof rewardsDistributionAddress], - functionName: 'depositById', - args: [id], - }) as const, - ), - query: { enabled: isConnected && !!allDepositIds }, - }) - - const deposits = depositsQueries.data - ?.flatMap((query) => query.result) - .filter((deposit): deposit is NonNullable => deposit !== undefined) - - const operators = allDepositIds - ? Object.fromEntries( - (deposits ?? []) - .filter((deposit): deposit is NonNullable => deposit !== undefined) - .map((deposit, idx) => [ - deposit.delegatee, - { ...deposit, depositId: allDepositIds[idx] }, - ]), - ) - : {} - - const stackableNodes = _operators.map((node) => { - const nodeDeposits = operators?.[node.operator] - return { - ...node, - deposits: nodeDeposits, - } - }) - // TODO: sort by staked & total deposit amount (?) - - return { - data: isConnected ? stackableNodes : formatStackableNodeData(initialData?.nodes), - } -} diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx index 1f912cb..d51f8db 100644 --- a/src/components/stake/increase-stake.tsx +++ b/src/components/stake/increase-stake.tsx @@ -9,9 +9,9 @@ import { FormMessage, } from '@/components/ui/form' import { Input } from '@/components/ui/input' -import { useReadRiverTokenBalanceOf } from '@/contracts' +import { useReadRewardsDistributionDepositById, useReadRiverTokenBalanceOf } from '@/contracts' +import type { StackableOperator } from '@/data/requests' import { useIncreaseStake } from '@/lib/hooks/use-increase-stake' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' import { zodResolver } from '@hookform/resolvers/zod' import type { DialogContentProps } from '@radix-ui/react-dialog' import { useCallback, useEffect, useMemo } from 'react' @@ -23,15 +23,19 @@ import { MaxButton } from '../max-button' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' -import { NodeCard } from './node-card' +import { OperatorCard } from './operator-card' type IncreaseStakeFormProps = { - node: StackableNodeData - depositId: bigint // TODO: how should we archicture around this? - onStakeFinish?: (amount: number) => void + operator: StackableOperator + depositId: bigint + onIncreaseStakeFinish?: (amount: number) => void } -export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseStakeFormProps) { +export function IncreaseStakeForm({ + operator, + depositId, + onIncreaseStakeFinish, +}: IncreaseStakeFormProps) { const { address } = useAccount() const { data: balance } = useReadRiverTokenBalanceOf({ args: [address!], @@ -60,22 +64,21 @@ export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseSt }, }) - const { - isCurrentDepositLoading, - currentDeposit, - increaseStake, - isPending, - isTxPending, - isTxConfirmed, - } = useIncreaseStake(depositId) + const { data: currentDeposit, isPending: isCurrentDepositPending } = + useReadRewardsDistributionDepositById({ + args: [depositId], + query: { enabled: !!address }, + }) + + const { increaseStake, isPending, isTxPending, isTxConfirmed } = useIncreaseStake(depositId) const isStaking = isPending || isTxPending useEffect(() => { if (isTxConfirmed) { - onStakeFinish?.(form.getValues('amount')) + onIncreaseStakeFinish?.(form.getValues('amount')) form.reset() } - }, [isTxConfirmed, onStakeFinish, form]) + }, [isTxConfirmed, onIncreaseStakeFinish, form]) const handleSetMax = useCallback(() => { form.setValue('amount', Number(avaliableBalance)) @@ -92,19 +95,19 @@ export function IncreaseStakeForm({ node, depositId, onStakeFinish }: IncreaseSt className="space-y-6 py-4" >
+ Stake to: + +
+
Currently Staked: - {isCurrentDepositLoading ? ( + {isCurrentDepositPending ? ( ) : ( - + {formatUnits(currentDeposit?.amount ?? 0n, 18)} RVR )}
-
- Stake to: - -
{ return ( @@ -150,7 +153,11 @@ export const IncreaseStakeDialogContent = ({ Increase Stake - + ) } diff --git a/src/components/stake/initiate-withdraw.tsx b/src/components/stake/initiate-withdraw.tsx index b3168ae..8ec46d6 100644 --- a/src/components/stake/initiate-withdraw.tsx +++ b/src/components/stake/initiate-withdraw.tsx @@ -1,57 +1,76 @@ 'use client' import { Button } from '@/components/ui/button' -import { useReadRiverTokenBalanceOf } from '@/contracts' +import { useReadRewardsDistributionDepositById } from '@/contracts' +import type { StackableOperator } from '@/data/requests' import { useInitiateWithdraw } from '@/lib/hooks/use-initiate-withdraw' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' -import { useStake } from '@/lib/hooks/use-stake' import type { DialogContentProps } from '@radix-ui/react-dialog' +import { useEffect } from 'react' import { formatUnits } from 'viem' import { useAccount } from 'wagmi' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' +import { Label } from '../ui/label' import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' -import { NodeCard } from './node-card' +import { OperatorCard } from './operator-card' type InitiateWithdrawFormProps = { - node: StackableNodeData - depositId: bigint // TODO: how should we archicture around this? - onStakeFinish?: (amount: number) => void + operator: StackableOperator + depositId: bigint + onInitiateWithdrawFinish?: () => void } -export function InitiateWithdrawForm({ node }: InitiateWithdrawFormProps) { +export function InitiateWithdrawForm({ + operator, + depositId, + onInitiateWithdrawFinish, +}: InitiateWithdrawFormProps) { const { address } = useAccount() - const { data: balance } = useReadRiverTokenBalanceOf({ - args: [address!], - query: { enabled: !!address }, - }) - const avaliableBalance = balance || 0n - const { isStakingStateLoading, stakingState } = useStake() + const { data: currentDeposit, isPending: isCurrentDepositPending } = + useReadRewardsDistributionDepositById({ + args: [depositId], + query: { enabled: !!address }, + }) + const { initiateWithdraw, isPending, isTxPending, isTxConfirmed } = useInitiateWithdraw() const isWithdrawing = isPending || isTxPending + useEffect(() => { + if (isTxConfirmed) { + onInitiateWithdrawFinish?.() + } + }, [isTxConfirmed, onInitiateWithdrawFinish]) + return (
- Currently Staked: - {isStakingStateLoading ? ( + Currently delegated to: + +
+ +
+ + {isCurrentDepositPending ? ( ) : ( - - {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + + {formatUnits(currentDeposit?.amount ?? 0n, 18)} RVR )}
-
- Currently delegated to: - -
- - Initiating withdraw will take 3 days lock up period, after which you can withdraw the tokens - to your wallet. + + You must do a full withdraw. Initiating withdraw will require a 30 days lock up period, + after which you can withdraw the tokens to your wallet. You will not be earning rewards + during the lock up period. -
@@ -59,9 +78,9 @@ export function InitiateWithdrawForm({ node }: InitiateWithdrawFormProps) { } export const InitiateWithdrawDialogContent = ({ - node, + operator, depositId, - onStakeFinish, + onInitiateWithdrawFinish, ...rest }: InitiateWithdrawFormProps & DialogContentProps) => { return ( @@ -69,7 +88,11 @@ export const InitiateWithdrawDialogContent = ({ Initiate Withdraw - + ) } diff --git a/src/components/stake/node-card.tsx b/src/components/stake/node-card.tsx deleted file mode 100644 index d4b3671..0000000 --- a/src/components/stake/node-card.tsx +++ /dev/null @@ -1,210 +0,0 @@ -'use client' - -import { Button } from '@/components/ui/button' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' -import { useWithdraw } from '@/lib/hooks/use-withdraw' -import { useWithdrawTimer } from '@/lib/hooks/use-withdraw-timer' -import { cn, formatUptime } from '@/lib/utils' -import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' -import { ArrowRightLeftIcon, EllipsisVertical, LogOutIcon } from 'lucide-react' -import { useMemo, useState } from 'react' -import { Dialog, DialogTrigger } from '../ui/dialog' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '../ui/dropdown-menu' -import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' -import { Typography } from '../ui/typography' -import type { StackableNodeDataWithDeposits } from './all-operators' -import { IncreaseStakeDialogContent } from './increase-stake' -import { RedelegateDialog, RedelegateDialogContent, RedelegateProvider } from './redelegate' -import { StakeDialogContent } from './stake-to-operator' -import { WithdrawDialogContent } from './withdraw' - -export interface NodeCardProps { - node: StackableNodeDataWithDeposits - allNodes?: StackableNodeData[] - className?: string - showButton?: boolean - onSelect?: () => void - ringColor?: string -} - -type Status = 'stakeable' | 'staked' | 'locked' | 'can-withdraw' - -export function NodeCard({ - node, - className, - showButton, - allNodes, - onSelect, - ringColor, -}: NodeCardProps) { - const name = new URL(node.data.record.url).hostname - const { lockCooldown } = useWithdraw(node.deposits?.depositId) - const withdrawTimer = useWithdrawTimer(lockCooldown) - - const [openRedelegate, setOpenRedelegate] = useState(false) - const [openWithdraw, setOpenWithdraw] = useState(false) - - const status = useMemo(() => { - if (!node.deposits) return 'stakeable' - if (node.deposits.pendingWithdrawal > 0n) { - // If there's a pending withdrawal, check if we have a timer - return withdrawTimer ? 'locked' : 'can-withdraw' - } - if (node.deposits.amount > 0n) return 'staked' - return 'stakeable' - }, [node.deposits, withdrawTimer]) satisfies Status - - return ( -
- {/* Header */} -
-
- - {name} - -
- -
- - {node.data.http20.elapsed} HTTP/2 - - {node.data.grpc.elapsed} gRPC - - } - /> - - - - - {formatPrecisionNumber(node.data.estimatedApr, 2)}% - - - APR may vary and depends on delegation amount or total period reward. - - - } - /> - {/* TODO: unsure if we need to format this to 18 decimals - test later */} - {node.deposits?.amount && ( - {node.deposits.amount} RVR} /> - )} -
- - {/* Bottom Row */} - {onSelect && ( -
- -
- )} - {showButton ? ( -
- {status === 'stakeable' && ( - - - - - - - )} - {status === 'staked' && node.deposits?.depositId && ( - <> - - - - - - - - - - - - setOpenRedelegate(true)} - asChild - > -
- - Redelegate -
-
- setOpenWithdraw(true)} asChild> -
- - Withdraw -
-
-
-
- - )} - {status === 'locked' && ( - - )} - {status === 'can-withdraw' && node.deposits?.depositId && ( - - - - - - - )} -
- ) : null} - - - - - - - - - - -
- ) -} - -const InfoRow = ({ label, value }: { label: React.ReactNode; value: React.ReactNode }) => { - return ( -
- - {label} - - - {value} - -
- ) -} diff --git a/src/components/stake/operator-card.tsx b/src/components/stake/operator-card.tsx new file mode 100644 index 0000000..9d555ae --- /dev/null +++ b/src/components/stake/operator-card.tsx @@ -0,0 +1,318 @@ +'use client' + +import { Button } from '@/components/ui/button' +import type { StackableOperator } from '@/data/requests' +import { useWithdraw } from '@/lib/hooks/use-withdraw' +import { useWithdrawTimer } from '@/lib/hooks/use-withdraw-timer' +import { cn, formatUptime } from '@/lib/utils' +import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' +import { ArrowRightLeftIcon, EllipsisVertical, InfoIcon, LogOutIcon, XIcon } from 'lucide-react' +import { useMemo, useState } from 'react' +import { formatUnits } from 'viem' +import { Dialog, DialogTrigger } from '../ui/dialog' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '../ui/dropdown-menu' +import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' +import { Typography } from '../ui/typography' +import { toast } from '../ui/use-toast' +import { IncreaseStakeDialogContent } from './increase-stake' +import { InitiateWithdrawDialogContent } from './initiate-withdraw' +import { RedelegateDialog, RedelegateDialogContent, RedelegateProvider } from './redelegate' +import { StakeDialogContent } from './stake-to-operator' +import { WithdrawDialogContent } from './withdraw' + +export interface NodeCardProps { + operator: StackableOperator + deposits?: { + depositId: bigint + amount: bigint + pendingWithdrawal: bigint + } + allOperators?: StackableOperator[] + className?: string + showButton?: boolean + button?: React.ReactNode + onSelect?: (operator: StackableOperator) => void + ringColor?: string +} + +type StakeState = 'stakeable' | 'staked' | 'locked' | 'can-withdraw' + +export function OperatorCard({ + operator, + deposits, + className, + showButton, + allOperators, + button, + ringColor, +}: NodeCardProps) { + const depositId = deposits?.depositId ?? 1n // TODO: Remove this + const { lockCooldown } = useWithdraw(depositId) + const withdrawTimer = useWithdrawTimer(lockCooldown) + + const [openRedelegate, setOpenRedelegate] = useState(false) + const [openWithdraw, setOpenWithdraw] = useState(false) + const [openCancelWithdraw, setOpenCancelWithdraw] = useState(false) + + const stakeState = useMemo(() => { + if (!deposits) return 'stakeable' + if (deposits.pendingWithdrawal > 0n) { + // If there's a pending withdrawal, check if we have a timer + return withdrawTimer ? 'locked' : 'can-withdraw' + } + if (deposits.amount > 0n) return 'staked' + return 'stakeable' + }, [deposits, withdrawTimer]) satisfies StakeState + + return ( +
+ {/* Header */} +
+
+ + {operator.name} + +
+ +
+ + {operator.metrics.http20}ms HTTP + + {operator.metrics.grpc}ms gRPC + + } + /> + + + + + {formatPrecisionNumber(operator.estimatedApr, 2)}% + + + + APR may vary and depends on delegation amount or total period reward. + + + } + /> + {deposits?.amount && ( + {deposits.amount} RVR} /> + )} +
+ + {/* Bottom Row */} + {button &&
{button}
} + {showButton ? ( +
+ {stakeState === 'stakeable' && ( + + + + + { + toast({ + title: 'Stake finished', + description: `You have staked ${formatUnits(BigInt(amount), 18)} RVR to ${operator.name}`, + }) + }} + /> + + )} + {stakeState === 'staked' && deposits?.depositId && ( + <> + + + + + + + + + + + + setOpenRedelegate(true)} + asChild + > +
+ + Redelegate +
+
+ setOpenWithdraw(true)} asChild> +
+ + Withdraw +
+
+
+
+ + )} + {stakeState === 'locked' && ( + <> + + + + + + + setOpenCancelWithdraw(true)} + asChild + > +
+ + Cancel Withdraw +
+
+
+
+ + )} + {stakeState === 'can-withdraw' && depositId && ( + <> + + + + + { + setOpenWithdraw(false) + toast({ + title: 'Withdraw finished.', + description: `You have withdrawn ${formatUnits(BigInt(amount), 18)} RVR.`, + }) + }} + /> + + + + + + + setOpenCancelWithdraw(true)} + asChild + > +
+ + Cancel Withdraw +
+
+
+
+ + )} +
+ ) : null} + + + + + + + + {/* Cancel withdraw is pretty much redelegating */} + + + + + + + + { + setOpenWithdraw(false) + toast({ + title: 'Withdraw initiated', + description: 'Your withdrawal is being processed', + }) + }} + /> + +
+ ) +} + +const InfoRow = ({ + label, + value, + variant, +}: { + label: React.ReactNode + value: React.ReactNode + variant?: 'default' | 'staked' +}) => { + return ( +
+ + {label} + + + {value} + +
+ ) +} diff --git a/src/components/stake/redelegate.tsx b/src/components/stake/redelegate.tsx index d1cb9e7..a77ec81 100644 --- a/src/components/stake/redelegate.tsx +++ b/src/components/stake/redelegate.tsx @@ -1,26 +1,31 @@ import { Button } from '@/components/ui/button' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import { useReadRewardsDistributionDepositById } from '@/contracts' +import type { StackableOperator } from '@/data/requests' import { cn } from '@/lib/utils' import { Dialog, type DialogContentProps, type DialogProps } from '@radix-ui/react-dialog' import { ArrowLeft } from 'lucide-react' import { createContext, useContext, useState } from 'react' +import { formatUnits } from 'viem' import { RedelegateButton } from '../delegate/redelegate-button' import { DialogContent, DialogHeader, DialogTitle, closeStyle } from '../ui/dialog' +import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' -import { NodeCard } from './node-card' +import { OperatorCard } from './operator-card' type RedelegateFormProps = { - currentNode: StackableNodeData - availableNodes: StackableNodeData[] + currentOperator: StackableOperator + availableOperators: StackableOperator[] depositId: bigint + isCancelWithdraw?: boolean onRedelegateFinish?: () => void } export const RedelegateDialogContent = ({ - currentNode, - availableNodes, + currentOperator, + availableOperators, depositId, onRedelegateFinish, + isCancelWithdraw, ...rest }: RedelegateFormProps & DialogContentProps) => { const { @@ -30,6 +35,9 @@ export const RedelegateDialogContent = ({ setSelectedOperator, setShowOperatorSelect, } = useContext(RedelegateContext) + const { data: deposit, isPending: isPendingDeposit } = useReadRewardsDistributionDepositById({ + args: [depositId], + }) // TODO: animate height x.x return ( @@ -45,7 +53,11 @@ export const RedelegateDialogContent = ({ )} - {showOperatorSelect ? 'Select a new operator' : 'Redelegate'} + {showOperatorSelect + ? 'Select a new operator' + : isCancelWithdraw + ? 'Cancel Withdraw and Redelegate' + : 'Redelegate'} {showOperatorSelect && ( @@ -58,7 +70,7 @@ export const RedelegateDialogContent = ({
Currently delegated to: - +
Redelegate to: @@ -67,16 +79,22 @@ export const RedelegateDialogContent = ({ variant={selectedOperator ? 'secondary' : 'primary'} onClick={() => setShowOperatorSelect(true)} > - {selectedOperator ? ( - {new URL(selectedOperator.data.record.url).hostname} - ) : ( - 'Select Operator' - )} + {selectedOperator ? {selectedOperator.name} : 'Select Operator'}
+
+ Currently Staked: + {isPendingDeposit ? ( + + ) : ( + + {formatUnits(deposit?.amount ?? 0n, 18)} RVR + + )} +
{ onRedelegateFinish?.() @@ -89,31 +107,34 @@ export const RedelegateDialogContent = ({ {showOperatorSelect && (
- {availableNodes - .filter((node) => node.data.record.operator !== currentNode.data.record.operator) - .map((node) => ( - { - setSelectedOperator(node) - setShowOperatorSelect(false) - }} + {availableOperators + .filter((op) => op.address !== currentOperator.address) + .map((operator) => ( + { + setSelectedOperator(operator) + setShowOperatorSelect(false) + }} + className="w-full" + > + Select + } /> ))}
- {/* scroll bottom fade out gradient */} -
-
-
)} @@ -122,8 +143,8 @@ export const RedelegateDialogContent = ({ const RedelegateContext = createContext<{ onOpenChange: (open: boolean) => void - selectedOperator: StackableNodeData | undefined - setSelectedOperator: (operator: StackableNodeData | undefined) => void + selectedOperator: StackableOperator | undefined + setSelectedOperator: (operator: StackableOperator | undefined) => void showOperatorSelect: boolean setShowOperatorSelect: (show: boolean) => void open: boolean @@ -139,7 +160,7 @@ const RedelegateContext = createContext<{ export const RedelegateProvider = ({ children }: { children: React.ReactNode }) => { const [open, setOpen] = useState(false) const [showOperatorSelect, setShowOperatorSelect] = useState(false) - const [selectedOperator, setSelectedOperator] = useState() + const [selectedOperator, setSelectedOperator] = useState() return ( void } -export function StakeForm({ node, onStakeFinish }: StakeFormProps) { +export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { const { address } = useAccount() const { data: balance } = useReadRiverTokenBalanceOf({ args: [address!], @@ -46,6 +46,9 @@ export function StakeForm({ node, onStakeFinish }: StakeFormProps) { .refine((val) => val <= avaliableBalance, { message: 'Amount can not be greater than available balance', }), + beneficiary: z.string().refine((val) => isAddress(val), { + message: 'Invalid address', + }), }), [avaliableBalance], ) @@ -54,6 +57,7 @@ export function StakeForm({ node, onStakeFinish }: StakeFormProps) { resolver: zodResolver(formSchema), defaultValues: { amount: 0, + beneficiary: address, }, }) @@ -76,16 +80,35 @@ export function StakeForm({ node, onStakeFinish }: StakeFormProps) {
stake({ - args: [BigInt(values.amount), node.data.record.operator, address!], + args: [BigInt(values.amount), operator.address, values.beneficiary as Address], }), )} className="space-y-6 py-4" >
Stake to: - +
+ ( + +
+ Beneficiary +
+ + Beneficiary is the address that will receive the rewards from the operator. + + + + + +
+ )} + /> + { @@ -129,7 +152,7 @@ export const StakeDialogContent = ({ Stake to Operator - + ) } diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index c442b46..ad96dc4 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -1,7 +1,7 @@ 'use client' -import type { StakeableNodesResponse } from '@/data/requests' -import { useStakeableNodes } from '@/lib/hooks/use-node-data' +import type { StakeableOperatorsResponse } from '@/data/requests' import { useStake } from '@/lib/hooks/use-stake' +import { useStakeableOperators } from '@/lib/hooks/use-stakeable-operators' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' import { useMemo } from 'react' import { formatUnits } from 'viem' @@ -16,11 +16,10 @@ const RIVER_TOKEN_TOTAL_SUPPLY = 10000000000000000000000000000n export const TotalSupplyCard = ({ initialData, }: { - initialData: StakeableNodesResponse | undefined + initialData: StakeableOperatorsResponse | undefined }) => { - const { isStakingStateLoading, stakingState } = useStake() - - const { networkEstimatedApy } = useStakeableNodes({ initialData, liveQuery: true }) + const { isStakingStatePending, stakingState } = useStake() + const { networkEstimatedApy } = useStakeableOperators({ initialData, liveQuery: true }) const stakedPercentage = useMemo(() => { if (!stakingState?.totalStaked) return 0 const totalStaked = Number(stakingState.totalStaked) @@ -38,7 +37,7 @@ export const TotalSupplyCard = ({ Staked
- {isStakingStateLoading ? ( + {isStakingStatePending ? ( ) : ( {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR diff --git a/src/components/stake/withdraw.tsx b/src/components/stake/withdraw.tsx index 4a35c2c..396617c 100644 --- a/src/components/stake/withdraw.tsx +++ b/src/components/stake/withdraw.tsx @@ -1,41 +1,48 @@ 'use client' import { Button } from '@/components/ui/button' -import type { StackableNodeData } from '@/lib/hooks/use-node-data' +import type { StackableOperator } from '@/data/requests' import { useWithdraw } from '@/lib/hooks/use-withdraw' import type { DialogContentProps } from '@radix-ui/react-dialog' +import { useEffect } from 'react' import { formatUnits } from 'viem' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' -import { NodeCard } from './node-card' +import { OperatorCard } from './operator-card' type WithdrawFormProps = { - node: StackableNodeData - depositId: bigint // TODO: how should we archicture around this? - onStakeFinish?: (amount: number) => void + operator: StackableOperator + depositId: bigint + onWithdrawFinish?: (amount: number) => void } -export function WithdrawForm({ node, depositId }: WithdrawFormProps) { +export function WithdrawForm({ operator, depositId, onWithdrawFinish }: WithdrawFormProps) { const { withdraw, isPending, isTxPending, isTxConfirmed, amountToWithdraw, - isAmountToWithdrawLoading, + isAmountToWithdrawPending, } = useWithdraw(depositId) const isWithdrawing = isPending || isTxPending + useEffect(() => { + if (isTxConfirmed) { + onWithdrawFinish?.(Number(amountToWithdraw)) + } + }, [isTxConfirmed, onWithdrawFinish]) + return (
Currently delegated to: - +
Amount to withdraw: - {isAmountToWithdrawLoading ? ( + {isAmountToWithdrawPending ? ( ) : ( @@ -44,11 +51,6 @@ export function WithdrawForm({ node, depositId }: WithdrawFormProps) { )}
- - Initiating withdraw will take 3 days lock up period, after which you can withdraw the tokens - to your wallet. - -
) diff --git a/src/constants/fake.ts b/src/constants/fake.ts new file mode 100644 index 0000000..6c12908 --- /dev/null +++ b/src/constants/fake.ts @@ -0,0 +1,1137 @@ +/// @ts-nocheck For now +/// TODO: remove later - thats only for localdev +import type { StackableOperator } from '@/data/requests' + +export const FAKE_OPERATORS: StackableOperator[] = [ + { + name: 'Luganode', + nodes: [ + { + record: { + address: '0xE98EA85dC784723C684C992484F586D96820C264', + url: 'https://alpha-1.river.lgns.net', + operator: '0xdE42f8Fa9B9f856A8D0C3e92e25905BD8bC44545', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '157ms', + timeline: { + dns_done: '9ms', + connect_done: '11ms', + tls_handshake_done: '22ms', + wrote_request: '22ms', + got_first_response_byte: '157ms', + total: '157ms', + }, + response: { + status: 'OK', + instance_id: '3IM4BNPuDaDk', + address: '0xE98EA85dC784723C684C992484F586D96820C264', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T17:49:11Z', + uptime: '27h31m55.044538886s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '82.526799ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790958, + latency: '133.096856ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '18.990359ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386243, + latency: '35.514032ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '36.215246ms', + }, + { + result: 'OK', + chain_id: 100, + block: 37943467, + latency: '36.456164ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398549, + latency: '36.3556ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '3.129.69.26:443', + dns_addresses: ['3.129.69.26'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '30ms', + timeline: { + dns_done: '9ms', + connect_done: '10ms', + tls_handshake_done: '29ms', + wrote_request: '29ms', + got_first_response_byte: '30ms', + total: '30ms', + }, + response: { + status: 'OK', + instance_id: '3IM4BNPuDaDk', + address: '0xE98EA85dC784723C684C992484F586D96820C264', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T17:49:11Z', + uptime: '27h31m54.918687718s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '3.129.69.26:443', + dns_addresses: ['3.129.69.26'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '39ms', + timeline: { + dns_done: '9ms', + connect_done: '10ms', + tls_handshake_done: '20ms', + wrote_request: '20ms', + got_first_response_byte: '39ms', + total: '39ms', + }, + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T17:49:11Z', + uptime: '1d3h31m55s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '3.129.69.26:443', + dns_addresses: ['3.129.69.26'], + }, + river_eth_balance: '0.107628236063948847', + base_eth_balance: '0.089143339301375282', + }, + { + record: { + address: '0x5a35a7995D6c9992C08e6324C56E74dEdD863d86', + url: 'https://alpha-2.river.lgns.net', + operator: '0xdE42f8Fa9B9f856A8D0C3e92e25905BD8bC44545', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '190ms', + timeline: { + dns_done: '12ms', + connect_done: '21ms', + tls_handshake_done: '31ms', + wrote_request: '39ms', + got_first_response_byte: '190ms', + total: '190ms', + }, + response: { + status: 'OK', + instance_id: 'xhM5uNs7IybR', + address: '0x5a35a7995D6c9992C08e6324C56E74dEdD863d86', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-08T11:28:27Z', + uptime: '9h52m38.906814257s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '110.057226ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790958, + latency: '150.35121ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '23.669562ms', + }, + { + result: 'OK', + chain_id: 100, + block: 37943467, + latency: '38.387381ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '43.094085ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386243, + latency: '43.684143ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398549, + latency: '50.480541ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '18.117.89.208:443', + dns_addresses: ['18.117.89.208'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '44ms', + timeline: { + dns_done: '12ms', + connect_done: '31ms', + tls_handshake_done: '43ms', + wrote_request: '43ms', + got_first_response_byte: '43ms', + total: '44ms', + }, + response: { + status: 'OK', + instance_id: 'xhM5uNs7IybR', + address: '0x5a35a7995D6c9992C08e6324C56E74dEdD863d86', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-08T11:28:27Z', + uptime: '9h52m38.760435263s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '18.117.89.208:443', + dns_addresses: ['18.117.89.208'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '50ms', + timeline: { + dns_done: '12ms', + connect_done: '23ms', + tls_handshake_done: '48ms', + wrote_request: '48ms', + got_first_response_byte: '49ms', + total: '50ms', + }, + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-08T11:28:27Z', + uptime: '9h52m39s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '18.117.89.208:443', + dns_addresses: ['18.117.89.208'], + }, + river_eth_balance: '0.121221141746259726', + base_eth_balance: '0.093045196282216968', + }, + { + record: { + address: '0xFc224c846DE2810C7c991fc34914DeF8BDACCc5e', + url: 'https://alpha-3.river.lgns.net', + operator: '0xdE42f8Fa9B9f856A8D0C3e92e25905BD8bC44545', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '204ms', + timeline: { + dns_done: '10ms', + connect_done: '11ms', + tls_handshake_done: '20ms', + wrote_request: '30ms', + got_first_response_byte: '204ms', + total: '204ms', + }, + response: { + status: 'OK', + instance_id: 'GUWrqUooPBgH', + address: '0xFc224c846DE2810C7c991fc34914DeF8BDACCc5e', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-06T13:51:55Z', + uptime: '55h29m10.962278852s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '89.915658ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '172.746298ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '34.393147ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464282, + latency: '35.591043ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '40.273679ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398549, + latency: '47.098126ms', + }, + { + result: 'OK', + chain_id: 100, + block: 37943467, + latency: '105.765013ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '18.221.164.4:443', + dns_addresses: ['18.221.164.4'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '32ms', + timeline: { + dns_done: '10ms', + connect_done: '10ms', + tls_handshake_done: '31ms', + wrote_request: '31ms', + got_first_response_byte: '32ms', + total: '32ms', + }, + response: { + status: 'OK', + instance_id: 'GUWrqUooPBgH', + address: '0xFc224c846DE2810C7c991fc34914DeF8BDACCc5e', + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-06T13:51:55Z', + uptime: '55h29m10.79053734s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '18.221.164.4:443', + dns_addresses: ['18.221.164.4'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '23ms', + timeline: { + dns_done: '10ms', + connect_done: '10ms', + tls_handshake_done: '21ms', + wrote_request: '21ms', + got_first_response_byte: '23ms', + total: '23ms', + }, + version: 'river/mainnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-06T13:51:55Z', + uptime: '2d7h29m11s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '18.221.164.4:443', + dns_addresses: ['18.221.164.4'], + }, + river_eth_balance: '0.121482423977797209', + base_eth_balance: '0.093091336842780532', + }, + ], + commissionPercentage: 10, + estimatedApr: 0.4752461969196518, + metrics: { + http20: 35, + grpc: 47, + grpc_start_time: '2025-01-07T17:49:11Z', + }, + address: '0xdE42f8Fa9B9f856A8D0C3e92e25905BD8bC44545', + }, + { + name: 'Haneda', + nodes: [ + { + record: { + address: '0xB8617dfa0383C7193dDe95e1FF96cfFab141a4Ae', + url: 'https://haneda-1.nodes.towns-u4.com', + operator: '0xbB6Ade9f54743E1e5f5A05373D6cf26513d3f424', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '735ms', + timeline: { + dns_done: '39ms', + connect_done: '172ms', + tls_handshake_done: '312ms', + wrote_request: '312ms', + got_first_response_byte: '735ms', + total: '735ms', + }, + response: { + status: 'OK', + instance_id: 'inbCcNqIRy34', + address: '0xB8617dfa0383C7193dDe95e1FF96cfFab141a4Ae', + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-08T04:18:36Z', + uptime: '17h2m30.862470574s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '278.459836ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '120.237197ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '119.226451ms', + }, + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '120.518343ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '123.258853ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398550, + latency: '124.171918ms', + }, + { + result: 'OK', + chain_id: 100, + block: 37943467, + latency: '201.775321ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '34.176.237.240:443', + dns_addresses: ['34.176.237.240'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '448ms', + timeline: { + dns_done: '39ms', + connect_done: '172ms', + tls_handshake_done: '314ms', + wrote_request: '314ms', + got_first_response_byte: '447ms', + total: '448ms', + }, + response: { + status: 'OK', + instance_id: 'inbCcNqIRy34', + address: '0xB8617dfa0383C7193dDe95e1FF96cfFab141a4Ae', + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-08T04:18:36Z', + uptime: '17h2m30.574207049s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '34.176.237.240:443', + dns_addresses: ['34.176.237.240'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '442ms', + timeline: { + dns_done: '38ms', + connect_done: '170ms', + tls_handshake_done: '309ms', + wrote_request: '309ms', + got_first_response_byte: '442ms', + total: '442ms', + }, + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-08T04:18:36Z', + uptime: '17h2m31s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '34.176.237.240:443', + dns_addresses: ['34.176.237.240'], + }, + river_eth_balance: '0.092186247783662467', + base_eth_balance: '0.097082205544577973', + }, + { + record: { + address: '0x9C2cc27B2D73CFcC3e5b1A9d884253eEc17B626C', + url: 'https://haneda-2.nodes.towns-u4.com', + operator: '0xbB6Ade9f54743E1e5f5A05373D6cf26513d3f424', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '706ms', + timeline: { + dns_done: '38ms', + connect_done: '170ms', + tls_handshake_done: '310ms', + wrote_request: '310ms', + got_first_response_byte: '706ms', + total: '706ms', + }, + response: { + status: 'OK', + instance_id: 'vf96y4JDpTzm', + address: '0x9C2cc27B2D73CFcC3e5b1A9d884253eEc17B626C', + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-07T19:18:32Z', + uptime: '26h2m34.25304932s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '263.369671ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '123.704592ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '119.574839ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398550, + latency: '121.862758ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '122.477181ms', + }, + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '124.050526ms', + }, + { + result: 'OK', + chain_id: 100, + block: 37943467, + latency: '199.810981ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '34.176.20.224:443', + dns_addresses: ['34.176.20.224'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '425ms', + timeline: { + dns_done: '38ms', + connect_done: '165ms', + tls_handshake_done: '298ms', + wrote_request: '298ms', + got_first_response_byte: '425ms', + total: '425ms', + }, + response: { + status: 'OK', + instance_id: 'vf96y4JDpTzm', + address: '0x9C2cc27B2D73CFcC3e5b1A9d884253eEc17B626C', + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-07T19:18:32Z', + uptime: '26h2m33.976352433s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '34.176.20.224:443', + dns_addresses: ['34.176.20.224'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '422ms', + timeline: { + dns_done: '37ms', + connect_done: '164ms', + tls_handshake_done: '295ms', + wrote_request: '295ms', + got_first_response_byte: '422ms', + total: '422ms', + }, + version: 'river_u4/mainnet/2024-12-31-4/d0ea3b5', + start_time: '2025-01-07T19:18:32Z', + uptime: '1d2h2m34s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '34.176.20.224:443', + dns_addresses: ['34.176.20.224'], + }, + river_eth_balance: '0.118167727820827489', + base_eth_balance: '0.096922604104511709', + }, + ], + commissionPercentage: 20, + estimatedApr: 0.4224410639285794, + metrics: { + http20: 445, + grpc: 424, + grpc_start_time: '2025-01-08T04:18:36Z', + }, + address: '0xbB6Ade9f54743E1e5f5A05373D6cf26513d3f424', + }, + { + name: 'Axol', + nodes: [ + { + record: { + address: '0xa7f7D83843aB78706344D3Ae882b1d4f9404F254', + url: 'https://river-dub-omega-01.axol.io', + operator: '0x6C170403278651190494381181FC4358bB9b7B57', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '692ms', + timeline: { + dns_done: '46ms', + connect_done: '140ms', + tls_handshake_done: '239ms', + wrote_request: '239ms', + got_first_response_byte: '692ms', + total: '692ms', + }, + response: { + status: 'OK', + instance_id: 'uX9pVttlqE7k', + address: '0xa7f7D83843aB78706344D3Ae882b1d4f9404F254', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.696454287s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '170.001299ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '93.988189ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '59.648057ms', + }, + { + result: 'OK', + chain_id: 10200, + block: 13726504, + latency: '73.906972ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '99.339792ms', + }, + { + result: 'OK', + chain_id: 84532, + block: 20301488, + latency: '106.222548ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398550, + latency: '255.217742ms', + }, + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '339.329581ms', + }, + { + result: 'OK', + chain_id: 11155111, + block: 7449244, + latency: '358.265604ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '200.69.11.152:443', + dns_addresses: ['200.69.11.152'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '336ms', + timeline: { + dns_done: '47ms', + connect_done: '141ms', + tls_handshake_done: '242ms', + wrote_request: '242ms', + got_first_response_byte: '336ms', + total: '336ms', + }, + response: { + status: 'OK', + instance_id: 'uX9pVttlqE7k', + address: '0xa7f7D83843aB78706344D3Ae882b1d4f9404F254', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.338993435s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '200.69.11.152:443', + dns_addresses: ['200.69.11.152'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '336ms', + timeline: { + dns_done: '47ms', + connect_done: '141ms', + tls_handshake_done: '242ms', + wrote_request: '242ms', + got_first_response_byte: '336ms', + total: '336ms', + }, + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '200.69.11.152:443', + dns_addresses: ['200.69.11.152'], + }, + river_eth_balance: '0.795026491367613032', + base_eth_balance: '0.129870406516328600', + }, + { + record: { + address: '0x01A7dCd51409758f220c171c209eF3E1C8b10F1E', + url: 'https://river-dub-omega-02.axol.io', + operator: '0x6C170403278651190494381181FC4358bB9b7B57', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '756ms', + timeline: { + dns_done: '42ms', + connect_done: '138ms', + tls_handshake_done: '238ms', + wrote_request: '238ms', + got_first_response_byte: '756ms', + total: '756ms', + }, + response: { + status: 'OK', + instance_id: 'YkPv273u78b5', + address: '0x01A7dCd51409758f220c171c209eF3E1C8b10F1E', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.841482265s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '168.442106ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '93.960018ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 10200, + block: 13726504, + latency: '73.499712ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '94.058204ms', + }, + { + result: 'OK', + chain_id: 84532, + block: 20301488, + latency: '110.309288ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398550, + latency: '297.667097ms', + }, + { + result: 'OK', + chain_id: 11155111, + block: 7449244, + latency: '316.527869ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '341.800151ms', + }, + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '422.256644ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '200.69.11.153:443', + dns_addresses: ['200.69.11.153'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '328ms', + timeline: { + dns_done: '42ms', + connect_done: '136ms', + tls_handshake_done: '234ms', + wrote_request: '234ms', + got_first_response_byte: '328ms', + total: '328ms', + }, + response: { + status: 'OK', + instance_id: 'YkPv273u78b5', + address: '0x01A7dCd51409758f220c171c209eF3E1C8b10F1E', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.415315973s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '200.69.11.153:443', + dns_addresses: ['200.69.11.153'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '333ms', + timeline: { + dns_done: '42ms', + connect_done: '137ms', + tls_handshake_done: '237ms', + wrote_request: '237ms', + got_first_response_byte: '333ms', + total: '333ms', + }, + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '200.69.11.153:443', + dns_addresses: ['200.69.11.153'], + }, + river_eth_balance: '0.794242051040776380', + base_eth_balance: '0.124948363916885319', + }, + { + record: { + address: '0xC6CF68A1BCD3B9285fe1d13c128953a14Dd1Bb60', + url: 'https://river-dub-omega-03.axol.io', + operator: '0x6C170403278651190494381181FC4358bB9b7B57', + status: 2, + status_text: 'Operational', + }, + http11: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '567ms', + timeline: { + dns_done: '6ms', + connect_done: '102ms', + tls_handshake_done: '203ms', + wrote_request: '203ms', + got_first_response_byte: '566ms', + total: '567ms', + }, + response: { + status: 'OK', + instance_id: 'KE5RWxnFfuko', + address: '0xC6CF68A1BCD3B9285fe1d13c128953a14Dd1Bb60', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.675946795s', + graffiti: 'River Node welcomes you!', + river: { + result: 'OK', + chain_id: 550, + block: 10116597, + latency: '198.347433ms', + }, + base: { + result: 'OK', + chain_id: 8453, + block: 24790959, + latency: '98.645409ms', + }, + other_chains: [ + { + result: 'OK', + chain_id: 10200, + block: 13726504, + latency: '54.191311ms', + }, + { + result: 'OK', + chain_id: 1, + block: 21582410, + latency: '73.122858ms', + }, + { + result: 'OK', + chain_id: 10, + block: 130386244, + latency: '79.002434ms', + }, + { + result: 'OK', + chain_id: 137, + block: 66464283, + latency: '92.126687ms', + }, + { + result: 'OK', + chain_id: 84532, + block: 20301488, + latency: '102.024993ms', + }, + { + result: 'OK', + chain_id: 11155111, + block: 7449244, + latency: '104.2362ms', + }, + { + result: 'OK', + chain_id: 42161, + block: 293398550, + latency: '267.27843ms', + }, + ], + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/1.1', + used_tls: true, + remote_address: '200.69.11.154:443', + dns_addresses: ['200.69.11.154'], + }, + http20: { + success: true, + status: 200, + status_text: '200 OK', + elapsed: '294ms', + timeline: { + dns_done: '6ms', + connect_done: '101ms', + tls_handshake_done: '200ms', + wrote_request: '200ms', + got_first_response_byte: '294ms', + total: '294ms', + }, + response: { + status: 'OK', + instance_id: 'KE5RWxnFfuko', + address: '0xC6CF68A1BCD3B9285fe1d13c128953a14Dd1Bb60', + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12.405451594s', + graffiti: 'River Node welcomes you!', + x_chain_blockchains: [1, 8453, 137, 42161, 10, 100], + }, + protocol: 'HTTP/2.0', + used_tls: true, + remote_address: '200.69.11.154:443', + dns_addresses: ['200.69.11.154'], + }, + grpc: { + success: true, + status_text: 'OK', + elapsed: '299ms', + timeline: { + dns_done: '6ms', + connect_done: '101ms', + tls_handshake_done: '203ms', + wrote_request: '203ms', + got_first_response_byte: '299ms', + total: '299ms', + }, + version: 'river/testnet-release/12-31-24_3/d0ea3b5', + start_time: '2025-01-07T22:21:54Z', + uptime: '22h59m12s', + graffiti: 'River Node welcomes you!', + protocol: 'grpc', + x_http_version: 'HTTP/2.0', + remote_address: '200.69.11.154:443', + dns_addresses: ['200.69.11.154'], + }, + river_eth_balance: '0.793654243314083635', + base_eth_balance: '0.124967936208800308', + }, + ], + commissionPercentage: 10, + estimatedApr: 0.4752461969196518, + metrics: { + http20: 336, + grpc: 331, + grpc_start_time: '2025-01-07T22:21:54Z', + }, + address: '0x6C170403278651190494381181FC4358bB9b7B57', + }, +] diff --git a/src/constants/hostname-to-operator.ts b/src/constants/hostname-to-operator.ts new file mode 100644 index 0000000..b88f035 --- /dev/null +++ b/src/constants/hostname-to-operator.ts @@ -0,0 +1,10 @@ +// Lookup table from a piece of the operator's hostname to the operator's name +// Used to display a fancy name for the operator in the UI +export const HOSTNAME_TO_OPERATOR_NAME = { + 'lgns.net': 'Luganode', + framework: 'Framework', + 'figment.io': 'Figment', + 'axol.io': 'Axol', + haneda: 'Haneda', + 'hnt-labs': 'HNT Labs', +} diff --git a/src/data/requests.ts b/src/data/requests.ts index 99b7e71..dc80f45 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -1,3 +1,4 @@ +import { HOSTNAME_TO_OPERATOR_NAME } from '@/constants/hostname-to-operator' import { SECOND_MS } from '@/constants/time-ms' import { nodeOperatorAbi, @@ -42,7 +43,7 @@ export const getRiverNodes = async (env: 'gamma' | 'omega') => { try { const res = await fetch(`${randomNode.url}/debug/multi/json`) if (!res.ok) throw new Error(`${randomNode.url} failed with status: ${res.status}`) - const data = (await res.json()) as NodeStatusSchema + const data = (await res.json()) as NodeDebugMultiJsonSchema return data.nodes } catch (error) { attempts++ @@ -58,11 +59,11 @@ export const getRiverNodes = async (env: 'gamma' | 'omega') => { } const zodAddress = z.string().refine(isAddress) -export type NodeStatusSchema = z.infer +export type NodeDebugMultiJsonSchema = z.infer export type NodeData = Awaited>[number] -export const nodeStatusSchema = z.object({ +export const nodeDebugMultiJsonSchema = z.object({ nodes: z.array( z.object({ record: z.object({ @@ -137,8 +138,6 @@ export const nodeStatusSchema = z.object({ elapsed: z.string(), }) -export type StackableNode = Awaited>['nodes'][number] - const estimatedApyOfNetwork = (rewardRate: bigint, totalStaked: bigint) => { const apy = (Number(rewardRate) / Number(totalStaked) / 1e36) * (365 * 24 * 60 * 60) return apy @@ -150,9 +149,25 @@ const operatorApr = (commissionRate: bigint, networkApr: number) => { return apr } -export type StakeableNodesResponse = Awaited> +export type StackableOperator = { + name: string + nodes: NodeData[] + commissionPercentage: number + estimatedApr: number + address: Address + metrics: { + http20: number + grpc: number + grpc_start_time: string + } +} + +export type StakeableOperatorsResponse = { + operators: StackableOperator[] + networkEstimatedApy: number +} -export const getStakeableNodes = async (env: 'gamma' | 'omega') => { +export const getStakeableOperators = async (env: 'gamma' | 'omega') => { const chain = env === 'gamma' ? baseSepolia : base const chainId = chain.id const client = createPublicClient({ @@ -186,12 +201,64 @@ export const getStakeableNodes = async (env: 'gamma' | 'omega') => { }, {}, ) + + const operatorMap = nodes.reduce>((map, node) => { + const operatorAddress = node.record.operator + if (!map[operatorAddress]) { + map[operatorAddress] = [] + } + map[operatorAddress].push(node) + return map + }, {}) + + // Group nodes by unique operator address + const operators = uniqueOperators.map((operatorAddress) => { + const nodes = operatorMap[operatorAddress] + const commissionRateInBps = operatorCommissionMap[operatorAddress] + const estimatedApr = operatorApr(commissionRateInBps, networkApy) + + // Use first node's URL to derive operator name + const hostname = new URL(nodes[0].record.url).hostname + // return fancy name if key matches the expected hostname + const displayName = Object.entries(HOSTNAME_TO_OPERATOR_NAME).find(([key]) => + hostname.includes(key), + )?.[1] + const name = displayName ?? hostname + + const [httpLatencies, grpcLatencies] = nodes.map((node) => [ + parseLatency(node.http20.elapsed), + parseLatency(node.grpc.elapsed), + ]) + + return { + name, + nodes, + commissionPercentage: Number(commissionRateInBps) / 100, + estimatedApr, + metrics: { + http20: Math.round(getMedian(httpLatencies)), + grpc: Math.round(getMedian(grpcLatencies)), + // TODO: median of uptime + grpc_start_time: nodes[0].grpc.start_time, + }, + address: operatorAddress, + } + }) + return { - nodes: nodeData.nodes.map((node) => { - const commissionRateInBps = operatorCommissionMap[node.record.operator] - const estimatedApr = operatorApr(commissionRateInBps, networkApy) - return { ...node, estimatedApr, commissionPercentage: Number(commissionRateInBps) / 100 } - }), + operators, networkEstimatedApy: networkApy, } } + +const getMedian = (arr: number[]) => { + if (!arr.length) return 0 + const sorted = [...arr].sort((a, b) => a - b) + const mid = Math.floor(sorted.length / 2) + return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid] +} + +const parseLatency = (latency: string) => { + const [value] = latency.split('ms') + return Number(value) +} diff --git a/src/lib/hooks/use-increase-stake.ts b/src/lib/hooks/use-increase-stake.ts index cc00810..638f042 100644 --- a/src/lib/hooks/use-increase-stake.ts +++ b/src/lib/hooks/use-increase-stake.ts @@ -21,16 +21,13 @@ export const useIncreaseStake = (depositId: bigint) => { hash: hash, }) - const { - queryKey: currentDepositQueryKey, - data: currentDeposit, - isLoading: isCurrentDepositLoading, - } = useReadRewardsDistributionDepositById({ + const { queryKey: currentDepositQueryKey } = useReadRewardsDistributionDepositById({ args: [depositId], query: { enabled: !!address, }, }) + const { queryKey: stakingStateQueryKey } = useReadRewardsDistributionStakingState({ query: { enabled: !!address, @@ -49,7 +46,5 @@ export const useIncreaseStake = (depositId: bigint) => { isPending, isTxPending, isTxConfirmed, - currentDeposit, - isCurrentDepositLoading, } } diff --git a/src/lib/hooks/use-initiate-withdraw.ts b/src/lib/hooks/use-initiate-withdraw.ts index a9e9c40..e488b8d 100644 --- a/src/lib/hooks/use-initiate-withdraw.ts +++ b/src/lib/hooks/use-initiate-withdraw.ts @@ -7,7 +7,13 @@ export const useInitiateWithdraw = () => { writeContract: initiateWithdraw, data: hash, isPending, - } = useWriteRewardsDistributionInitiateWithdraw() + } = useWriteRewardsDistributionInitiateWithdraw({ + mutation: { + onError: (error) => { + console.error(error) + }, + }, + }) const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ hash: hash, }) diff --git a/src/lib/hooks/use-river-nodes.ts b/src/lib/hooks/use-river-nodes.ts index 9431446..b88fdd2 100644 --- a/src/lib/hooks/use-river-nodes.ts +++ b/src/lib/hooks/use-river-nodes.ts @@ -33,13 +33,13 @@ export const useRiverNodes = ({ }) const nodeConnections = useMemo(() => { - return formatNodeData(data) + return formatNodeToDataWithStatus(data) }, [data]) return nodeConnections } -export const formatNodeData = (nodes: RawNodeData[] | undefined) => { +export const formatNodeToDataWithStatus = (nodes: RawNodeData[] | undefined) => { if (!nodes) return [] const operators = new Set() return nodes.map((n, i) => { diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts index 8449ab2..8297d0c 100644 --- a/src/lib/hooks/use-stake.ts +++ b/src/lib/hooks/use-stake.ts @@ -5,10 +5,9 @@ import { } from '@/contracts' import { useQueryClient } from '@tanstack/react-query' import { useEffect } from 'react' -import { useAccount, useWaitForTransactionReceipt } from 'wagmi' +import { useWaitForTransactionReceipt } from 'wagmi' export const useStake = () => { - const { address } = useAccount() const qc = useQueryClient() const { writeContract: stake, data: hash, isPending } = useWriteRewardsDistributionStake() @@ -19,7 +18,7 @@ export const useStake = () => { const { queryKey: stakingStateQueryKey, data: stakingState, - isLoading: isStakingStateLoading, + isPending: isStakingStatePending, } = useReadRewardsDistributionStakingState() useEffect(() => { @@ -34,6 +33,6 @@ export const useStake = () => { isTxPending, isTxConfirmed, stakingState, - isStakingStateLoading, + isStakingStatePending, } } diff --git a/src/lib/hooks/use-stakeable-operators.ts b/src/lib/hooks/use-stakeable-operators.ts new file mode 100644 index 0000000..daab9b6 --- /dev/null +++ b/src/lib/hooks/use-stakeable-operators.ts @@ -0,0 +1,104 @@ +import { SECOND_MS } from '@/constants/time-ms' +import { + rewardsDistributionAbi, + rewardsDistributionAddress, + useReadRewardsDistributionGetDepositsByDepositor, +} from '@/contracts' +import { + getStakeableOperators, + type StackableOperator, + type StakeableOperatorsResponse, +} from '@/data/requests' +import { useQuery } from '@tanstack/react-query' +import { baseSepolia } from 'viem/chains' +import { useAccount, useReadContracts } from 'wagmi' + +export const useStakeableOperators = ({ + initialData, + liveQuery, +}: { + initialData?: StakeableOperatorsResponse + liveQuery?: boolean +}) => { + const { chainId } = useAccount() + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' + const { data, isLoading } = useQuery({ + queryKey: ['stakeable-operators', env], + queryFn: () => getStakeableOperators(env), + refetchInterval: liveQuery ? 30 * SECOND_MS : undefined, + initialData, + }) + + return { + operators: data?.operators ?? [], + networkEstimatedApy: data?.networkEstimatedApy ?? 0, + isLoading, + } +} + +export type OperatorWithDeposits = StackableOperator & { + deposits?: Deposit +} + +type Deposit = { + depositId: bigint + amount: bigint + owner: `0x${string}` + commissionEarningPower: bigint + delegatee: `0x${string}` + pendingWithdrawal: bigint + beneficiary: `0x${string}` +} + +export const useOperatorsWithDeposits = (initialData?: StakeableOperatorsResponse) => { + const { address, isConnected, chainId } = useAccount() + const { operators } = useStakeableOperators({ + initialData, + liveQuery: true, + }) + const { data: allDepositIds } = useReadRewardsDistributionGetDepositsByDepositor({ + args: [address!], + query: { enabled: isConnected }, + }) + + const depositsQueries = useReadContracts({ + contracts: (allDepositIds || []).map( + (id) => + ({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress[chainId as keyof typeof rewardsDistributionAddress], + functionName: 'depositById', + args: [id], + }) as const, + ), + query: { enabled: isConnected && !!allDepositIds }, + }) + + const deposits = depositsQueries.data + ?.flatMap((query) => query.result) + .filter((deposit): deposit is NonNullable => deposit !== undefined) + + const operatorDeposits = allDepositIds + ? Object.fromEntries( + (deposits ?? []) + .filter((deposit): deposit is NonNullable => deposit !== undefined) + // The key is the delegatee, which is the operator address + .map((deposit, idx) => [ + deposit.delegatee, + { ...deposit, depositId: allDepositIds[idx] }, + ]), + ) + : {} + + const operatorsWithDeposits = operators.map((operator: StackableOperator) => { + const operatorDeposit = operatorDeposits?.[operator.address] + return { + ...operator, + deposits: operatorDeposit, + } + }) + + return { + data: isConnected ? operatorsWithDeposits : operators, + } +} diff --git a/src/lib/hooks/use-withdraw.ts b/src/lib/hooks/use-withdraw.ts index 14be716..b33dd29 100644 --- a/src/lib/hooks/use-withdraw.ts +++ b/src/lib/hooks/use-withdraw.ts @@ -11,7 +11,7 @@ import { useAccount, useWaitForTransactionReceipt } from 'wagmi' export const useWithdraw = (depositId: bigint | undefined) => { const { address } = useAccount() const qc = useQueryClient() - const { data: lockCooldown, isLoading: isLockCooldownLoading } = useReadRiverTokenLockCooldown({ + const { data: lockCooldown, isPending: isLockCooldownPending } = useReadRiverTokenLockCooldown({ args: [address!], query: { enabled: !!address, @@ -25,7 +25,7 @@ export const useWithdraw = (depositId: bigint | undefined) => { const { data: deposit, - isLoading: isAmountToWithdrawLoading, + isPending: isAmountToWithdrawPending, queryKey: depositQueryKey, } = useReadRewardsDistributionDepositById({ args: [depositId!], @@ -54,8 +54,8 @@ export const useWithdraw = (depositId: bigint | undefined) => { isTxPending, isTxConfirmed, amountToWithdraw, - isAmountToWithdrawLoading, + isAmountToWithdrawPending, lockCooldown, - isLockCooldownLoading, + isLockCooldownPending, } } From 4cd8a60b0e093d338fa23385d16ad12a3a76ac51 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 9 Jan 2025 01:14:03 -0300 Subject: [PATCH 32/44] chore: operator name is `${company} {ocurrency}` --- src/data/requests.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/data/requests.ts b/src/data/requests.ts index dc80f45..b510b9d 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -211,6 +211,8 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { return map }, {}) + const operatorNameOccurency: Record = {} + // Group nodes by unique operator address const operators = uniqueOperators.map((operatorAddress) => { const nodes = operatorMap[operatorAddress] @@ -224,6 +226,8 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { hostname.includes(key), )?.[1] const name = displayName ?? hostname + operatorNameOccurency[name] = (operatorNameOccurency?.[name] ?? 0) + 1 + const occurency = operatorNameOccurency[name] const [httpLatencies, grpcLatencies] = nodes.map((node) => [ parseLatency(node.http20.elapsed), @@ -231,7 +235,7 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { ]) return { - name, + name: `${name} ${occurency}`, nodes, commissionPercentage: Number(commissionRateInBps) / 100, estimatedApr, From c08e228883c38b39f95eae0eeab5625949fa7ff5 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Thu, 9 Jan 2025 15:44:58 -0300 Subject: [PATCH 33/44] chore: parse amount to number --- src/components/stake/increase-stake.tsx | 11 ++++++----- src/components/stake/stake-to-operator.tsx | 11 +++++++---- src/lib/hooks/use-stake.ts | 12 +++++++++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx index d51f8db..691e427 100644 --- a/src/components/stake/increase-stake.tsx +++ b/src/components/stake/increase-stake.tsx @@ -47,10 +47,10 @@ export function IncreaseStakeForm({ z.object({ amount: z .number() - .refine((val) => Number(val) > 0, { + .refine((val) => val > 0, { message: 'Amount must be a positive number', }) - .refine((val) => val <= avaliableBalance, { + .refine((val) => BigInt(val) <= avaliableBalance, { message: 'Amount can not be greater than available balance', }), }), @@ -59,9 +59,6 @@ export function IncreaseStakeForm({ const form = useForm>({ resolver: zodResolver(formSchema), - defaultValues: { - amount: 0, - }, }) const { data: currentDeposit, isPending: isCurrentDepositPending } = @@ -123,6 +120,10 @@ export function IncreaseStakeForm({ type="number" placeholder="0" {...field} + onChange={(e) => { + const value = Number(e.target.value) + field.onChange(value) + }} className="[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none" /> diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 31106c4..69aa32a 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -40,10 +40,10 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { z.object({ amount: z .number() - .refine((val) => Number(val) > 0, { + .refine((val) => val > 0, { message: 'Amount must be a positive number', }) - .refine((val) => val <= avaliableBalance, { + .refine((val) => BigInt(val) <= avaliableBalance, { message: 'Amount can not be greater than available balance', }), beneficiary: z.string().refine((val) => isAddress(val), { @@ -56,7 +56,6 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { - amount: 0, beneficiary: address, }, }) @@ -66,7 +65,7 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { useEffect(() => { if (isTxConfirmed) { - onStakeFinish?.(form.getValues('amount')) + onStakeFinish?.(Number(form.getValues('amount'))) form.reset() } }, [isTxConfirmed, onStakeFinish, form]) @@ -123,6 +122,10 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { type="number" placeholder="0" {...field} + onChange={(e) => { + const value = Number(e.target.value) + field.onChange(value) + }} className="[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none" /> diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts index 8297d0c..fd3f818 100644 --- a/src/lib/hooks/use-stake.ts +++ b/src/lib/hooks/use-stake.ts @@ -10,7 +10,17 @@ import { useWaitForTransactionReceipt } from 'wagmi' export const useStake = () => { const qc = useQueryClient() - const { writeContract: stake, data: hash, isPending } = useWriteRewardsDistributionStake() + const { + writeContract: stake, + data: hash, + isPending, + } = useWriteRewardsDistributionStake({ + mutation: { + onError: (error) => { + console.error(error) + }, + }, + }) const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ hash: hash, }) From d584663be4484db2e483b78d77dfa3e914693d24 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Fri, 10 Jan 2025 16:11:33 -0300 Subject: [PATCH 34/44] chore: format rvr amount properly using Intl api --- src/components/claim/claim-page.tsx | 4 ++-- src/components/stake/increase-stake.tsx | 6 +++--- src/components/stake/initiate-withdraw.tsx | 4 ++-- src/components/stake/redelegate.tsx | 4 ++-- src/components/stake/stake-to-operator.tsx | 5 +++-- src/components/stake/total-supply.tsx | 4 ++-- src/components/stake/withdraw.tsx | 4 ++-- src/components/stake/your-account.tsx | 6 +++--- src/components/stake/your-rewards.tsx | 4 ++-- src/lib/utils/formatRVRAmount.ts | 4 ++++ 10 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 src/lib/utils/formatRVRAmount.ts diff --git a/src/components/claim/claim-page.tsx b/src/components/claim/claim-page.tsx index 69b539b..fe3d033 100644 --- a/src/components/claim/claim-page.tsx +++ b/src/components/claim/claim-page.tsx @@ -1,6 +1,6 @@ import { useClaim } from '@/lib/hooks/use-claim' import { cn } from '@/lib/utils' -import { formatUnits } from 'viem' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { base, baseSepolia } from 'viem/chains' import { useAccount, useSwitchChain } from 'wagmi' import { Button } from '../ui/button' @@ -80,7 +80,7 @@ export const ClaimPage = () => { !!claimableBalance && 'font-mono font-medium tabular-nums', )} > - {!claimableBalance ? 0 : formatUnits(claimableBalance, 18)} + {!claimableBalance ? 0 : formatRVRAmount(claimableBalance)} )}
@@ -129,7 +129,7 @@ export function IncreaseStakeForm({ - Available Balance {formatUnits(avaliableBalance, 18)} RVR + Available Balance {formatRVRAmount(avaliableBalance)} RVR )} diff --git a/src/components/stake/initiate-withdraw.tsx b/src/components/stake/initiate-withdraw.tsx index 8ec46d6..62cbe41 100644 --- a/src/components/stake/initiate-withdraw.tsx +++ b/src/components/stake/initiate-withdraw.tsx @@ -3,9 +3,9 @@ import { Button } from '@/components/ui/button' import { useReadRewardsDistributionDepositById } from '@/contracts' import type { StackableOperator } from '@/data/requests' import { useInitiateWithdraw } from '@/lib/hooks/use-initiate-withdraw' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import type { DialogContentProps } from '@radix-ui/react-dialog' import { useEffect } from 'react' -import { formatUnits } from 'viem' import { useAccount } from 'wagmi' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { Label } from '../ui/label' @@ -53,7 +53,7 @@ export function InitiateWithdrawForm({ ) : ( - {formatUnits(currentDeposit?.amount ?? 0n, 18)} RVR + {formatRVRAmount(currentDeposit?.amount ?? 0n)} RVR )}
diff --git a/src/components/stake/redelegate.tsx b/src/components/stake/redelegate.tsx index a77ec81..c7b3d22 100644 --- a/src/components/stake/redelegate.tsx +++ b/src/components/stake/redelegate.tsx @@ -5,12 +5,12 @@ import { cn } from '@/lib/utils' import { Dialog, type DialogContentProps, type DialogProps } from '@radix-ui/react-dialog' import { ArrowLeft } from 'lucide-react' import { createContext, useContext, useState } from 'react' -import { formatUnits } from 'viem' import { RedelegateButton } from '../delegate/redelegate-button' import { DialogContent, DialogHeader, DialogTitle, closeStyle } from '../ui/dialog' import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' import { OperatorCard } from './operator-card' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' type RedelegateFormProps = { currentOperator: StackableOperator @@ -88,7 +88,7 @@ export const RedelegateDialogContent = ({ ) : ( - {formatUnits(deposit?.amount ?? 0n, 18)} RVR + {formatRVRAmount(deposit?.amount ?? 0n)} RVR )}
diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 69aa32a..6adbfcf 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -16,12 +16,13 @@ import { zodResolver } from '@hookform/resolvers/zod' import type { DialogContentProps } from '@radix-ui/react-dialog' import { useCallback, useEffect, useMemo } from 'react' import { useForm } from 'react-hook-form' -import { formatUnits, isAddress, type Address } from 'viem' +import { isAddress, type Address } from 'viem' import { useAccount } from 'wagmi' import * as z from 'zod' import { MaxButton } from '../max-button' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { OperatorCard } from './operator-card' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' type StakeFormProps = { operator: StackableOperator @@ -131,7 +132,7 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { - Available Balance {formatUnits(avaliableBalance, 18)} RVR + Available Balance {formatRVRAmount(avaliableBalance)} RVR )} diff --git a/src/components/stake/total-supply.tsx b/src/components/stake/total-supply.tsx index ad96dc4..42ae6b3 100644 --- a/src/components/stake/total-supply.tsx +++ b/src/components/stake/total-supply.tsx @@ -3,8 +3,8 @@ import type { StakeableOperatorsResponse } from '@/data/requests' import { useStake } from '@/lib/hooks/use-stake' import { useStakeableOperators } from '@/lib/hooks/use-stakeable-operators' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { useMemo } from 'react' -import { formatUnits } from 'viem' import { PieChart } from '../pie-chart' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { Skeleton } from '../ui/skeleton' @@ -40,7 +40,7 @@ export const TotalSupplyCard = ({ {isStakingStatePending ? ( ) : ( - {formatUnits(stakingState?.totalStaked ?? 0n, 18)} RVR + {formatRVRAmount(stakingState?.totalStaked ?? 0n)} RVR )}
diff --git a/src/components/stake/withdraw.tsx b/src/components/stake/withdraw.tsx index 396617c..ad65d1f 100644 --- a/src/components/stake/withdraw.tsx +++ b/src/components/stake/withdraw.tsx @@ -2,9 +2,9 @@ import { Button } from '@/components/ui/button' import type { StackableOperator } from '@/data/requests' import { useWithdraw } from '@/lib/hooks/use-withdraw' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import type { DialogContentProps } from '@radix-ui/react-dialog' import { useEffect } from 'react' -import { formatUnits } from 'viem' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { Skeleton } from '../ui/skeleton' import { Typography } from '../ui/typography' @@ -46,7 +46,7 @@ export function WithdrawForm({ operator, depositId, onWithdrawFinish }: Withdraw ) : ( - {formatUnits(amountToWithdraw ?? 0n, 18)} RVR + {formatRVRAmount(amountToWithdraw ?? 0n)} RVR )}
diff --git a/src/components/stake/your-account.tsx b/src/components/stake/your-account.tsx index 55b4f17..bb2cd70 100644 --- a/src/components/stake/your-account.tsx +++ b/src/components/stake/your-account.tsx @@ -4,8 +4,8 @@ import { useReadRewardsDistributionStakedByDepositor, useReadRiverTokenBalanceOf, } from '@/contracts' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { useEffect, useRef } from 'react' -import { formatUnits } from 'viem' import { useAccount } from 'wagmi' import { Button } from '../ui/button' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' @@ -45,7 +45,7 @@ export const YourAccountCard = () => { isBalancePending ? ( ) : ( - {formatUnits(balance ?? 0n, 18)} RVR + {formatRVRAmount(balance ?? 0n)} RVR ) ) : ( - @@ -57,7 +57,7 @@ export const YourAccountCard = () => { isStakedByUserPending ? ( ) : ( - {formatUnits(stakedByUser ?? 0n, 18)} RVR + {formatRVRAmount(stakedByUser ?? 0n)} RVR ) ) : ( - diff --git a/src/components/stake/your-rewards.tsx b/src/components/stake/your-rewards.tsx index 4eef028..03d9c81 100644 --- a/src/components/stake/your-rewards.tsx +++ b/src/components/stake/your-rewards.tsx @@ -1,7 +1,7 @@ 'use client' import { useClaim } from '@/lib/hooks/use-claim' -import { formatUnits } from 'viem' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { useAccount } from 'wagmi' import { Button } from '../ui/button' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' @@ -29,7 +29,7 @@ export const YourRewardsCard = () => { isLoadingClaimableBalance ? ( ) : ( - {formatUnits(claimableBalance ?? 0n, 18)} RVR + {formatRVRAmount(claimableBalance ?? 0n)} RVR ) ) : ( - diff --git a/src/lib/utils/formatRVRAmount.ts b/src/lib/utils/formatRVRAmount.ts new file mode 100644 index 0000000..e21f9b6 --- /dev/null +++ b/src/lib/utils/formatRVRAmount.ts @@ -0,0 +1,4 @@ +const NumberFormat = new Intl.NumberFormat('en-US') + +export const formatRVRAmount = (amount: bigint | number) => + NumberFormat.format(Number(amount) / 1e18) From 77ee3b5080c5f1941cad32e517bf5077f87fb061 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Fri, 10 Jan 2025 16:13:40 -0300 Subject: [PATCH 35/44] =?UTF-8?q?new=20design=20for=20operator=20card=20?= =?UTF-8?q?=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/stake/operator-card.tsx | 102 ++++++++++++------------- tailwind.config.js | 1 - 2 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/components/stake/operator-card.tsx b/src/components/stake/operator-card.tsx index 9d555ae..089c9bd 100644 --- a/src/components/stake/operator-card.tsx +++ b/src/components/stake/operator-card.tsx @@ -6,9 +6,10 @@ import { useWithdraw } from '@/lib/hooks/use-withdraw' import { useWithdrawTimer } from '@/lib/hooks/use-withdraw-timer' import { cn, formatUptime } from '@/lib/utils' import { formatPrecisionNumber } from '@/lib/utils/formatPrecisionNumber' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { ArrowRightLeftIcon, EllipsisVertical, InfoIcon, LogOutIcon, XIcon } from 'lucide-react' import { useMemo, useState } from 'react' -import { formatUnits } from 'viem' +import { useAccount } from 'wagmi' import { Dialog, DialogTrigger } from '../ui/dialog' import { DropdownMenu, @@ -17,7 +18,6 @@ import { DropdownMenuTrigger, } from '../ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' -import { Typography } from '../ui/typography' import { toast } from '../ui/use-toast' import { IncreaseStakeDialogContent } from './increase-stake' import { InitiateWithdrawDialogContent } from './initiate-withdraw' @@ -51,7 +51,8 @@ export function OperatorCard({ button, ringColor, }: NodeCardProps) { - const depositId = deposits?.depositId ?? 1n // TODO: Remove this + const { isConnected } = useAccount() + const depositId = deposits?.depositId const { lockCooldown } = useWithdraw(depositId) const withdrawTimer = useWithdrawTimer(lockCooldown) @@ -71,46 +72,58 @@ export function OperatorCard({ return (
{/* Header */} -
-
- +
+
+ {operator.name}
-
- - {operator.metrics.http20}ms HTTP - - {operator.metrics.grpc}ms gRPC - - } - /> - - - +
+
Health
+
+ + {operator.metrics.grpc}ms gRPC +
+
+
+
Uptime
+
+ {formatUptime(new Date(operator.metrics.grpc_start_time))} +
+
+
+
Commission
+
{`${operator.commissionPercentage}%`}
+
+
+
- {formatPrecisionNumber(operator.estimatedApr, 2)}% - + Est. APR + APR may vary and depends on delegation amount or total period reward. - } - /> +
+
+ {formatPrecisionNumber(operator.estimatedApr, 2)}% +
+
{deposits?.amount && ( - {deposits.amount} RVR} /> +
+ Staked + + {formatRVRAmount(deposits.amount)} RVR + +
)}
@@ -121,20 +134,22 @@ export function OperatorCard({ {stakeState === 'stakeable' && ( - + { toast({ title: 'Stake finished', - description: `You have staked ${formatUnits(BigInt(amount), 18)} RVR to ${operator.name}`, + description: `You have staked ${formatRVRAmount(BigInt(amount))} RVR to ${operator.name}`, }) }} /> )} - {stakeState === 'staked' && deposits?.depositId && ( + {stakeState === 'staked' && depositId && ( <> @@ -220,7 +235,7 @@ export function OperatorCard({ setOpenWithdraw(false) toast({ title: 'Withdraw finished.', - description: `You have withdrawn ${formatUnits(BigInt(amount), 18)} RVR.`, + description: `You have withdrawn ${formatRVRAmount(amount)} RVR.`, }) }} /> @@ -293,26 +308,3 @@ export function OperatorCard({
) } - -const InfoRow = ({ - label, - value, - variant, -}: { - label: React.ReactNode - value: React.ReactNode - variant?: 'default' | 'staked' -}) => { - return ( -
- - {label} - - - {value} - -
- ) -} diff --git a/tailwind.config.js b/tailwind.config.js index 36f82a0..93741f8 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -98,7 +98,6 @@ module.exports = { require('tailwindcss-animate'), require('@tailwindcss/forms'), require('@tailwindcss/typography'), - require('@tailwindcss/line-clamp'), require('@tailwindcss/aspect-ratio'), require('tailwindcss-radix')(), addVariablesForColors, From 71cb8f2bef0339086acf476082c0e25d6aa18be3 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 19:18:16 -0300 Subject: [PATCH 36/44] show operator address below the name --- src/components/stake/operator-card.tsx | 10 +++++++--- src/components/wallet-address.tsx | 7 ++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/components/stake/operator-card.tsx b/src/components/stake/operator-card.tsx index 089c9bd..e7521a6 100644 --- a/src/components/stake/operator-card.tsx +++ b/src/components/stake/operator-card.tsx @@ -19,6 +19,7 @@ import { } from '../ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip' import { toast } from '../ui/use-toast' +import { WalletAddress } from '../wallet-address' import { IncreaseStakeDialogContent } from './increase-stake' import { InitiateWithdrawDialogContent } from './initiate-withdraw' import { RedelegateDialog, RedelegateDialogContent, RedelegateProvider } from './redelegate' @@ -78,9 +79,12 @@ export function OperatorCard({ {/* Header */}
- - {operator.name} - +
+ + {operator.name} + + +
diff --git a/src/components/wallet-address.tsx b/src/components/wallet-address.tsx index d91c0a9..3c1689f 100644 --- a/src/components/wallet-address.tsx +++ b/src/components/wallet-address.tsx @@ -1,19 +1,20 @@ import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard' -import { formatAddress } from '@/lib/utils' +import { cn, formatAddress } from '@/lib/utils' import { Check, Copy } from 'lucide-react' import { Typography } from './ui/typography' type AddressProps = { address: `0x${string}` + className?: string } -export const WalletAddress = ({ address }: AddressProps) => { +export const WalletAddress = ({ address, className }: AddressProps) => { const { copy, hasCopied } = useCopyToClipboard() return ( {formatAddress(address)} {hasCopied ? ( From 95f5e170a7188f7be169e385ecc5da388c4c5c39 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 20:15:53 -0300 Subject: [PATCH 37/44] fix: fetch operators from gamma --- src/constants/hostname-to-operator.ts | 2 ++ src/constants/river-env.ts | 6 ++++++ src/data/requests.ts | 21 +++++++++++++-------- 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/constants/river-env.ts diff --git a/src/constants/hostname-to-operator.ts b/src/constants/hostname-to-operator.ts index b88f035..8301eb6 100644 --- a/src/constants/hostname-to-operator.ts +++ b/src/constants/hostname-to-operator.ts @@ -7,4 +7,6 @@ export const HOSTNAME_TO_OPERATOR_NAME = { 'axol.io': 'Axol', haneda: 'Haneda', 'hnt-labs': 'HNT Labs', + 'unit410.com': 'Unit410', + 'towns.com': 'Towns', } diff --git a/src/constants/river-env.ts b/src/constants/river-env.ts new file mode 100644 index 0000000..1a635a5 --- /dev/null +++ b/src/constants/river-env.ts @@ -0,0 +1,6 @@ +export const RiverEnv = { + omega: 'omega', + gamma: 'gamma', +} as const + +export type RiverEnv = (typeof RiverEnv)[keyof typeof RiverEnv] diff --git a/src/data/requests.ts b/src/data/requests.ts index b510b9d..bcc2438 100644 --- a/src/data/requests.ts +++ b/src/data/requests.ts @@ -1,4 +1,5 @@ import { HOSTNAME_TO_OPERATOR_NAME } from '@/constants/hostname-to-operator' +import type { RiverEnv } from '@/constants/river-env' import { SECOND_MS } from '@/constants/time-ms' import { nodeOperatorAbi, @@ -13,7 +14,7 @@ import { createPublicClient, http, isAddress, type Address } from 'viem' import { base, baseSepolia } from 'viem/chains' import { z } from 'zod' -const getRandomNode = async (env: 'gamma' | 'omega') => { +const getRandomNode = async (env: RiverEnv) => { const chain = env === 'gamma' ? riverGamma : river const chainId = chain.id const riverClient = createPublicClient({ @@ -30,7 +31,7 @@ const getRandomNode = async (env: 'gamma' | 'omega') => { return { node: randomNode, length: operationalNodes.length } } -export const getRiverNodes = async (env: 'gamma' | 'omega') => { +export const getRiverNodes = async (env: RiverEnv) => { let attempts = 0 let lastError let lastNode @@ -229,10 +230,12 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { operatorNameOccurency[name] = (operatorNameOccurency?.[name] ?? 0) + 1 const occurency = operatorNameOccurency[name] - const [httpLatencies, grpcLatencies] = nodes.map((node) => [ - parseLatency(node.http20.elapsed), - parseLatency(node.grpc.elapsed), - ]) + const http20Elapsed = nodes + .map((node) => parseLatency(node.http20.elapsed)) + .filter((latency) => latency !== undefined) as number[] + const grpcElapsed = nodes + .map((node) => parseLatency(node.grpc.elapsed)) + .filter((latency) => latency !== undefined) as number[] return { name: `${name} ${occurency}`, @@ -240,8 +243,8 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { commissionPercentage: Number(commissionRateInBps) / 100, estimatedApr, metrics: { - http20: Math.round(getMedian(httpLatencies)), - grpc: Math.round(getMedian(grpcLatencies)), + http20: http20Elapsed.length ? Math.round(getMedian(http20Elapsed)) : 0, + grpc: grpcElapsed.length ? Math.round(getMedian(grpcElapsed)) : 0, // TODO: median of uptime grpc_start_time: nodes[0].grpc.start_time, }, @@ -257,12 +260,14 @@ export const getStakeableOperators = async (env: 'gamma' | 'omega') => { const getMedian = (arr: number[]) => { if (!arr.length) return 0 + if (arr.length === 1) return arr[0] const sorted = [...arr].sort((a, b) => a - b) const mid = Math.floor(sorted.length / 2) return sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid] } const parseLatency = (latency: string) => { + if (!latency) return const [value] = latency.split('ms') return Number(value) } From 01e81c395fbd6ed17f8556b494d7467f3709ced5 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 20:37:49 -0300 Subject: [PATCH 38/44] fix: change data if you change river env --- src/components/stake/all-operators.tsx | 9 ++++++++- src/components/stake/stake-to-operator.tsx | 2 +- src/lib/hooks/use-river-nodes.ts | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/stake/all-operators.tsx b/src/components/stake/all-operators.tsx index 5d94b03..c5bdfb1 100644 --- a/src/components/stake/all-operators.tsx +++ b/src/components/stake/all-operators.tsx @@ -5,20 +5,27 @@ import { useOperatorsWithDeposits, type OperatorWithDeposits, } from '@/lib/hooks/use-stakeable-operators' +import { useAccount } from 'wagmi' import { Typography } from '../ui/typography' import { OperatorCard } from './operator-card' +import { baseSepolia } from 'viem/chains' export const AllOperators = ({ initialData, }: { initialData: StakeableOperatorsResponse | undefined }) => { const { data: operatorsWithDeposits } = useOperatorsWithDeposits(initialData) + const { chainId } = useAccount() + const env = chainId === baseSepolia.id ? 'gamma' : 'omega' return (
-

All Operators

+

+ All Operators + {env === 'gamma' ? ' (Gamma)' : ''} +

To distribute power on the network, please delegate to top performing operators. diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 6adbfcf..11fb34c 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -12,6 +12,7 @@ import { Input } from '@/components/ui/input' import { useReadRiverTokenBalanceOf } from '@/contracts' import type { StackableOperator } from '@/data/requests' import { useStake } from '@/lib/hooks/use-stake' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { zodResolver } from '@hookform/resolvers/zod' import type { DialogContentProps } from '@radix-ui/react-dialog' import { useCallback, useEffect, useMemo } from 'react' @@ -22,7 +23,6 @@ import * as z from 'zod' import { MaxButton } from '../max-button' import { DialogContent, DialogHeader, DialogTitle } from '../ui/dialog' import { OperatorCard } from './operator-card' -import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' type StakeFormProps = { operator: StackableOperator diff --git a/src/lib/hooks/use-river-nodes.ts b/src/lib/hooks/use-river-nodes.ts index b88fdd2..66ae7f3 100644 --- a/src/lib/hooks/use-river-nodes.ts +++ b/src/lib/hooks/use-river-nodes.ts @@ -24,7 +24,7 @@ export const useRiverNodes = ({ liveQuery, }: { initialData?: RawNodeData[]; liveQuery?: boolean } = {}) => { const { chainId } = useAccount() - const env = chainId === baseSepolia.id ? 'gamma' : 'omega' + const env = useMemo(() => (chainId === baseSepolia.id ? 'gamma' : 'omega'), [chainId]) const { data } = useQuery({ queryKey: ['nodeStatus', env], queryFn: () => getRiverNodes(env), From a40bc54f03953a939ac6932dc9eb6795d3745d14 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 21:19:06 -0300 Subject: [PATCH 39/44] update reward distribution contract abi --- src/contracts.ts | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ wagmi.config.ts | 22 +++++++++++++- 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/contracts.ts b/src/contracts.ts index 23b1c19..fe2e246 100644 --- a/src/contracts.ts +++ b/src/contracts.ts @@ -784,6 +784,19 @@ export const rewardsDistributionAbi = [ ], name: 'OwnershipTransferred', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'PeriodRewardAmountSet', + }, { type: 'event', anonymous: false, @@ -1027,6 +1040,13 @@ export const rewardsDistributionAbi = [ outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], stateMutability: 'view', }, + { + type: 'function', + inputs: [], + name: 'getPeriodRewardAmount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, { type: 'function', inputs: [], @@ -1097,6 +1117,13 @@ export const rewardsDistributionAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [{ name: 'amount', internalType: 'uint256', type: 'uint256' }], + name: 'setPeriodRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', inputs: [ @@ -3477,6 +3504,19 @@ export const useReadRewardsDistributionGetDepositsByDepositor = functionName: 'getDepositsByDepositor', }) +/** + * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"getPeriodRewardAmount"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useReadRewardsDistributionGetPeriodRewardAmount = + /*#__PURE__*/ createUseReadContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'getPeriodRewardAmount', + }) + /** * Wraps __{@link useReadContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"implementation"` * @@ -3669,6 +3709,19 @@ export const useWriteRewardsDistributionRedelegate = functionName: 'redelegate', }) +/** + * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setPeriodRewardAmount"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWriteRewardsDistributionSetPeriodRewardAmount = + /*#__PURE__*/ createUseWriteContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'setPeriodRewardAmount', + }) + /** * Wraps __{@link useWriteContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` * @@ -3850,6 +3903,19 @@ export const useSimulateRewardsDistributionRedelegate = functionName: 'redelegate', }) +/** + * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setPeriodRewardAmount"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useSimulateRewardsDistributionSetPeriodRewardAmount = + /*#__PURE__*/ createUseSimulateContract({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + functionName: 'setPeriodRewardAmount', + }) + /** * Wraps __{@link useSimulateContract}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `functionName` set to `"setRewardNotifier"` * @@ -4096,6 +4162,19 @@ export const useWatchRewardsDistributionOwnershipTransferredEvent = eventName: 'OwnershipTransferred', }) +/** + * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"PeriodRewardAmountSet"` + * + * - [__View Contract on Base Basescan__](https://basescan.org/address/0x7c0422b31401C936172C897802CF0373B35B7698) + * - [__View Contract on Base Sepolia Basescan__](https://sepolia.basescan.org/address/0x08cC41b782F27d62995056a4EF2fCBAe0d3c266F) + */ +export const useWatchRewardsDistributionPeriodRewardAmountSetEvent = + /*#__PURE__*/ createUseWatchContractEvent({ + abi: rewardsDistributionAbi, + address: rewardsDistributionAddress, + eventName: 'PeriodRewardAmountSet', + }) + /** * Wraps __{@link useWatchContractEvent}__ with `abi` set to __{@link rewardsDistributionAbi}__ and `eventName` set to `"Redelegate"` * diff --git a/wagmi.config.ts b/wagmi.config.ts index d0427b8..52383cc 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -14,7 +14,7 @@ const env = loadEnv({ envDir: process.cwd(), }) -// https://sepolia.basescan.org/address/0x1bDcd58340c47Bb30A4fbD83016bBea2C63dE130#code +// https://sepolia.basescan.org/address/0x2852B5F72eE5A8867563c55547C1376CbbbBC7B3#code const rewardDistributionAbi = [ { inputs: [ @@ -188,6 +188,12 @@ const rewardDistributionAbi = [ name: 'OwnershipTransferred', type: 'event', }, + { + anonymous: false, + inputs: [{ indexed: false, internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'PeriodRewardAmountSet', + type: 'event', + }, { anonymous: false, inputs: [ @@ -340,6 +346,13 @@ const rewardDistributionAbi = [ stateMutability: 'view', type: 'function', }, + { + inputs: [], + name: 'getPeriodRewardAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, { inputs: [], name: 'implementation', @@ -410,6 +423,13 @@ const rewardDistributionAbi = [ stateMutability: 'nonpayable', type: 'function', }, + { + inputs: [{ internalType: 'uint256', name: 'amount', type: 'uint256' }], + name: 'setPeriodRewardAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, { inputs: [ { internalType: 'address', name: 'notifier', type: 'address' }, From 0711dacfd615f4849a62bba534bce82c856b491b Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 23:48:32 -0300 Subject: [PATCH 40/44] feat: approve first, then stake --- src/components/stake/increase-stake.tsx | 83 +++++++++++--- src/components/stake/operator-card.tsx | 126 +++++++++++++++------ src/components/stake/stake-to-operator.tsx | 88 +++++++++++--- src/lib/hooks/use-approve.ts | 38 +++++++ 4 files changed, 274 insertions(+), 61 deletions(-) create mode 100644 src/lib/hooks/use-approve.ts diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx index 5f51851..a4504b1 100644 --- a/src/components/stake/increase-stake.tsx +++ b/src/components/stake/increase-stake.tsx @@ -9,14 +9,21 @@ import { FormMessage, } from '@/components/ui/form' import { Input } from '@/components/ui/input' -import { useReadRewardsDistributionDepositById, useReadRiverTokenBalanceOf } from '@/contracts' +import { + rewardsDistributionAddress as _rewardsDistributionAddress, + useReadRewardsDistributionDepositById, + useReadRiverTokenBalanceOf, +} from '@/contracts' import type { StackableOperator } from '@/data/requests' +import { useApprove } from '@/lib/hooks/use-approve' import { useIncreaseStake } from '@/lib/hooks/use-increase-stake' import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { zodResolver } from '@hookform/resolvers/zod' import type { DialogContentProps } from '@radix-ui/react-dialog' -import { useCallback, useEffect, useMemo } from 'react' +import { useQueryClient } from '@tanstack/react-query' +import { useCallback, useEffect, useMemo, useState } from 'react' import { useForm } from 'react-hook-form' +import { parseUnits } from 'viem' import { useAccount } from 'wagmi' import * as z from 'zod' import { MaxButton } from '../max-button' @@ -28,7 +35,7 @@ import { OperatorCard } from './operator-card' type IncreaseStakeFormProps = { operator: StackableOperator depositId: bigint - onIncreaseStakeFinish?: (amount: number) => void + onIncreaseStakeFinish?: (amount: bigint) => void } export function IncreaseStakeForm({ @@ -36,7 +43,10 @@ export function IncreaseStakeForm({ depositId, onIncreaseStakeFinish, }: IncreaseStakeFormProps) { - const { address } = useAccount() + const { address, chainId } = useAccount() + const rewardsDistributionAddress = + _rewardsDistributionAddress[chainId as keyof typeof _rewardsDistributionAddress] + const queryClient = useQueryClient() const { data: balance } = useReadRiverTokenBalanceOf({ args: [address!], query: { enabled: !!address }, @@ -57,10 +67,20 @@ export function IncreaseStakeForm({ [avaliableBalance], ) + const { + allowance, + approve, + isApproving, + isApproveTxPending, + isApproveTxConfirmed, + queryKey: allowanceQueryKey, + } = useApprove(rewardsDistributionAddress) + const form = useForm>({ resolver: zodResolver(formSchema), }) + const [lastAmount, setLastAmount] = useState(0) const { data: currentDeposit, isPending: isCurrentDepositPending } = useReadRewardsDistributionDepositById({ args: [depositId], @@ -68,14 +88,31 @@ export function IncreaseStakeForm({ }) const { increaseStake, isPending, isTxPending, isTxConfirmed } = useIncreaseStake(depositId) - const isStaking = isPending || isTxPending useEffect(() => { if (isTxConfirmed) { - onIncreaseStakeFinish?.(form.getValues('amount')) - form.reset() + queryClient.invalidateQueries({ queryKey: allowanceQueryKey }) + onIncreaseStakeFinish?.(parseUnits(lastAmount.toString(), 18)) } - }, [isTxConfirmed, onIncreaseStakeFinish, form]) + }, [isTxConfirmed, onIncreaseStakeFinish, form, queryClient, allowanceQueryKey, lastAmount]) + + const isAllowed = + !!allowance && + BigInt(allowance) >= BigInt(parseUnits((form.watch('amount') ?? 0).toString(), 18)) + + const isStaking = isPending || isTxPending + const isWaitingForApproval = isApproving || isApproveTxPending + + useEffect(() => { + if (isApproveTxConfirmed && !isStaking) { + const amount = form.getValues('amount') + if (!amount) return + setLastAmount(amount) + increaseStake({ + args: [depositId, parseUnits(amount.toString(), 18)], + }) + } + }, [isApproveTxConfirmed, form, increaseStake, depositId, isStaking, setLastAmount]) const handleSetMax = useCallback(() => { form.setValue('amount', Number(avaliableBalance)) @@ -84,11 +121,18 @@ export function IncreaseStakeForm({ return ( + onSubmit={form.handleSubmit((values) => { + if (!isAllowed) { + approve({ + args: [rewardsDistributionAddress, parseUnits(values.amount.toString(), 18)], + }) + return + } + setLastAmount(values.amount) increaseStake({ - args: [depositId, BigInt(values.amount)], - }), - )} + args: [depositId, parseUnits(values.amount.toString(), 18)], + }) + })} className="space-y-6 py-4" >
@@ -135,8 +179,19 @@ export function IncreaseStakeForm({ )} /> - diff --git a/src/components/stake/operator-card.tsx b/src/components/stake/operator-card.tsx index e7521a6..ea2493e 100644 --- a/src/components/stake/operator-card.tsx +++ b/src/components/stake/operator-card.tsx @@ -57,9 +57,24 @@ export function OperatorCard({ const { lockCooldown } = useWithdraw(depositId) const withdrawTimer = useWithdrawTimer(lockCooldown) - const [openRedelegate, setOpenRedelegate] = useState(false) - const [openWithdraw, setOpenWithdraw] = useState(false) - const [openCancelWithdraw, setOpenCancelWithdraw] = useState(false) + const [open, setOpen] = useState< + 'stake' | 'increase-stake' | 'redelegate' | 'withdraw' | 'cancel-withdraw' | null + >(null) + const { + isStakeOpen, + isIncreaseStakeOpen, + isRedelegateOpen, + isWithdrawOpen, + isCancelWithdrawOpen, + } = useMemo(() => { + return { + isStakeOpen: open === 'stake', + isIncreaseStakeOpen: open === 'increase-stake', + isRedelegateOpen: open === 'redelegate', + isWithdrawOpen: open === 'withdraw', + isCancelWithdrawOpen: open === 'cancel-withdraw', + } + }, [open]) const stakeState = useMemo(() => { if (!deposits) return 'stakeable' @@ -136,30 +151,51 @@ export function OperatorCard({ {showButton ? (
{stakeState === 'stakeable' && ( - - - - - { - toast({ - title: 'Stake finished', - description: `You have staked ${formatRVRAmount(BigInt(amount))} RVR to ${operator.name}`, - }) - }} - /> - + <> + setOpen(open ? 'stake' : null)} + > + + + + { + toast({ + title: 'Stake finished', + description: `You have staked ${formatRVRAmount(BigInt(amount))} RVR to ${operator.name}`, + }) + setOpen(null) + }} + /> + + )} {stakeState === 'staked' && depositId && ( <> - + setOpen(open ? 'increase-stake' : null)} + > - + { + toast({ + title: 'Increase stake finished', + description: `You have increased your stake to ${formatRVRAmount(BigInt(amount) + deposits.amount)} RVR to ${operator.name}`, + }) + setOpen(null) + }} + /> @@ -174,17 +210,13 @@ export function OperatorCard({ - setOpenRedelegate(true)} - asChild - > + setOpen('redelegate')} asChild>
Redelegate
- setOpenWithdraw(true)} asChild> + setOpen('withdraw')} asChild>
Withdraw @@ -214,7 +246,7 @@ export function OperatorCard({ setOpenCancelWithdraw(true)} + onClick={() => setOpen('cancel-withdraw')} asChild >
@@ -236,7 +268,7 @@ export function OperatorCard({ operator={operator} depositId={depositId} onWithdrawFinish={(amount) => { - setOpenWithdraw(false) + setOpen(null) toast({ title: 'Withdraw finished.', description: `You have withdrawn ${formatRVRAmount(amount)} RVR.`, @@ -259,7 +291,7 @@ export function OperatorCard({ setOpenCancelWithdraw(true)} + onClick={() => setOpen('cancel-withdraw')} asChild >
@@ -275,37 +307,63 @@ export function OperatorCard({ ) : null} - + setOpen(open ? 'redelegate' : null)} + modal + > { + toast({ + title: 'Redelegation finished', + description: `You redelegated your stake to ${redelegatedOperator.name}`, + }) + setOpen(null) + }} /> {/* Cancel withdraw is pretty much redelegating */} - + setOpen(open ? 'cancel-withdraw' : null)} + modal + > { + toast({ + title: 'Withdraw cancelled', + description: 'Your withdrawal has been cancelled', + }) + setOpen(null) + }} /> - + setOpen(open ? 'withdraw' : null)} + > { - setOpenWithdraw(false) toast({ title: 'Withdraw initiated', description: 'Your withdrawal is being processed', }) + setOpen(null) }} /> diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 11fb34c..0c18ff8 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -9,15 +9,20 @@ import { FormMessage, } from '@/components/ui/form' import { Input } from '@/components/ui/input' -import { useReadRiverTokenBalanceOf } from '@/contracts' +import { + rewardsDistributionAddress as _rewardsDistributionAddress, + useReadRiverTokenBalanceOf, +} from '@/contracts' import type { StackableOperator } from '@/data/requests' +import { useApprove } from '@/lib/hooks/use-approve' import { useStake } from '@/lib/hooks/use-stake' import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' import { zodResolver } from '@hookform/resolvers/zod' import type { DialogContentProps } from '@radix-ui/react-dialog' -import { useCallback, useEffect, useMemo } from 'react' +import { useQueryClient } from '@tanstack/react-query' +import { useCallback, useEffect, useMemo, useState } from 'react' import { useForm } from 'react-hook-form' -import { isAddress, type Address } from 'viem' +import { isAddress, parseUnits, type Address } from 'viem' import { useAccount } from 'wagmi' import * as z from 'zod' import { MaxButton } from '../max-button' @@ -30,7 +35,10 @@ type StakeFormProps = { } export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { - const { address } = useAccount() + const { address, chainId } = useAccount() + const rewardsDistributionAddress = + _rewardsDistributionAddress[chainId as keyof typeof _rewardsDistributionAddress] + const queryClient = useQueryClient() const { data: balance } = useReadRiverTokenBalanceOf({ args: [address!], query: { enabled: !!address }, @@ -54,6 +62,15 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { [avaliableBalance], ) + const { + allowance, + approve, + isApproving, + isApproveTxPending, + isApproveTxConfirmed, + queryKey: allowanceQueryKey, + } = useApprove(rewardsDistributionAddress) + const form = useForm>({ resolver: zodResolver(formSchema), defaultValues: { @@ -61,15 +78,38 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { }, }) + const [lastAmount, setLastAmount] = useState(0) const { stake, isPending, isTxPending, isTxConfirmed } = useStake() - const isStaking = isPending || isTxPending useEffect(() => { if (isTxConfirmed) { - onStakeFinish?.(Number(form.getValues('amount'))) + queryClient.invalidateQueries({ queryKey: allowanceQueryKey }) + onStakeFinish?.(lastAmount) form.reset() } - }, [isTxConfirmed, onStakeFinish, form]) + }, [isTxConfirmed, onStakeFinish, form, queryClient, allowanceQueryKey, lastAmount]) + + const isAllowed = + !!allowance && + BigInt(allowance) >= BigInt(parseUnits((form.watch('amount') ?? 0).toString(), 18)) + + const isStaking = isPending || isTxPending + const isWaitingForApproval = isApproving || isApproveTxPending + + useEffect(() => { + if (isApproveTxConfirmed && !isStaking) { + const amount = form.getValues('amount') + if (!amount) return + setLastAmount(amount) + stake({ + args: [ + parseUnits(amount.toString(), 18), + operator.address, + form.getValues('beneficiary') as Address, + ], + }) + } + }, [form, isApproveTxConfirmed, isStaking, operator.address, stake, setLastAmount]) const handleSetMax = useCallback(() => { form.setValue('amount', Number(avaliableBalance)) @@ -78,11 +118,22 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { return (
+ onSubmit={form.handleSubmit((values) => { + if (!isAllowed) { + approve({ + args: [rewardsDistributionAddress, parseUnits(values.amount.toString(), 18)], + }) + return + } + setLastAmount(values.amount) stake({ - args: [BigInt(values.amount), operator.address, values.beneficiary as Address], - }), - )} + args: [ + parseUnits(values.amount.toString(), 18), + operator.address, + values.beneficiary as Address, + ], + }) + })} className="space-y-6 py-4" >
@@ -138,8 +189,19 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { )} /> - diff --git a/src/lib/hooks/use-approve.ts b/src/lib/hooks/use-approve.ts new file mode 100644 index 0000000..ca9633a --- /dev/null +++ b/src/lib/hooks/use-approve.ts @@ -0,0 +1,38 @@ +import { useReadRiverTokenAllowance, useWriteRiverTokenApprove } from '@/contracts' +import type { Address } from 'viem' +import { useAccount, useWaitForTransactionReceipt } from 'wagmi' + +export const useApprove = (to: Address) => { + const { address } = useAccount() + const { data: allowance, queryKey: allowanceQueryKey } = useReadRiverTokenAllowance({ + args: [address!, to], + query: { + enabled: !!address, + }, + }) + + const { + writeContract: approve, + isPending: isApprovePending, + data: hash, + } = useWriteRiverTokenApprove({ + mutation: { + onError: (err) => { + console.error(err) + }, + }, + }) + + const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ + hash, + }) + + return { + allowance, + isApproving: isApprovePending, + isApproveTxPending: isTxPending, + isApproveTxConfirmed: isTxConfirmed, + approve, + queryKey: allowanceQueryKey, + } +} From 02d182cbc4103fec2e4efb9a81f1a9d954930bdb Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Mon, 13 Jan 2025 23:50:08 -0300 Subject: [PATCH 41/44] tons of cache invalidations --- src/components/delegate/delegate-section.tsx | 10 +++++++++- src/components/delegate/redelegate-button.tsx | 11 ++++------- src/components/delegate/redelegate-dialog.tsx | 3 +++ src/components/stake/redelegate.tsx | 9 +++++---- src/components/stake/stake-to-operator.tsx | 4 ++-- src/lib/hooks/use-claim.ts | 3 +-- src/lib/hooks/use-increase-stake.ts | 10 +++++++--- src/lib/hooks/use-initiate-withdraw.ts | 11 +++++++++++ src/lib/hooks/use-redelegate.ts | 10 +++++++--- src/lib/hooks/use-stake.ts | 6 ++++-- src/lib/hooks/use-stakeable-operators.ts | 1 + src/lib/hooks/use-withdraw.ts | 6 ++++-- 12 files changed, 58 insertions(+), 26 deletions(-) diff --git a/src/components/delegate/delegate-section.tsx b/src/components/delegate/delegate-section.tsx index a229d3a..71e396e 100644 --- a/src/components/delegate/delegate-section.tsx +++ b/src/components/delegate/delegate-section.tsx @@ -1,9 +1,10 @@ import { useRedelegate } from '@/lib/hooks/use-redelegate' -import { cn } from '@/lib/utils' +import { cn, formatAddress } from '@/lib/utils' import { useRouter, useSearchParams } from 'next/navigation' import { Button } from '../ui/button' import { Dialog, DialogTrigger } from '../ui/dialog' import { Typography } from '../ui/typography' +import { toast } from '../ui/use-toast' import { WalletInfo } from '../wallet-info' import { AuthorizeClaimerForm } from './authorize-claimer-form' import { DelegateForm } from './delegate-form' @@ -73,6 +74,13 @@ export const DelegateSection = () => { { + toast({ + title: `You've redelegated your RVR balance to ${ + redelegatedOperator.name ?? formatAddress(redelegatedOperator.address) + }.`, + }) + }} variant="secondary" /> ) : ( diff --git a/src/components/delegate/redelegate-button.tsx b/src/components/delegate/redelegate-button.tsx index 8afc013..6ea4129 100644 --- a/src/components/delegate/redelegate-button.tsx +++ b/src/components/delegate/redelegate-button.tsx @@ -1,6 +1,6 @@ +import type { StackableOperator } from '@/data/requests' import { useRedelegate } from '@/lib/hooks/use-redelegate' import { useOperatorsWithDeposits } from '@/lib/hooks/use-stakeable-operators' -import { formatAddress } from '@/lib/utils' import { Check } from 'lucide-react' import { useEffect, useMemo } from 'react' import type { Address } from 'viem' @@ -18,7 +18,7 @@ export const RedelegateButton = ({ delegatedAddress: Address | undefined variant?: 'primary' | 'secondary' className?: string - onRedelegateFinish?: () => void + onRedelegateFinish?: (operator: StackableOperator) => void }) => { const { toast } = useToast() const { isTxConfirmed, isPending, isTxPending, writeRedelegate } = useRedelegate() @@ -30,12 +30,9 @@ export const RedelegateButton = ({ useEffect(() => { if (isTxConfirmed && delegatedAddress) { - toast({ - title: `You've redelegated your RVR balance to ${formatAddress(delegatedAddress)}.`, - }) - onRedelegateFinish?.() + onRedelegateFinish?.(lookup[delegatedAddress]) } - }, [delegatedAddress, isTxConfirmed, onRedelegateFinish, toast]) + }, [delegatedAddress, isTxConfirmed, lookup, onRedelegateFinish, toast]) return (
diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 0c18ff8..3ff365e 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -200,8 +200,8 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { : isWaitingForApproval ? 'Approving...' : isStaking - ? 'Increasing Stake...' - : 'Increase Stake'} + ? 'Staking...' + : 'Stake'} diff --git a/src/lib/hooks/use-claim.ts b/src/lib/hooks/use-claim.ts index 1e1ecba..a8b50c7 100644 --- a/src/lib/hooks/use-claim.ts +++ b/src/lib/hooks/use-claim.ts @@ -61,8 +61,7 @@ export const useClaim = () => { .then(() => { confetti.clearCanvas() }), - qc.invalidateQueries({ queryKey: [riverBalanceQueryKey] }), - qc.invalidateQueries({ queryKey: [riverClaimBalanceQueryKey] }), + qc.invalidateQueries({ queryKey: [riverBalanceQueryKey, riverClaimBalanceQueryKey] }), ]) } }, [confetti, isTxConfirmed, qc, riverBalanceQueryKey, riverClaimBalanceQueryKey]) diff --git a/src/lib/hooks/use-increase-stake.ts b/src/lib/hooks/use-increase-stake.ts index 638f042..2d55acf 100644 --- a/src/lib/hooks/use-increase-stake.ts +++ b/src/lib/hooks/use-increase-stake.ts @@ -7,6 +7,7 @@ import { import { useQueryClient } from '@tanstack/react-query' import { useEffect } from 'react' import { useAccount, useWaitForTransactionReceipt } from 'wagmi' +import { useOperatorsWithDeposits } from './use-stakeable-operators' export const useIncreaseStake = (depositId: bigint) => { const { address } = useAccount() @@ -34,12 +35,15 @@ export const useIncreaseStake = (depositId: bigint) => { }, }) + const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() + useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [currentDepositQueryKey] }) - qc.invalidateQueries({ queryKey: [stakingStateQueryKey] }) + qc.invalidateQueries({ + queryKey: [currentDepositQueryKey, stakingStateQueryKey, operatorsQueryKey], + }) } - }, [isTxConfirmed, qc, currentDepositQueryKey, stakingStateQueryKey]) + }, [isTxConfirmed, qc, currentDepositQueryKey, stakingStateQueryKey, operatorsQueryKey]) return { increaseStake, diff --git a/src/lib/hooks/use-initiate-withdraw.ts b/src/lib/hooks/use-initiate-withdraw.ts index e488b8d..65e6265 100644 --- a/src/lib/hooks/use-initiate-withdraw.ts +++ b/src/lib/hooks/use-initiate-withdraw.ts @@ -1,8 +1,12 @@ 'use client' import { useWriteRewardsDistributionInitiateWithdraw } from '@/contracts' +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' import { useWaitForTransactionReceipt } from 'wagmi' +import { useOperatorsWithDeposits } from './use-stakeable-operators' export const useInitiateWithdraw = () => { + const qc = useQueryClient() const { writeContract: initiateWithdraw, data: hash, @@ -14,10 +18,17 @@ export const useInitiateWithdraw = () => { }, }, }) + const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() const { isLoading: isTxPending, isSuccess: isTxConfirmed } = useWaitForTransactionReceipt({ hash: hash, }) + useEffect(() => { + if (isTxConfirmed) { + qc.invalidateQueries({ queryKey: [operatorsQueryKey] }) + } + }, [isTxConfirmed, operatorsQueryKey, qc]) + return { initiateWithdraw, isPending, diff --git a/src/lib/hooks/use-redelegate.ts b/src/lib/hooks/use-redelegate.ts index cb6a510..8e5054a 100644 --- a/src/lib/hooks/use-redelegate.ts +++ b/src/lib/hooks/use-redelegate.ts @@ -11,6 +11,7 @@ import { useEffect, useMemo } from 'react' import type { Address } from 'viem' import { base, baseSepolia } from 'viem/chains' import { useAccount, useReadContracts, useWaitForTransactionReceipt } from 'wagmi' +import { useOperatorsWithDeposits } from './use-stakeable-operators' const isRiverInvalidTokenAmountError = (error: Error) => { return error.message.includes('River__InvalidTokenAmount') @@ -23,7 +24,6 @@ const isBase = (chainId?: number) => { export const useRedelegate = () => { const qc = useQueryClient() const { address, chainId } = useAccount() - const { data: depositIds } = useReadRewardsDistributionGetDepositsByDepositor({ args: [address!], }) @@ -83,12 +83,16 @@ export const useRedelegate = () => { }) const { queryKey: delegateeQueryKey } = useReadRiverTokenDelegates() + const { queryKey: depositQueryKey } = useReadRewardsDistributionGetDepositsByDepositor({ + args: [address!], + }) + const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: delegateeQueryKey }) + qc.invalidateQueries({ queryKey: [delegateeQueryKey, depositQueryKey, operatorsQueryKey] }) } - }, [delegateeQueryKey, isTxConfirmed, qc]) + }, [delegateeQueryKey, depositQueryKey, isTxConfirmed, operatorsQueryKey, qc]) return { isTxConfirmed, diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts index fd3f818..e07314e 100644 --- a/src/lib/hooks/use-stake.ts +++ b/src/lib/hooks/use-stake.ts @@ -6,6 +6,7 @@ import { import { useQueryClient } from '@tanstack/react-query' import { useEffect } from 'react' import { useWaitForTransactionReceipt } from 'wagmi' +import { useOperatorsWithDeposits } from './use-stakeable-operators' export const useStake = () => { const qc = useQueryClient() @@ -30,12 +31,13 @@ export const useStake = () => { data: stakingState, isPending: isStakingStatePending, } = useReadRewardsDistributionStakingState() + const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [stakingStateQueryKey] }) + qc.invalidateQueries({ queryKey: [stakingStateQueryKey, operatorsQueryKey] }) } - }, [isTxConfirmed, qc, stakingStateQueryKey]) + }, [isTxConfirmed, qc, stakingStateQueryKey, operatorsQueryKey]) return { stake, diff --git a/src/lib/hooks/use-stakeable-operators.ts b/src/lib/hooks/use-stakeable-operators.ts index daab9b6..50ae450 100644 --- a/src/lib/hooks/use-stakeable-operators.ts +++ b/src/lib/hooks/use-stakeable-operators.ts @@ -100,5 +100,6 @@ export const useOperatorsWithDeposits = (initialData?: StakeableOperatorsRespons return { data: isConnected ? operatorsWithDeposits : operators, + queryKey: depositsQueries.queryKey, } } diff --git a/src/lib/hooks/use-withdraw.ts b/src/lib/hooks/use-withdraw.ts index b33dd29..5520167 100644 --- a/src/lib/hooks/use-withdraw.ts +++ b/src/lib/hooks/use-withdraw.ts @@ -7,6 +7,7 @@ import { import { useQueryClient } from '@tanstack/react-query' import { useCallback, useEffect } from 'react' import { useAccount, useWaitForTransactionReceipt } from 'wagmi' +import { useOperatorsWithDeposits } from './use-stakeable-operators' export const useWithdraw = (depositId: bigint | undefined) => { const { address } = useAccount() @@ -33,6 +34,7 @@ export const useWithdraw = (depositId: bigint | undefined) => { enabled: !!depositId, }, }) + const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() const amountToWithdraw = deposit?.amount const withdraw = useCallback(() => { @@ -44,9 +46,9 @@ export const useWithdraw = (depositId: bigint | undefined) => { useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: depositQueryKey }) + qc.invalidateQueries({ queryKey: [depositQueryKey, operatorsQueryKey] }) } - }, [isTxConfirmed]) + }, [depositQueryKey, isTxConfirmed, operatorsQueryKey, qc]) return { withdraw, From 048dd7c77db633626588deb93867a7b0ccd4f7a4 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 14 Jan 2025 18:34:31 -0300 Subject: [PATCH 42/44] fix: staking / approving text --- src/components/stake/increase-stake.tsx | 13 ++++++------- src/components/stake/stake-to-operator.tsx | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/stake/increase-stake.tsx b/src/components/stake/increase-stake.tsx index a4504b1..33fe150 100644 --- a/src/components/stake/increase-stake.tsx +++ b/src/components/stake/increase-stake.tsx @@ -185,13 +185,12 @@ export function IncreaseStakeForm({ disabled={isStaking || isWaitingForApproval} isLoading={isStaking || isWaitingForApproval} > - {!isAllowed - ? 'Approve' - : isWaitingForApproval - ? 'Approving...' - : isStaking - ? 'Increasing Stake...' - : 'Increase Stake'} + {(() => { + if (isStaking) return 'Increasing Stake...' + if (isWaitingForApproval) return 'Approving...' + if (!isAllowed) return 'Approve' + return 'Increase Stake' + })()} diff --git a/src/components/stake/stake-to-operator.tsx b/src/components/stake/stake-to-operator.tsx index 3ff365e..36e5071 100644 --- a/src/components/stake/stake-to-operator.tsx +++ b/src/components/stake/stake-to-operator.tsx @@ -195,13 +195,12 @@ export function StakeForm({ operator, onStakeFinish }: StakeFormProps) { disabled={isStaking || isWaitingForApproval} isLoading={isStaking || isWaitingForApproval} > - {!isAllowed - ? 'Approve' - : isWaitingForApproval - ? 'Approving...' - : isStaking - ? 'Staking...' - : 'Stake'} + {(() => { + if (isStaking) return 'Staking...' + if (isWaitingForApproval) return 'Approving...' + if (!isAllowed) return 'Approve' + return 'Stake' + })()} From ffb41fd3cb356bdc9f8bf36f2c802851c1712ddf Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 14 Jan 2025 18:35:04 -0300 Subject: [PATCH 43/44] fix cache invalidation --- src/lib/hooks/use-claim.ts | 3 ++- src/lib/hooks/use-increase-stake.ts | 18 ++++++++++++++---- src/lib/hooks/use-initiate-withdraw.ts | 2 +- src/lib/hooks/use-redelegate.ts | 4 +++- src/lib/hooks/use-stake.ts | 8 ++++++-- src/lib/hooks/use-withdraw.ts | 3 ++- 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/lib/hooks/use-claim.ts b/src/lib/hooks/use-claim.ts index a8b50c7..707a2f7 100644 --- a/src/lib/hooks/use-claim.ts +++ b/src/lib/hooks/use-claim.ts @@ -61,7 +61,8 @@ export const useClaim = () => { .then(() => { confetti.clearCanvas() }), - qc.invalidateQueries({ queryKey: [riverBalanceQueryKey, riverClaimBalanceQueryKey] }), + qc.invalidateQueries({ queryKey: riverBalanceQueryKey }), + qc.invalidateQueries({ queryKey: riverClaimBalanceQueryKey }), ]) } }, [confetti, isTxConfirmed, qc, riverBalanceQueryKey, riverClaimBalanceQueryKey]) diff --git a/src/lib/hooks/use-increase-stake.ts b/src/lib/hooks/use-increase-stake.ts index 2d55acf..2f09422 100644 --- a/src/lib/hooks/use-increase-stake.ts +++ b/src/lib/hooks/use-increase-stake.ts @@ -1,6 +1,7 @@ 'use client' import { useReadRewardsDistributionDepositById, + useReadRewardsDistributionGetDepositsByDepositor, useReadRewardsDistributionStakingState, useWriteRewardsDistributionIncreaseStake, } from '@/contracts' @@ -36,14 +37,23 @@ export const useIncreaseStake = (depositId: bigint) => { }) const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() + const { queryKey: depositsQueryKey } = useReadRewardsDistributionGetDepositsByDepositor() useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ - queryKey: [currentDepositQueryKey, stakingStateQueryKey, operatorsQueryKey], - }) + qc.invalidateQueries({ queryKey: currentDepositQueryKey }) + qc.invalidateQueries({ queryKey: stakingStateQueryKey }) + qc.invalidateQueries({ queryKey: operatorsQueryKey }) + qc.invalidateQueries({ queryKey: depositsQueryKey }) } - }, [isTxConfirmed, qc, currentDepositQueryKey, stakingStateQueryKey, operatorsQueryKey]) + }, [ + isTxConfirmed, + qc, + currentDepositQueryKey, + stakingStateQueryKey, + operatorsQueryKey, + depositsQueryKey, + ]) return { increaseStake, diff --git a/src/lib/hooks/use-initiate-withdraw.ts b/src/lib/hooks/use-initiate-withdraw.ts index 65e6265..5e43845 100644 --- a/src/lib/hooks/use-initiate-withdraw.ts +++ b/src/lib/hooks/use-initiate-withdraw.ts @@ -25,7 +25,7 @@ export const useInitiateWithdraw = () => { useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [operatorsQueryKey] }) + qc.invalidateQueries({ queryKey: operatorsQueryKey }) } }, [isTxConfirmed, operatorsQueryKey, qc]) diff --git a/src/lib/hooks/use-redelegate.ts b/src/lib/hooks/use-redelegate.ts index 8e5054a..215820e 100644 --- a/src/lib/hooks/use-redelegate.ts +++ b/src/lib/hooks/use-redelegate.ts @@ -90,7 +90,9 @@ export const useRedelegate = () => { useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [delegateeQueryKey, depositQueryKey, operatorsQueryKey] }) + qc.invalidateQueries({ queryKey: delegateeQueryKey }) + qc.invalidateQueries({ queryKey: depositQueryKey }) + qc.invalidateQueries({ queryKey: operatorsQueryKey }) } }, [delegateeQueryKey, depositQueryKey, isTxConfirmed, operatorsQueryKey, qc]) diff --git a/src/lib/hooks/use-stake.ts b/src/lib/hooks/use-stake.ts index e07314e..502f788 100644 --- a/src/lib/hooks/use-stake.ts +++ b/src/lib/hooks/use-stake.ts @@ -1,5 +1,6 @@ 'use client' import { + useReadRewardsDistributionGetDepositsByDepositor, useReadRewardsDistributionStakingState, useWriteRewardsDistributionStake, } from '@/contracts' @@ -32,12 +33,15 @@ export const useStake = () => { isPending: isStakingStatePending, } = useReadRewardsDistributionStakingState() const { queryKey: operatorsQueryKey } = useOperatorsWithDeposits() + const { queryKey: depositsQueryKey } = useReadRewardsDistributionGetDepositsByDepositor() useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [stakingStateQueryKey, operatorsQueryKey] }) + qc.invalidateQueries({ queryKey: stakingStateQueryKey }) + qc.invalidateQueries({ queryKey: operatorsQueryKey }) + qc.invalidateQueries({ queryKey: depositsQueryKey }) } - }, [isTxConfirmed, qc, stakingStateQueryKey, operatorsQueryKey]) + }, [isTxConfirmed, qc, stakingStateQueryKey, operatorsQueryKey, depositsQueryKey]) return { stake, diff --git a/src/lib/hooks/use-withdraw.ts b/src/lib/hooks/use-withdraw.ts index 5520167..b8b7435 100644 --- a/src/lib/hooks/use-withdraw.ts +++ b/src/lib/hooks/use-withdraw.ts @@ -46,7 +46,8 @@ export const useWithdraw = (depositId: bigint | undefined) => { useEffect(() => { if (isTxConfirmed) { - qc.invalidateQueries({ queryKey: [depositQueryKey, operatorsQueryKey] }) + qc.invalidateQueries({ queryKey: depositQueryKey }) + qc.invalidateQueries({ queryKey: operatorsQueryKey }) } }, [depositQueryKey, isTxConfirmed, operatorsQueryKey, qc]) From fd1637e5b0ce0009d8f335af5dc6f00b1a6ac756 Mon Sep 17 00:00:00 2001 From: Miguel Nascimento Date: Tue, 21 Jan 2025 13:00:50 -0300 Subject: [PATCH 44/44] wip: my stakes profile page (slow - no ssr) --- .../stake/profile/connect-wallet.tsx | 32 +++++ .../stake/profile/my-stakes.tsx | 116 ++++++++++++++++++ .../(requires-wallet)/stake/profile/page.tsx | 35 ++++++ src/components/features/features-mobile.tsx | 6 +- src/components/stake/all-operators.tsx | 31 +++-- src/components/stake/your-account.tsx | 86 ++++++------- src/components/stake/your-rewards.tsx | 1 + src/components/ui/card.tsx | 37 +++++- src/lib/hooks/use-stakeable-operators.ts | 29 +++-- 9 files changed, 304 insertions(+), 69 deletions(-) create mode 100644 src/app/(requires-wallet)/stake/profile/connect-wallet.tsx create mode 100644 src/app/(requires-wallet)/stake/profile/my-stakes.tsx create mode 100644 src/app/(requires-wallet)/stake/profile/page.tsx diff --git a/src/app/(requires-wallet)/stake/profile/connect-wallet.tsx b/src/app/(requires-wallet)/stake/profile/connect-wallet.tsx new file mode 100644 index 0000000..fdc95fd --- /dev/null +++ b/src/app/(requires-wallet)/stake/profile/connect-wallet.tsx @@ -0,0 +1,32 @@ +import { DelegateAscii } from '@/components/delegate/delegate-ascii' +import { ConnectWalletButton } from '@/components/ui/connect-wallet-button' +import { Typography } from '@/components/ui/typography' +import { cn } from '@/lib/utils' + +export const ConnectWalletSection = () => { + return ( +
+ +
+ + My Stakes + + + View your staked RVR + +
+ Connect Wallet +
+ ) +} diff --git a/src/app/(requires-wallet)/stake/profile/my-stakes.tsx b/src/app/(requires-wallet)/stake/profile/my-stakes.tsx new file mode 100644 index 0000000..896a2d8 --- /dev/null +++ b/src/app/(requires-wallet)/stake/profile/my-stakes.tsx @@ -0,0 +1,116 @@ +import { OperatorCard } from '@/components/stake/operator-card' +import { SwitchToBase } from '@/components/switch-to-base' +import { Button, buttonVariants } from '@/components/ui/button' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import { useOperatorsWithDeposits, type Deposit } from '@/lib/hooks/use-stakeable-operators' +import { useWithdraw } from '@/lib/hooks/use-withdraw' +import { useWithdrawTimer } from '@/lib/hooks/use-withdraw-timer' +import { cn } from '@/lib/utils' +import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' +import Link from 'next/link' +import { useMemo } from 'react' + +export const MyStakesSection = () => { + // TODO: this is slow and should be better with a better initial data + const { data: operators, pendingWithdrawals } = useOperatorsWithDeposits() + + const myStakes = useMemo(() => operators.filter((operator) => operator.deposits), [operators]) + + return ( +
+
+ + +
+

My Stakes

+ {myStakes.length === 0 ? ( +
+
+

+ You currently have no stakes. Stake to start earning rewards. +

+
+ + Stake + +
+
+
+ ) : ( +
2 ? 'md:grid-cols-2' : 'md:grid-cols-1', + )} + > + {myStakes.map((operator) => ( + + ))} +
+ )} +
+ {pendingWithdrawals && ( +
+

Pending Withdrawals

+
2 ? 'grid-cols-2' : 'grid-cols-1', + )} + > + {pendingWithdrawals.map((withdrawal) => ( + + ))} +
+
+ )} +
+
+ ) +} + +const WithdrawalCard = ({ withdrawal }: { withdrawal: Deposit }) => { + const { lockCooldown } = useWithdraw(withdrawal.depositId) + const withdrawTimer = useWithdrawTimer(lockCooldown) + const isWithdrawable = withdrawTimer === null + + return ( + + + + {formatRVRAmount(withdrawal.pendingWithdrawal)} RVR + + + +

+
+ Time left + {withdrawTimer} +
+
+ + {isWithdrawable && } +
+
+
+ ) +} diff --git a/src/app/(requires-wallet)/stake/profile/page.tsx b/src/app/(requires-wallet)/stake/profile/page.tsx new file mode 100644 index 0000000..21d91d1 --- /dev/null +++ b/src/app/(requires-wallet)/stake/profile/page.tsx @@ -0,0 +1,35 @@ +'use client' + +import { Loader2 } from 'lucide-react' +import dynamic from 'next/dynamic' +import { useAccount } from 'wagmi' + +const Loading = () => { + return ( +
+
+ +
+
+ ) +} + +const ConnectWalletSection = dynamic( + () => import('./connect-wallet').then((mod) => mod.ConnectWalletSection), + { + loading: Loading, + ssr: false, + }, +) + +const MyStakesSection = dynamic(() => import('./my-stakes').then((mod) => mod.MyStakesSection), { + loading: Loading, + ssr: false, +}) + +const MyStakesPage = () => { + const { isConnected } = useAccount() + return isConnected ? : +} + +export default MyStakesPage diff --git a/src/components/features/features-mobile.tsx b/src/components/features/features-mobile.tsx index 98d6b82..cd189b9 100644 --- a/src/components/features/features-mobile.tsx +++ b/src/components/features/features-mobile.tsx @@ -3,7 +3,7 @@ /* eslint-disable react/jsx-no-target-blank */ import { SiteDataQuery } from '@/gql/graphql' import Image from 'next/image' -import { Card, CardContent } from '../ui/card' +import { CardContent, HoverableCard } from '../ui/card' import { Typography } from '../ui/typography' export default function FeaturesMobile({ cms }: { cms: SiteDataQuery }) { @@ -22,7 +22,7 @@ export default function FeaturesMobile({ cms }: { cms: SiteDataQuery }) { diff --git a/src/components/stake/all-operators.tsx b/src/components/stake/all-operators.tsx index c5bdfb1..bde55f0 100644 --- a/src/components/stake/all-operators.tsx +++ b/src/components/stake/all-operators.tsx @@ -9,13 +9,14 @@ import { useAccount } from 'wagmi' import { Typography } from '../ui/typography' import { OperatorCard } from './operator-card' +import { Loader2 } from 'lucide-react' import { baseSepolia } from 'viem/chains' export const AllOperators = ({ initialData, }: { initialData: StakeableOperatorsResponse | undefined }) => { - const { data: operatorsWithDeposits } = useOperatorsWithDeposits(initialData) + const { data: operatorsWithDeposits, isLoading } = useOperatorsWithDeposits(initialData) const { chainId } = useAccount() const env = chainId === baseSepolia.id ? 'gamma' : 'omega' @@ -30,17 +31,23 @@ export const AllOperators = ({ To distribute power on the network, please delegate to top performing operators.
-
- {operatorsWithDeposits.map((operator: OperatorWithDeposits) => ( - - ))} -
+ {isLoading ? ( +
+ +
+ ) : ( +
+ {operatorsWithDeposits.map((operator: OperatorWithDeposits) => ( + + ))} +
+ )}
) } diff --git a/src/components/stake/your-account.tsx b/src/components/stake/your-account.tsx index bb2cd70..c21c3da 100644 --- a/src/components/stake/your-account.tsx +++ b/src/components/stake/your-account.tsx @@ -4,10 +4,11 @@ import { useReadRewardsDistributionStakedByDepositor, useReadRiverTokenBalanceOf, } from '@/contracts' +import { cn } from '@/lib/utils' import { formatRVRAmount } from '@/lib/utils/formatRVRAmount' -import { useEffect, useRef } from 'react' +import Link from 'next/link' import { useAccount } from 'wagmi' -import { Button } from '../ui/button' +import { buttonVariants } from '../ui/button' import { Card, CardContent, CardHeader, CardTitle } from '../ui/card' import { ConnectWalletButton } from '../ui/connect-wallet-button' import { Skeleton } from '../ui/skeleton' @@ -25,54 +26,53 @@ export const YourAccountCard = () => { query: { enabled: isConnected && !!address }, }) - const allOperatorsListRef = useRef(null) - - useEffect(() => { - // not getting the from the parent with useRef - // because we dont want the parent to be a client component - allOperatorsListRef.current = document.getElementById('all-operators') - }, []) - return ( - + Your Account -
- Wallet Balance - {isConnected ? ( - isBalancePending ? ( - - ) : ( - {formatRVRAmount(balance ?? 0n)} RVR - ) - ) : ( - - - )} -
-
- Staked - {isConnected ? ( - isStakedByUserPending ? ( - - ) : ( - {formatRVRAmount(stakedByUser ?? 0n)} RVR - ) - ) : ( - - - )} -
{isConnected ? ( - + <> +
+ Wallet Balance + {isConnected ? ( + isBalancePending ? ( + + ) : ( + {formatRVRAmount(balance ?? 0n)} RVR + ) + ) : ( + - + )} +
+
+ Staked + {isConnected ? ( + isStakedByUserPending ? ( + + ) : ( + {formatRVRAmount(stakedByUser ?? 0n)} RVR + ) + ) : ( + - + )} +
+ + View Account + + ) : ( - Connect Wallet to Stake + <> +

Log in to view your account

+ Log In + )}
diff --git a/src/components/stake/your-rewards.tsx b/src/components/stake/your-rewards.tsx index 03d9c81..7e90d6b 100644 --- a/src/components/stake/your-rewards.tsx +++ b/src/components/stake/your-rewards.tsx @@ -18,6 +18,7 @@ export const YourRewardsCard = () => { isTxPending, claimReward, } = useClaim() + if (!isConnected) return null return ( diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index 9011c5e..e4267f3 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -7,6 +7,39 @@ const Card = React.forwardRef< React.HTMLAttributes & { disableHover?: boolean } +>( + ( + { + className, + children, + disableHover, + onMouseLeave, + onMouseEnter, + ...props + }: React.PropsWithChildren & { disableHover?: boolean }>, + ref, + ) => { + return ( +
+ {children} +
+ ) + }, +) +Card.displayName = 'Card' + +const HoverableCard = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & { + disableHover?: boolean + } >( ( { @@ -51,7 +84,7 @@ const Card = React.forwardRef< ) }, ) -Card.displayName = 'Card' +HoverableCard.displayName = 'HoverableCard' const CardHeader = React.forwardRef>( ({ className, ...props }, ref) => ( @@ -97,4 +130,4 @@ const CardFooter = React.forwardRef { const { address, isConnected, chainId } = useAccount() const { operators } = useStakeableOperators({ initialData, liveQuery: true, }) - const { data: allDepositIds } = useReadRewardsDistributionGetDepositsByDepositor({ - args: [address!], - query: { enabled: isConnected }, - }) + const { data: allDepositIds, isLoading: allDepositIdsLoading } = + useReadRewardsDistributionGetDepositsByDepositor({ + args: [address!], + query: { enabled: isConnected }, + }) const depositsQueries = useReadContracts({ contracts: (allDepositIds || []).map( @@ -74,9 +76,15 @@ export const useOperatorsWithDeposits = (initialData?: StakeableOperatorsRespons query: { enabled: isConnected && !!allDepositIds }, }) - const deposits = depositsQueries.data - ?.flatMap((query) => query.result) - .filter((deposit): deposit is NonNullable => deposit !== undefined) + const deposits = allDepositIds + ? depositsQueries.data + ?.flatMap((query) => query.result) + .filter((deposit): deposit is NonNullable => deposit !== undefined) + .map((deposit, idx) => ({ + ...deposit, + depositId: allDepositIds[idx], + })) + : [] const operatorDeposits = allDepositIds ? Object.fromEntries( @@ -99,7 +107,10 @@ export const useOperatorsWithDeposits = (initialData?: StakeableOperatorsRespons }) return { - data: isConnected ? operatorsWithDeposits : operators, + data: operatorsWithDeposits, queryKey: depositsQueries.queryKey, + isLoading: + allDepositIdsLoading || depositsQueries.isLoading || operatorsWithDeposits.length === 0, + pendingWithdrawals: deposits?.filter((deposit) => deposit.pendingWithdrawal > 0n), } }