Skip to content

Commit

Permalink
[ENG-3749] feat: runes tokens list, balances, and send flow (#80)
Browse files Browse the repository at this point in the history
* feat: init structure for send rune flow with flag for testnet only

* add hook

* add runes api client

* feat: handle rune token display on home and token dashboard (#81)

* wip

* chore: tweak token dashboard for runes and add tokens to home send bottomsheet

* remove TODOs that are handled now

* touchup

* chore: update text to support runes in receive screen

* chore: dry

* chore: remove runes list from client store

* chore: remvoe todos related to texts

* chore: remove useGetRuneFungibleTokens config todo

---------

Co-authored-by: fede erbes <fedeerbes@gmail.com>

* Manage tokens screen for runes support (#84)

* refactor key variables to improve readability

* updates

* major refactor stx coinslist & support runes in manage token page for testnet

* remove conditonals and improve performance

* add figma for mainnet coming soon

* chore: add protocol icons for stacks, brc20 and runes tokens (#83)

* chore: add protocol icons for stacks, brc20 and runes tokens

* fix: token image loader and clean render logic

* chore: use our runes logo and remove square styles

* chore: use a default size const

* fix: font size and add missing protocol to brc20 tokens

* updates

* fix stx icon issue

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>

* standardize currency typing and improve variable namings

* revert logic + touchup

* touchup

* add rune icon

* add typing

* rename variable

* progress

* progress

* fix button disabled

* fix amount validations and display error msg

* chore: use core pr version with runes support

* Tim/eng 3814 receive runes screen design check (#91)

* fix: receive bottom sheet icons and blur

* Update en.json

Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

---------

Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

* nits

* Terence/fix edge case renderings (#95)

* fix (#94)

* fix

* Update src/app/ui-library/input.tsx

Co-authored-by: Tim Man <tim@secretkeylabs.com>

* fix

* use variant

* use brc

* fix expression readability

* fix sip coins which are hidden by manage token list should not be sendable in send coins list (#96)

* update key

* fix: remove unused route

* fix: coin dashboard should show names and no protocol if none

* standardize ticker icon for no image tickers

* remove deprecated usage

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* fix up logic

* refactor: manage tokens for runes (#98)

* refactor: manage tokens for runes

* fix: be more strict on toggle handler

* chore: minor cleanup

* chore: minor diff clean up

* update remaining FT to sip-10

* testing (#93)

* touchup currencyTypes logic to go back to using FT, fixes, prepare improved receive screen for STX, BTC, ORD

* update receive coin screen to handle STX & BTC

* fix type issue

* revert console log

* revert changes

* logic fix

* remove unused component

* Tim/refactor manage tokens (#99)

* refactor: brc20 and sip10 tokens should use react-query hooks

and no longer store balances in redux

* fix: define a redux migration callback to keep user settings for manage tokens

* fix: brc20 ft list merge

* update remaining FT to sip-10

* testing (#93)

* touchup currencyTypes logic to go back to using FT, fixes, prepare improved receive screen for STX, BTC, ORD

* update receive coin screen to handle STX & BTC

* fix type issue

* refactor: brc20 and sip10 tokens should use react-query hooks

and no longer store balances in redux

* test

* revert

* fix: also remove coins from redux state in migration

* chore: consistent naming

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>
Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

* fix: fix typing and null case for redux migration function

* chore: bump to latest beta core

* refactorings

* typo

* use bigint and fix amount precision

* fix debounce

* update core

* remove script info

* chore: bump core version

* hack: update confirmTransaction to handle runes v1

* allow display input/output

* revert runes icon to use square

* chore: core version with undefined runes fix

* additional check

* update logo

* Empty rune list message scenario and error message (#107)

* feat: init structure for send rune flow with flag for testnet only

* add hook

* add runes api client

* feat: handle rune token display on home and token dashboard (#81)

* wip

* chore: tweak token dashboard for runes and add tokens to home send bottomsheet

* remove TODOs that are handled now

* touchup

* chore: update text to support runes in receive screen

* chore: dry

* chore: remove runes list from client store

* chore: remvoe todos related to texts

* chore: remove useGetRuneFungibleTokens config todo

---------

Co-authored-by: fede erbes <fedeerbes@gmail.com>

* Manage tokens screen for runes support (#84)

* refactor key variables to improve readability

* updates

* major refactor stx coinslist & support runes in manage token page for testnet

* remove conditonals and improve performance

* add figma for mainnet coming soon

* chore: add protocol icons for stacks, brc20 and runes tokens (#83)

* chore: add protocol icons for stacks, brc20 and runes tokens

* fix: token image loader and clean render logic

* chore: use our runes logo and remove square styles

* chore: use a default size const

* fix: font size and add missing protocol to brc20 tokens

* updates

* fix stx icon issue

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>

* standardize currency typing and improve variable namings

* revert logic + touchup

* touchup

* add rune icon

* add typing

* rename variable

* progress

* progress

* chore: use core pr version with runes support

* fix button disabled

* fix amount validations and display error msg

* Tim/eng 3814 receive runes screen design check (#91)

* fix: receive bottom sheet icons and blur

* Update en.json

Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

---------

Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

* nits

* fix (#94)

* Terence/fix edge case renderings (#95)

* fix (#94)

* fix

* Update src/app/ui-library/input.tsx

Co-authored-by: Tim Man <tim@secretkeylabs.com>

* fix

* use variant

* use brc

* fix expression readability

* fix sip coins which are hidden by manage token list should not be sendable in send coins list (#96)

* update key

* fix: remove unused route

* fix: coin dashboard should show names and no protocol if none

* standardize ticker icon for no image tickers

* remove deprecated usage

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* Update src/locales/en.json

* fix up logic

* refactor: manage tokens for runes (#98)

* refactor: manage tokens for runes

* fix: be more strict on toggle handler

* chore: minor cleanup

* chore: minor diff clean up

* update remaining FT to sip-10

* testing (#93)

* touchup currencyTypes logic to go back to using FT, fixes, prepare improved receive screen for STX, BTC, ORD

* update receive coin screen to handle STX & BTC

* fix type issue

* revert console log

* revert changes

* logic fix

* remove unused component

* Tim/refactor manage tokens (#99)

* refactor: brc20 and sip10 tokens should use react-query hooks

and no longer store balances in redux

* fix: define a redux migration callback to keep user settings for manage tokens

* fix: brc20 ft list merge

* update remaining FT to sip-10

* testing (#93)

* touchup currencyTypes logic to go back to using FT, fixes, prepare improved receive screen for STX, BTC, ORD

* update receive coin screen to handle STX & BTC

* fix type issue

* refactor: brc20 and sip10 tokens should use react-query hooks

and no longer store balances in redux

* test

* revert

* fix: also remove coins from redux state in migration

* chore: consistent naming

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>
Co-authored-by: Terence Ng <terence.ng@cakedefi.com>

* fix: fix typing and null case for redux migration function

* chore: bump to latest beta core

* refactorings

* typo

* use bigint and fix amount precision

* fix debounce

* update core

* remove script info

* chore: bump core version

* hack: update confirmTransaction to handle runes v1

* allow display input/output

* revert runes icon to use square

* chore: core version with undefined runes fix

* additional check

* update logo

* push

* push

---------

Co-authored-by: Tim Man <tim@secretkeylabs.com>
Co-authored-by: fede erbes <fedeerbes@gmail.com>
Co-authored-by: Victor Kirov <victor.kirov@gmail.com>

* update label

* fix: overflow on send rune amound input, when long balance (#105)

* fix: overflow on send rune amound input, when long balance

* refactor: move the complications to the input component file

* fix: set allowNegative=false to fix warnings for number format (#106)

* fix: set allowNegative=false to fix warnings for number format

* fix: styling of stx tx transaction history

* fix balance becoming exponential string for large digits

* fix large amount / decimal formatting

* touchup

* adjust gap to cater max scenario

* update display ellipsis for high digit/decimal values

* small fix

* fix: css balance token tile

* fix: cleaner css

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>

* fix (#109)

* [ENG-3193] refactor: Refactor away from selectedOrdinal (#791)

* commit changes

* remove selectedOrdinal for raresat screen

* update recover screens

* fix translation text

* revert non null assertion

* fix bug

* fix merge

* fix (#109)

* fixes (#110)

* fixes

* remove log

* disable rbf

* pull latest core to support rbf

* Update core and fix map key for txn history

---------

Co-authored-by: Victor Kirov <victor.kirov@gmail.com>

* [ENG-3193] refactor: Refactor away from selectedOrdinal (#791)

* commit changes

* remove selectedOrdinal for raresat screen

* update recover screens

* fix translation text

* revert non null assertion

* fix bug

* fix merge

* chore: bump core to v11.1.1 (#806)

* chore: Bump core to 11.1.2 (#807)

* chore: bump to latest beta core

* update lock

* use mobile values

* fix render

* Solve missing name

* Fallback for SIP-10 FungibleTokens with missing name

* chore: bump core to v11.3.0

---------

Co-authored-by: Terence Ng <ngtere@live.com.sg>
Co-authored-by: Terence Ng <terence.ng@cakedefi.com>
Co-authored-by: fede erbes <fedeerbes@gmail.com>
Co-authored-by: Victor Kirov <victor.kirov@gmail.com>
Co-authored-by: jordankzf <jordan@secretkeylabs.com>
  • Loading branch information
6 people committed Mar 11, 2024
1 parent a1ddb2e commit 851598c
Show file tree
Hide file tree
Showing 83 changed files with 2,564 additions and 1,646 deletions.
505 changes: 385 additions & 120 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"@phosphor-icons/react": "^2.0.10",
"@react-spring/web": "^9.6.1",
"@scure/btc-signer": "1.2.1",
"@secretkeylabs/xverse-core": "11.1.2",
"@secretkeylabs/xverse-core": "11.3.0",
"@stacks/connect": "7.4.1",
"@stacks/stacks-blockchain-api-types": "6.1.1",
"@stacks/transactions": "6.9.0",
Expand Down
11 changes: 10 additions & 1 deletion src/app/components/confirmBtcTransaction/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ActionButton from '@components/button';
import LedgerConnectionView from '@components/ledger/connectLedgerView';
import useWalletSelector from '@hooks/useWalletSelector';
import TransportFactory from '@ledgerhq/hw-transport-webusb';
import { btcTransaction, Transport } from '@secretkeylabs/xverse-core';
import { btcTransaction, FungibleToken, Transport } from '@secretkeylabs/xverse-core';
import Callout from '@ui-library/callout';
import { StickyHorizontalSplitButtonContainer, StyledP } from '@ui-library/common.styled';
import Spinner from '@ui-library/spinner';
Expand Down Expand Up @@ -52,6 +52,9 @@ type Props = {
isSubmitting: boolean;
isBroadcast?: boolean;
isError?: boolean;
token?: FungibleToken;
amountToSend?: string;
recipientAddress?: string;
showAccountHeader?: boolean;
hideBottomBar?: boolean;
cancelText: string;
Expand All @@ -76,6 +79,9 @@ function ConfirmBtcTransaction({
isSubmitting,
isBroadcast,
isError = false,
token,
amountToSend,
recipientAddress,
cancelText,
confirmText,
onConfirm,
Expand Down Expand Up @@ -167,6 +173,9 @@ function ConfirmBtcTransaction({
</ReviewTransactionText>
{!isBroadcast && <BroadcastCallout bodyText={t('PSBT_NO_BROADCAST_DISCLAIMER')} />}
<TransactionSummary
token={token}
amountToSend={amountToSend}
recipientAddress={recipientAddress}
inputs={inputs}
outputs={outputs}
feeOutput={feeOutput}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default function Amount({ amount }: Props) {
return (
<RowCenter>
<AvatarContainer>
<Avatar src={<TokenImage token="BTC" loading={false} size={32} />} />
<Avatar src={<TokenImage currency="BTC" loading={false} size={32} />} />
</AvatarContainer>
<RowCenter spaceBetween>
<div>
Expand Down
93 changes: 93 additions & 0 deletions src/app/components/confirmBtcTransaction/itemRow/runeAmount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import TokenImage from '@components/tokenImage';
import { FungibleToken } from '@secretkeylabs/xverse-core';
import Avatar from '@ui-library/avatar';
import { StyledP } from '@ui-library/common.styled';
import { getFtTicker } from '@utils/tokens';
import { useTranslation } from 'react-i18next';
import { NumericFormat } from 'react-number-format';
import styled from 'styled-components';

type Props = {
amountSats: number;
token: FungibleToken;
amountToSend: string;
};

const Container = styled.div({
width: '100%',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
});

const AvatarContainer = styled.div`
margin-right: ${(props) => props.theme.space.xs};
`;

const ColumnContainer = styled.div({
width: '100%',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
gap: '24px',
whiteSpace: 'nowrap',
overflow: 'hidden',
});

const NumberTypeContainer = styled.div`
text-align: right;
overflow: hidden;
`;

const EllipsisStyledP = styled(StyledP)`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;

export default function RuneAmount({ amountSats, token, amountToSend }: Props) {
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });

return (
<Container>
<AvatarContainer>
<Avatar
src={
<TokenImage
currency="FT"
fungibleToken={token}
showProtocolIcon={false}
loading={false}
size={32}
/>
}
/>
</AvatarContainer>
<ColumnContainer>
<div>
<StyledP typography="body_medium_m" color="white_200">
{t('AMOUNT')}
</StyledP>
<StyledP typography="body_medium_s" color="white_400">
{t('BITCOIN_VALUE')}
</StyledP>
</div>
<NumberTypeContainer>
<NumericFormat
value={amountToSend}
displayType="text"
thousandSeparator
suffix={` ${getFtTicker(token)}`}
renderText={(value: string) => (
<EllipsisStyledP typography="body_medium_m">{value}</EllipsisStyledP>
)}
/>
<StyledP typography="body_medium_s" color="white_400">
{`${amountSats} ${t('SATS')}`}
</StyledP>
</NumberTypeContainer>
</ColumnContainer>
</Container>
);
}
26 changes: 15 additions & 11 deletions src/app/components/confirmBtcTransaction/transactionSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import useWalletSelector from '@hooks/useWalletSelector';
import AssetModal from '@components/assetModal';
import TransferFeeView from '@components/transferFeeView';
import useBtcFeeRate from '@hooks/useBtcFeeRate';
import { btcTransaction, getBtcFiatEquivalent } from '@secretkeylabs/xverse-core';
import { btcTransaction, FungibleToken, getBtcFiatEquivalent } from '@secretkeylabs/xverse-core';
import SelectFeeRate from '@ui-components/selectFeeRate';
import Callout from '@ui-library/callout';
import { BLOG_LINK } from '@utils/constants';
Expand Down Expand Up @@ -38,10 +38,12 @@ const UnconfirmedInputCallout = styled(Callout)`

type Props = {
isPartialTransaction: boolean;

inputs: btcTransaction.EnhancedInput[];
outputs: btcTransaction.EnhancedOutput[];
feeOutput?: btcTransaction.TransactionFeeOutput;
token?: FungibleToken;
amountToSend?: string;
recipientAddress?: string;
getFeeForFeeRate?: (
feeRate: number,
useEffectiveFeeRate?: boolean,
Expand All @@ -52,10 +54,13 @@ type Props = {
};

function TransactionSummary({
isPartialTransaction,
inputs,
outputs,
feeOutput,
isPartialTransaction,
token,
amountToSend,
recipientAddress,
isSubmitting,
getFeeForFeeRate,
onFeeRateSet,
Expand Down Expand Up @@ -104,6 +109,9 @@ function TransactionSummary({

const showFeeSelector = !!(feeRate && getFeeForFeeRate && onFeeRateSet);

// TODO - TEMP SOLUTION - we should detect this via the txContext (input/outputs) for proper PSBT support (v2)
const isRuneTransaction = token && token.protocol === 'runes' && amountToSend && recipientAddress;

return (
<>
{inscriptionToShow && (
Expand All @@ -125,31 +133,27 @@ function TransactionSummary({
anchorRedirect={`${BLOG_LINK}/rare-satoshis`}
/>
)}

{isUnConfirmedInput && (
<UnconfirmedInputCallout bodyText={t('UNCONFIRMED_UTXO_WARNING')} variant="warning" />
)}

<TransferSection
outputs={outputs}
inputs={inputs}
isPartialTransaction={isPartialTransaction}
token={token}
amountToSend={amountToSend}
recipientAddress={recipientAddress}
onShowInscription={setInscriptionToShow}
netAmount={-netAmount}
/>

<ReceiveSection
outputs={outputs}
onShowInscription={setInscriptionToShow}
netAmount={netAmount}
/>

<TxInOutput inputs={inputs} outputs={outputs} />

{hasOutputScript && <ScriptCallout bodyText={t('SCRIPT_OUTPUT_TX')} />}

{!isRuneTransaction && hasOutputScript && <ScriptCallout bodyText={t('SCRIPT_OUTPUT_TX')} />}
<TransactionDetailComponent title={t('NETWORK')} value={network.type} />

{feeOutput && !showFeeSelector && (
<TransferFeeView
fee={new BigNumber(feeOutput.amount)}
Expand Down
34 changes: 32 additions & 2 deletions src/app/components/confirmBtcTransaction/transferSection.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import RuneAmount from '@components/confirmBtcTransaction/itemRow/runeAmount';
import useWalletSelector from '@hooks/useWalletSelector';
import { btcTransaction } from '@secretkeylabs/xverse-core';
import { ArrowRight } from '@phosphor-icons/react';
import { btcTransaction, FungibleToken } from '@secretkeylabs/xverse-core';
import { StyledP } from '@ui-library/common.styled';
import { getTruncatedAddress } from '@utils/helper';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import Theme from '../../../theme';
import Amount from './itemRow/amount';
import AmountWithInscriptionSatribute from './itemRow/amountWithInscriptionSatribute';
import InscriptionSatributeRow from './itemRow/inscriptionSatributeRow';
Expand Down Expand Up @@ -34,12 +38,24 @@ const Header = styled(RowCenter)((props) => ({
padding: `0 ${props.theme.space.m}`,
}));

const StyledStyledP = styled(StyledP)`
display: flex;
align-items: center;
`;

const StyledArrowRight = styled(ArrowRight)({
marginRight: 4,
});

type Props = {
outputs: btcTransaction.EnhancedOutput[];
inputs: btcTransaction.EnhancedInput[];
isPartialTransaction: boolean;
netAmount: number;
onShowInscription: (inscription: btcTransaction.IOInscription) => void;
token?: FungibleToken;
amountToSend?: string;
recipientAddress?: string;
};

// if isPartialTransaction, we use inputs instead of outputs
Expand All @@ -49,6 +65,9 @@ function TransferSection({
isPartialTransaction,
netAmount,
onShowInscription,
token,
amountToSend,
recipientAddress,
}: Props) {
const { btcAddress, ordinalsAddress } = useWalletSelector();
const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' });
Expand Down Expand Up @@ -80,16 +99,27 @@ function TransferSection({

if (!hasData) return null;

const isRuneTransaction = token && amountToSend && recipientAddress;

return (
<Container>
<Header spaceBetween>
<StyledP typography="body_medium_m" color="white_200">
{t('YOU_WILL_TRANSFER')}
</StyledP>
{isRuneTransaction && (
<StyledStyledP typography="body_medium_m" color="white_200">
<StyledArrowRight weight="bold" color={Theme.colors.white_0} size={16} />
{getTruncatedAddress(recipientAddress, 6)}
</StyledStyledP>
)}
</Header>
{showAmount && (
<RowContainer>
<Amount amount={netAmount} />
{isRuneTransaction && (
<RuneAmount amountSats={546} token={token} amountToSend={amountToSend} />
)}
{!isRuneTransaction && <Amount amount={netAmount} />}
<AmountWithInscriptionSatribute
inscriptions={inscriptionsFromPayment}
satributes={satributesFromPayment}
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/receiveCardComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function ReceiveCardComponent({
}: Props) {
const [isCopied, setIsCopied] = useState(false);
const { t } = useTranslation('translation', { keyPrefix: 'NFT_DASHBOARD_SCREEN' });
let addressText = 'Receive Ordinals & BRC20 tokens';
let addressText = 'Receive Ordinals, Runes & BRC20 tokens';

if (currency === 'BTC') addressText = 'Receive payments in BTC';
if (currency === 'STX') addressText = 'Receive STX, Stacks NFTs & SIP-10';
Expand Down
22 changes: 10 additions & 12 deletions src/app/components/recipientComponent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,15 @@ function RecipientComponent({
const { stxBtcRate, btcFiatRate, fiatCurrency, ordinalsAddress } = useWalletSelector();

useEffect(() => {
let amountInCurrency;
if (currencyType === 'FT') {
amountInCurrency = new BigNumber(value).multipliedBy(fungibleToken?.tokenFiatRate!);
if (amountInCurrency.isLessThan(0.01)) {
amountInCurrency = '0.01';
}
} else {
amountInCurrency = getFiatEquivalent(
setFiatAmount(
getFiatEquivalent(
Number(value),
currencyType,
BigNumber(stxBtcRate),
BigNumber(btcFiatRate),
fungibleToken,
);
}
setFiatAmount(amountInCurrency);
),
);
}, [value]);

function getFtTicker() {
Expand Down Expand Up @@ -193,7 +186,12 @@ function RecipientComponent({

return (
<TokenContainer>
<TokenImage token={currencyType} loading={false} size={32} fungibleToken={fungibleToken} />
<TokenImage
currency={currencyType}
loading={false}
size={32}
fungibleToken={fungibleToken}
/>
</TokenContainer>
);
};
Expand Down
Loading

0 comments on commit 851598c

Please sign in to comment.