diff --git a/src/components/guides/steps/amm/MintFeeAmmLiquidity.tsx b/src/components/guides/steps/amm/MintFeeAmmLiquidity.tsx index 7fa3dfc2..e8cf3b95 100644 --- a/src/components/guides/steps/amm/MintFeeAmmLiquidity.tsx +++ b/src/components/guides/steps/amm/MintFeeAmmLiquidity.tsx @@ -4,20 +4,19 @@ import * as React from 'react' import { parseUnits } from 'viem' import { useConnection, useConnectionEffect } from 'wagmi' import { Hooks } from 'wagmi/tempo' +import LucideCheck from '~icons/lucide/check' +import LucideCircle from '~icons/lucide/circle' import { useDemoContext } from '../../../DemoContext' import { Button, ExplorerLink, Step } from '../../Demo' -import { alphaUsd } from '../../tokens' +import { alphaUsd, pathUsd } from '../../tokens' import type { DemoStepProps } from '../types' -const validatorToken = alphaUsd - -export function MintFeeAmmLiquidity(props: DemoStepProps & { waitForBalance: boolean }) { +export function MintFeeAmmLiquidity(props: DemoStepProps & { waitForBalance?: boolean }) { const { stepNumber, last = false, waitForBalance = true } = props const { address } = useConnection() const { getData } = useDemoContext() const queryClient = useQueryClient() - // Get the address of the token created in a previous step const tokenAddress = getData('tokenAddress') const { data: metadata } = Hooks.token.useGetMetadata({ @@ -27,6 +26,12 @@ export function MintFeeAmmLiquidity(props: DemoStepProps & { waitForBalance: boo account: address, token: tokenAddress, }) + + const [pathUsdMinted, setPathUsdMinted] = React.useState(false) + const [alphaUsdMinted, setAlphaUsdMinted] = React.useState(false) + const [pathUsdTxHash, setPathUsdTxHash] = React.useState() + const [alphaUsdTxHash, setAlphaUsdTxHash] = React.useState() + const mintFeeLiquidity = Hooks.amm.useMintSync({ mutation: { onSettled() { @@ -35,48 +40,127 @@ export function MintFeeAmmLiquidity(props: DemoStepProps & { waitForBalance: boo }, }, }) + useConnectionEffect({ onDisconnect() { mintFeeLiquidity.reset() + setPathUsdMinted(false) + setAlphaUsdMinted(false) + setPathUsdTxHash(undefined) + setAlphaUsdTxHash(undefined) }, }) + const handleMintAll = React.useCallback(async () => { + if (!address || !tokenAddress) return + + if (!pathUsdMinted) { + await new Promise((resolve) => { + mintFeeLiquidity.mutate( + { + userTokenAddress: tokenAddress, + validatorTokenAddress: pathUsd, + validatorTokenAmount: parseUnits('100', 6), + to: address, + feeToken: alphaUsd, + }, + { + onSuccess(data) { + setPathUsdMinted(true) + setPathUsdTxHash(data.receipt.transactionHash) + resolve() + }, + onError() { + resolve() + }, + }, + ) + }) + } + + if (!alphaUsdMinted) { + mintFeeLiquidity.mutate( + { + userTokenAddress: tokenAddress, + validatorTokenAddress: alphaUsd, + validatorTokenAmount: parseUnits('100', 6), + to: address, + feeToken: alphaUsd, + }, + { + onSuccess(data) { + setAlphaUsdMinted(true) + setAlphaUsdTxHash(data.receipt.transactionHash) + }, + }, + ) + } + }, [address, tokenAddress, pathUsdMinted, alphaUsdMinted, mintFeeLiquidity]) + const active = React.useMemo(() => { const balanceCheck = waitForBalance ? Boolean(tokenBalance && tokenBalance > 0n) : true return Boolean(address && tokenAddress && balanceCheck) }, [address, tokenAddress, tokenBalance, waitForBalance]) + const allMinted = pathUsdMinted && alphaUsdMinted + const someMinted = pathUsdMinted || alphaUsdMinted + return ( { - if (!address || !tokenAddress) return - mintFeeLiquidity.mutate({ - userTokenAddress: tokenAddress, - validatorTokenAddress: validatorToken, - validatorTokenAmount: parseUnits('100', 6), - to: address, - feeToken: alphaUsd, - }) - }} + variant={active ? (allMinted ? 'default' : 'accent') : 'default'} + disabled={!active || mintFeeLiquidity.isPending} + onClick={handleMintAll} type="button" className="font-normal text-[14px] -tracking-[2%]" > - Add Liquidity + {mintFeeLiquidity.isPending + ? 'Adding...' + : allMinted + ? 'Done' + : someMinted + ? 'Continue Adding' + : 'Add Liquidity'} } + error={mintFeeLiquidity.error} number={stepNumber} - title={`Mint 100 pathUSD of Fee Liquidity for ${metadata ? metadata.name : 'your token'}.`} + title={`Add fee liquidity for ${metadata ? metadata.name : 'your token'}.`} > - {mintFeeLiquidity.data && ( -
+ {someMinted && ( +
- +
+
+ {pathUsdMinted ? ( + + ) : ( + + )} + pathUSD + {pathUsdTxHash && ( + + + + )} +
+
+ {alphaUsdMinted ? ( + + ) : ( + + )} + AlphaUSD + {alphaUsdTxHash && ( + + + + )} +
+
)} diff --git a/src/pages/guide/issuance/use-for-fees.mdx b/src/pages/guide/issuance/use-for-fees.mdx index 2cf128f4..8da2b434 100644 --- a/src/pages/guide/issuance/use-for-fees.mdx +++ b/src/pages/guide/issuance/use-for-fees.mdx @@ -32,9 +32,11 @@ First, create and mint your stablecoin by following the [Create a Stablecoin](/g ### Add fee pool liquidity -Before users can pay fees with your token, ensure there is sufficient liquidity in the fee pool. On the Moderato testnet, all validators expect fees in AlphaUSD, so you need to add AlphaUSD liquidity to your token's fee pool. +Before users can pay fees with your token, you need to provide liquidity in the Fee AMM between your token and each of the tokens accepted by validators. -Add liquidity to your token's fee pool: +To determine which validator tokens are needed, sample recent blocks and check the miner's preferred fee token using `getValidatorToken` on the FeeManager contract. For example, on Moderato testnet, validators accept fees in pathUSD and AlphaUSD. On mainnet, this token mix is different and subject to change. + +Add liquidity to your token's fee pool for each validator token: :::code-group @@ -303,6 +305,8 @@ Regularly check your token's fee pool reserves to ensure users can consistently Keep sufficient validator token reserves in your fee pool to handle expected transaction volume. Consider your user base size and typical transaction frequency when determining reserve levels. +As fees accrue in your token, the pool will run low on validator tokens and need to be rebalanced. Use [`rebalanceSwap`](/guide/stablecoin-dex/managing-fee-liquidity#rebalance-liquidity) to replenish validator token reserves when they become depleted. + ### Test before launch Before promoting fee payments with your token, thoroughly test the flow on testnet: