From d395fceb80ee0f80581eb9c4f4e9b990c130018b Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 10:41:37 +0900 Subject: [PATCH 01/26] [embed] add getSIWEMessage and add condition to show siwe ui --- .../modal_variants/eth/make_sig_eth_modal.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx index 24d99c541..e710d41f5 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx @@ -1,10 +1,35 @@ import { type FC } from "react"; import type { MakeEthereumSigData } from "@oko-wallet/oko-sdk-core"; +import { parseSiweMessage, type SiweMessage } from "viem/siwe"; +import type { SignableMessage } from "viem"; import { MakeArbitrarySigModal } from "./arbitrary_sig/make_arbitrary_sig_modal"; import { MakeTxSigModal } from "./tx_sig/make_tx_sig_modal"; import { MakeEIP712SigModal } from "./eip712_sig/make_eip712_sig_modal"; +function getSiweMessage(message: SignableMessage): SiweMessage | undefined { + if (typeof message !== "string") { + return undefined; + } + const siweMsg = parseSiweMessage(message); + + //NOTE - If any required field in SiweMessage is empty, + // it is determined not to be Siwe. + if ( + siweMsg.address && + siweMsg.chainId && + siweMsg.domain && + siweMsg.version && + siweMsg.nonce && + siweMsg.uri && + siweMsg.address.startsWith("0x") + ) { + return siweMsg as SiweMessage; + } + + return undefined; +} + export const MakeSignatureEthModal: FC = ({ getIsAborted, data, @@ -21,6 +46,12 @@ export const MakeSignatureEthModal: FC = ({ ); } case "arbitrary": { + const siweMessage = getSiweMessage(data.payload.data.message); + const isSiweMessage = !!siweMessage; + if (isSiweMessage) { + return <>{siweMessage}; + } + return ( Date: Thu, 11 Dec 2025 10:55:11 +0900 Subject: [PATCH 02/26] [embed] separate getSiweMessage func and make relative path import to absolute path --- .../modal_variants/eth/get_siwe_message.ts | 27 +++++++++++++++ .../modal_variants/eth/make_sig_eth_modal.tsx | 33 +++---------------- 2 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts diff --git a/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts b/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts new file mode 100644 index 000000000..62d421691 --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts @@ -0,0 +1,27 @@ +import type { SignableMessage } from "viem"; +import { parseSiweMessage, type SiweMessage } from "viem/siwe"; + +export function getSiweMessage( + message: SignableMessage, +): SiweMessage | undefined { + if (typeof message !== "string") { + return undefined; + } + const siweMsg = parseSiweMessage(message); + + //NOTE - If any required field in SiweMessage is empty, + // it is determined not to be Siwe. + if ( + siweMsg.address && + siweMsg.chainId && + siweMsg.domain && + siweMsg.version && + siweMsg.nonce && + siweMsg.uri && + siweMsg.address.startsWith("0x") + ) { + return siweMsg as SiweMessage; + } + + return undefined; +} diff --git a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx index e710d41f5..fcbca3afb 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx @@ -1,34 +1,11 @@ import { type FC } from "react"; import type { MakeEthereumSigData } from "@oko-wallet/oko-sdk-core"; -import { parseSiweMessage, type SiweMessage } from "viem/siwe"; -import type { SignableMessage } from "viem"; -import { MakeArbitrarySigModal } from "./arbitrary_sig/make_arbitrary_sig_modal"; -import { MakeTxSigModal } from "./tx_sig/make_tx_sig_modal"; -import { MakeEIP712SigModal } from "./eip712_sig/make_eip712_sig_modal"; - -function getSiweMessage(message: SignableMessage): SiweMessage | undefined { - if (typeof message !== "string") { - return undefined; - } - const siweMsg = parseSiweMessage(message); - - //NOTE - If any required field in SiweMessage is empty, - // it is determined not to be Siwe. - if ( - siweMsg.address && - siweMsg.chainId && - siweMsg.domain && - siweMsg.version && - siweMsg.nonce && - siweMsg.uri && - siweMsg.address.startsWith("0x") - ) { - return siweMsg as SiweMessage; - } - - return undefined; -} +import { MakeArbitrarySigModal } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal"; +import { MakeTxSigModal } from "@oko-wallet-attached/components/modal_variants/eth/tx_sig/make_tx_sig_modal"; +import { MakeEIP712SigModal } from "@oko-wallet-attached/components/modal_variants/eth/eip712_sig/make_eip712_sig_modal"; +import { MakeSiweSigModal } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_arbitrary_sig_modal"; +import { getSiweMessage } from "@oko-wallet-attached/components/modal_variants/eth/get_siwe_message"; export const MakeSignatureEthModal: FC = ({ getIsAborted, From e74e854a69827a94f1cd22ae058b6ed1a7f2662b Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 11:53:34 +0900 Subject: [PATCH 03/26] [embed] add VITE_PUBLIC_S3_BUCKET_URL in env --- embed/oko_attached/oko_attached.env.example | 1 + embed/oko_attached/src/global.d.ts | 1 + embed/oko_attached/src/requests/endpoints.ts | 3 +++ 3 files changed, 5 insertions(+) diff --git a/embed/oko_attached/oko_attached.env.example b/embed/oko_attached/oko_attached.env.example index ed4b9fc1a..ef524b885 100644 --- a/embed/oko_attached/oko_attached.env.example +++ b/embed/oko_attached/oko_attached.env.example @@ -7,3 +7,4 @@ VITE_TX_INTERPRETER_API_ENDPOINT=https://tx-interpreter.keplr.app VITE_AMPLITUDE_API_KEY= VITE_IPFS_GATEWAY_URL= VITE_TELEGRAM_BOT_NAME=telegram_bot_name +VITE_PUBLIC_S3_BUCKET_URL=https://oko-wallet.s3.ap-northeast-2.amazonaws.com diff --git a/embed/oko_attached/src/global.d.ts b/embed/oko_attached/src/global.d.ts index 9069b3ce8..3fe598ea1 100644 --- a/embed/oko_attached/src/global.d.ts +++ b/embed/oko_attached/src/global.d.ts @@ -22,6 +22,7 @@ declare global { VITE_AMPLITUDE_API_KEY: string; VITE_IPFS_GATEWAY_URL: string; VITE_TELEGRAM_BOT_NAME: string; + VITE_PUBLIC_S3_BUCKET_URL: string; } } diff --git a/embed/oko_attached/src/requests/endpoints.ts b/embed/oko_attached/src/requests/endpoints.ts index 1ac5144a5..61ae0aa4b 100644 --- a/embed/oko_attached/src/requests/endpoints.ts +++ b/embed/oko_attached/src/requests/endpoints.ts @@ -6,3 +6,6 @@ export const TX_INTERPRETER_API_ENDPOINT = import.meta.env export const DEMO_WEB_ORIGIN = import.meta.env.VITE_DEMO_WEB_ORIGIN; export const OKO_API_ENDPOINT = import.meta.env.VITE_OKO_API_ENDPOINT; + +export const OKO_PUBLIC_S3_BUCKET_URL = import.meta.env + .VITE_PUBLIC_S3_BUCKET_URL; From a8185aa87cb0f47c28d5fb09ffc84d9dfebce595 Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 15:39:54 +0900 Subject: [PATCH 04/26] [embed] make inner comp of SignerAddressOrEmail exported to share - and add SignerAddressOrEmailForSiwe to be applied other style --- .../signer_address_or_email.tsx | 78 +++++++++++++------ .../index.tsx | 56 +++++++++++++ .../styles.module.scss | 23 ++++++ 3 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/index.tsx create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/styles.module.scss diff --git a/embed/oko_attached/src/components/modal_variants/common/metadata_content/signer_address_or_email/signer_address_or_email.tsx b/embed/oko_attached/src/components/modal_variants/common/metadata_content/signer_address_or_email/signer_address_or_email.tsx index 8752ac10e..d5fdbfb47 100644 --- a/embed/oko_attached/src/components/modal_variants/common/metadata_content/signer_address_or_email/signer_address_or_email.tsx +++ b/embed/oko_attached/src/components/modal_variants/common/metadata_content/signer_address_or_email/signer_address_or_email.tsx @@ -8,25 +8,67 @@ import styles from "./signer_address_or_email.module.scss"; interface SignerAddressOrEmailProps { signer: string; origin: string; + initialViewType?: "View Address" | "Login Info"; } +interface ViewProps { + value: string; + origin: string; + type: "address" | "email"; + prefix?: string; +} + +export const SignerAddressOrEmailView: FC = ({ + value, + type, + origin, + prefix, +}) => { + const email = useAppState((state) => state.getWallet(origin)?.email); + const displayValue = + type === "address" ? `${value.slice(0, 9)}...${value.slice(-9)}` : email; + + return ( + + {prefix && `${prefix} `} + {displayValue} + + ); +}; + +export const SignerAddressOrEmailChangeViewTypeButton: FC<{ + viewType: "View Address" | "Login Info"; + onClick: () => void; +}> = ({ viewType, onClick }) => { + return ( +
+ + + {viewType} + +
+ ); +}; + export const SignerAddressOrEmail: FC = ({ signer, origin, + initialViewType = "View Address", }) => { const [viewType, setViewType] = useState<"View Address" | "Login Info">( - "View Address", + initialViewType, ); - const email = useAppState((state) => state.getWallet(origin)?.email); switch (viewType) { case "View Address": return (
- - {signer.slice(0, 9)}...{signer.slice(-9)} - - + setViewType("Login Info")} /> @@ -35,10 +77,12 @@ export const SignerAddressOrEmail: FC = ({ case "Login Info": return (
- - {email} - - + setViewType("View Address")} /> @@ -46,17 +90,3 @@ export const SignerAddressOrEmail: FC = ({ ); } }; - -const ChangeViewTypeButton: FC<{ - viewType: "View Address" | "Login Info"; - onClick: () => void; -}> = ({ viewType, onClick }) => { - return ( -
- - - {viewType} - -
- ); -}; diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/index.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/index.tsx new file mode 100644 index 000000000..263b2cd6f --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/index.tsx @@ -0,0 +1,56 @@ +import { useState, type FC } from "react"; + +import styles from "./styles.module.scss"; +import { + SignerAddressOrEmailChangeViewTypeButton, + SignerAddressOrEmailView, +} from "@oko-wallet-attached/components/modal_variants/common/metadata_content/signer_address_or_email/signer_address_or_email"; + +interface SignerAddressOrEmailProps { + signer: string; + origin: string; + initialViewType?: "View Address" | "Login Info"; +} + +export const SignerAddressOrEmailForSiwe: FC = ({ + signer, + origin, + initialViewType = "View Address", +}) => { + const [viewType, setViewType] = useState<"View Address" | "Login Info">( + initialViewType, + ); + + switch (viewType) { + case "View Address": + return ( +
+ + setViewType("Login Info")} + /> +
+ ); + case "Login Info": + return ( +
+ + setViewType("View Address")} + /> +
+ ); + } +}; diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/styles.module.scss b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/styles.module.scss new file mode 100644 index 000000000..3c83eb1f3 --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe/styles.module.scss @@ -0,0 +1,23 @@ +.wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + width: 100%; + word-break: break-all; + word-wrap: break-word; + overflow-wrap: break-word; +} + +.changeViewTypeButton { + display: flex; + padding: 4px 8px; + align-items: center; + gap: 4px; + flex-shrink: 0; + + cursor: pointer; + border-radius: 12px; + background: var(--bg-secondary); + width: fit-content; +} From 20da61e19f4d4f251f7dbe08fca95a271892d83a Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 17:37:21 +0900 Subject: [PATCH 05/26] [sandbox] add Sign SIWE Message (with wrong URI) button for testing --- .../playground/_components/SiweSignWidget.tsx | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/sandbox/sandbox_evm/src/app/playground/_components/SiweSignWidget.tsx b/sandbox/sandbox_evm/src/app/playground/_components/SiweSignWidget.tsx index 077a0609a..52af94408 100644 --- a/sandbox/sandbox_evm/src/app/playground/_components/SiweSignWidget.tsx +++ b/sandbox/sandbox_evm/src/app/playground/_components/SiweSignWidget.tsx @@ -14,14 +14,23 @@ export function SiweSignWidget() { const [signedMessage, setSignedMessage] = useState(""); - const handleSiweSign = async () => { + const handleSiweSign = async (isWrongUriTest: boolean = false) => { if (!walletClient || !address || !chainId) { return; } + const localDomain = + typeof window !== "undefined" ? window.location.host : "localhost:3000"; + const localUri = + typeof window !== "undefined" + ? window.location.href + : "http://localhost:3000"; + const wrongDomain = "demo.oko.app"; + const wrongUri = "https://demo.oko.app/test"; + const siweMessage = createSiweMessage({ - domain: "oko-wallet-sandbox.vercel.app", - uri: "https://oko-wallet-sandbox.vercel.app", + domain: isWrongUriTest ? wrongDomain : localDomain, + uri: isWrongUriTest ? wrongUri : localUri, address, chainId, nonce: generateSiweNonce(), @@ -63,13 +72,21 @@ export function SiweSignWidget() {

+ + {error && (
{error?.message} From ba73e8679b3dbb3ccb157141f27e9f4ff1479b33 Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 17:40:34 +0900 Subject: [PATCH 06/26] [embed] add className props --- .../make_sig_modal_code_block_container.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/embed/oko_attached/src/components/modal_variants/common/make_signature/make_sig_modal_code_block_container.tsx b/embed/oko_attached/src/components/modal_variants/common/make_signature/make_sig_modal_code_block_container.tsx index 9c752676f..72f14ef53 100644 --- a/embed/oko_attached/src/components/modal_variants/common/make_signature/make_sig_modal_code_block_container.tsx +++ b/embed/oko_attached/src/components/modal_variants/common/make_signature/make_sig_modal_code_block_container.tsx @@ -1,13 +1,17 @@ import type { FC, ReactNode } from "react"; +import cn from "classnames"; import styles from "./make_sig_modal_code_block_container.module.scss"; export interface MakeSignatureRawCodeBlockContainerProps { children: ReactNode; + className?: string; } export const MakeSignatureRawCodeBlockContainer: FC< MakeSignatureRawCodeBlockContainerProps -> = ({ children }) => { - return
{children}
; +> = ({ children, className }) => { + return ( +
{children}
+ ); }; From fcde32cbfa387b71ba78531313f2247bfd78a0c4 Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 17:47:02 +0900 Subject: [PATCH 07/26] [embed] add SiweSigTitleBadge --- .../siwe_sig/siwe_sig_title_badge/index.tsx | 27 +++++++++++++++++++ .../siwe_sig_title_badge/styles.module.scss | 17 ++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/styles.module.scss diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx new file mode 100644 index 000000000..c1e6602bf --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx @@ -0,0 +1,27 @@ +import { OKO_PUBLIC_S3_BUCKET_URL } from "@oko-wallet-attached/requests/endpoints"; + +import styles from "./styles.module.scss"; + +export const SiweSigTitleBadge = ({ isDarkMode }: { isDarkMode: boolean }) => { + const imageUrl = { + png: isDarkMode + ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.png` + : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.png`, + webp: isDarkMode + ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.webp` + : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.webp`, + }; + + return ( +
+ + + sign siwe title image + +
+ ); +}; diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/styles.module.scss b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/styles.module.scss new file mode 100644 index 000000000..3ce9dd31e --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/styles.module.scss @@ -0,0 +1,17 @@ +picture { + margin: 0; + padding: 0; + width: 8.1875rem; + height: 3.75rem; +} + +.imageContainer { + display: flex; + align-items: center; + justify-content: center; + + .image { + width: 8.1875rem; + height: 3.75rem; + } +} From a7a07fb00699da77629767c471d821e90aee56fb Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 17:48:19 +0900 Subject: [PATCH 08/26] [embed] change file name and add verifySiweMessage --- .../modal_variants/eth/get_siwe_message.ts | 27 -------- .../modal_variants/eth/siwe_message.ts | 65 +++++++++++++++++++ 2 files changed, 65 insertions(+), 27 deletions(-) delete mode 100644 embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts create mode 100644 embed/oko_attached/src/components/modal_variants/eth/siwe_message.ts diff --git a/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts b/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts deleted file mode 100644 index 62d421691..000000000 --- a/embed/oko_attached/src/components/modal_variants/eth/get_siwe_message.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { SignableMessage } from "viem"; -import { parseSiweMessage, type SiweMessage } from "viem/siwe"; - -export function getSiweMessage( - message: SignableMessage, -): SiweMessage | undefined { - if (typeof message !== "string") { - return undefined; - } - const siweMsg = parseSiweMessage(message); - - //NOTE - If any required field in SiweMessage is empty, - // it is determined not to be Siwe. - if ( - siweMsg.address && - siweMsg.chainId && - siweMsg.domain && - siweMsg.version && - siweMsg.nonce && - siweMsg.uri && - siweMsg.address.startsWith("0x") - ) { - return siweMsg as SiweMessage; - } - - return undefined; -} diff --git a/embed/oko_attached/src/components/modal_variants/eth/siwe_message.ts b/embed/oko_attached/src/components/modal_variants/eth/siwe_message.ts new file mode 100644 index 000000000..224857abe --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/siwe_message.ts @@ -0,0 +1,65 @@ +import type { SignableMessage } from "viem"; +import { parseSiweMessage, type SiweMessage } from "viem/siwe"; + +const ALLOW_PROTOCOLS = ["https:"]; +const BYPASS_HOSTS = ["localhost"]; + +export function getSiweMessage( + message: SignableMessage, +): SiweMessage | undefined { + if (typeof message !== "string") { + return undefined; + } + const siweMsg = parseSiweMessage(message); + + //NOTE - If any required field in SiweMessage is empty, + // it is determined not to be Siwe. + if ( + siweMsg.address && + siweMsg.chainId && + siweMsg.domain && + siweMsg.version && + siweMsg.nonce && + siweMsg.uri && + siweMsg.address.startsWith("0x") + ) { + return siweMsg as SiweMessage; + } + + return undefined; +} + +export function verifySiweMessage( + message: SiweMessage, + origin: string, +): boolean { + try { + const { + origin: originByPayload, + protocol: protocolByPayload, + host: hostByPayload, + } = new URL(origin); + const { origin: originByTxUri, protocol: protocolByTxUri } = new URL( + message.uri, + ); + + if (originByPayload !== originByTxUri || hostByPayload !== message.domain) { + console.log("originByPayload", originByPayload); + return false; + } + + // If scheme is not HTTPS, return false (when hostname is not localhost) + if ( + !BYPASS_HOSTS.includes(hostByPayload.split(":")[0]) && + (!ALLOW_PROTOCOLS.includes(protocolByPayload) || + !ALLOW_PROTOCOLS.includes(protocolByTxUri)) + ) { + return false; + } + } catch (error) { + console.error(error); + return false; + } + + return true; +} From 1f40373163d03ada18921b0ef99236357bcf3a1b Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 17:48:48 +0900 Subject: [PATCH 09/26] [embed] add EthereumSiweSignatureContent and apply --- .../make_arbitrary_sig_modal.tsx | 12 ++- ...thereum_siwe_signature_content.module.scss | 27 +++++ .../siwe_sig/make_siwe-siganature_content.tsx | 99 +++++++++++++++++++ .../modal_variants/eth/make_sig_eth_modal.tsx | 8 -- 4 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/ethereum_siwe_signature_content.module.scss create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx index 2973a1de1..214b1f07f 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx @@ -11,6 +11,8 @@ import { useArbitrarySigModal } from "./hooks/use_arbitrary_sig_modal"; import { ArbitrarySignatureDesc } from "@oko-wallet-attached/components/modal_variants/common/arbitrary_sig_desc/arbitrary_signature_desc"; import { EthereumArbitrarySignatureContent } from "./ethereum_arbitrary_signature_content"; import { SignWithOkoBox } from "@oko-wallet-attached/components/sign_with_oko_box/sign_with_oko_box"; +import { getSiweMessage } from "@oko-wallet-attached/components/modal_variants/eth/siwe_message"; +import { EthereumSiweSignatureContent } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content"; export const MakeArbitrarySigModal: React.FC = ({ getIsAborted, @@ -31,6 +33,8 @@ export const MakeArbitrarySigModal: React.FC = ({ modalId, }); + const siweMessage = getSiweMessage(data.payload.data.message); + return (
@@ -39,10 +43,14 @@ export const MakeArbitrarySigModal: React.FC = ({
- + {!!siweMessage ? ( + + ) : ( + + )}
- + {!hasOnChainSchema && } diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/ethereum_siwe_signature_content.module.scss b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/ethereum_siwe_signature_content.module.scss new file mode 100644 index 000000000..12e659b2e --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/ethereum_siwe_signature_content.module.scss @@ -0,0 +1,27 @@ +.messageContainer { + padding: 0.75rem 1rem; + + .messageContent { + padding: 0; + min-height: 0; + } +} + +.metadataContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.chainInfoContainer { + padding: 0.75rem 1rem; + border-radius: 0.75rem; + background-color: var(--bg-secondary); + + .chainInfoRow { + display: flex; + align-items: center; + justify-content: space-between; + } +} diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx new file mode 100644 index 000000000..81ffd11d0 --- /dev/null +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx @@ -0,0 +1,99 @@ +import React from "react"; +import type { EthereumArbitrarySignPayload } from "@oko-wallet/oko-sdk-core"; +import { Spacing } from "@oko-wallet/oko-common-ui/spacing"; +import { Typography } from "@oko-wallet/oko-common-ui/typography"; + +import styles from "./ethereum_siwe_signature_content.module.scss"; +import { + getSiweMessage, + verifySiweMessage, +} from "@oko-wallet-attached/components/modal_variants/eth/siwe_message"; +import { SiweSigTitleBadge } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge"; +import { SignerAddressOrEmailForSiwe } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/signer_address_or_email_for_siwe"; +import { MakeSignatureRawCodeBlockContainer } from "@oko-wallet-attached/components/modal_variants/common/make_signature/make_sig_modal_code_block_container"; +import { MakeSignatureRawCodeBlock } from "@oko-wallet-attached/components/modal_variants/common/make_signature/make_sig_modal_code_block"; + +interface EthereumSiweSignatureContentProps { + payload: EthereumArbitrarySignPayload; +} + +export const EthereumSiweSignatureContent: React.FC< + EthereumSiweSignatureContentProps +> = ({ payload }) => { + const message = getSiweMessage(payload.data.message); + + if (!message) { + // @unreachable + throw new Error("unreachable"); + } + + const isValidSiweMessage = verifySiweMessage(message, payload.origin); + if (!isValidSiweMessage) { + throw new Error("Invalid SIWE message"); + } + + return ( +
+ +
+ + + Sign in to + + + + + {payload.origin.replace(/^https?:\/\//, "")} + + + + +
+ + + +
+
+ + Estimated in balance + + + No changes + +
+ + +
+ + Network + + + {payload.chain_info.chain_name} + +
+
+ {/* */} + + + + + Message + + + + + +
+ ); +}; diff --git a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx index fcbca3afb..f0d78447c 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/make_sig_eth_modal.tsx @@ -4,8 +4,6 @@ import type { MakeEthereumSigData } from "@oko-wallet/oko-sdk-core"; import { MakeArbitrarySigModal } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal"; import { MakeTxSigModal } from "@oko-wallet-attached/components/modal_variants/eth/tx_sig/make_tx_sig_modal"; import { MakeEIP712SigModal } from "@oko-wallet-attached/components/modal_variants/eth/eip712_sig/make_eip712_sig_modal"; -import { MakeSiweSigModal } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_arbitrary_sig_modal"; -import { getSiweMessage } from "@oko-wallet-attached/components/modal_variants/eth/get_siwe_message"; export const MakeSignatureEthModal: FC = ({ getIsAborted, @@ -23,12 +21,6 @@ export const MakeSignatureEthModal: FC = ({ ); } case "arbitrary": { - const siweMessage = getSiweMessage(data.payload.data.message); - const isSiweMessage = !!siweMessage; - if (isSiweMessage) { - return <>{siweMessage}; - } - return ( Date: Thu, 11 Dec 2025 18:00:27 +0900 Subject: [PATCH 10/26] [embed] add theme in SiweSigTitleBadge --- .../make_arbitrary_sig_modal.tsx | 5 +++- .../siwe_sig/make_siwe-siganature_content.tsx | 6 +++-- .../siwe_sig/siwe_sig_title_badge/index.tsx | 24 ++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx index 214b1f07f..781c00e58 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx @@ -44,7 +44,10 @@ export const MakeArbitrarySigModal: React.FC = ({
{!!siweMessage ? ( - + ) : ( )} diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx index 81ffd11d0..e2e9183c0 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content.tsx @@ -2,6 +2,7 @@ import React from "react"; import type { EthereumArbitrarySignPayload } from "@oko-wallet/oko-sdk-core"; import { Spacing } from "@oko-wallet/oko-common-ui/spacing"; import { Typography } from "@oko-wallet/oko-common-ui/typography"; +import type { Theme } from "@oko-wallet/oko-common-ui/theme"; import styles from "./ethereum_siwe_signature_content.module.scss"; import { @@ -15,11 +16,12 @@ import { MakeSignatureRawCodeBlock } from "@oko-wallet-attached/components/modal interface EthereumSiweSignatureContentProps { payload: EthereumArbitrarySignPayload; + theme: Theme | null; } export const EthereumSiweSignatureContent: React.FC< EthereumSiweSignatureContentProps -> = ({ payload }) => { +> = ({ payload, theme }) => { const message = getSiweMessage(payload.data.message); if (!message) { @@ -34,7 +36,7 @@ export const EthereumSiweSignatureContent: React.FC< return (
- +
diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx index c1e6602bf..100fed16d 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_sig_title_badge/index.tsx @@ -1,15 +1,23 @@ -import { OKO_PUBLIC_S3_BUCKET_URL } from "@oko-wallet-attached/requests/endpoints"; +import type { Theme } from "@oko-wallet/oko-common-ui/theme"; +import { OKO_PUBLIC_S3_BUCKET_URL } from "@oko-wallet-attached/requests/endpoints"; import styles from "./styles.module.scss"; -export const SiweSigTitleBadge = ({ isDarkMode }: { isDarkMode: boolean }) => { +interface SiweSigTitleBadgeProps { + theme: Theme | null; +} +export const SiweSigTitleBadge: React.FC = ({ + theme, +}) => { const imageUrl = { - png: isDarkMode - ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.png` - : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.png`, - webp: isDarkMode - ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.webp` - : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.webp`, + png: + theme === "dark" + ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.png` + : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.png`, + webp: + theme === "dark" + ? `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_dark.webp` + : `${OKO_PUBLIC_S3_BUCKET_URL}/assets/oko_siwe_sign_badge_light.webp`, }; return ( From b7db0d2f3ac4c9c804d87832aaf6eef9def4bb7d Mon Sep 17 00:00:00 2001 From: blacktoast Date: Tue, 23 Dec 2025 17:47:22 +0900 Subject: [PATCH 11/26] [embed] make getFaviconUrl utils func --- .../common/metadata_content/metadata_content.tsx | 14 +------------- embed/oko_attached/src/utils/favicon.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 embed/oko_attached/src/utils/favicon.ts diff --git a/embed/oko_attached/src/components/modal_variants/common/metadata_content/metadata_content.tsx b/embed/oko_attached/src/components/modal_variants/common/metadata_content/metadata_content.tsx index 78807c69a..6bf5d5d84 100644 --- a/embed/oko_attached/src/components/modal_variants/common/metadata_content/metadata_content.tsx +++ b/embed/oko_attached/src/components/modal_variants/common/metadata_content/metadata_content.tsx @@ -6,19 +6,7 @@ import { Typography } from "@oko-wallet/oko-common-ui/typography"; import styles from "./metadata_content.module.scss"; import { SignerAddressOrEmail } from "./signer_address_or_email/signer_address_or_email"; import { Avatar } from "@oko-wallet-attached/components/avatar/avatar"; - -function getFaviconUrl(origin: string): string { - if (!origin) return ""; - - try { - const parsed = new URL(origin); - return `https://www.google.com/s2/favicons?domain_url=${encodeURIComponent( - parsed.origin, - )}`; - } catch (error) { - return ""; - } -} +import { getFaviconUrl } from "@oko-wallet-attached/utils/favicon"; interface MakeSignatureModalMetadataContentProps { origin: string; diff --git a/embed/oko_attached/src/utils/favicon.ts b/embed/oko_attached/src/utils/favicon.ts new file mode 100644 index 000000000..dc91aa124 --- /dev/null +++ b/embed/oko_attached/src/utils/favicon.ts @@ -0,0 +1,12 @@ +export function getFaviconUrl(origin: string): string { + if (!origin) return ""; + + try { + const parsed = new URL(origin); + return `https://www.google.com/s2/favicons?domain_url=${encodeURIComponent( + parsed.origin, + )}`; + } catch (error) { + return ""; + } +} From 892198ba928060330d47a67b62e2f94e3e416ba7 Mon Sep 17 00:00:00 2001 From: blacktoast Date: Tue, 23 Dec 2025 17:50:41 +0900 Subject: [PATCH 12/26] [embed] add inValidOrigin warning box design --- .../make_arbitrary_sig_modal.tsx | 39 ++++++++++++++++-- ...thereum_siwe_signature_content.module.scss | 11 +++++ .../siwe_sig/make_siwe-siganature_content.tsx | 36 ++++++++++++---- .../siwe-risk-warning-box.module.scss | 20 +++++++++ .../siwe_sig/siwe-risk-warning-box.tsx | 41 +++++++++++++++++++ 5 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe-risk-warning-box.module.scss create mode 100644 embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe-risk-warning-box.tsx diff --git a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx index 781c00e58..f75829a8c 100644 --- a/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx +++ b/embed/oko_attached/src/components/modal_variants/eth/arbitrary_sig/make_arbitrary_sig_modal.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo, useState } from "react"; import type { MakeArbitrarySigData } from "@oko-wallet/oko-sdk-core"; import { XCloseIcon } from "@oko-wallet/oko-common-ui/icons/x_close"; import { Spacing } from "@oko-wallet/oko-common-ui/spacing"; @@ -11,18 +11,29 @@ import { useArbitrarySigModal } from "./hooks/use_arbitrary_sig_modal"; import { ArbitrarySignatureDesc } from "@oko-wallet-attached/components/modal_variants/common/arbitrary_sig_desc/arbitrary_signature_desc"; import { EthereumArbitrarySignatureContent } from "./ethereum_arbitrary_signature_content"; import { SignWithOkoBox } from "@oko-wallet-attached/components/sign_with_oko_box/sign_with_oko_box"; -import { getSiweMessage } from "@oko-wallet-attached/components/modal_variants/eth/siwe_message"; +import { + getSiweMessage, + verifySiweMessage, +} from "@oko-wallet-attached/components/modal_variants/eth/siwe_message"; import { EthereumSiweSignatureContent } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/make_siwe-siganature_content"; +import { SiweRiskWarningCheckBox } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe-risk-warning-box"; export const MakeArbitrarySigModal: React.FC = ({ getIsAborted, data, modalId, }) => { + const siweMessage = getSiweMessage(data.payload.data.message); + const isValidSiweMessage = siweMessage + ? verifySiweMessage(siweMessage, data.payload.origin) + : false; + const [isSiweRiskWarningChecked, setIsSiweRiskWarningChecked] = + useState(false); + const { onReject, onApprove, - isApproveEnabled, + isApproveEnabled: isApproveEnabledOriginal, isLoading, isDemo, theme, @@ -32,8 +43,18 @@ export const MakeArbitrarySigModal: React.FC = ({ data, modalId, }); + const isApproveEnabled = useMemo(() => { + if (siweMessage && !isValidSiweMessage) { + return isApproveEnabledOriginal && isSiweRiskWarningChecked; + } - const siweMessage = getSiweMessage(data.payload.data.message); + return isApproveEnabledOriginal; + }, [ + isApproveEnabledOriginal, + isSiweRiskWarningChecked, + siweMessage, + isValidSiweMessage, + ]); return (
@@ -58,6 +79,16 @@ export const MakeArbitrarySigModal: React.FC = ({ + {siweMessage && !isValidSiweMessage && ( + <> + + + + )} +
*/ -const DropdownTrigger: React.FC = ({ +const DropdownTrigger: FC = ({ children, className, asChild = false, @@ -159,9 +162,9 @@ const DropdownTrigger: React.FC = ({ } }; - if (asChild && React.isValidElement(children)) { + if (asChild && isValidElement(children)) { const childProps = (children as React.ReactElement).props; - return React.cloneElement(children as React.ReactElement, { + return cloneElement(children as React.ReactElement, { ref: triggerRef, onClick: handleClick, onKeyDown: handleKeyDown, @@ -190,7 +193,7 @@ const DropdownTrigger: React.FC = ({ ); }; -const DropdownContent: React.FC = ({ +const DropdownContent: FC = ({ children, className, defaultOffsetFromTrigger = 4, @@ -261,7 +264,7 @@ const DropdownContent: React.FC = ({ return createPortal(content, document.body); }; -const DropdownItem: React.FC = ({ +const DropdownItem: FC = ({ children, onClick, disabled = false, @@ -305,7 +308,7 @@ const DropdownItem: React.FC = ({ ); }; -const DropdownDivider: React.FC = ({ className }) => { +const DropdownDivider: FC = ({ className }) => { return
; }; diff --git a/ui/oko_common_ui/src/icons/apple_icon.tsx b/ui/oko_common_ui/src/icons/apple_icon.tsx index 1bc257850..b37396ab6 100644 --- a/ui/oko_common_ui/src/icons/apple_icon.tsx +++ b/ui/oko_common_ui/src/icons/apple_icon.tsx @@ -1,6 +1,6 @@ -import React from "react"; +import { type FC } from "react"; -export const AppleIcon: React.FC = ({ size = 20 }) => { +export const AppleIcon: FC = ({ size = 20 }) => { return ( = ({ +export const ArrowUpRightIcon: FC = ({ className, size = 16, color = "currentColor", diff --git a/ui/oko_common_ui/src/icons/chart_outlined.tsx b/ui/oko_common_ui/src/icons/chart_outlined.tsx index 6fad9674b..89971594d 100644 --- a/ui/oko_common_ui/src/icons/chart_outlined.tsx +++ b/ui/oko_common_ui/src/icons/chart_outlined.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const ChartOutlinedIcon: React.FC = ({ +export const ChartOutlinedIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/check_circle_outlined.tsx b/ui/oko_common_ui/src/icons/check_circle_outlined.tsx index 4269d1121..14fc978fb 100644 --- a/ui/oko_common_ui/src/icons/check_circle_outlined.tsx +++ b/ui/oko_common_ui/src/icons/check_circle_outlined.tsx @@ -1,7 +1,8 @@ -import React from "react"; +import { type FC } from "react"; + import type { BasicIconProps } from "./types"; -export const CheckCircleOutlinedIcon: React.FC = ({ +export const CheckCircleOutlinedIcon: FC = ({ className, color = "currentColor", size = 16, diff --git a/ui/oko_common_ui/src/icons/chevron_down.tsx b/ui/oko_common_ui/src/icons/chevron_down.tsx index 7c34b0925..6e03a7bf8 100644 --- a/ui/oko_common_ui/src/icons/chevron_down.tsx +++ b/ui/oko_common_ui/src/icons/chevron_down.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const ChevronDownIcon: React.FC = ({ +export const ChevronDownIcon: FC = ({ className, color = "currentColor", size = 16, diff --git a/ui/oko_common_ui/src/icons/chevron_up.tsx b/ui/oko_common_ui/src/icons/chevron_up.tsx index 0c12287db..e77f16bc3 100644 --- a/ui/oko_common_ui/src/icons/chevron_up.tsx +++ b/ui/oko_common_ui/src/icons/chevron_up.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const ChevronUpIcon: React.FC = ({ +export const ChevronUpIcon: FC = ({ className, color = "currentColor", size = 16, diff --git a/ui/oko_common_ui/src/icons/close_button_icon.tsx b/ui/oko_common_ui/src/icons/close_button_icon.tsx index bbb29551b..a7e045fe8 100644 --- a/ui/oko_common_ui/src/icons/close_button_icon.tsx +++ b/ui/oko_common_ui/src/icons/close_button_icon.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const CloseButtonIcon: React.FC = ({ +export const CloseButtonIcon: FC = ({ className, color = "#A4A7AE", size = 12, diff --git a/ui/oko_common_ui/src/icons/code.tsx b/ui/oko_common_ui/src/icons/code.tsx index c4dc1c299..f698509d0 100644 --- a/ui/oko_common_ui/src/icons/code.tsx +++ b/ui/oko_common_ui/src/icons/code.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const CodeIcon: React.FC = ({ +export const CodeIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/copy_outlined.tsx b/ui/oko_common_ui/src/icons/copy_outlined.tsx index c71ca75a2..aae92258d 100644 --- a/ui/oko_common_ui/src/icons/copy_outlined.tsx +++ b/ui/oko_common_ui/src/icons/copy_outlined.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const CopyOutlinedIcon: React.FC = ({ +export const CopyOutlinedIcon: FC = ({ className, color = "currentColor", }) => { diff --git a/ui/oko_common_ui/src/icons/cosmos_icon.tsx b/ui/oko_common_ui/src/icons/cosmos_icon.tsx index 1e0896dcd..efbbe58fb 100644 --- a/ui/oko_common_ui/src/icons/cosmos_icon.tsx +++ b/ui/oko_common_ui/src/icons/cosmos_icon.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; -export const CosmosIcon: React.FC = ({ +export const CosmosIcon: FC = ({ width = 16, height = 16, }) => { diff --git a/ui/oko_common_ui/src/icons/discord_icon.tsx b/ui/oko_common_ui/src/icons/discord_icon.tsx index 26f1e1874..9389f0241 100644 --- a/ui/oko_common_ui/src/icons/discord_icon.tsx +++ b/ui/oko_common_ui/src/icons/discord_icon.tsx @@ -1,6 +1,6 @@ -import React from "react"; +import type { FC } from "react"; -export const DiscordIcon: React.FC = ({ size = 20 }) => { +export const DiscordIcon: FC = ({ size = 20 }) => { return ( = ({ +export const DoorOutlinedIcon: FC = ({ className, color = "currentColor", }) => { diff --git a/ui/oko_common_ui/src/icons/edit.tsx b/ui/oko_common_ui/src/icons/edit.tsx index 757387d71..d344431b4 100644 --- a/ui/oko_common_ui/src/icons/edit.tsx +++ b/ui/oko_common_ui/src/icons/edit.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const EditIcon: React.FC = ({ +export const EditIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/empty_state_icon.tsx b/ui/oko_common_ui/src/icons/empty_state_icon.tsx index 9852751b1..3f53d76de 100644 --- a/ui/oko_common_ui/src/icons/empty_state_icon.tsx +++ b/ui/oko_common_ui/src/icons/empty_state_icon.tsx @@ -1,6 +1,6 @@ import type { BasicIconProps } from "./types"; -export const EmptyStateIcon: React.FC = ({ +export const EmptyStateIcon: FC = ({ className, size = 28, }) => { diff --git a/ui/oko_common_ui/src/icons/error_icon.tsx b/ui/oko_common_ui/src/icons/error_icon.tsx index ccd451d53..60d08eef0 100644 --- a/ui/oko_common_ui/src/icons/error_icon.tsx +++ b/ui/oko_common_ui/src/icons/error_icon.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const ErrorIcon: React.FC = ({ +export const ErrorIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/ethereum_blue_icon.tsx b/ui/oko_common_ui/src/icons/ethereum_blue_icon.tsx index 9d3f2e45f..b48335061 100644 --- a/ui/oko_common_ui/src/icons/ethereum_blue_icon.tsx +++ b/ui/oko_common_ui/src/icons/ethereum_blue_icon.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; -export const EthereumBlueIcon: React.FC = ({ +export const EthereumBlueIcon: FC = ({ width = 16, height = 16, }) => { diff --git a/ui/oko_common_ui/src/icons/ethereum_icon.tsx b/ui/oko_common_ui/src/icons/ethereum_icon.tsx index 971f38fea..01b357297 100644 --- a/ui/oko_common_ui/src/icons/ethereum_icon.tsx +++ b/ui/oko_common_ui/src/icons/ethereum_icon.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; -export const EthereumIcon: React.FC = ({ +export const EthereumIcon: FC = ({ width = 16, height = 16, }) => { diff --git a/ui/oko_common_ui/src/icons/external_link_outlined.tsx b/ui/oko_common_ui/src/icons/external_link_outlined.tsx index 8ecb63c2e..a582fbcc1 100644 --- a/ui/oko_common_ui/src/icons/external_link_outlined.tsx +++ b/ui/oko_common_ui/src/icons/external_link_outlined.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const ExternalLinkOutlinedIcon: React.FC = ({ +export const ExternalLinkOutlinedIcon: FC = ({ className, color = "currentColor", }) => { diff --git a/ui/oko_common_ui/src/icons/eye.tsx b/ui/oko_common_ui/src/icons/eye.tsx index 3422fb513..ce55f2422 100644 --- a/ui/oko_common_ui/src/icons/eye.tsx +++ b/ui/oko_common_ui/src/icons/eye.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const EyeIcon: React.FC = ({ +export const EyeIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/google_icon.tsx b/ui/oko_common_ui/src/icons/google_icon.tsx index d02d6de9a..e3019111b 100644 --- a/ui/oko_common_ui/src/icons/google_icon.tsx +++ b/ui/oko_common_ui/src/icons/google_icon.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; -export const GoogleIcon: React.FC = ({ +export const GoogleIcon: FC = ({ width = 16, height = 16, }) => { diff --git a/ui/oko_common_ui/src/icons/home_outlined.tsx b/ui/oko_common_ui/src/icons/home_outlined.tsx index e6a8ba83f..0a0e7d96c 100644 --- a/ui/oko_common_ui/src/icons/home_outlined.tsx +++ b/ui/oko_common_ui/src/icons/home_outlined.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const HomeOutlinedIcon: React.FC = ({ +export const HomeOutlinedIcon: FC = ({ className, color = "currentColor", }) => { diff --git a/ui/oko_common_ui/src/icons/info_circle.tsx b/ui/oko_common_ui/src/icons/info_circle.tsx index 566d665f4..a8a787165 100644 --- a/ui/oko_common_ui/src/icons/info_circle.tsx +++ b/ui/oko_common_ui/src/icons/info_circle.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const InfoCircleIcon: React.FC = ({ +export const InfoCircleIcon: FC = ({ className, color = "#535862", }) => { diff --git a/ui/oko_common_ui/src/icons/keplr_icon.tsx b/ui/oko_common_ui/src/icons/keplr_icon.tsx index 843f06716..8c80dbf55 100644 --- a/ui/oko_common_ui/src/icons/keplr_icon.tsx +++ b/ui/oko_common_ui/src/icons/keplr_icon.tsx @@ -2,10 +2,7 @@ import React from "react"; import { s3BucketURL } from "./paths"; -export const KeplrIcon: React.FC = ({ - width = 20, - height = 20, -}) => { +export const KeplrIcon: FC = ({ width = 20, height = 20 }) => { return ( = ({ - width = 20, - height = 20, -}) => { +export const LeapIcon: FC = ({ width = 20, height = 20 }) => { return ( = ({ +export const LoadingIcon: FC = ({ className, color = "currentColor", backgroundColor = "transparent", diff --git a/ui/oko_common_ui/src/icons/loading_circle_icon.tsx b/ui/oko_common_ui/src/icons/loading_circle_icon.tsx index 1697e3c2f..4a9e5742d 100644 --- a/ui/oko_common_ui/src/icons/loading_circle_icon.tsx +++ b/ui/oko_common_ui/src/icons/loading_circle_icon.tsx @@ -1,8 +1,10 @@ -import type { BasicIconProps } from "./types"; -import styles from "./loading_circle_icon.module.scss"; import cn from "classnames"; +import type { FC } from "react"; + +import styles from "./loading_circle_icon.module.scss"; +import type { BasicIconProps } from "./types"; -export const LoadingCircleIcon: React.FC = ({ +export const LoadingCircleIcon: FC = ({ className, size = 62, }) => { diff --git a/ui/oko_common_ui/src/icons/logo_text_icon.tsx b/ui/oko_common_ui/src/icons/logo_text_icon.tsx index 477d4ed58..b19a7e6ce 100644 --- a/ui/oko_common_ui/src/icons/logo_text_icon.tsx +++ b/ui/oko_common_ui/src/icons/logo_text_icon.tsx @@ -2,7 +2,7 @@ import React from "react"; import { s3BucketURL } from "./paths"; -export const LogoTextIcon: React.FC = ({ +export const LogoTextIcon: FC = ({ width = 54.231, height = "auto", style, diff --git a/ui/oko_common_ui/src/icons/logout.tsx b/ui/oko_common_ui/src/icons/logout.tsx index 49a5062bb..149a8fab3 100644 --- a/ui/oko_common_ui/src/icons/logout.tsx +++ b/ui/oko_common_ui/src/icons/logout.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const LogoutIcon: React.FC = ({ +export const LogoutIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/mailbox.tsx b/ui/oko_common_ui/src/icons/mailbox.tsx index 15470e2b3..08278146c 100644 --- a/ui/oko_common_ui/src/icons/mailbox.tsx +++ b/ui/oko_common_ui/src/icons/mailbox.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const MailboxIcon: React.FC = ({ +export const MailboxIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/metamask_icon.tsx b/ui/oko_common_ui/src/icons/metamask_icon.tsx index ba834b06b..5f45cbdf6 100644 --- a/ui/oko_common_ui/src/icons/metamask_icon.tsx +++ b/ui/oko_common_ui/src/icons/metamask_icon.tsx @@ -2,7 +2,7 @@ import React from "react"; import { s3BucketURL } from "./paths"; -export const MetamaskIcon: React.FC = ({ +export const MetamaskIcon: FC = ({ width = 20, height = 20, }) => { diff --git a/ui/oko_common_ui/src/icons/oko_logo_icon.tsx b/ui/oko_common_ui/src/icons/oko_logo_icon.tsx index 232c7421b..c4156c823 100644 --- a/ui/oko_common_ui/src/icons/oko_logo_icon.tsx +++ b/ui/oko_common_ui/src/icons/oko_logo_icon.tsx @@ -1,9 +1,9 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; import type { Theme } from "@oko-wallet-common-ui/theme/theme_provider"; -export const OkoLogoIcon: React.FC = ({ +export const OkoLogoIcon: FC = ({ width = 84, height = 32, className, diff --git a/ui/oko_common_ui/src/icons/oko_logo_with_name_icon.tsx b/ui/oko_common_ui/src/icons/oko_logo_with_name_icon.tsx index f8b30e7d3..9f4ff1a36 100644 --- a/ui/oko_common_ui/src/icons/oko_logo_with_name_icon.tsx +++ b/ui/oko_common_ui/src/icons/oko_logo_with_name_icon.tsx @@ -1,9 +1,9 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; import type { Theme } from "@oko-wallet-common-ui/theme/theme_provider"; -export const OkoLogoWithNameIcon: React.FC = ({ +export const OkoLogoWithNameIcon: FC = ({ width = 39, height = 14, className, diff --git a/ui/oko_common_ui/src/icons/oko_product_logo_icon.tsx b/ui/oko_common_ui/src/icons/oko_product_logo_icon.tsx index af9760af8..9c7b0f2ec 100644 --- a/ui/oko_common_ui/src/icons/oko_product_logo_icon.tsx +++ b/ui/oko_common_ui/src/icons/oko_product_logo_icon.tsx @@ -6,7 +6,7 @@ import type { Theme } from "@oko-wallet-common-ui/theme/theme_provider"; /** * @deprecated Use OkoLogoIcon instead */ -export const OkoProductLogoIcon: React.FC = ({ +export const OkoProductLogoIcon: FC = ({ width = 323.702, height = 128, className, diff --git a/ui/oko_common_ui/src/icons/osmosis_icon.tsx b/ui/oko_common_ui/src/icons/osmosis_icon.tsx index 52a5dcf08..91a4f105c 100644 --- a/ui/oko_common_ui/src/icons/osmosis_icon.tsx +++ b/ui/oko_common_ui/src/icons/osmosis_icon.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import { type FC } from "react"; import { s3BucketURL } from "./paths"; -export const OsmosisIcon: React.FC = ({ +export const OsmosisIcon: FC = ({ width = 16, height = 16, }) => { diff --git a/ui/oko_common_ui/src/icons/password.tsx b/ui/oko_common_ui/src/icons/password.tsx index a9a8de30d..7e581d00b 100644 --- a/ui/oko_common_ui/src/icons/password.tsx +++ b/ui/oko_common_ui/src/icons/password.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const PasswordIcon: React.FC = ({ +export const PasswordIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/plus.tsx b/ui/oko_common_ui/src/icons/plus.tsx index c28e3fab6..cc93128d2 100644 --- a/ui/oko_common_ui/src/icons/plus.tsx +++ b/ui/oko_common_ui/src/icons/plus.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const PlusIcon: React.FC = ({ +export const PlusIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/search.tsx b/ui/oko_common_ui/src/icons/search.tsx index 3cb5845db..2002b2da3 100644 --- a/ui/oko_common_ui/src/icons/search.tsx +++ b/ui/oko_common_ui/src/icons/search.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const SearchIcon: React.FC = ({ +export const SearchIcon: FC = ({ className, color = "#A4A7AE", }) => { diff --git a/ui/oko_common_ui/src/icons/setting_icon.tsx b/ui/oko_common_ui/src/icons/setting_icon.tsx index 67f42100d..13c71d025 100644 --- a/ui/oko_common_ui/src/icons/setting_icon.tsx +++ b/ui/oko_common_ui/src/icons/setting_icon.tsx @@ -1,6 +1,6 @@ import type { BasicIconProps } from "./types"; -export const SettingIcon: React.FC = ({ +export const SettingIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/telegram_icon.tsx b/ui/oko_common_ui/src/icons/telegram_icon.tsx index 563147bf3..dcff952b7 100644 --- a/ui/oko_common_ui/src/icons/telegram_icon.tsx +++ b/ui/oko_common_ui/src/icons/telegram_icon.tsx @@ -1,6 +1,6 @@ -import React from "react"; +import { type FC } from "react"; -export const TelegramIcon: React.FC = ({ size = 20 }) => { +export const TelegramIcon: FC = ({ size = 20 }) => { return ( = ({ +export const ThreeDotsVerticalIcon: FC = ({ className, color = "currentColor", }) => { diff --git a/ui/oko_common_ui/src/icons/users.tsx b/ui/oko_common_ui/src/icons/users.tsx index 65f9c53f4..984082f3e 100644 --- a/ui/oko_common_ui/src/icons/users.tsx +++ b/ui/oko_common_ui/src/icons/users.tsx @@ -1,6 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const UsersIcon: React.FC = ({ +export const UsersIcon: FC = ({ className, color = "currentColor", size = 20, diff --git a/ui/oko_common_ui/src/icons/warning_icon.tsx b/ui/oko_common_ui/src/icons/warning_icon.tsx index 61b4c110a..4e3bd6d05 100644 --- a/ui/oko_common_ui/src/icons/warning_icon.tsx +++ b/ui/oko_common_ui/src/icons/warning_icon.tsx @@ -1,9 +1,8 @@ +import type { FC } from "react"; + import type { BasicIconProps } from "./types"; -export const WarningIcon: React.FC = ({ - className, - size = 42, -}) => { +export const WarningIcon: FC = ({ className, size = 42 }) => { return ( = ({ +export const XCloseIcon: FC = ({ className, size = 20, color = "#A4A7AE", diff --git a/ui/oko_common_ui/src/icons/x_icon.tsx b/ui/oko_common_ui/src/icons/x_icon.tsx index 6fef8243a..71e2d5639 100644 --- a/ui/oko_common_ui/src/icons/x_icon.tsx +++ b/ui/oko_common_ui/src/icons/x_icon.tsx @@ -1,6 +1,6 @@ -import React from "react"; +import { type FC } from "react"; -export const XIcon: React.FC = ({ size = 24 }) => { +export const XIcon: FC = ({ size = 24 }) => { return ( void; } -export const Input: React.FC = ({ +export const Input: FC = ({ variant = "default", inputSize = "md", fullWidth = false, diff --git a/ui/oko_common_ui/src/logo/logo.tsx b/ui/oko_common_ui/src/logo/logo.tsx index ecbda5e6f..07972e8ae 100644 --- a/ui/oko_common_ui/src/logo/logo.tsx +++ b/ui/oko_common_ui/src/logo/logo.tsx @@ -1,3 +1,5 @@ +import type { FC } from "react"; + import styles from "./logo.module.scss"; import { OkoLogoIcon } from "@oko-wallet-common-ui/icons/oko_logo_icon"; import type { Theme } from "@oko-wallet-common-ui/theme/theme_provider"; @@ -9,7 +11,7 @@ export interface LogoProps { theme?: Theme | null; } -export const Logo: React.FC = ({ +export const Logo: FC = ({ width = 58, height = 22, className, diff --git a/ui/oko_common_ui/src/otp_input/otp_input.tsx b/ui/oko_common_ui/src/otp_input/otp_input.tsx index 118d823e4..e24262a0e 100644 --- a/ui/oko_common_ui/src/otp_input/otp_input.tsx +++ b/ui/oko_common_ui/src/otp_input/otp_input.tsx @@ -1,8 +1,9 @@ -import React, { +import { useState, useRef, type KeyboardEvent, type ClipboardEvent, + type FC, } from "react"; import styles from "./otp_input.module.scss"; @@ -25,7 +26,7 @@ function isComplete(digits: string[], length: number): boolean { ); } -export const OtpInput: React.FC = ({ +export const OtpInput: FC = ({ length, value, onChange, diff --git a/ui/oko_common_ui/src/skeleton/skeleton.tsx b/ui/oko_common_ui/src/skeleton/skeleton.tsx index 7b09c680d..af8260a5d 100644 --- a/ui/oko_common_ui/src/skeleton/skeleton.tsx +++ b/ui/oko_common_ui/src/skeleton/skeleton.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import type { FC } from "react"; import "./skeleton.scss"; @@ -9,7 +9,7 @@ interface SkeletonProps { className?: string; } -export const Skeleton: React.FC = ({ +export const Skeleton: FC = ({ width = "100%", height = "1em", borderRadius = "12px", diff --git a/ui/oko_common_ui/src/table/table.tsx b/ui/oko_common_ui/src/table/table.tsx index 1893dbee9..a9fc26e7c 100644 --- a/ui/oko_common_ui/src/table/table.tsx +++ b/ui/oko_common_ui/src/table/table.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { type FC } from "react"; import cn from "classnames"; import styles from "./table.module.scss"; @@ -32,7 +32,7 @@ export interface TableHeaderCellProps sortable?: boolean; } -export const Table: React.FC> = ({ +export const Table: FC> = ({ variant = "default", size = "md", children, @@ -64,7 +64,7 @@ export const Table: React.FC> = ({ ); }; -export const TableHead: React.FC> = ({ +export const TableHead: FC> = ({ children, className, ...rest @@ -76,7 +76,7 @@ export const TableHead: React.FC> = ({ ); }; -export const TableBody: React.FC> = ({ +export const TableBody: FC> = ({ children, className, ...rest @@ -88,7 +88,7 @@ export const TableBody: React.FC> = ({ ); }; -export const TableRow: React.FC> = ({ +export const TableRow: FC> = ({ selected = false, children, className, @@ -109,7 +109,7 @@ export const TableRow: React.FC> = ({ ); }; -export const TableCell: React.FC> = ({ +export const TableCell: FC> = ({ align = "left", children, className, @@ -124,7 +124,7 @@ export const TableCell: React.FC> = ({ ); }; -export const TableHeaderCell: React.FC< +export const TableHeaderCell: FC< React.PropsWithChildren > = ({ align = "left", sortable = false, children, className, ...rest }) => { const headerClassName = cn( diff --git a/ui/oko_common_ui/src/theme/theme_provider.tsx b/ui/oko_common_ui/src/theme/theme_provider.tsx index 80d68d34d..8aefdfd1d 100644 --- a/ui/oko_common_ui/src/theme/theme_provider.tsx +++ b/ui/oko_common_ui/src/theme/theme_provider.tsx @@ -1,12 +1,12 @@ "use client"; -import React, { createContext, type PropsWithChildren } from "react"; +import { createContext, type FC, type PropsWithChildren } from "react"; export type Theme = "light" | "dark" | "system"; export const ThemeContext = createContext("system"); -export const ThemeProvider: React.FC> = ({ +export const ThemeProvider: FC> = ({ children, theme, }) => { diff --git a/ui/oko_common_ui/src/toggle/toggle.tsx b/ui/oko_common_ui/src/toggle/toggle.tsx index a70ccf50b..198e017fd 100644 --- a/ui/oko_common_ui/src/toggle/toggle.tsx +++ b/ui/oko_common_ui/src/toggle/toggle.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import { type FC } from "react"; import cn from "classnames"; import styles from "./toggle.module.scss"; @@ -12,7 +12,7 @@ export interface ToggleProps { className?: string; } -export const Toggle: React.FC = ({ +export const Toggle: FC = ({ onChange, checked = false, disabled = false, diff --git a/ui/oko_common_ui/tsconfig.json b/ui/oko_common_ui/tsconfig.json index de4b67d7c..2c609d655 100644 --- a/ui/oko_common_ui/tsconfig.json +++ b/ui/oko_common_ui/tsconfig.json @@ -15,15 +15,10 @@ "rootDir": ".", "jsx": "preserve", "incremental": true, - "plugins": [ - { - "name": "next" - } - ], "paths": { "@oko-wallet-common-ui/*": ["./src/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "include": ["**/*.ts", "**/*.tsx"], "exclude": ["node_modules"] }