diff --git a/src/components/common/overall-layout/layout.tsx b/src/components/common/overall-layout/layout.tsx index dbbeda9..d651b53 100644 --- a/src/components/common/overall-layout/layout.tsx +++ b/src/components/common/overall-layout/layout.tsx @@ -76,6 +76,56 @@ class WalletErrorBoundary extends Component< } } +// Component to track layout content changes +function LayoutContentTracker({ + children, + router, + pageIsPublic, + userAddress +}: { + children: ReactNode; + router: ReturnType; + pageIsPublic: boolean; + userAddress: string | undefined; +}) { + const prevPathRef = useRef(router.pathname); + const prevQueryRef = useRef(JSON.stringify(router.query)); + + useEffect(() => { + const handleRouteChangeStart = (url: string) => { + // Route change started + }; + + const handleRouteChangeComplete = (url: string) => { + prevPathRef.current = router.pathname; + prevQueryRef.current = JSON.stringify(router.query); + }; + + const handleRouteChangeError = (err: Error, url: string) => { + // Route change error + }; + + router.events.on('routeChangeStart', handleRouteChangeStart); + router.events.on('routeChangeComplete', handleRouteChangeComplete); + router.events.on('routeChangeError', handleRouteChangeError); + + return () => { + router.events.off('routeChangeStart', handleRouteChangeStart); + router.events.off('routeChangeComplete', handleRouteChangeComplete); + router.events.off('routeChangeError', handleRouteChangeError); + }; + }, [router]); + + useEffect(() => { + if (router.pathname !== prevPathRef.current || JSON.stringify(router.query) !== prevQueryRef.current) { + prevPathRef.current = router.pathname; + prevQueryRef.current = JSON.stringify(router.query); + } + }, [router.pathname, router.query]); + + return <>{children}; +} + export default function RootLayout({ children, }: { @@ -631,7 +681,9 @@ export default function RootLayout({ } > - {pageIsPublic || userAddress ? children : } + + {pageIsPublic || userAddress ? children : } + diff --git a/src/components/pages/wallet/new-transaction/index.tsx b/src/components/pages/wallet/new-transaction/index.tsx index 6d9e509..bfd7720 100644 --- a/src/components/pages/wallet/new-transaction/index.tsx +++ b/src/components/pages/wallet/new-transaction/index.tsx @@ -73,9 +73,10 @@ import RecipientCsv from "./RecipientCsv"; import { truncateTokenSymbol } from "@/utils/strings"; import { UserPlus } from "lucide-react"; -export default function PageNewTransaction() { +export default function PageNewTransaction({ onSuccess }: { onSuccess?: () => void } = {}) { const { connected } = useWallet(); const userAddress = useUserStore((state) => state.userAddress); + const router = useRouter(); const { appWallet } = useAppWallet(); const { multisigWallet } = useMultisigWallet(); const [addDescription, setAddDescription] = useState(true); @@ -95,14 +96,16 @@ export default function PageNewTransaction() { const loading = useSiteStore((state) => state.loading); const setLoading = useSiteStore((state) => state.setLoading); const { toast } = useToast(); - const router = useRouter(); const [assets, setAssets] = useState(["lovelace"]); const walletAssetMetadata = useWalletsStore( (state) => state.walletAssetMetadata, ); const [previewTxBody, setPreviewTxBody] = useState<{ inputs: Array<{ txHash: string; outputIndex: number }>; - outputs: Array<{ address: string; amount: Array<{ unit: string; quantity: string }> }>; + outputs: Array<{ + address: string; + amount: Array<{ unit: string; quantity: string }>; + }>; changeAddress?: string; } | null>(null); @@ -118,52 +121,76 @@ export default function PageNewTransaction() { { walletId: appWallet?.id ?? "" }, { enabled: !!appWallet?.id, - } + }, ); // Create address lookup maps - const contactMap = useMemo>(() => { + const contactMap = useMemo< + Map + >(() => { if (!contacts) return new Map(); - const map = new Map(); - contacts.forEach((contact: { address: string; name: string; description?: string | null }) => { - map.set(contact.address, { name: contact.name, description: contact.description ?? undefined }); - }); + const map = new Map< + string, + { name: string; description?: string | null } + >(); + contacts.forEach( + (contact: { + address: string; + name: string; + description?: string | null; + }) => { + map.set(contact.address, { + name: contact.name, + description: contact.description ?? undefined, + }); + }, + ); return map; }, [contacts]); // Function to get address label - const getAddressLabel = useCallback((address: string): { label: string; type: "self" | "signer" | "contact" | "unknown" } => { - if (!appWallet) return { label: "", type: "unknown" }; - - // Check if it's the multisig wallet address - if (address === appWallet.address) { - return { label: "Self (Multisig)", type: "self" }; - } - - // Check if it's a signer - const signerIndex = appWallet.signersAddresses?.findIndex((addr) => addr === address); - if (signerIndex !== undefined && signerIndex >= 0) { - const signerDescription = appWallet.signersDescriptions?.[signerIndex] || `Signer ${signerIndex + 1}`; - return { label: signerDescription, type: "signer" }; - } - - // Check if it's a contact - const contact = contactMap.get(address); - if (contact) { - return { label: contact.name, type: "contact" }; - } - - return { label: "", type: "unknown" }; - }, [appWallet, contactMap]); + const getAddressLabel = useCallback( + ( + address: string, + ): { label: string; type: "self" | "signer" | "contact" | "unknown" } => { + if (!appWallet) return { label: "", type: "unknown" }; + + // Check if it's the multisig wallet address + if (address === appWallet.address) { + return { label: "Self (Multisig)", type: "self" }; + } + + // Check if it's a signer + const signerIndex = appWallet.signersAddresses?.findIndex( + (addr) => addr === address, + ); + if (signerIndex !== undefined && signerIndex >= 0) { + const signerDescription = + appWallet.signersDescriptions?.[signerIndex] || + `Signer ${signerIndex + 1}`; + return { label: signerDescription, type: "signer" }; + } + + // Check if it's a contact + const contact = contactMap.get(address); + if (contact) { + return { label: contact.name, type: "contact" }; + } + + return { label: "", type: "unknown" }; + }, + [appWallet, contactMap], + ); useEffect(() => { reset(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Calculate final UTxOs that will be used in transaction (after keepRelevant filtering) const finalSelectedUtxos = useMemo(() => { if (manualUtxos.length === 0) return []; - + if (sendAllAssets) { return manualUtxos; } @@ -191,15 +218,25 @@ export default function PageNewTransaction() { (Number(assetMap.get(unit) || 0) + thisAmount).toString(), ); if (unit !== "lovelace") { - assetMap.set("lovelace", (Number(assetMap.get("lovelace") || 0) + 1160000).toString()); + assetMap.set( + "lovelace", + (Number(assetMap.get("lovelace") || 0) + 1160000).toString(), + ); } } } if (assetMap.size === 0) return manualUtxos; - + return keepRelevant(assetMap, manualUtxos); - }, [manualUtxos, sendAllAssets, recipientAddresses, amounts, assets, walletAssetMetadata]); + }, [ + manualUtxos, + sendAllAssets, + recipientAddresses, + amounts, + assets, + walletAssetMetadata, + ]); // Preview transaction outputs as user prepares the transaction useEffect(() => { @@ -239,7 +276,10 @@ export default function PageNewTransaction() { (Number(assetMap.get(unit) || 0) + thisAmount).toString(), ); if (unit !== "lovelace") { - assetMap.set("lovelace", (Number(assetMap.get("lovelace") || 0) + 1160000).toString()); + assetMap.set( + "lovelace", + (Number(assetMap.get("lovelace") || 0) + 1160000).toString(), + ); } } } @@ -251,8 +291,11 @@ export default function PageNewTransaction() { })); // Build output array for preview - const previewOutputs: Array<{ address: string; amount: Array<{ unit: string; quantity: string }> }> = []; - + const previewOutputs: Array<{ + address: string; + amount: Array<{ unit: string; quantity: string }>; + }> = []; + if (!sendAllAssets && outputs.length > 0) { for (const output of outputs) { previewOutputs.push({ @@ -262,19 +305,24 @@ export default function PageNewTransaction() { unit: output.unit, quantity: output.amount, }, - ...(output.unit !== "lovelace" ? [{ - unit: "lovelace", - quantity: "1160000", - }] : []) + ...(output.unit !== "lovelace" + ? [ + { + unit: "lovelace", + quantity: "1160000", + }, + ] + : []), ], }); } } // Determine change address - const changeAddress = sendAllAssets && outputs.length > 0 - ? outputs[0]!.address - : appWallet.address; + const changeAddress = + sendAllAssets && outputs.length > 0 + ? outputs[0]!.address + : appWallet.address; setPreviewTxBody({ inputs, @@ -294,6 +342,8 @@ export default function PageNewTransaction() { finalSelectedUtxos, sendAllAssets, walletAssetMetadata, + // Note: router.pathname is checked inside the effect, not in dependencies + // to prevent infinite loops when router object changes ]); function reset() { @@ -343,7 +393,10 @@ export default function PageNewTransaction() { (Number(assetMap.get(unit) || 0) + thisAmount).toString(), ); if (unit !== "lovelace") { - assetMap.set("lovelace", (Number(assetMap.get("lovelace") || 0) + 1160000).toString()); + assetMap.set( + "lovelace", + (Number(assetMap.get("lovelace") || 0) + 1160000).toString(), + ); } } } @@ -360,8 +413,8 @@ export default function PageNewTransaction() { } const txBuilder = getTxBuilder(network); - const paymentScript = appWallet.scriptCbor - if(!paymentScript) return + const paymentScript = appWallet.scriptCbor; + if (!paymentScript) return; for (const utxo of selectedUtxos) { txBuilder @@ -371,10 +424,9 @@ export default function PageNewTransaction() { utxo.output.amount, utxo.output.address, ) - .txInScript(paymentScript) + .txInScript(paymentScript); } - if (!sendAllAssets) { for (let i = 0; i < outputs.length; i++) { txBuilder.txOut(outputs[i]!.address, [ @@ -383,10 +435,14 @@ export default function PageNewTransaction() { quantity: outputs[i]!.amount, }, // if unit is not lovelace, add 1160000 lovelace as native assets are not allowed to be in an output alone. - ...(outputs[i]!.unit !== "lovelace" ? [{ - unit: "lovelace", - quantity: "1160000", - }] : []) + ...(outputs[i]!.unit !== "lovelace" + ? [ + { + unit: "lovelace", + quantity: "1160000", + }, + ] + : []), ]); } } @@ -456,7 +512,10 @@ export default function PageNewTransaction() { } function addMultisigSignerAsRecipient(signerIndex: number) { - if (appWallet?.signersAddresses && appWallet.signersAddresses[signerIndex]) { + if ( + appWallet?.signersAddresses && + appWallet.signersAddresses[signerIndex] + ) { const signerAddress = appWallet.signersAddresses[signerIndex]!; setRecipientAddresses([...recipientAddresses, signerAddress]); setAmounts([...amounts, ""]); @@ -464,24 +523,30 @@ export default function PageNewTransaction() { } } + // Match deposit page behavior - don't return early, handle undefined in functions that need it + // This prevents unmount/remount cycles that cause "Cancel rendering route" errors + + if (!appWallet) { + return null; + } + return ( -
-
+
+ {/* Hide title/description when used in modal (they're in DialogHeader) */} +
New Transaction -

- Create a new multisig transaction by specifying recipients, amounts, and transaction details. +

+ Create a new multisig transaction by specifying recipients, amounts, + and transaction details.

-
- +
+
{ if (e.target.value.length <= 128) @@ -492,12 +557,13 @@ export default function PageNewTransaction() { - +

- Add a brief description to help other signers understand the purpose of this transaction. - This will be visible to all wallet members when reviewing the transaction. + Add a brief description to help other signers understand + the purpose of this transaction. This will be visible to + all wallet members when reviewing the transaction.

@@ -505,7 +571,11 @@ export default function PageNewTransaction() {
{description.length > 0 && (
- = 128 ? "text-destructive" : ""}> + = 128 ? "text-destructive" : "" + } + > {description.length}/128
@@ -513,8 +583,8 @@ export default function PageNewTransaction() {
- @@ -527,16 +597,22 @@ export default function PageNewTransaction() { amounts={amounts} assets={assets} /> - + {/* Desktop Table */} -
+
- Address - Amount - Asset + + Address + + + Amount + + + Asset + @@ -557,74 +633,95 @@ export default function PageNewTransaction() { ))} -
+
- + - + - {appWallet?.signersAddresses?.map((signerAddress, index) => { - const signerDescription = appWallet.signersDescriptions?.[index] || `Signer ${index + 1}`; + {appWallet?.signersAddresses?.map( + (signerAddress, index) => { + const signerDescription = + appWallet.signersDescriptions?.[index] || + `Signer ${index + 1}`; - return ( - addMultisigSignerAsRecipient(index)} - className="flex flex-col items-start gap-1" - > - {signerDescription} - - {signerAddress.slice(0, 20)}... - - - ); - })} + return ( + + addMultisigSignerAsRecipient(index) + } + className="flex flex-col items-start gap-1" + > + + {signerDescription} + + + {signerAddress.slice(0, 20)}... + + + ); + }, + )} - + {contacts && contacts.length > 0 && ( { - setRecipientAddresses([...recipientAddresses, contact.address]); + setRecipientAddresses([ + ...recipientAddresses, + contact.address, + ]); setAmounts([...amounts, ""]); setAssets([...assets, "lovelace"]); }} - className="h-8 sm:h-9 flex-1 sm:flex-none" + className="h-8 flex-1 sm:h-9 sm:flex-none" /> )}
@@ -651,39 +748,43 @@ export default function PageNewTransaction() { getAddressLabel={getAddressLabel} /> ))} - + {/* Mobile Add Buttons */}
- +
- + - {appWallet?.signersAddresses?.map((signerAddress, index) => { - const signerDescription = appWallet.signersDescriptions?.[index] || `Signer ${index + 1}`; - - return ( - addMultisigSignerAsRecipient(index)} - className="flex flex-col items-start gap-1" - > - {signerDescription} - - {signerAddress.slice(0, 20)}... - - - ); - })} + {appWallet?.signersAddresses?.map( + (signerAddress, index) => { + const signerDescription = + appWallet.signersDescriptions?.[index] || + `Signer ${index + 1}`; + + return ( + + addMultisigSignerAsRecipient(index) + } + className="flex flex-col items-start gap-1" + > + + {signerDescription} + + + {signerAddress.slice(0, 20)}... + + + ); + }, + )} - + {contacts && contacts.length > 0 && ( { - setRecipientAddresses([...recipientAddresses, contact.address]); + setRecipientAddresses([ + ...recipientAddresses, + contact.address, + ]); setAmounts([...amounts, ""]); setAssets([...assets, "lovelace"]); }} @@ -727,99 +839,63 @@ export default function PageNewTransaction() {
- -
- {/* UTxO Selector Subsection */} - {appWallet && ( - { - setManualUtxos(utxos); - setManualSelected(manual); - }} - recipientAmounts={amounts} - recipientAssets={assets} - /> - )} - - {/* Transaction Preview - Only show if outputs are defined */} - {(previewTxBody?.outputs.length ?? 0) > 0 || sendAllAssets ? ( -
-

Transaction Preview

-
- {/* Input UTxOs for Transaction */} -
-

Input UTxOs ({finalSelectedUtxos.length})

- {finalSelectedUtxos.length > 0 ? ( - <> - {/* Mobile Card Layout */} -
- {finalSelectedUtxos.map((utxo, index) => ( -
-
- {utxo.input.outputIndex} - - - - {utxo.input.txHash.slice(0, 8)}...{utxo.input.txHash.slice(-8)} - -
-
- {Array.isArray(utxo.output.amount) ? ( - utxo.output.amount.map((unit: any, j: number) => { - const assetMetadata = walletAssetMetadata[unit.unit]; - const decimals = - unit.unit === "lovelace" - ? 6 - : (assetMetadata?.decimals ?? 0); - const assetName = - unit.unit === "lovelace" - ? "₳" - : assetMetadata?.ticker - ? `$${truncateTokenSymbol(assetMetadata.ticker)}` - : truncateTokenSymbol(unit.unit); - return ( - - {j > 0 && ,} - {(parseFloat(unit.quantity) / Math.pow(10, decimals)).toFixed(6)} {assetName} - - ); - }) - ) : ( - No amount data - )} -
-
- ))} -
+ +
+ {/* UTxO Selector Subsection */} + {appWallet && ( + { + setManualUtxos(utxos); + setManualSelected(manual); + }} + recipientAmounts={amounts} + recipientAssets={assets} + /> + )} - {/* Desktop Table Layout */} -
-
- - - Tx Index - Hash - Outputs - - - + {/* Transaction Preview - Only show if outputs are defined */} + {(previewTxBody?.outputs.length ?? 0) > 0 || sendAllAssets ? ( +
+

+ Transaction Preview +

+
+ {/* Input UTxOs for Transaction */} +
+

+ Input UTxOs ({finalSelectedUtxos.length}) +

+ {finalSelectedUtxos.length > 0 ? ( + <> + {/* Mobile Card Layout */} +
{finalSelectedUtxos.map((utxo, index) => ( - - - {utxo.input.outputIndex}-{utxo.input.txHash.slice(0, 10)}...{utxo.input.txHash.slice(-10)} - - -
- {Array.isArray(utxo.output.amount) ? ( - utxo.output.amount.map((unit: any, j: number) => { - const assetMetadata = walletAssetMetadata[unit.unit]; +
+
+ + {utxo.input.outputIndex} + + - + + {utxo.input.txHash.slice(0, 8)}... + {utxo.input.txHash.slice(-8)} + +
+
+ {Array.isArray(utxo.output.amount) ? ( + utxo.output.amount.map( + (unit: any, j: number) => { + const assetMetadata = + walletAssetMetadata[unit.unit]; const decimals = unit.unit === "lovelace" ? 6 @@ -831,308 +907,477 @@ export default function PageNewTransaction() { ? `$${truncateTokenSymbol(assetMetadata.ticker)}` : truncateTokenSymbol(unit.unit); return ( - - {j > 0 && ,} - {(parseFloat(unit.quantity) / Math.pow(10, decimals)).toFixed(6)} {assetName} + + {j > 0 && ( + + , + + )} + {( + parseFloat(unit.quantity) / + Math.pow(10, decimals) + ).toFixed(6)}{" "} + {assetName} ); - }) - ) : ( - No amount data - )} -
- - - ))} - -
-
- - ) : ( -
-

- {manualUtxos.length === 0 - ? "No UTxOs selected. Use the selector above to choose UTxOs for this transaction." - : "Selected UTxOs will be filtered based on recipient requirements. Select UTxOs above to see them here."} -

-
- )} -
- - {/* Output UTxOs */} -
-

Output UTxOs ({previewTxBody?.outputs.length ?? 0})

- {previewTxBody ? ( -
- {previewTxBody.outputs.length > 0 ? ( - <> - {/* Mobile Card Layout */} -
- {previewTxBody.outputs.map((output, index) => { - const addressLabel = getAddressLabel(output.address); - return ( -
-
- {addressLabel.label && ( -
- - {addressLabel.label} - -
+ }, + ) + ) : ( + + No amount data + )} -
- {output.address.slice(0, 12)}...{output.address.slice(-12)} -
-
-
- {output.amount.map((asset, assetIndex) => { - const assetMetadata = walletAssetMetadata[asset.unit]; - const decimals = - asset.unit === "lovelace" - ? 6 - : (assetMetadata?.decimals ?? 0); - const assetName = - asset.unit === "lovelace" - ? "₳" - : assetMetadata?.ticker - ? `$${truncateTokenSymbol(assetMetadata.ticker)}` - : truncateTokenSymbol(asset.unit); - const formattedAmount = (parseFloat(asset.quantity) / Math.pow(10, decimals)).toFixed(6); - return ( - - {formattedAmount} {assetName} - - ); - })}
- ); - })} + ))}
{/* Desktop Table Layout */} -
+
- Address - Amount + + Tx Index - Hash + + + Outputs + + {finalSelectedUtxos.map((utxo, index) => ( + + + {utxo.input.outputIndex}- + {utxo.input.txHash.slice(0, 10)}... + {utxo.input.txHash.slice(-10)} + + +
+ {Array.isArray(utxo.output.amount) ? ( + utxo.output.amount.map( + (unit: any, j: number) => { + const assetMetadata = + walletAssetMetadata[unit.unit]; + const decimals = + unit.unit === "lovelace" + ? 6 + : (assetMetadata?.decimals ?? + 0); + const assetName = + unit.unit === "lovelace" + ? "₳" + : assetMetadata?.ticker + ? `$${truncateTokenSymbol(assetMetadata.ticker)}` + : truncateTokenSymbol( + unit.unit, + ); + return ( + + {j > 0 && ( + + , + + )} + {( + parseFloat(unit.quantity) / + Math.pow(10, decimals) + ).toFixed(6)}{" "} + {assetName} + + ); + }, + ) + ) : ( + + No amount data + + )} +
+
+
+ ))} +
+
+
+ + ) : ( +
+

+ {manualUtxos.length === 0 + ? "No UTxOs selected. Use the selector above to choose UTxOs for this transaction." + : "Selected UTxOs will be filtered based on recipient requirements. Select UTxOs above to see them here."} +

+
+ )} +
+ + {/* Output UTxOs */} +
+

+ Output UTxOs ({previewTxBody?.outputs.length ?? 0}) +

+ {previewTxBody ? ( +
+ {previewTxBody.outputs.length > 0 ? ( + <> + {/* Mobile Card Layout */} +
{previewTxBody.outputs.map((output, index) => { - const addressLabel = getAddressLabel(output.address); + const addressLabel = getAddressLabel( + output.address, + ); return ( - - -
+
+
{addressLabel.label && ( -
- +
+ {addressLabel.label}
)} -
- {output.address.slice(0, 20)}...{output.address.slice(-20)} +
+ {output.address.slice(0, 12)}... + {output.address.slice(-12)}
- -
- {output.amount.map((asset, assetIndex) => { - const assetMetadata = walletAssetMetadata[asset.unit]; - const decimals = - asset.unit === "lovelace" - ? 6 - : (assetMetadata?.decimals ?? 0); - const assetName = - asset.unit === "lovelace" - ? "₳" - : assetMetadata?.ticker - ? `$${truncateTokenSymbol(assetMetadata.ticker)}` - : truncateTokenSymbol(asset.unit); - const formattedAmount = (parseFloat(asset.quantity) / Math.pow(10, decimals)).toFixed(6); - return ( - - {formattedAmount} {assetName} - - ); - })} + {output.amount.map( + (asset, assetIndex) => { + const assetMetadata = + walletAssetMetadata[asset.unit]; + const decimals = + asset.unit === "lovelace" + ? 6 + : (assetMetadata?.decimals ?? 0); + const assetName = + asset.unit === "lovelace" + ? "₳" + : assetMetadata?.ticker + ? `$${truncateTokenSymbol(assetMetadata.ticker)}` + : truncateTokenSymbol( + asset.unit, + ); + const formattedAmount = ( + parseFloat(asset.quantity) / + Math.pow(10, decimals) + ).toFixed(6); + return ( + + {formattedAmount} {assetName} + + ); + }, + )}
-
- - ); +
+ ); })} - - -
- - ) : sendAllAssets ? ( -
-

- All assets will be sent to: {previewTxBody.changeAddress?.slice(0, 20)}...{previewTxBody.changeAddress?.slice(-20)} -

-
- ) : ( -
-

No outputs defined

-
- )} -
- ) : ( -

Configure recipients and select UTxOs to see preview

- )} -
-
+
- {/* Change Address - Below both sections */} - {previewTxBody?.changeAddress && !sendAllAssets && (() => { - const changeAddressLabel = getAddressLabel(previewTxBody.changeAddress); - return ( -
-

Change Address

-
- {changeAddressLabel.label && ( -
- - {changeAddressLabel.label} - -
- )} -

- {previewTxBody.changeAddress} + {/* Desktop Table Layout */} +

+ + + + + Address + + + Amount + + + + + {previewTxBody.outputs.map( + (output, index) => { + const addressLabel = getAddressLabel( + output.address, + ); + return ( + + +
+ {addressLabel.label && ( +
+ + {addressLabel.label} + +
+ )} +
+ {output.address.slice(0, 20)}... + {output.address.slice(-20)} +
+
+
+ +
+ {output.amount.map( + (asset, assetIndex) => { + const assetMetadata = + walletAssetMetadata[ + asset.unit + ]; + const decimals = + asset.unit === "lovelace" + ? 6 + : (assetMetadata?.decimals ?? + 0); + const assetName = + asset.unit === "lovelace" + ? "₳" + : assetMetadata?.ticker + ? `$${truncateTokenSymbol(assetMetadata.ticker)}` + : truncateTokenSymbol( + asset.unit, + ); + const formattedAmount = ( + parseFloat(asset.quantity) / + Math.pow(10, decimals) + ).toFixed(6); + return ( + + {formattedAmount}{" "} + {assetName} + + ); + }, + )} +
+
+
+ ); + }, + )} +
+
+
+ + ) : sendAllAssets ? ( +
+

+ All assets will be sent to:{" "} + + {previewTxBody.changeAddress?.slice(0, 20)}... + {previewTxBody.changeAddress?.slice(-20)} + +

+
+ ) : ( +
+

+ No outputs defined +

+
+ )} +
+ ) : ( +

+ Configure recipients and select UTxOs to see preview

-
+ )}
- ); - })()} -
- ) : null} -
- - - -
-