diff --git a/apps/extension/src/components/dropdown/dropdown.tsx b/apps/extension/src/components/dropdown/dropdown.tsx index 61ddde72fc..b39300d6ab 100644 --- a/apps/extension/src/components/dropdown/dropdown.tsx +++ b/apps/extension/src/components/dropdown/dropdown.tsx @@ -20,6 +20,7 @@ export const Dropdown: FunctionComponent = ({ menuContainerMaxHeight, allowSearch, searchExcludedKeys, + direction = "down", }) => { const [isOpen, setIsOpen] = React.useState(false); const wrapperRef = useRef(null); @@ -124,24 +125,36 @@ export const Dropdown: FunctionComponent = ({ - + + + - 0}> + 0} + direction={direction} + size={size} + > - {filteredItems.map((item) => ( - { - onSelect(item.key); - setIsOpen(false); - }} - > - {item.label} - - ))} + + {filteredItems.map((item) => ( + { + onSelect(item.key); + setIsOpen(false); + }} + > + {item.label} + + ))} + diff --git a/apps/extension/src/components/dropdown/styles.ts b/apps/extension/src/components/dropdown/styles.ts index e1e8774c45..528cc5317b 100644 --- a/apps/extension/src/components/dropdown/styles.ts +++ b/apps/extension/src/components/dropdown/styles.ts @@ -9,6 +9,15 @@ export const Styles = { position: relative; `, + DropdownContainer: styled.div<{ + direction: "up" | "down"; + }>` + display: flex; + flex-direction: ${(props) => + props.direction === "down" ? "column" : "column-reverse"}; + position: relative; + `, + SelectedContainer: styled.div<{ isOpen: boolean; size: string; @@ -68,6 +77,8 @@ export const Styles = { `, MenuContainer: styled.div.withConfig<{ isOpen: boolean; + direction: "up" | "down"; + size: string; }>({ shouldForwardProp: (prop) => { if (prop === "isOpen") { @@ -77,10 +88,19 @@ export const Styles = { }, })` position: absolute; + ${({ direction, size }) => + direction === "down" + ? "" + : size === "small" + ? "bottom: 2.5rem;" + : "bottom: 3.25rem;"} width: 100%; - margin-top: 0.375rem; + ${({ direction }) => + direction === "down" + ? "margin-top: 0.375rem" + : "margin-bottom: 0.375rem"}; z-index: 1; @@ -115,6 +135,13 @@ export const Styles = { } }}; `, + + MenuItemsContainer: styled.div<{ direction: "up" | "down" }>` + display: flex; + flex-direction: ${({ direction }) => + direction === "down" ? "column" : "column-reverse"}; + `, + MenuContainerScroll: styled(SimpleBar).withConfig<{ menuContainerMaxHeight?: string; }>({ diff --git a/apps/extension/src/components/dropdown/types.ts b/apps/extension/src/components/dropdown/types.ts index 6931e1d37f..1399e6d381 100644 --- a/apps/extension/src/components/dropdown/types.ts +++ b/apps/extension/src/components/dropdown/types.ts @@ -19,4 +19,6 @@ export interface DropdownProps { allowSearch?: boolean; searchExcludedKeys?: string[]; + + direction?: "up" | "down"; } diff --git a/apps/extension/src/pages/starknet/components/account-activation-modal/index.tsx b/apps/extension/src/pages/starknet/components/account-activation-modal/index.tsx index 5e8996b673..2457a21537 100644 --- a/apps/extension/src/pages/starknet/components/account-activation-modal/index.tsx +++ b/apps/extension/src/pages/starknet/components/account-activation-modal/index.tsx @@ -19,8 +19,8 @@ import { import { Button } from "../../../../components/button"; import { Column, Columns } from "../../../../components/column"; import { - GetStarknetKeyParamsMsg, SubmitStarknetTxHashMsg, + GetStarknetKeyParamsSelectedMsg, } from "@keplr-wallet/background"; import { InExtensionMessageRequester } from "@keplr-wallet/router-extension"; import { BACKGROUND_PORT } from "@keplr-wallet/router"; @@ -148,7 +148,7 @@ export const AccountActivationModal: FunctionComponent<{ }> => { noop(gasSimulationRefresher.count); - const msg = new GetStarknetKeyParamsMsg(senderConfig.chainId); + const msg = new GetStarknetKeyParamsSelectedMsg(senderConfig.chainId); const params = await new InExtensionMessageRequester().sendMessage( BACKGROUND_PORT, msg @@ -275,7 +275,7 @@ export const AccountActivationModal: FunctionComponent<{ onClick={async () => { if (feeConfig.maxFee && feeConfig.maxGasPrice) { try { - const msg = new GetStarknetKeyParamsMsg( + const msg = new GetStarknetKeyParamsSelectedMsg( senderConfig.chainId ); const params = @@ -359,7 +359,7 @@ export const AccountActivationModal: FunctionComponent<{ .waitFreshResponse(); if (res?.data) { starknetAccount.setIsDeployingAccount(false); - + if (feeConfig.fee != null) { starknetQueries.queryStarknetERC20Balance .getBalance( diff --git a/apps/extension/src/pages/starknet/components/input/fee-control/index.tsx b/apps/extension/src/pages/starknet/components/input/fee-control/index.tsx index eb384469de..12f6095967 100644 --- a/apps/extension/src/pages/starknet/components/input/fee-control/index.tsx +++ b/apps/extension/src/pages/starknet/components/input/fee-control/index.tsx @@ -477,6 +477,8 @@ export const FeeControl: FunctionComponent<{ align="bottom" maxHeight="95vh" close={() => setIsModalOpen(false)} + forceNotUseSimplebar={true} + forceNotOverflowAuto={true} > setIsModalOpen(false)} diff --git a/apps/extension/src/pages/starknet/components/input/fee-control/modal.tsx b/apps/extension/src/pages/starknet/components/input/fee-control/modal.tsx index a28930fc01..69cc576754 100644 --- a/apps/extension/src/pages/starknet/components/input/fee-control/modal.tsx +++ b/apps/extension/src/pages/starknet/components/input/fee-control/modal.tsx @@ -103,6 +103,7 @@ export const TransactionFeeModal: FunctionComponent<{ feeConfig.setType(key as "ETH" | "STRK"); }} size="large" + direction="up" /> {(() => { diff --git a/apps/extension/src/pages/starknet/sign/tx/view.tsx b/apps/extension/src/pages/starknet/sign/tx/view.tsx index 496660e372..51dacef31f 100644 --- a/apps/extension/src/pages/starknet/sign/tx/view.tsx +++ b/apps/extension/src/pages/starknet/sign/tx/view.tsx @@ -399,7 +399,7 @@ export const SignStarknetTxView: FunctionComponent<{ calls: interactionData.data.transactions, details: interactionData.data.details, }, - null, + (_, v) => (typeof v === "bigint" ? v.toString() : v), 2 )} diff --git a/packages/background/src/keyring-starknet/handler.ts b/packages/background/src/keyring-starknet/handler.ts index 2ff555cd55..458cf4b11e 100644 --- a/packages/background/src/keyring-starknet/handler.ts +++ b/packages/background/src/keyring-starknet/handler.ts @@ -12,7 +12,7 @@ import { RequestSignStarknetDeployAccountTx, RequestJsonRpcToStarknetMsg, GetStarknetKeysForEachVaultSettledMsg, - GetStarknetKeyParamsMsg, + GetStarknetKeyParamsSelectedMsg, } from "./messages"; import { KeyRingStarknetService } from "./service"; import { PermissionInteractiveService } from "../permission-interactive"; @@ -56,10 +56,10 @@ export const getHandler: ( env, msg as GetStarknetKeysForEachVaultSettledMsg ); - case GetStarknetKeyParamsMsg: - return handleGetStarknetKeyParamsMsg(service)( + case GetStarknetKeyParamsSelectedMsg: + return handleGetStarknetKeyParamsSelectedMsg(service)( env, - msg as GetStarknetKeyParamsMsg + msg as GetStarknetKeyParamsSelectedMsg ); default: throw new KeplrError("keyring", 221, "Unknown msg type"); @@ -192,10 +192,10 @@ const handleGetStarknetKeysForEachVaultSettledMsg: ( }; }; -const handleGetStarknetKeyParamsMsg: ( +const handleGetStarknetKeyParamsSelectedMsg: ( service: KeyRingStarknetService -) => InternalHandler = (service) => { +) => InternalHandler = (service) => { return async (_, msg) => { - return await service.getStarknetKeyParams(msg.chainId); + return await service.getStarknetKeyParamsSelected(msg.chainId); }; }; diff --git a/packages/background/src/keyring-starknet/init.ts b/packages/background/src/keyring-starknet/init.ts index 2248fd3fe6..b89e669e2b 100644 --- a/packages/background/src/keyring-starknet/init.ts +++ b/packages/background/src/keyring-starknet/init.ts @@ -7,7 +7,7 @@ import { RequestSignStarknetDeployAccountTx, RequestJsonRpcToStarknetMsg, GetStarknetKeysForEachVaultSettledMsg, - GetStarknetKeyParamsMsg, + GetStarknetKeyParamsSelectedMsg, } from "./messages"; import { ROUTE } from "./constants"; import { getHandler } from "./handler"; @@ -24,7 +24,7 @@ export function init( router.registerMessage(RequestSignStarknetDeployAccountTx); router.registerMessage(RequestJsonRpcToStarknetMsg); router.registerMessage(GetStarknetKeysForEachVaultSettledMsg); - router.registerMessage(GetStarknetKeyParamsMsg); + router.registerMessage(GetStarknetKeyParamsSelectedMsg); router.addHandler(ROUTE, getHandler(service, permissionInteractionService)); } diff --git a/packages/background/src/keyring-starknet/messages.ts b/packages/background/src/keyring-starknet/messages.ts index ff10c34a78..c378665d0c 100644 --- a/packages/background/src/keyring-starknet/messages.ts +++ b/packages/background/src/keyring-starknet/messages.ts @@ -246,7 +246,7 @@ export class GetStarknetKeysForEachVaultSettledMsg extends Message< } } -export class GetStarknetKeyParamsMsg extends Message<{ +export class GetStarknetKeyParamsSelectedMsg extends Message<{ pubKey: Uint8Array; address: Uint8Array; salt: Uint8Array; @@ -257,7 +257,7 @@ export class GetStarknetKeyParamsMsg extends Message<{ yHigh: Uint8Array; }> { public static type() { - return "get-starknet-key-params"; + return "get-starknet-key-params-selected"; } constructor(public readonly chainId: string) { @@ -275,6 +275,6 @@ export class GetStarknetKeyParamsMsg extends Message<{ } type(): string { - return GetStarknetKeyParamsMsg.type(); + return GetStarknetKeyParamsSelectedMsg.type(); } } diff --git a/packages/background/src/keyring-starknet/service.ts b/packages/background/src/keyring-starknet/service.ts index 0fd9b51a89..f5114f3dee 100644 --- a/packages/background/src/keyring-starknet/service.ts +++ b/packages/background/src/keyring-starknet/service.ts @@ -113,7 +113,7 @@ export class KeyRingStarknetService { pubKey: Uint8Array; address: Uint8Array; }> { - const params = await this.getStarknetKeyParams(chainId); + const params = await this.getStarknetKeyParams(vaultId, chainId); return { name: this.keyRingService.getKeyRingName(vaultId), hexAddress: `0x${Buffer.from(params.address).toString("hex")}`, @@ -122,7 +122,26 @@ export class KeyRingStarknetService { }; } - async getStarknetKeyParams(chainId: string): Promise<{ + async getStarknetKeyParamsSelected(chainId: string): Promise<{ + pubKey: Uint8Array; + address: Uint8Array; + salt: Uint8Array; + classHash: Uint8Array; + xLow: Uint8Array; + xHigh: Uint8Array; + yLow: Uint8Array; + yHigh: Uint8Array; + }> { + return await this.getStarknetKeyParams( + this.keyRingService.selectedVaultId, + chainId + ); + } + + async getStarknetKeyParams( + vaultId: string, + chainId: string + ): Promise<{ pubKey: Uint8Array; address: Uint8Array; salt: Uint8Array; @@ -136,7 +155,6 @@ export class KeyRingStarknetService { if (!("starknet" in chainInfo)) { throw new Error("Chain is not a starknet chain"); } - const vaultId = this.keyRingService.selectedVaultId; const pubKey = await this.keyRingService.getPubKey(chainId, vaultId); const vault = this.vaultService.getVault("keyRing", vaultId); diff --git a/packages/background/src/token-erc20/service.ts b/packages/background/src/token-erc20/service.ts index d731a6dc5b..b0650316db 100644 --- a/packages/background/src/token-erc20/service.ts +++ b/packages/background/src/token-erc20/service.ts @@ -95,7 +95,10 @@ export class TokenERC20Service { // Validate contract Address if ( !contractAddress.match(/^0x[0-9A-Fa-f]*$/) || - (contractAddress.length !== 42 && contractAddress.length !== 66) + (contractAddress.length !== 42 && + // For Starknet, contract address length can be 65 or 66. + contractAddress.length !== 65 && + contractAddress.length !== 66) ) { throw new Error("Contract address is not valid hex address"); } diff --git a/packages/chain-validator/src/schema.ts b/packages/chain-validator/src/schema.ts index b785d1e0f7..34e5f5f03a 100644 --- a/packages/chain-validator/src/schema.ts +++ b/packages/chain-validator/src/schema.ts @@ -79,7 +79,7 @@ export const ERC20CurrencySchema = ( .keys({ type: Joi.string().equal("erc20").required(), contractAddress: Joi.string() - .pattern(/(^(0x)[0-9a-fA-F]{40}$)|(^(0x)[0-9a-fA-F]{64}$)/) + .pattern(/(^(0x)[0-9a-fA-F]{40}$)|(^(0x)[0-9a-fA-F]{63,64}$)/) .required(), }) .custom((value: Secret20Currency) => {