Skip to content

Commit

Permalink
feat: sign shielding tx
Browse files Browse the repository at this point in the history
  • Loading branch information
euharrison committed Nov 15, 2024
1 parent c63b98a commit e811bcb
Show file tree
Hide file tree
Showing 7 changed files with 477 additions and 20 deletions.
74 changes: 64 additions & 10 deletions apps/namadillo/src/App/Masp/MaspShield.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,47 @@ import {
import { allDefaultAccountsAtom } from "atoms/accounts";
import { namadaTransparentAssetsAtom } from "atoms/balance/atoms";
import { chainParametersAtom } from "atoms/chain/atoms";
import { shieldTxAtom } from "atoms/shield/atoms";
import BigNumber from "bignumber.js";
import clsx from "clsx";
import { AnimatePresence, motion } from "framer-motion";
import { useTransactionActions } from "hooks/useTransactionActions";
import { wallets } from "integrations";
import { getAssetImageUrl } from "integrations/utils";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import namadaChain from "registry/namada.json";
import { Address } from "types";
import {
Address,
PartialTransferTransactionData,
TransferStep,
TransferTransactionData,
} from "types";
import { MaspTopHeader } from "./MaspTopHeader";

export const MaspShield: React.FC = () => {
const [searchParams, setSearchParams] = useSearchParams();

const chainParameters = useAtomValue(chainParametersAtom);
const defaultAccounts = useAtomValue(allDefaultAccountsAtom);
const { data: availableAssets, isLoading: isLoadingBalances } = useAtomValue(
const { data: availableAssets, isLoading: isLoadingAssets } = useAtomValue(
namadaTransparentAssetsAtom
);
const performShieldTransfer = useAtomValue(shieldTxAtom);

const [currentStep, setCurrentStep] = useState(0);
const [generalErrorMessage, setGeneralErrorMessage] = useState("");

const [transaction, setTransaction] =
useState<PartialTransferTransactionData>();

const {
transactions: myTransactions,
findByHash,
storeTransaction,
} = useTransactionActions();

const chainId = chainParameters.data?.chainId;

const sourceAddress = defaultAccounts.data?.find(
Expand All @@ -54,6 +71,15 @@ export const MaspShield: React.FC = () => {

const assetImage = selectedAsset ? getAssetImageUrl(selectedAsset.asset) : "";

useEffect(() => {
if (transaction?.hash) {
const tx = findByHash(transaction.hash);
if (tx) {
setTransaction(tx);
}
}
}, [myTransactions]);

const onChangeSelectedAsset = (address?: Address): void => {
setSearchParams(
(currentParams) => {
Expand Down Expand Up @@ -93,10 +119,39 @@ export const MaspShield: React.FC = () => {
throw new Error("No transaction fee is set");
}

// TODO do the transaction
alert(
"// TODO \n" + JSON.stringify({ amount, destinationAddress }, null, 2)
);
setTransaction({
type: "TransparentToShielded",
currentStep: TransferStep.Sign,
asset: selectedAsset.asset,
chainId,
});

const txResponse = await performShieldTransfer.mutateAsync({
sourceAddress,
destinationAddress,
tokenAddress: selectedAsset.originalAddress,
amount,
});

// TODO review and improve this data to be more precise and full of details
const tx: TransferTransactionData = {
type: "TransparentToShielded",
currentStep: TransferStep.Complete,
sourceAddress,
destinationAddress,
asset: selectedAsset.asset,
amount,
rpc: txResponse.msg.payload.chain.rpcUrl,
chainId: txResponse.msg.payload.chain.chainId,
hash: txResponse.encodedTx.txs[0]?.hash,
feePaid: txResponse.encodedTx.wrapperTxProps.feeAmount,
resultTxHash: txResponse.encodedTx.txs[0]?.innerTxHashes[0],
status: "success",
createdAt: new Date(),
updatedAt: new Date(),
};
setTransaction(tx);
storeTransaction(tx);

setCurrentStep(2);
} catch (err) {
Expand All @@ -121,7 +176,7 @@ export const MaspShield: React.FC = () => {
>
<TransferModule
source={{
isLoadingAssets: isLoadingBalances,
isLoadingAssets,
availableAssets,
selectedAssetAddress,
availableAmount: selectedAsset?.amount,
Expand All @@ -139,8 +194,7 @@ export const MaspShield: React.FC = () => {
isShielded: true,
}}
transactionFee={transactionFee}
// TODO
// isSubmitting={something.isPending}
isSubmitting={performShieldTransfer.isPending}
errorMessage={generalErrorMessage}
onSubmitTransfer={onSubmitTransfer}
/>
Expand Down
74 changes: 64 additions & 10 deletions apps/namadillo/src/App/Masp/MaspUnshield.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,47 @@ import {
import { allDefaultAccountsAtom } from "atoms/accounts";
import { namadaShieldedAssetsAtom } from "atoms/balance/atoms";
import { chainParametersAtom } from "atoms/chain/atoms";
import { unshieldTxAtom } from "atoms/shield/atoms";
import BigNumber from "bignumber.js";
import clsx from "clsx";
import { AnimatePresence, motion } from "framer-motion";
import { useTransactionActions } from "hooks/useTransactionActions";
import { wallets } from "integrations";
import { getAssetImageUrl } from "integrations/utils";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import namadaChain from "registry/namada.json";
import { Address } from "types";
import {
Address,
PartialTransferTransactionData,
TransferStep,
TransferTransactionData,
} from "types";
import { MaspTopHeader } from "./MaspTopHeader";

export const MaspUnshield: React.FC = () => {
const [searchParams, setSearchParams] = useSearchParams();

const chainParameters = useAtomValue(chainParametersAtom);
const defaultAccounts = useAtomValue(allDefaultAccountsAtom);
const { data: availableAssets, isLoading: isLoadingBalances } = useAtomValue(
const { data: availableAssets, isLoading: isLoadingAssets } = useAtomValue(
namadaShieldedAssetsAtom
);
const performUnshieldTransfer = useAtomValue(unshieldTxAtom);

const [currentStep, setCurrentStep] = useState(0);
const [generalErrorMessage, setGeneralErrorMessage] = useState("");

const [transaction, setTransaction] =
useState<PartialTransferTransactionData>();

const {
transactions: myTransactions,
findByHash,
storeTransaction,
} = useTransactionActions();

const chainId = chainParameters.data?.chainId;

const sourceAddress = defaultAccounts.data?.find(
Expand All @@ -54,6 +71,15 @@ export const MaspUnshield: React.FC = () => {

const assetImage = selectedAsset ? getAssetImageUrl(selectedAsset.asset) : "";

useEffect(() => {
if (transaction?.hash) {
const tx = findByHash(transaction.hash);
if (tx) {
setTransaction(tx);
}
}
}, [myTransactions]);

const onChangeSelectedAsset = (address?: Address): void => {
setSearchParams(
(currentParams) => {
Expand Down Expand Up @@ -93,10 +119,39 @@ export const MaspUnshield: React.FC = () => {
throw new Error("No transaction fee is set");
}

// TODO do the transaction
alert(
"// TODO \n" + JSON.stringify({ amount, destinationAddress }, null, 2)
);
setTransaction({
type: "ShieldedToTransparent",
asset: selectedAsset.asset,
chainId,
currentStep: TransferStep.Sign,
});

const txResponse = await performUnshieldTransfer.mutateAsync({
sourceAddress,
destinationAddress,
tokenAddress: selectedAsset.originalAddress,
amount,
});

// TODO review and improve this data to be more precise and full of details
const tx: TransferTransactionData = {
type: "ShieldedToTransparent",
currentStep: TransferStep.Complete,
sourceAddress,
destinationAddress,
asset: selectedAsset.asset,
amount,
rpc: txResponse.msg.payload.chain.rpcUrl,
chainId: txResponse.msg.payload.chain.chainId,
hash: txResponse.encodedTx.txs[0]?.hash,
feePaid: txResponse.encodedTx.wrapperTxProps.feeAmount,
resultTxHash: txResponse.encodedTx.txs[0]?.innerTxHashes[0],
status: "success",
createdAt: new Date(),
updatedAt: new Date(),
};
setTransaction(tx);
storeTransaction(tx);

setCurrentStep(2);
} catch (err) {
Expand All @@ -121,7 +176,7 @@ export const MaspUnshield: React.FC = () => {
>
<TransferModule
source={{
isLoadingAssets: isLoadingBalances,
isLoadingAssets: isLoadingAssets,
availableAssets,
selectedAssetAddress,
availableAmount: selectedAsset?.amount,
Expand All @@ -140,8 +195,7 @@ export const MaspUnshield: React.FC = () => {
isShielded: false,
}}
transactionFee={transactionFee}
// TODO
// isSubmitting={something.isPending}
isSubmitting={performUnshieldTransfer.isPending}
errorMessage={generalErrorMessage}
onSubmitTransfer={onSubmitTransfer}
/>
Expand Down
38 changes: 38 additions & 0 deletions apps/namadillo/src/atoms/shield/atoms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { defaultAccountAtom } from "atoms/accounts";
import { chainAtom } from "atoms/chain";
import { indexerUrlAtom, rpcUrlAtom } from "atoms/settings";
import { atomWithMutation } from "jotai-tanstack-query";
import {
ShieldTransferParams,
submitShieldTx,
submitUnshieldTx,
UnshieldTransferParams,
} from "./services";

export const shieldTxAtom = atomWithMutation((get) => {
const rpcUrl = get(rpcUrlAtom);
const { data: account } = get(defaultAccountAtom);
const { data: chain } = get(chainAtom);
const indexerUrl = get(indexerUrlAtom);

return {
mutationKey: ["shield-tx"],
mutationFn: async (params: ShieldTransferParams) => {
return await submitShieldTx(rpcUrl, account!, chain!, indexerUrl, params);
},
};
});

export const unshieldTxAtom = atomWithMutation((get) => {
const rpcUrl = get(rpcUrlAtom);
const { data: account } = get(defaultAccountAtom);
const { data: chain } = get(chainAtom);
const indexerUrl = get(indexerUrlAtom);

return {
mutationKey: ["unshield-tx"],
mutationFn: async (params: UnshieldTransferParams) => {
return submitUnshieldTx(rpcUrl, account!, chain!, indexerUrl, params);
},
};
});
Loading

0 comments on commit e811bcb

Please sign in to comment.