From d395fceb80ee0f80581eb9c4f4e9b990c130018b Mon Sep 17 00:00:00 2001 From: blacktoast Date: Thu, 11 Dec 2025 10:41:37 +0900 Subject: [PATCH 01/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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/25] [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 && ( + <> + + + + )} +