Skip to content

Commit

Permalink
Merge pull request #3137 from dusk-network/feature-3136
Browse files Browse the repository at this point in the history
web-wallet: Refactor MigrationContract
  • Loading branch information
nortonandreev authored Dec 13, 2024
2 parents 0286f0b + d58017a commit c3e8428
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 90 deletions.
167 changes: 92 additions & 75 deletions web-wallet/src/lib/containers/MigrateContract/MigrateContract.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { mdiArrowLeft, mdiArrowRight, mdiWalletOutline } from "@mdi/js";
import { getAccount, switchChain } from "@wagmi/core";
import { formatUnits, parseUnits } from "viem";
import { onDestroy, onMount } from "svelte";
import { onMount } from "svelte";
import { tokens } from "./tokenConfig";
import { getDecimalSeparator } from "$lib/dusk/number";
import {
Expand All @@ -28,7 +28,7 @@
Textbox,
} from "$lib/dusk/components";
import { logo } from "$lib/dusk/icons";
import { settingsStore, walletStore } from "$lib/stores";
import { settingsStore } from "$lib/stores";
import {
account,
modal,
Expand Down Expand Up @@ -68,15 +68,12 @@
/** @type {boolean} */
const migrationInProgress = false;
/** @type {bigint} */
/** @type {undefined | bigint} */
let connectedWalletBalance;
/** @type {string} */
let amount = "";
/** @type {HTMLInputElement | null} */
let amountInput;
/** @type {boolean} */
let isMigrationInitialized = false;
Expand All @@ -89,14 +86,28 @@
/** @type {boolean} */
let isInputDisabled = false;
$: ({ address, chainId, isConnected } = $account);
$: ({ currentProfile } = $walletStore);
$: currentAddress = currentProfile ? currentProfile.address.toString() : "";
$: isAmountValid =
!!amount &&
parseUnits(amount.replace(",", "."), ercDecimals) >=
parseUnits(minAmount, ercDecimals) &&
parseUnits(amount.replace(",", "."), ercDecimals) <= connectedWalletBalance;
$: walletState = {
address: $account?.address,
chainId: $account?.chainId,
isConnected: $account?.isConnected,
};
$: isAmountValid = (() => {
if (!amount) {
return false;
}
try {
const parsedAmount = parseUnits(amount.replace(",", "."), ercDecimals);
const minParsed = parseUnits(minAmount, ercDecimals);
return (
parsedAmount >= minParsed &&
parsedAmount <= (connectedWalletBalance ?? 0n)
);
} catch (err) {
return false;
}
})();
$: amount = slashDecimals(cleanNumberString(amount, getDecimalSeparator()));
/**
Expand All @@ -108,15 +119,16 @@
try {
await switchChain(wagmiConfig, { chainId: id });
connectedWalletBalance = await getBalance();
} catch (e) {
selectedChain = chainId === erc20.chainId ? erc20.name : bep20.name;
} catch (err) {
selectedChain =
walletState.chainId === erc20.chainId ? erc20.name : bep20.name;
}
}
/** Emits the switchChain event to the third-party wallet when the ExclusiveChoice UI is interacted with */
// @ts-ignore
async function onChainSwitch(e) {
if (!isConnected) {
if (!walletState.isConnected) {
return;
}
amount = "";
Expand All @@ -132,26 +144,24 @@
async function switchToSelectedChain() {
const currentChainId =
selectedChain === erc20.name ? erc20.chainId : bep20.chainId;
if (chainId !== currentChainId) {
if (walletState.chainId !== currentChainId) {
await handleSwitchChain(currentChainId);
}
}
async function getBalance() {
const walletAccount = getAccount(wagmiConfig);
if (!walletAccount.address) {
throw new Error("Address is undefined");
try {
const walletAccount = getAccount(wagmiConfig);
if (!walletAccount.address) {
throw new Error("Wallet not connected.");
}
return await getBalanceOfCoin(
walletAccount.address,
tokens[network][selectedChain].contract
);
} catch (err) {
return 0n;
}
return await getBalanceOfCoin(
walletAccount.address,
tokens[network][selectedChain].contract
);
}
function incrementStep() {
migrationStep++;
}
/**
Expand All @@ -172,28 +182,30 @@
screenWidth = entry.contentRect.width;
});
(async () => {
if (isConnected) {
const init = async () => {
if (walletState?.isConnected) {
await walletDisconnect();
}
modal.subscribeEvents(async (e) => {
const handleModalEvents = async (
/** @type {{ data: { event: string; }; }} */ e
) => {
if (e.data.event === "CONNECT_SUCCESS") {
switchToSelectedChain();
connectedWalletBalance = undefined;
await switchToSelectedChain();
connectedWalletBalance = await getBalance();
}
});
amountInput = document.querySelector(".migrate__input-field");
};
resizeObserver.observe(document.body);
})();
modal.subscribeEvents(handleModalEvents);
};
return () => resizeObserver.disconnect();
});
init();
onDestroy(async () => {
await walletDisconnect();
return () => {
resizeObserver.disconnect();
};
});
</script>
Expand Down Expand Up @@ -237,23 +249,31 @@
bind:value={selectedChain}
on:change={onChainSwitch}
/>
{#if isConnected && address}
{#if walletState.isConnected && walletState.address}
<p class="migrate__token-header">Connected Wallet:</p>
<p class="migrate__token-address">
{middleEllipsis(address, calculateAdaptiveCharCount(screenWidth))}
{middleEllipsis(
walletState.address,
calculateAdaptiveCharCount(screenWidth)
)}
</p>
<div class="migrate__token-balance">
Balance: <span
>{slashDecimals(
formatUnits(connectedWalletBalance ?? 0n, ercDecimals)
)}
{selectedChain} DUSK</span
>
</div>
<span class="migrate__token-balance">
{#if connectedWalletBalance === undefined}
Loading Balance...
{:else}
Balance:
<span
>{slashDecimals(
formatUnits(connectedWalletBalance ?? 0n, ercDecimals)
)}
{selectedChain} DUSK</span
>
{/if}
</span>
{/if}
</div>
{#if isConnected && address && connectedWalletBalance}
{#if walletState.isConnected && walletState.address && connectedWalletBalance && connectedWalletBalance > 0n}
<div class="migrate__amount">
<div class="migrate__amount-header">
<div class="migrate__amount-token">
Expand All @@ -279,15 +299,7 @@
size="small"
variant="tertiary"
on:click={() => {
if (amountInput) {
amountInput.value = formatUnits(
connectedWalletBalance,
ercDecimals
);
}
amount = slashDecimals(
formatUnits(connectedWalletBalance, ercDecimals)
);
amount = formatUnits(connectedWalletBalance ?? 0n, ercDecimals);
}}
text="USE MAX"
disabled={isInputDisabled}
Expand All @@ -307,13 +319,13 @@
</div>
{/if}
{#if isConnected && isAmountValid && isMigrationInitialized}
{#if walletState.isConnected && isAmountValid && isMigrationInitialized}
<div class="migrate__wizard">
<Stepper steps={2} activeStep={migrationStep} variant="secondary" />
{#if migrationStep === 0}
<ApproveMigration
on:incrementStep={incrementStep}
on:incrementStep={() => migrationStep++}
on:initApproval={() => {
isInputDisabled = true;
}}
Expand All @@ -327,30 +339,24 @@
{:else}
<ExecuteMigration
amount={parseUnits(amount.replace(",", "."), ercDecimals)}
{currentAddress}
currentAddress={walletState.address ?? ""}
migrationContract={tokens[network][selectedChain].migrationContract}
/>
{/if}
</div>
{/if}
{#if !isConnected}
{#if !walletState.isConnected}
<Button
icon={{ path: mdiWalletOutline }}
text={`CONNECT TO ${selectedChain === tokens[network]["ERC-20"].name ? "ETHEREUM" : "BSC"}`}
on:click={() => modal.open()}
/>
{:else if !connectedWalletBalance}
{:else if connectedWalletBalance === 0n}
<Banner variant="warning" title="No DUSK available">
<p>The connected wallet has no DUSK tokens available.</p>
</Banner>
<Button
text="Disconnect"
on:click={async () => {
await walletDisconnect();
}}
/>
{:else if !isMigrationInitialized && address}
{:else if !isMigrationInitialized && walletState.address}
<Button
text="INITIALIZE MIGRATION"
on:click={() => {
Expand All @@ -360,6 +366,17 @@
/>
{/if}
</article>
{#if walletState.isConnected}
<Button
text="Disconnect Wallet"
on:click={async () => {
await walletDisconnect();
}}
variant="tertiary"
/>
{/if}
<AppAnchorButton
href="/dashboard"
icon={{ path: mdiArrowLeft }}
Expand Down
22 changes: 9 additions & 13 deletions web-wallet/src/lib/migration/walletConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ import { createAppKit } from "@reown/appkit";
import { WagmiAdapter } from "@reown/appkit-adapter-wagmi";
// eslint-disable-next-line import/no-unresolved
import { bsc, mainnet, sepolia } from "@reown/appkit/networks";
import {
disconnect,
getAccount,
getBalance,
reconnect,
watchAccount,
} from "@wagmi/core";
import { disconnect, getAccount, getBalance, watchAccount } from "@wagmi/core";
import { readable } from "svelte/store";

// Required project metadata
Expand All @@ -31,9 +25,7 @@ const wagmiAdapter = new WagmiAdapter({

export const wagmiConfig = wagmiAdapter.wagmiConfig;

reconnect(wagmiConfig);

// Create the Web3 modal with the WAGMI config
// Create the Reown App Kit modal
export const modal = createAppKit({
adapters: [wagmiAdapter],
features: {
Expand All @@ -51,18 +43,22 @@ export const modal = createAppKit({
// Note that this can change at will by the user outside
// of the app itself
export const account = readable(getAccount(wagmiConfig), (set) => {
watchAccount(wagmiConfig, {
set(getAccount(wagmiConfig));
return watchAccount(wagmiConfig, {
onChange(newAccount) {
set(newAccount);
},
});
});

/** @param {*} address */
/** @param {`0x${string}`} address */
export const accountBalance = (address) =>
getBalance(wagmiConfig, {
address: address,
blockTag: "latest",
});

export const walletDisconnect = () => disconnect(wagmiConfig);
export async function walletDisconnect() {
await disconnect(wagmiConfig);
await modal?.disconnect();
}
3 changes: 1 addition & 2 deletions web-wallet/src/lib/navigation/logout.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import { walletStore } from "$lib/stores";
* @param {boolean} isForced
* @returns {ReturnType<goto>}
*/
const logout = (isForced) => {
const logout = async (isForced) => {
walletStore.reset();

return goto(`/${isForced ? "forced-logout" : ""}`);
};

Expand Down

0 comments on commit c3e8428

Please sign in to comment.