Skip to content

Conversation

@qardpeet
Copy link
Contributor

@qardpeet qardpeet commented Oct 8, 2025

Includes most of the "dumb" UI components needed to make spot work:

  • Tradeform
  • Market selector & Stats display
  • Search
  • Token info
  • User holdings table

Will push up a separate pr that moves as much as state & serialization into redux/bonsai as possible.

Currently missing localization, will prioritize that last after API integration and Solana tx signing are done.

@qardpeet qardpeet requested a review from a team as a code owner October 8, 2025 17:30
@vercel
Copy link

vercel bot commented Oct 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
v4-staging Ready Ready Preview Comment Dec 9, 2025 5:38am
v4-testnet Ready Ready Preview Comment Dec 9, 2025 5:38am

Comment on lines 575 to 585
${({ $polarity }) =>
$polarity === NumberSign.Positive &&
css`
color: var(--color-positive) !important;
`}
${({ $polarity }) =>
$polarity === NumberSign.Negative &&
css`
color: var(--color-negative) !important;
`}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think we can merge these two into a ternary so we only access props once.

Does it need the !important override?


const price = Number(SOL_PRICE_USDC);
const toSol = buyType === SpotBuyType.USDC && nextBuyType === SpotBuyType.SOL;
const factor = toSol ? 1 / price : price;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may want to ensure price is not 0

Comment on lines 135 to 136
onValueChange={(v) => {
setTradeType(v as SpotFormType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think theres a way to make this a generic so v doesn't have to be typescase with as

}: {
className?: string;
marketId: string;
variant?: 'perp' | 'spot';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this ever be undefined?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I guess its so you can do the default. Not sure if we should just make it explicit on every <FavoriteButton> use

export function setUpTokenMetadataQuery(store: RootStore) {
return createStoreEffect(
store,
(state) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be a selector otherwise it's a new return object every time and will restart the lifecycle every time any store update happens.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remember to localize and add the textKeys to the validation errors

}
}

const minUsdAmount = 0.1; // Minimum $0.10 USD
Copy link
Contributor

@jaredvu jaredvu Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since this is a true const we should rename MIN_SPOT_USD_AMOUNT and put top level of file

className?: string;
withBaseFont?: boolean;
withSignColor?: boolean;
withPolarityColor?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: polarity feels like a stretch semantically (i get the connection tho). withSignedValueColor or something might be more accurate

};
setCosmosWallets();
}, [hdKey?.mnemonic, getCosmosOfflineSigner]);
}, [hdKey?.mnemonic, getCosmosOfflineSigner, canDeriveSolanaWallet]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is canDeriveSolanaWallet necessary? It doesn't seem like its referenced in this side effect and if hdKey.mnemonic is not undefined then i think we already know that we are not utilizing keplr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, accidentally left it in there good catch!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the removal of blocked geo from the derivation flow, how are we preventing users from interacting with perps as a whole?

const { checkForGeo } = useEnvFeatures();
const location = useLocation();

const isSpotPage = location.pathname.startsWith(AppRoute.Spot);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use useMatchinstead of useLocation + startsWith


type CustomNoticationOptions = {
id: string;
id?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove? will this not cause key issues later down the line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the id already had a default in place:

const id = options?.id ?? Date.now().toString();

body: 'Transaction failed. Please try again.',
},
{
toastDuration: 8000,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not have matching toastDuration between success and failure state?

resolveSymbol: async (tokenSymbol, onSymbolResolvedCallback) => {
const symbolInfo = createSpotSymbolInfo(tokenSymbol);
const tokenPrice = await waitForSelector(store, (s) => BonsaiCore.spot.tokenPrice.data(s));
const symbolInfo = createSpotSymbolInfo(tokenSymbol, tokenPrice);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokenSymbol and tokenMint are being used interchangeably right? in the createSpotSymbolInfo, it uses tokenSymbol (mint) everywhere. Do we actually every use the real token symbol?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no we don't, its named in a bad way it should be just the mint

Comment on lines 59 to 60
ticker: tokenSymbol,
name: tokenSymbol,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not sure which of these is the display info in the TradingView chart

* adjust spot form error logic
* withSignedValueColor in Output
* make MIN_SOL_RESERVE 0.002
* useMatch instead of useLocation
* normalize toast duration for spot trading
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://solana.com/developers/cookbook/wallets/restore-from-mnemonic

Can we do a quick audit to make sure that your bip44 derivation comes out with the same as from the Solana cookbook? The only part of your implementation that i am unsure of is needing the seedHex to call derivePath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants