Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .changeset/chilly-mangos-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/react-native-adapter": minor
---

Updated required dependencies
7 changes: 7 additions & 0 deletions .changeset/soft-colts-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"thirdweb": minor
---

Support for enclave wallet migration in React Native

this change requires the latest version of the `@thirdweb-dev/react-native-adapter` package to be installed.
6 changes: 2 additions & 4 deletions packages/react-native-adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@
},
"./package.json": "./package.json"
},
"files": [
"dist/*",
"src/*"
],
"files": ["dist/*", "src/*"],
"dependencies": {
"@aws-sdk/client-kms": "3.670.0",
"@aws-sdk/client-lambda": "3.670.0",
"@aws-sdk/credential-providers": "3.670.0",
"@mobile-wallet-protocol/client": "0.0.3",
Expand Down
4 changes: 4 additions & 0 deletions packages/thirdweb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@
"@aws-sdk/client-lambda": {
"optional": true
},
"@aws-sdk/client-kms": {
"optional": true
},
"@aws-sdk/credential-providers": {
"optional": true
},
Expand Down Expand Up @@ -279,6 +282,7 @@
"node": ">=18"
},
"devDependencies": {
"@aws-sdk/client-kms": "3.670.0",
"@aws-sdk/client-lambda": "3.670.0",
"@aws-sdk/credential-providers": "3.670.0",
"@biomejs/biome": "1.9.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import type { ThirdwebClient } from "../../../../client/client.js";
import { resolveScheme } from "../../../../utils/ipfs.js";
import { nativeLocalStorage } from "../../../../utils/storage/nativeStorage.js";
import { getWalletInfo } from "../../../../wallets/__generated__/getWalletInfo.js";
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
Expand All @@ -25,10 +27,11 @@ import { RNImage } from "./RNImage.js";
export const WalletImage = (props: {
theme: Theme;
wallet: Wallet;
client: ThirdwebClient;
size: number;
avatar?: string | null;
}) => {
const { wallet, avatar, size } = props;
const { wallet, avatar, size, client } = props;

const { data: imageData } = useQuery({
queryKey: ["wallet-image", wallet.id, wallet.getAccount()?.address],
Expand All @@ -55,7 +58,7 @@ export const WalletImage = (props: {
try {
const externalWalletImage = await getWalletInfo(activeEOAId, true);
if (externalWalletImage) {
return externalWalletImage;
return resolveScheme({ client, uri: externalWalletImage });
}
} catch {}

Expand Down
21 changes: 19 additions & 2 deletions packages/thirdweb/src/react/native/ui/connect/ConnectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useCallback, useState } from "react";
import { Platform, StyleSheet, View } from "react-native";
import { SvgXml } from "react-native-svg";
import type { Chain } from "../../../../chains/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import type { MultiStepAuthProviderType } from "../../../../wallets/in-app/core/authentication/types.js";
import type { InAppWalletAuth } from "../../../../wallets/in-app/core/wallet/types.js";
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
Expand Down Expand Up @@ -269,6 +270,7 @@ export function ConnectModal(
<WalletLoadingView
theme={theme}
wallet={modalState.wallet}
client={client}
authProvider={modalState.authMethod}
/>
{containerType === "modal" ? (
Expand Down Expand Up @@ -328,6 +330,7 @@ export function ConnectModal(
)}
<SignInView
theme={theme}
client={client}
siweAuth={siweAuth}
onSignIn={() => props.onClose?.()}
onError={(error) => setModalState({ screen: "error", error })}
Expand Down Expand Up @@ -462,10 +465,12 @@ export function ConnectModal(
function WalletLoadingView({
theme,
wallet,
client,
authProvider,
}: {
theme: Theme;
wallet: Wallet;
client: ThirdwebClient;
authProvider?: InAppWalletAuth;
}) {
const walletInfo = useWalletInfo(wallet.id);
Expand Down Expand Up @@ -500,7 +505,12 @@ function WalletLoadingView({
/>
</View>
) : (
<WalletImage theme={theme} size={90} wallet={wallet} />
<WalletImage
theme={theme}
size={90}
wallet={wallet}
client={client}
/>
)}
</WalletLoadingThumbnail>
<Spacer size="xl" />
Expand All @@ -522,12 +532,14 @@ function WalletLoadingView({
function SignInView({
theme,
siweAuth,
client,
onSignIn,
onError,
onDisconnect,
}: {
theme: Theme;
siweAuth: ReturnType<typeof useSiweAuth>;
client: ThirdwebClient;
onSignIn: () => void;
onError: (error: string) => void;
onDisconnect: () => void;
Expand All @@ -552,7 +564,12 @@ function SignInView({
imageSize={100}
animate={isSigningIn}
>
<WalletImage theme={theme} size={90} wallet={wallet} />
<WalletImage
theme={theme}
size={90}
wallet={wallet}
client={client}
/>
</WalletLoadingThumbnail>
<Spacer size="xl" />
<ThemedText theme={theme} type="subtitle">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function ConnectedButton(
},
) {
const theme = parseTheme(props.theme);
const { account, wallet } = props;
const { account, wallet, client } = props;
const walletChain = useActiveWalletChain();
const { pfp, name, balanceQuery } = useConnectedWalletDetails(
props.client,
Expand All @@ -40,7 +40,13 @@ export function ConnectedButton(
}}
>
<View style={styles.row}>
<WalletImage theme={theme} size={40} wallet={wallet} avatar={pfp} />
<WalletImage
theme={theme}
size={40}
wallet={wallet}
avatar={pfp}
client={client}
/>
<View style={styles.col}>
<ThemedText
theme={theme}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export function ConnectedModal(props: ConnectedModalProps) {
<ReceiveScreen
account={props.account}
wallet={props.wallet}
client={props.client}
theme={theme}
containerType={props.containerType}
onBack={() => setModalState({ screen: "account" })}
Expand Down Expand Up @@ -161,7 +162,7 @@ export function ConnectedModal(props: ConnectedModalProps) {
}

const AccountHeader = (props: ConnectedModalProps) => {
const { account, wallet, theme } = props;
const { account, wallet, theme, client } = props;
const walletChain = useActiveWalletChain();
const { pfp, name, balanceQuery } = useConnectedWalletDetails(
props.client,
Expand All @@ -171,7 +172,13 @@ const AccountHeader = (props: ConnectedModalProps) => {
);
return (
<View style={styles.accountHeaderContainer}>
<WalletImage theme={theme} size={70} wallet={wallet} avatar={pfp} />
<WalletImage
theme={theme}
size={70}
wallet={wallet}
avatar={pfp}
client={client}
/>
<SmartAccountBadge client={props.client} theme={theme} />
<Spacer size="smd" />
<Address account={account} theme={theme} addressOrENS={name} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { StyleSheet, View } from "react-native";
import type { ThirdwebClient } from "../../../../client/client.js";
import { shortenAddress } from "../../../../utils/address.js";
import type { Account, Wallet } from "../../../../wallets/interfaces/wallet.js";
import type { Theme } from "../../../core/design-system/index.js";
Expand All @@ -16,10 +17,12 @@ type ReceiveScreenProps = {
onClose?: () => void;
onBack?: () => void;
containerType: ContainerType;
client: ThirdwebClient;
};

export const ReceiveScreen = (props: ReceiveScreenProps) => {
const { wallet, account, theme, onClose, onBack, containerType } = props;
const { wallet, account, theme, onClose, onBack, containerType, client } =
props;

return (
<>
Expand All @@ -32,7 +35,7 @@ export const ReceiveScreen = (props: ReceiveScreenProps) => {
/>
<View style={styles.container}>
{/* TODO (rn) QR code scanning */}
<WalletImage theme={theme} wallet={wallet} size={80} />
<WalletImage theme={theme} wallet={wallet} size={80} client={client} />
<Spacer size="lg" />
<View
style={[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { ThirdwebClient } from "../../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
import { getClientFetch } from "../../../../../utils/fetch.js";
import type { Ecosystem } from "../../../core/wallet/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import { getClientFetch } from "../../../../utils/fetch.js";
import type { UserWallet } from "../wallet/enclave-wallet.js";
import type { Ecosystem } from "../wallet/types.js";

/**
* Generate a new enclave wallet using an auth token
Expand Down Expand Up @@ -34,10 +35,7 @@ export async function generateWallet({
}

const { wallet } = (await response.json()) as {
wallet: {
address: string;
type: "enclave";
};
wallet: UserWallet;
};

return wallet;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { ThirdwebClient } from "../../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
import { getClientFetch } from "../../../../../utils/fetch.js";
import type { UserStatus } from "../../../core/wallet/enclave-wallet.js";
import type { Ecosystem } from "../../../core/wallet/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import { getClientFetch } from "../../../../utils/fetch.js";
import type { UserStatus } from "../wallet/enclave-wallet.js";
import type { Ecosystem } from "../wallet/types.js";

/**
* Gets the user's status from the backend.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import type { ThirdwebClient } from "../../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
import { getClientFetch } from "../../../../../utils/fetch.js";
import { stringify } from "../../../../../utils/json.js";
import type { ClientScopedStorage } from "../../../core/authentication/client-scoped-storage.js";
import type { Ecosystem } from "../../../core/wallet/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import { getClientFetch } from "../../../../utils/fetch.js";
import { stringify } from "../../../../utils/json.js";
import type { ClientScopedStorage } from "../authentication/client-scoped-storage.js";

export async function signMessage({
client,
ecosystem,
payload: { message, isRaw },
storage,
}: {
client: ThirdwebClient;
ecosystem?: Ecosystem;
payload: {
message: string;
isRaw: boolean;
};
storage: ClientScopedStorage;
}) {
const clientFetch = getClientFetch(client, ecosystem);
const authToken = await storage.getAuthCookie();
const ecosystem = storage.ecosystem;
const clientFetch = getClientFetch(client, ecosystem);

if (!authToken) {
throw new Error("No auth token found when signing message");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import type { ThirdwebClient } from "../../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
import type { Hex } from "../../../../../utils/encoding/hex.js";
import { getClientFetch } from "../../../../../utils/fetch.js";
import { stringify } from "../../../../../utils/json.js";
import type { ClientScopedStorage } from "../../../core/authentication/client-scoped-storage.js";
import type { Ecosystem } from "../../../core/wallet/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import type { Hex } from "../../../../utils/encoding/hex.js";
import { getClientFetch } from "../../../../utils/fetch.js";
import { stringify } from "../../../../utils/json.js";
import type { ClientScopedStorage } from "../authentication/client-scoped-storage.js";

export async function signTransaction({
client,
ecosystem,
payload,
storage,
}: {
client: ThirdwebClient;
ecosystem?: Ecosystem;
payload: Record<string, Hex | number | undefined>;
storage: ClientScopedStorage;
}) {
const clientFetch = getClientFetch(client, ecosystem);
const authToken = await storage.getAuthCookie();
const ecosystem = storage.ecosystem;
const clientFetch = getClientFetch(client, ecosystem);

if (!authToken) {
throw new Error("No auth token found when signing transaction");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
import type { TypedData } from "abitype";
import type { TypedDataDefinition } from "viem";
import type { ThirdwebClient } from "../../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../../utils/domains.js";
import { getClientFetch } from "../../../../../utils/fetch.js";
import { stringify } from "../../../../../utils/json.js";
import type { ClientScopedStorage } from "../../../core/authentication/client-scoped-storage.js";
import type { Ecosystem } from "../../../core/wallet/types.js";
import type { ThirdwebClient } from "../../../../client/client.js";
import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
import { getClientFetch } from "../../../../utils/fetch.js";
import { stringify } from "../../../../utils/json.js";
import type { ClientScopedStorage } from "../authentication/client-scoped-storage.js";

export async function signTypedData<
const typedData extends TypedData | Record<string, unknown>,
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
>({
client,
ecosystem,
payload,
storage,
}: {
client: ThirdwebClient;
ecosystem?: Ecosystem;
payload: TypedDataDefinition<typedData, primaryType>;
storage: ClientScopedStorage;
}) {
const clientFetch = getClientFetch(client, ecosystem);
const authToken = await storage.getAuthCookie();
const ecosystem = storage.ecosystem;
const clientFetch = getClientFetch(client, ecosystem);

if (!authToken) {
throw new Error("No auth token found when signing typed data");
Expand Down
Loading
Loading