Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
5597edc
Integrates dynamic via native api
hernan-clich Aug 6, 2025
ffeb99f
Using widgets
hernan-clich Aug 7, 2025
07a0f66
Restored compatibility for EIP-6963
hernan-clich Aug 7, 2025
8b4647e
Setting flip to true
hernan-clich Aug 7, 2025
483c40d
Added chains manually
hernan-clich Aug 7, 2025
d9a2841
Cleanup
hernan-clich Aug 8, 2025
366a037
Merge branch 'main' into feat/integrate-dynamic-vite
hernan-clich Aug 8, 2025
d193144
Fix lint errors
hernan-clich Aug 8, 2025
567e850
Renamed hooks and cleared logs
hernan-clich Aug 8, 2025
47304e8
Use Univ Sign in Global wallet and Css overrides
hernan-clich Aug 23, 2025
c345f03
Applying proper overrides
hernan-clich Aug 23, 2025
b4172ec
Add sdk api core
hernan-clich Aug 23, 2025
b97cfbc
Opening USI GWallet directly
hernan-clich Aug 26, 2025
42c190e
Remove context overrides
hernan-clich Aug 26, 2025
e9232c8
Using UniversalSignInContextProvider
hernan-clich Aug 26, 2025
4f74b5b
Removed all dynamic libs from project
hernan-clich Aug 26, 2025
f3b2676
Corrected import
hernan-clich Aug 26, 2025
cb09977
Use connectUniversalSignIn fn
hernan-clich Aug 28, 2025
f48bd85
Correct modal semantics
hernan-clich Aug 28, 2025
c3e1d36
Installed zeta wallet
hernan-clich Aug 28, 2025
c925ed5
Merge branch 'main' into feat/integrate-dynamic-vite
fadeev Sep 5, 2025
c9e419c
Fix runtime issue by splitting AppContent
hernan-clich Sep 17, 2025
65bff90
Bump wallet lib
hernan-clich Sep 17, 2025
eb95949
Updated dynamic version header
hernan-clich Sep 17, 2025
5131416
Remove silly comment
hernan-clich Sep 17, 2025
cf08228
Removed unused chain data
hernan-clich Sep 17, 2025
ce19b3c
Made small type fixes
hernan-clich Sep 17, 2025
2452439
Optimize provider wrapping
hernan-clich Sep 17, 2025
b291c21
Using resolution for clunky noble hashes
hernan-clich Sep 17, 2025
16ed979
Removed unnecessary file extensions on imports
hernan-clich Sep 17, 2025
3f30d8d
Bump wallet lib
hernan-clich Sep 18, 2025
021ff23
Completed conditional rendering setup of providers
hernan-clich Sep 18, 2025
1c6cffd
Add resolutions for noble libs
hernan-clich Sep 18, 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
5 changes: 5 additions & 0 deletions examples/hello/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@zetachain/toolkit": "16.0.1",
"@zetachain/wallet": "1.0.12",
"clsx": "^2.1.1",
"ethers": "^6.13.2",
"react": "^19.1.0",
Expand All @@ -32,5 +33,9 @@
"typescript": "~5.8.3",
"typescript-eslint": "^8.35.1",
"vite": "^7.0.4"
},
"resolutions": {
"@noble/hashes": "1.8.0",
"@noble/curves": "1.9.7"
}
}
18 changes: 14 additions & 4 deletions examples/hello/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import { UniversalSignInContextProvider } from '@zetachain/wallet/react';

import { AppContent } from './AppContent';
import { Header } from './components/Header';
import { ThemeProvider } from './context/ThemeProvider';
import { USE_DYNAMIC_WALLET } from './constants/wallets';
import { useTheme } from './hooks/useTheme';

function App() {
return (
<ThemeProvider>
const { theme } = useTheme();

return USE_DYNAMIC_WALLET ? (
<UniversalSignInContextProvider environment="sandbox" theme={theme}>
<Header />
<AppContent />
</UniversalSignInContextProvider>
) : (
<>
<Header />
<AppContent />
</ThemeProvider>
</>
);
}

Expand Down
24 changes: 4 additions & 20 deletions examples/hello/frontend/src/AppContent.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
import { ConnectedContent } from './ConnectedContent';
import { SUPPORTED_CHAINS } from './constants/chains';
import { DisconnectedContent } from './DisconnectedContent';
import { useWallet } from './hooks/useWallet';
import { USE_DYNAMIC_WALLET } from './constants/wallets';
import { DynamicAppContent } from './DynamicAppContent';
import { Eip6963AppContent } from './Eip6963AppContent';

export function AppContent() {
const { account, selectedProvider, decimalChainId } = useWallet();

const supportedChain = SUPPORTED_CHAINS.find(
(chain) => chain.chainId === decimalChainId
);

if (!account || !selectedProvider) {
return <DisconnectedContent />;
}

return (
<ConnectedContent
selectedProvider={selectedProvider}
supportedChain={supportedChain}
/>
);
return USE_DYNAMIC_WALLET ? <DynamicAppContent /> : <Eip6963AppContent />;
}
44 changes: 0 additions & 44 deletions examples/hello/frontend/src/ConnectedContent.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,6 @@
}
}

.call-input {
background-color: rgba(var(--primary-color-rgb), 0.8);
font-size: 1.25rem;
height: 100%;
padding: 0.785rem;
width: 100%;
}

.call-button {
font-size: 1rem;
padding: 1rem;
transition: all 0.2s ease-in-out;
white-space: nowrap;
width: 100%;

&:disabled {
background-color: rgba(126, 126, 126, 0.5);
cursor: not-allowed;
opacity: 0.7;
}
}

.input-counter {
font-size: 1.5rem;
}

[data-theme='light'] .content-container-inner-description {
color: #696e75;

Expand Down Expand Up @@ -103,22 +77,4 @@
.content-container-inner-description {
font-size: 18px;
}

.input-container-inner {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
}

.call-input {
font-size: 1.75rem;
padding: 0.785rem;
}

.call-button {
font-size: 1.5rem;
padding: 1rem 2rem;
width: max-content;
}
}
73 changes: 70 additions & 3 deletions examples/hello/frontend/src/ConnectedContent.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
import './ConnectedContent.css';

import { type PrimaryWallet } from '@zetachain/wallet';

import { NetworkSelector } from './components/NetworkSelector';
import type { SupportedChain } from './constants/chains';
import { USE_DYNAMIC_WALLET } from './constants/wallets';
import { Footer } from './Footer';
import { useDynamicSwitchChainHook } from './hooks/useDynamicSwitchChainHook';
import { useSwitchChain } from './hooks/useSwitchChain';
import { MessageFlowCard } from './MessageFlowCard';
import type { EIP6963ProviderDetail } from './types/wallet';

interface ConnectedContentProps {
selectedProvider: EIP6963ProviderDetail;
selectedProvider: EIP6963ProviderDetail | null;
supportedChain: SupportedChain | undefined;
primaryWallet?: PrimaryWallet | null; // Dynamic wallet from context
}

export function ConnectedContent({
const DynamicConnectedContent = ({
selectedProvider,
supportedChain,
}: ConnectedContentProps) {
primaryWallet,
}: ConnectedContentProps) => {
const { switchChain } = useDynamicSwitchChainHook();

const handleNetworkSelect = (chain: SupportedChain) => {
switchChain(chain.chainId);
};

return (
<div className="main-container">
<div className="content-container">
<div className="content-container-inner">
<div className="content-container-inner-header">
<h1>Say Hello from</h1>
<NetworkSelector
selectedChain={supportedChain}
onNetworkSelect={handleNetworkSelect}
/>
</div>
<p className="content-container-inner-description">
Make a cross-chain call with a message from{' '}
{supportedChain?.name || 'a supported network'} to a universal
contract on ZetaChain that emits a{' '}
<span className="highlight">HelloEvent</span>.
</p>
</div>
<MessageFlowCard
selectedProvider={selectedProvider}
supportedChain={supportedChain}
primaryWallet={primaryWallet}
/>
</div>
<Footer />
</div>
);
};

const Eip6963ConnectedContent = ({
selectedProvider,
supportedChain,
primaryWallet,
}: ConnectedContentProps) => {
const { switchChain } = useSwitchChain();

const handleNetworkSelect = (chain: SupportedChain) => {
Expand Down Expand Up @@ -43,9 +89,30 @@ export function ConnectedContent({
<MessageFlowCard
selectedProvider={selectedProvider}
supportedChain={supportedChain}
primaryWallet={primaryWallet}
/>
</div>
<Footer />
</div>
);
};

export function ConnectedContent({
selectedProvider,
supportedChain,
primaryWallet,
}: ConnectedContentProps) {
return USE_DYNAMIC_WALLET ? (
<DynamicConnectedContent
selectedProvider={selectedProvider}
supportedChain={supportedChain}
primaryWallet={primaryWallet}
/>
) : (
<Eip6963ConnectedContent
selectedProvider={selectedProvider}
supportedChain={supportedChain}
primaryWallet={primaryWallet}
/>
);
}
10 changes: 8 additions & 2 deletions examples/hello/frontend/src/DisconnectedContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import './DisconnectedContent.css';

import { ConnectWallet } from './components/ConnectWallet';
import { ConnectDynamicWallet } from './components/ConnectDynamicWallet';
import { ConnectEip6963Wallet } from './components/ConnectEip6963Wallet';
import { IconAnimation } from './components/icons/IconAnimation';
import { IconZetaChainLogo } from './components/icons/IconZetaChainLogo';
import { USE_DYNAMIC_WALLET } from './constants/wallets';
import { Footer } from './Footer';

export function DisconnectedContent() {
Expand All @@ -21,7 +23,11 @@ export function DisconnectedContent() {
Connect your EVM wallet and trigger the Universal Hello contract on
ZetaChain testnet from any currently supported EVM chain.
</p>
<ConnectWallet />
{USE_DYNAMIC_WALLET ? (
<ConnectDynamicWallet />
) : (
<ConnectEip6963Wallet />
)}
</div>
<div className="hero-content-animation">
<IconAnimation />
Expand Down
30 changes: 30 additions & 0 deletions examples/hello/frontend/src/DynamicAppContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useUniversalSignInContext } from '@zetachain/wallet/react';

import { ConnectedContent } from './ConnectedContent';
import { SUPPORTED_CHAINS } from './constants/chains';
import { DisconnectedContent } from './DisconnectedContent';

export function DynamicAppContent() {
const { primaryWallet, network } = useUniversalSignInContext();

const account = primaryWallet?.address || null;
const decimalChainId = network || null;

const supportedChain = SUPPORTED_CHAINS.find(
(chain) => chain.chainId === decimalChainId
);

const isDisconnected = !account;

if (isDisconnected) {
return <DisconnectedContent />;
}

return (
<ConnectedContent
selectedProvider={null}
supportedChain={supportedChain}
primaryWallet={primaryWallet}
/>
);
}
25 changes: 25 additions & 0 deletions examples/hello/frontend/src/Eip6963AppContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ConnectedContent } from './ConnectedContent';
import { SUPPORTED_CHAINS } from './constants/chains';
import { DisconnectedContent } from './DisconnectedContent';
import { useEip6963Wallet } from './hooks/useEip6963Wallet';

export function Eip6963AppContent() {
const { selectedProvider, decimalChainId } = useEip6963Wallet();

const supportedChain = SUPPORTED_CHAINS.find(
(chain) => chain.chainId === decimalChainId
);

const isDisconnected = !selectedProvider;

if (isDisconnected) {
return <DisconnectedContent />;
}

return (
<ConnectedContent
selectedProvider={selectedProvider}
supportedChain={supportedChain}
/>
);
}
28 changes: 18 additions & 10 deletions examples/hello/frontend/src/MessageFlowCard.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import './MessageFlowCard.css';

import { evmCall } from '@zetachain/toolkit/chains/evm';
import { ethers, ZeroAddress } from 'ethers';
import { type PrimaryWallet } from '@zetachain/wallet';
import { ZeroAddress } from 'ethers';
import { useEffect, useRef, useState } from 'react';

import { Button } from './components/Button';
import { IconApprove, IconEnvelope, IconSendTitle } from './components/icons';
import { ConfirmedContent } from './ConfirmedContent';
import type { SupportedChain } from './constants/chains';
import { HELLO_UNIVERSAL_CONTRACT_ADDRESS } from './constants/contracts';
import type { EIP6963ProviderDetail } from './types/wallet';
import { getSignerAndProvider } from './utils/ethersHelpers';
import { formatNumberWithLocale } from './utils/formatNumber';

interface MessageFlowCardProps {
selectedProvider: EIP6963ProviderDetail;
selectedProvider: EIP6963ProviderDetail | null;
supportedChain: SupportedChain | undefined;
primaryWallet?: PrimaryWallet | null; // Dynamic wallet from context
}

export function MessageFlowCard({
selectedProvider,
supportedChain,
primaryWallet = null,
}: MessageFlowCardProps) {

const MAX_STRING_LENGTH = 2000;
const [isUserSigningTx, setIsUserSigningTx] = useState(false);
const [isTxReceiptLoading, setIsTxReceiptLoading] = useState(false);
Expand All @@ -33,17 +39,19 @@ export function MessageFlowCard({

const handleEvmCall = async () => {
try {
const ethersProvider = new ethers.BrowserProvider(
selectedProvider.provider
);
const signer =
(await ethersProvider.getSigner()) as ethers.AbstractSigner;
const signerAndProvider = await getSignerAndProvider({
selectedProvider,
primaryWallet,
});

if (!signerAndProvider) {
throw new Error('Failed to get signer');
}

const helloUniversalContractAddress =
'0x61a184EB30D29eD0395d1ADF38CC7d2F966c4A82';
const { signer } = signerAndProvider;

const evmCallParams = {
receiver: helloUniversalContractAddress,
receiver: HELLO_UNIVERSAL_CONTRACT_ADDRESS,
types: ['string'],
values: [stringValue],
revertOptions: {
Expand Down
Loading