Skip to content

Commit 8c16255

Browse files
authored
bump deps and fix undelegate (#234)
1 parent c66b3b8 commit 8c16255

7 files changed

Lines changed: 185 additions & 170 deletions

File tree

package.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@
1010
},
1111
"dependencies": {
1212
"@coral-xyz/anchor": "^0.31.0",
13-
"@helium/account-fetch-cache": "^0.10.13",
14-
"@helium/account-fetch-cache-hooks": "^0.10.13",
15-
"@helium/helium-react-hooks": "^0.10.13",
16-
"@helium/hpl-crons-sdk": "^0.10.13",
13+
"@helium/account-fetch-cache": "^0.10.14",
14+
"@helium/account-fetch-cache-hooks": "^0.10.14",
15+
"@helium/helium-react-hooks": "^0.10.14",
16+
"@helium/hpl-crons-sdk": "^0.10.14",
1717
"@helium/modular-governance-hooks": "^0.1.5",
1818
"@helium/modular-governance-idls": "^0.1.5",
19-
"@helium/no-emit-sdk": "^0.10.13",
19+
"@helium/no-emit-sdk": "^0.10.14",
2020
"@helium/organization-sdk": "^0.1.5",
21-
"@helium/spl-utils": "^0.10.13",
21+
"@helium/spl-utils": "^0.10.14",
2222
"@helium/state-controller-sdk": "^0.1.5",
2323
"@helium/tuktuk-sdk": "^0.0.8",
24-
"@helium/voter-stake-registry-hooks": "^0.10.13",
25-
"@helium/voter-stake-registry-sdk": "^0.10.13",
24+
"@helium/voter-stake-registry-hooks": "^0.10.14",
25+
"@helium/voter-stake-registry-sdk": "^0.10.14",
2626
"@hookform/resolvers": "^3.3.4",
2727
"@metaplex-foundation/mpl-token-metadata": "2.10.0",
2828
"@project-serum/anchor": "^0.26.0",
@@ -78,15 +78,15 @@
7878
"resolutions": {
7979
"@tanstack/react-query": "5.45.1",
8080
"@solana/web3.js": "^1.90.0",
81-
"@helium/account-fetch-cache": "^0.10.13",
82-
"@helium/account-fetch-cache-hooks": "^0.10.13",
83-
"@helium/helium-react-hooks": "^0.10.13",
84-
"@helium/voter-stake-registry-hooks": "^0.10.13",
81+
"@helium/account-fetch-cache": "^0.10.14",
82+
"@helium/account-fetch-cache-hooks": "^0.10.14",
83+
"@helium/helium-react-hooks": "^0.10.14",
84+
"@helium/voter-stake-registry-hooks": "^0.10.14",
8585
"@helium/modular-governance-idls": "^0.1.5",
86-
"@helium/spl-utils": "^0.10.13",
86+
"@helium/spl-utils": "^0.10.14",
8787
"@helium/modular-governance-hooks": "^0.1.5",
8888
"@solana/wallet-adapter-react": "^0.15.35",
89-
"@helium/voter-stake-registry-sdk": "^0.10.13"
89+
"@helium/voter-stake-registry-sdk": "^0.10.14"
9090
},
9191
"devDependencies": {
9292
"@tailwindcss/typography": "^0.5.10",

src/components/PositionManager/ConfirmationItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const ConfirmationItem: FC<{
1818
<div className="size-12 rounded-full relative">
1919
<Image alt={img.alt} src={img.src} fill />
2020
</div>
21-
<div className="flex flex-col items-center">
21+
<div className="flex flex-col text-center items-center">
2222
<span className="text-sm">{title}</span>
2323
<span className="font-medium">{description}</span>
2424
</div>

src/components/PositionManager/PositionManager.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
useSubDaos,
2323
useTransferPosition,
2424
useUnassignProxies,
25+
useUndelegatePosition,
2526
} from "@helium/voter-stake-registry-hooks";
2627
import { WalletSignTransactionError } from "@solana/wallet-adapter-base";
2728
import BN from "bn.js";
@@ -56,6 +57,7 @@ import { MOBILE_SUB_DAO_KEY } from "@/lib/constants";
5657
export type PositionAction =
5758
| "flip"
5859
| "delegate"
60+
| "undelegate"
5961
| "extend"
6062
| "split"
6163
| "merge"
@@ -178,13 +180,15 @@ export const PositionManager: FC<PositionManagerProps> = ({
178180
const [subDao, setSubDao] = useState<SubDaoWithMeta | null>(
179181
subDaos?.find((sd) => sd.pubkey.equals(MOBILE_SUB_DAO_KEY)) || null
180182
);
183+
181184
useEffect(() => {
182185
if (subDaos && !subDao) {
183186
setSubDao(
184187
subDaos.find((sd) => sd.pubkey.equals(MOBILE_SUB_DAO_KEY)) || null
185188
);
186189
}
187190
}, [subDaos, subDao]);
191+
188192
const {
189193
loading: isDelegating,
190194
delegatePosition,
@@ -195,6 +199,13 @@ export const PositionManager: FC<PositionManagerProps> = ({
195199
position,
196200
subDao: subDao || undefined,
197201
});
202+
203+
const { loading: isUndelegating, undelegatePosition } = useUndelegatePosition(
204+
{
205+
position,
206+
}
207+
);
208+
198209
const { loading: isTransfering, transferPosition } = useTransferPosition();
199210
const { loading: isSplitting, splitPosition } = useSplitPosition();
200211
const { loading: isExtending, extendPosition } = useExtendPosition();
@@ -330,6 +341,21 @@ export const PositionManager: FC<PositionManagerProps> = ({
330341
}
331342
};
332343

344+
const handleUndelegatePosition = async () => {
345+
try {
346+
await undelegatePosition({
347+
onInstructions: onInstructions(provider),
348+
});
349+
350+
toast("Position undelegated");
351+
reset();
352+
} catch (e: any) {
353+
if (!(e instanceof WalletSignTransactionError)) {
354+
toast(e.message || "Undelegation failed, please try again");
355+
}
356+
}
357+
};
358+
333359
const handleExtendPosition = async (values: LockTokensFormValues) => {
334360
try {
335361
await extendPosition({
@@ -531,9 +557,10 @@ export const PositionManager: FC<PositionManagerProps> = ({
531557
{action === "delegate" && (
532558
<UpdatePositionDelegationPrompt
533559
position={position}
534-
isSubmitting={isDelegating}
560+
isSubmitting={isDelegating || isUndelegating}
535561
onCancel={() => setAction(undefined)}
536562
onConfirm={handleDelegatePosition}
563+
onUndelegate={handleUndelegatePosition}
537564
automationEnabled={automationEnabled}
538565
setAutomationEnabled={setAutomationEnabled}
539566
subDao={subDao}
@@ -542,6 +569,7 @@ export const PositionManager: FC<PositionManagerProps> = ({
542569
prepaidTxFees={prepaidTxFees}
543570
/>
544571
)}
572+
{action === "undelegate" && <div>Test</div>}
545573
{action === "extend" && (
546574
<ExtendPositionPrompt
547575
position={position}

src/components/PositionManager/UpdatePositionDelegationPrompt.tsx

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
"use client";
22

3+
import { removeNullBytes } from "@/lib/utils";
34
import { useGovernance } from "@/providers/GovernanceProvider";
45
import { useSolanaUnixNow } from "@helium/helium-react-hooks";
56
import {
67
PositionWithMeta,
78
SubDaoWithMeta,
8-
useDataBurnSplit,
9-
useSubDaoDelegationSplit,
109
} from "@helium/voter-stake-registry-hooks";
1110
import { PublicKey } from "@solana/web3.js";
1211
import BN from "bn.js";
1312
import classNames from "classnames";
1413
import { Loader2, X } from "lucide-react";
1514
import React, { FC, useCallback, useMemo, useState } from "react";
1615
import { FaCircleArrowRight } from "react-icons/fa6";
16+
import { AutomationSettings } from "../AutomationSettings";
17+
import { DataSplitBars } from "../DataSplitBars";
1718
import { StepIndicator } from "../StepIndicator";
1819
import { SubDaoSelection } from "../SubDaoSelection";
1920
import { Button } from "../ui/button";
2021
import { ConfirmationItem } from "./ConfirmationItem";
21-
import { DataSplitBars } from "../DataSplitBars";
22-
import { AutomationSettings } from "../AutomationSettings";
23-
import { humanReadable } from "@/lib/utils";
2422

2523
export const UpdatePositionDelegationPrompt: FC<{
2624
position: PositionWithMeta;
2725
isSubmitting?: boolean;
2826
onCancel: () => void;
2927
onConfirm: (subDao?: SubDaoWithMeta) => Promise<void>;
28+
onUndelegate: () => Promise<void>;
3029
automationEnabled: boolean;
3130
setAutomationEnabled: (automationEnabled: boolean) => void;
3231
subDao: SubDaoWithMeta | null;
@@ -38,6 +37,7 @@ export const UpdatePositionDelegationPrompt: FC<{
3837
isSubmitting,
3938
onCancel,
4039
onConfirm,
40+
onUndelegate,
4141
subDao,
4242
setSubDao,
4343
automationEnabled,
@@ -46,7 +46,8 @@ export const UpdatePositionDelegationPrompt: FC<{
4646
prepaidTxFees = 0,
4747
}) => {
4848
const [step, setStep] = useState(1);
49-
const { subDaos, voteService } = useGovernance();
49+
const [isUndelegating, setIsUndelegating] = useState(false);
50+
const { subDaos } = useGovernance();
5051
const unixNow = useSolanaUnixNow() || Date.now() / 1000;
5152
const { lockup, isDelegated, delegatedSubDao } = position;
5253
const lockupKind = Object.keys(lockup.kind)[0] as string;
@@ -71,50 +72,12 @@ export const UpdatePositionDelegationPrompt: FC<{
7172
subDaos?.find((sd) => sd.pubkey.equals(position.delegatedSubDao!))
7273
?.dntMetadata;
7374

74-
const { data: revData, isLoading: revLoading } = useDataBurnSplit({
75-
voteService,
76-
});
77-
const { iot: iotDataUsageRev = 0, mobile: mobileDataUsageRev = 0 } =
78-
(revData || {}) as { iot: number; mobile: number };
79-
const { data: delegationData, isLoading: delegationLoading } =
80-
useSubDaoDelegationSplit({
81-
voteService,
82-
});
83-
const {
84-
iot: iotDelegation = new BN(0),
85-
mobile: mobileDelegation = new BN(0),
86-
} = (delegationData || {}) as { iot: BN; mobile: BN };
87-
88-
const totalDataUsage = Number(mobileDataUsageRev) + Number(iotDataUsageRev);
89-
const totalVetokens =
90-
mobileDelegation && iotDelegation
91-
? new BN(mobileDelegation).add(new BN(iotDelegation))
92-
: new BN(0);
93-
94-
const mobileDelegationPercentage =
95-
mobileDelegation && totalVetokens.gt(new BN(0))
96-
? new BN(mobileDelegation)
97-
.mul(new BN(10000))
98-
.div(totalVetokens)
99-
.toNumber() / 100
100-
: 0;
101-
102-
const iotDelegationPercentage =
103-
iotDelegation && totalVetokens.gt(new BN(0))
104-
? new BN(iotDelegation).mul(new BN(10000)).div(totalVetokens).toNumber() /
105-
100
106-
: 0;
107-
108-
const mobileDataUsagePercentage =
109-
totalDataUsage > 0
110-
? (Number(mobileDataUsageRev) / totalDataUsage) * 100
111-
: 0;
112-
113-
const iotDataUsagePercentage =
114-
totalDataUsage > 0 ? (Number(iotDataUsageRev) / totalDataUsage) * 100 : 0;
115-
11675
const handleSubmit = async () => {
117-
await onConfirm(selectedSubDao);
76+
if (isUndelegating) {
77+
await onUndelegate();
78+
} else {
79+
await onConfirm(selectedSubDao);
80+
}
11881
};
11982

12083
const setSelectedSubDaoPk = useCallback(
@@ -135,7 +98,13 @@ export const UpdatePositionDelegationPrompt: FC<{
13598
<div className="flex flex-col gap-4">
13699
<div className="flex flex-col gap-1">
137100
<div className="flex flex-row justify-between items-center">
138-
<h3>{step === 1 ? "Update Position" : "Update Delegation"}</h3>
101+
<h3>
102+
{step === 1
103+
? "Update Position"
104+
: isUndelegating
105+
? "Undelegate Position"
106+
: "Update Delegation"}
107+
</h3>
139108
<StepIndicator steps={2} currentStep={step} />
140109
</div>
141110
{step === 1 ? (
@@ -177,7 +146,7 @@ export const UpdatePositionDelegationPrompt: FC<{
177146
disabled={!isDelegated}
178147
className="flex-1"
179148
onClick={() => {
180-
setSelectedSubDaoPk(undefined);
149+
setIsUndelegating(true);
181150
setStep(step + 1);
182151
}}
183152
>
@@ -214,7 +183,9 @@ export const UpdatePositionDelegationPrompt: FC<{
214183
src: delegatedSubDaoMetadata?.json?.image,
215184
}}
216185
title="Delegating from..."
217-
description={delegatedSubDaoMetadata?.symbol.toUpperCase()}
186+
description={removeNullBytes(
187+
delegatedSubDaoMetadata?.symbol.toUpperCase()
188+
)}
218189
/>
219190
<FaCircleArrowRight className="size-6 absolute left-[calc(50%-0.75rem)] top-[calc(50%-0.75rem)]" />
220191
</>
@@ -229,7 +200,9 @@ export const UpdatePositionDelegationPrompt: FC<{
229200
src: selectedSubDaoMetadata?.json?.image,
230201
}}
231202
title="Delegating to..."
232-
description={selectedSubDaoMetadata?.symbol.toUpperCase()}
203+
description={removeNullBytes(
204+
selectedSubDaoMetadata?.symbol.toUpperCase()
205+
)}
233206
/>
234207
</div>
235208
)}
@@ -240,8 +213,14 @@ export const UpdatePositionDelegationPrompt: FC<{
240213
alt: delegatedSubDaoMetadata?.json?.name,
241214
src: delegatedSubDaoMetadata?.json?.image,
242215
}}
243-
title="Updating delegation"
244-
description={delegatedSubDaoMetadata?.symbol.toUpperCase()}
216+
title={
217+
isUndelegating
218+
? "Undelegating from..."
219+
: "Updating delegation"
220+
}
221+
description={removeNullBytes(
222+
delegatedSubDaoMetadata?.symbol.toUpperCase()
223+
)}
245224
/>
246225
)}
247226
</div>
@@ -253,6 +232,7 @@ export const UpdatePositionDelegationPrompt: FC<{
253232
disabled={isSubmitting}
254233
onClick={() => {
255234
setSelectedSubDaoPk(undefined);
235+
setIsUndelegating(false);
256236
setStep(step - 1);
257237
}}
258238
>
@@ -266,7 +246,11 @@ export const UpdatePositionDelegationPrompt: FC<{
266246
{isSubmitting && (
267247
<Loader2 className="size-5 animate-spin" />
268248
)}
269-
{isSubmitting ? "Updating Delegation..." : "Confirm"}
249+
{isSubmitting
250+
? isUndelegating
251+
? "Undelegating..."
252+
: "Updating delegation..."
253+
: "Confirm"}
270254
</Button>
271255
</div>
272256
<p className="text-xs text-muted-foreground text-center">

src/components/SubDaoSelection.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import classNames from "classnames";
66
import Image from "next/image";
77
import React, { FC } from "react";
88
import { Skeleton } from "./ui/skeleton";
9+
import { removeNullBytes } from "@/lib/utils";
910

1011
export const SubDaoSelection: FC<{
1112
hideNoneOption?: boolean;
@@ -72,9 +73,7 @@ export const SubDaoSelection: FC<{
7273
fill
7374
/>
7475
</div>
75-
{subDao.dntMetadata.symbol
76-
? subDao.dntMetadata.symbol.replace(/\u0000/g, "")
77-
: ""}
76+
{removeNullBytes(subDao.dntMetadata.symbol)}
7877
</div>
7978
</div>
8079
))}

src/lib/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,7 @@ export function debounce<T extends unknown[], U>(
440440
}
441441

442442
export const EPOCH_LENGTH = 60 * 60 * 24;
443+
444+
export const removeNullBytes = (str?: string): string => {
445+
return str ? str.replace(/\u0000/g, "") : "";
446+
};

0 commit comments

Comments
 (0)