Skip to content

Commit 8c1a639

Browse files
feat(packages): support timelock renew for delegation (#254)
1 parent 16c0831 commit 8c1a639

File tree

8 files changed

+53
-25
lines changed

8 files changed

+53
-25
lines changed

.cursor/mcp.json

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
11
{
2-
"mcpServers": {
3-
"nx-mcp": {
4-
"command": "npx",
5-
"args": [
6-
"-y",
7-
"nx-mcp@latest"
8-
]
9-
}
10-
}
2+
"mcpServers": {}
113
}

.github/workflows/service-release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ jobs:
7272
NEXT_PUBLIC_FF_ENABLE_LEDGER: ${{ vars.NEXT_PUBLIC_FF_ENABLE_LEDGER }}
7373
NEXT_PUBLIC_FF_PHASE_3: ${{ vars.NEXT_PUBLIC_FF_PHASE_3 }}
7474
NEXT_PUBLIC_FF_CO_STAKING: ${{ vars.NEXT_PUBLIC_FF_CO_STAKING }}
75+
NEXT_PUBLIC_FF_TIMELOCK_RENEWAL: ${{ vars.NEXT_PUBLIC_FF_TIMELOCK_RENEWAL }}
7576

7677
- name: Generate sha256sum checksum
7778
run: |

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ Thumbs.db
4747
.vscode
4848

4949
packages/*/.cursor
50-
.claude
50+
.claude

services/simple-staking/src/ui/common/components/Activity/components/StakeExpansionSection.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { useDelegationV2State } from "@/ui/common/state/DelegationV2State";
1818
import { useStakingExpansionState } from "@/ui/common/state/StakingExpansionState";
1919
import { StakingExpansionStep } from "@/ui/common/state/StakingExpansionTypes";
2020
import { DelegationWithFP } from "@/ui/common/types/delegationsV2";
21+
import FeatureFlagService from "@/ui/common/utils/FeatureFlagService";
2122

2223
import { ExpansionButton } from "./ExpansionButton";
2324

@@ -179,18 +180,20 @@ export function StakeExpansionSection({
179180
</AccordionSummary>
180181
<AccordionDetails className="space-y-3 px-4 pb-4">
181182
<div className="flex w-full flex-col gap-4">
182-
<ExpansionButton
183-
Icon={iconBSNFp}
184-
text="Add BSNs and Finality Providers"
185-
counter={`${currentBsnCount}/${maxFinalityProviders}`}
186-
onClick={handleAddBsnFp}
187-
disabled={
188-
!canExpandDelegation ||
189-
processing ||
190-
isUTXOsLoading ||
191-
isPendingExpansion
192-
}
193-
/>
183+
{FeatureFlagService.IsPhase3Enabled && (
184+
<ExpansionButton
185+
Icon={iconBSNFp}
186+
text="Add BSNs and Finality Providers"
187+
counter={`${currentBsnCount}/${maxFinalityProviders}`}
188+
onClick={handleAddBsnFp}
189+
disabled={
190+
!canExpandDelegation ||
191+
processing ||
192+
isUTXOsLoading ||
193+
isPendingExpansion
194+
}
195+
/>
196+
)}
194197
{hasVerifiedRenewal ? (
195198
<Hint
196199
tooltip="A timelock renewal is already verified. Please check 'Verified Stake Expansion' to complete it."

services/simple-staking/src/ui/common/components/ActivityCard/ActivityCard.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ interface ActivityCardProps {
5858

5959
export function ActivityCard({ data, className }: ActivityCardProps) {
6060
const shouldShowExpansion =
61-
FeatureFlagService.IsPhase3Enabled && !data.hideExpansionCompletely;
61+
FeatureFlagService.IsTimelockRenewalEnabled &&
62+
!data.hideExpansionCompletely;
6263

6364
return (
6465
<div

services/simple-staking/src/ui/common/components/ActivityCard/utils/activityCardTransformers.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { satoshiToBtc } from "@/ui/common/utils/btc";
1212
import { maxDecimals } from "@/ui/common/utils/maxDecimals";
1313
import { getExpansionType } from "@/ui/common/utils/stakingExpansionUtils";
1414
import { durationTillNow } from "@/ui/common/utils/time";
15+
import FeatureFlagService from "@/ui/common/utils/FeatureFlagService";
1516

1617
import { createBsnFpGroupedDetails } from "../../../utils/bsnFpGroupingUtils";
1718
import { ActivityCardData, ActivityCardDetailItem } from "../ActivityCard";
@@ -97,9 +98,12 @@ export function transformDelegationToActivityCard(
9798
// Check if expansion section should be shown
9899
// 1. Delegation is active and can expand from the api
99100
// 2. OR delegation is a broadcasted VERIFIED expansion (waiting for confirmations)
101+
// Note: canExpand will be removed soon and not taking effect for non-phase-3
102+
const canExpand = FeatureFlagService.IsTimelockRenewalEnabled
103+
? true
104+
: delegation.canExpand;
100105
const isActiveExpandable =
101-
delegation.state === DelegationV2StakingState.ACTIVE &&
102-
delegation.canExpand;
106+
delegation.state === DelegationV2StakingState.ACTIVE && canExpand;
103107

104108
const showExpansionSection =
105109
isActiveExpandable || options.isBroadcastedExpansion;

services/simple-staking/src/ui/common/utils/FeatureFlagService.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,15 @@ export default {
5656
get IsCoStakingEnabled() {
5757
return process.env.NEXT_PUBLIC_FF_CO_STAKING === "true";
5858
},
59+
60+
/**
61+
* Timelock Renewal feature flag
62+
*
63+
* Purpose: Enables timelock renewal functionality in the UI
64+
* Why needed: To gradually roll out timelock renewal feature
65+
* ETA for removal: TBD - Will be removed once timelock renewal is fully stable
66+
*/
67+
get IsTimelockRenewalEnabled() {
68+
return process.env.NEXT_PUBLIC_FF_TIMELOCK_RENEWAL === "true";
69+
},
5970
};

services/simple-staking/tests/utils/featureFlag/FeatureFlagService.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ describe("FeatureFlagService", () => {
6161
});
6262
});
6363

64+
describe("IsTimelockRenewalEnabled", () => {
65+
it("should return false when NEXT_PUBLIC_FF_TIMELOCK_RENEWAL is not set", () => {
66+
expect(FeatureFlagService.IsTimelockRenewalEnabled).toBe(false);
67+
});
68+
69+
it('should return false when NEXT_PUBLIC_FF_TIMELOCK_RENEWAL is set to "false"', () => {
70+
process.env.NEXT_PUBLIC_FF_TIMELOCK_RENEWAL = "false";
71+
expect(FeatureFlagService.IsTimelockRenewalEnabled).toBe(false);
72+
});
73+
74+
it('should return true when NEXT_PUBLIC_FF_TIMELOCK_RENEWAL is set to "true"', () => {
75+
process.env.NEXT_PUBLIC_FF_TIMELOCK_RENEWAL = "true";
76+
expect(FeatureFlagService.IsTimelockRenewalEnabled).toBe(true);
77+
});
78+
});
79+
6480
describe("Feature flag behavior", () => {
6581
it("should handle multiple feature flags independently", () => {
6682
process.env.NEXT_PUBLIC_FF_ENABLE_LEDGER = "false";

0 commit comments

Comments
 (0)