Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d395fce
[embed] add getSIWEMessage and add condition to show siwe ui
blacktoast Dec 11, 2025
8ca9c56
[embed] separate getSiweMessage func and make relative path import to…
blacktoast Dec 11, 2025
e74e854
[embed] add VITE_PUBLIC_S3_BUCKET_URL in env
blacktoast Dec 11, 2025
a8185aa
[embed] make inner comp of SignerAddressOrEmail exported to share
blacktoast Dec 11, 2025
20da61e
[sandbox] add Sign SIWE Message (with wrong URI) button for testing
blacktoast Dec 11, 2025
ba73e86
[embed] add className props
blacktoast Dec 11, 2025
fcde32c
[embed] add SiweSigTitleBadge
blacktoast Dec 11, 2025
a7a07fb
[embed] change file name and add verifySiweMessage
blacktoast Dec 11, 2025
1f40373
[embed] add EthereumSiweSignatureContent and apply
blacktoast Dec 11, 2025
a03f6c9
[embed] add theme in SiweSigTitleBadge
blacktoast Dec 11, 2025
b7db0d2
[embed] make getFaviconUrl utils func
blacktoast Dec 23, 2025
892198b
[embed] add inValidOrigin warning box design
blacktoast Dec 23, 2025
85cd4b6
[ui] when it is dark-mode, change check icon color
blacktoast Dec 23, 2025
c99798d
[embed] add chain icon
blacktoast Dec 23, 2025
c967ba0
[ci] add deploy oko-sandbox-evm command
blacktoast Dec 23, 2025
1b2ab33
[embed] change text
blacktoast Dec 23, 2025
817d5eb
[embed] add hoverColor
blacktoast Dec 24, 2025
3cd2596
[embed] adjust gap
blacktoast Dec 24, 2025
8f761e0
[embed] remove favicon and adjust style
blacktoast Dec 24, 2025
7de57b0
[ui] add custom classname props
blacktoast Dec 24, 2025
1dea141
[embed] adjust style
blacktoast Dec 24, 2025
38124be
oko_attached: fix typo
Ryz0nd Dec 30, 2025
ad614a0
oko_attached: unify file naming to underscore convention
Ryz0nd Dec 30, 2025
a4dd6e5
oko_attached: remove console
Ryz0nd Dec 30, 2025
bfb269c
Merge branch 'main' into retto/OKO-372
blacktoast Dec 31, 2025
8431c62
[attahced] apply ImageWithAlt
blacktoast Dec 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions embed/oko_attached/oko_attached.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -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 <div className={styles.codeBlockContainer}>{children}</div>;
> = ({ children, className }) => {
return (
<div className={cn(styles.codeBlockContainer, className)}>{children}</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@

cursor: pointer;
border-radius: 12px;
background: var(--bg-secondary);
background-color: var(--bg-secondary);
width: fit-content;

transition: background-color 0.15s ease-in-out;

&:hover {
background-color: var(--bg-secondary-hover);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<ViewProps> = ({
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 (
<Typography size="sm" color="brand-tertiary" weight="medium">
{prefix && `${prefix} `}
{displayValue}
</Typography>
);
};

export const SignerAddressOrEmailChangeViewTypeButton: FC<{
viewType: "View Address" | "Login Info";
onClick: () => void;
}> = ({ viewType, onClick }) => {
return (
<div onClick={onClick} className={styles.changeViewTypeButton}>
<EyeIcon size={12} color="var(--fg-quaternary)" />
<Typography size="xs" color="quaternary" weight="semibold">
{viewType}
</Typography>
</div>
);
};

export const SignerAddressOrEmail: FC<SignerAddressOrEmailProps> = ({
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 (
<div className={styles.wrapper}>
<Typography size="sm" color="brand-tertiary" weight="medium">
{signer.slice(0, 9)}...{signer.slice(-9)}
</Typography>
<ChangeViewTypeButton
<SignerAddressOrEmailView
value={signer}
type="address"
origin={origin}
/>
<SignerAddressOrEmailChangeViewTypeButton
viewType="Login Info"
onClick={() => setViewType("Login Info")}
/>
Expand All @@ -35,28 +77,16 @@ export const SignerAddressOrEmail: FC<SignerAddressOrEmailProps> = ({
case "Login Info":
return (
<div className={styles.wrapper}>
<Typography size="sm" color="brand-tertiary" weight="medium">
{email}
</Typography>
<ChangeViewTypeButton
<SignerAddressOrEmailView
value={signer}
type="email"
origin={origin}
/>
<SignerAddressOrEmailChangeViewTypeButton
viewType="View Address"
onClick={() => setViewType("View Address")}
/>
</div>
);
}
};

const ChangeViewTypeButton: FC<{
viewType: "View Address" | "Login Info";
onClick: () => void;
}> = ({ viewType, onClick }) => {
return (
<div onClick={onClick} className={styles.changeViewTypeButton}>
<EyeIcon size={12} color="var(--fg-quaternary)" />
<Typography size="xs" color="quaternary" weight="semibold">
{viewType}
</Typography>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -11,16 +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,
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_signature_content";
import { SiweRiskWarningCheckBox } from "@oko-wallet-attached/components/modal_variants/eth/arbitrary_sig/siwe_sig/siwe_risk_warning_box";

export const MakeArbitrarySigModal: React.FC<MakeArbitrarySigModalProps> = ({
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,
Expand All @@ -30,6 +43,18 @@ export const MakeArbitrarySigModal: React.FC<MakeArbitrarySigModalProps> = ({
data,
modalId,
});
const isApproveEnabled = useMemo(() => {
if (siweMessage && !isValidSiweMessage) {
return isApproveEnabledOriginal && isSiweRiskWarningChecked;
}

return isApproveEnabledOriginal;
}, [
isApproveEnabledOriginal,
isSiweRiskWarningChecked,
siweMessage,
isValidSiweMessage,
]);

return (
<div className={styles.container}>
Expand All @@ -39,13 +64,30 @@ export const MakeArbitrarySigModal: React.FC<MakeArbitrarySigModalProps> = ({
</div>

<div className={styles.modalInnerContentContainer}>
<EthereumArbitrarySignatureContent payload={data.payload} />
{!!siweMessage ? (
<EthereumSiweSignatureContent
payload={data.payload}
theme={theme}
/>
) : (
<EthereumArbitrarySignatureContent payload={data.payload} />
)}
</div>

<Spacing height={20} />
<Spacing height={!!siweMessage ? 12 : 20} />
{!hasOnChainSchema && <ArbitrarySignatureDesc />}

<Spacing height={20} />
<Spacing height={8} />

{siweMessage && !isValidSiweMessage && (
<>
<SiweRiskWarningCheckBox
checked={isSiweRiskWarningChecked}
onChange={setIsSiweRiskWarningChecked}
/>
<Spacing height={12} />
</>
)}

<div className={styles.buttonContainer}>
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.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;

.chainInfoRowContent {
display: flex;
align-items: center;
gap: 4px;
}
}
}

.originRow {
display: flex;
align-items: center;
gap: 4px;

padding: 0px 20px;

word-break: break-all;
text-align: center;

.originFavicon {
width: 20px;
height: 20px;
}
}
Loading