diff --git a/examples/react-native/package.json b/examples/react-native/package.json index 8ffb84f106..e68e61fe70 100644 --- a/examples/react-native/package.json +++ b/examples/react-native/package.json @@ -32,8 +32,7 @@ "react-native-modal": "^13.0.1", "react-native-svg": "^13.14.0", "react-native-web": "^0.19.11", - "react-native-windows": "^0.73.11", - "viem": "^2.9.26" + "react-native-windows": "^0.73.11" }, "devDependencies": { "@babel/core": "^7.24.4", diff --git a/examples/react-native/src/App.tsx b/examples/react-native/src/App.tsx index 78364e7650..7e2c5a0fde 100644 --- a/examples/react-native/src/App.tsx +++ b/examples/react-native/src/App.tsx @@ -4,42 +4,33 @@ import { config } from '@gluestack-ui/config'; import { Box, GluestackUIProvider, SafeAreaView } from '@gluestack-ui/themed'; import { LensConfig, LensProvider } from '@lens-protocol/react-native'; import { storage } from '@lens-protocol/react-native/storage/mmkv'; -import { useWalletConnectModal, IProvider } from '@walletconnect/modal-react-native'; -import React, { useMemo } from 'react'; -import { createWalletClient, custom, WalletClient } from 'viem'; +import { IProvider, useWalletConnectModal } from '@walletconnect/modal-react-native'; +import React, { useEffect, useRef } from 'react'; import { ConnectButton } from './components/ConnectButton'; import { Main } from './components/Main'; import { WalletConnectModal } from './components/WalletConnectModal'; -import { getLensEnvironment, getViemChain } from './utils/environment'; -import { bindings } from './utils/wallet'; - -type RequestArguments = Parameters[0]; +import { Deferred } from './utils/Deferred'; +import { bindings } from './utils/bindings'; +import { getLensEnvironment } from './utils/environment'; export function App() { const { provider } = useWalletConnectModal(); - const walletClient: WalletClient = useMemo( - () => - createWalletClient({ - chain: getViemChain(), - transport: custom({ - async request({ method, params }: RequestArguments) { - return provider?.request({ method, params }); - }, - }), - }), - [provider], - ); + const deferred = useRef(new Deferred()); - const lensConfig: LensConfig = useMemo( - () => ({ - bindings: bindings(walletClient), - environment: getLensEnvironment(), - storage: storage(), - }), - [walletClient], - ); + useEffect(() => { + if (provider) { + deferred.current.resolve(provider); + } + }, [provider]); + + const lensConfig: LensConfig = { + bindings: bindings(deferred.current.promise), + environment: getLensEnvironment(), + storage: storage(), + origin: 'https://nativelens.com', + }; return ( diff --git a/examples/react-native/src/components/ConnectButton.tsx b/examples/react-native/src/components/ConnectButton.tsx index 56d0daf8b8..fa4652eaec 100644 --- a/examples/react-native/src/components/ConnectButton.tsx +++ b/examples/react-native/src/components/ConnectButton.tsx @@ -1,14 +1,17 @@ import '@walletconnect/react-native-compat'; import { Button, ButtonText } from '@gluestack-ui/themed'; +import { useLogout } from '@lens-protocol/react-native'; import { useWalletConnectModal } from '@walletconnect/modal-react-native'; import React from 'react'; export function ConnectButton() { const { open, isConnected, provider } = useWalletConnectModal(); + const { execute: logout } = useLogout(); const onPress = () => { if (isConnected && provider) { void provider.disconnect(); + void logout(); } else { void open(); } diff --git a/examples/react-native/src/components/LoginForm.tsx b/examples/react-native/src/components/LoginForm.tsx index 36226e57eb..4aff17d90a 100644 --- a/examples/react-native/src/components/LoginForm.tsx +++ b/examples/react-native/src/components/LoginForm.tsx @@ -35,7 +35,7 @@ export function LoginForm({ address }: LoginFormProps) { Select a profile to log in - + {profiles.map((profile) => ( ))} diff --git a/examples/react-native/src/components/LogoutButton.tsx b/examples/react-native/src/components/LogoutButton.tsx deleted file mode 100644 index 9d770f65eb..0000000000 --- a/examples/react-native/src/components/LogoutButton.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Button, ButtonText } from '@gluestack-ui/themed'; -import { useLogout } from '@lens-protocol/react-native'; -import React from 'react'; - -export function LogoutButton() { - const { execute: logout, loading } = useLogout(); - - return ( - - ); -} diff --git a/examples/react-native/src/components/Main.tsx b/examples/react-native/src/components/Main.tsx index 43b507868e..2227a90d51 100644 --- a/examples/react-native/src/components/Main.tsx +++ b/examples/react-native/src/components/Main.tsx @@ -5,7 +5,6 @@ import React from 'react'; import { ErrorCallout } from './ErrorCallout'; import { LoginForm } from './LoginForm'; -import { LogoutButton } from './LogoutButton'; import { MyProfile } from './MyProfile'; export function Main() { @@ -44,7 +43,6 @@ export function Main() { Welcome {session.address}, you need a Profile to use this app. - ); } diff --git a/examples/react-native/src/components/MyProfile.tsx b/examples/react-native/src/components/MyProfile.tsx index 033bd1123a..d588c48903 100644 --- a/examples/react-native/src/components/MyProfile.tsx +++ b/examples/react-native/src/components/MyProfile.tsx @@ -12,8 +12,6 @@ import { import { Profile } from '@lens-protocol/react-native'; import React from 'react'; -import { LogoutButton } from './LogoutButton'; - type ProfileAvatarProps = { profile: Profile; }; @@ -34,6 +32,7 @@ function ProfileAvatar({ profile }: ProfileAvatarProps) { source={{ uri, }} + alt="profile image" /> )} @@ -94,10 +93,6 @@ export function MyProfile({ profile }: MyProfileProps) { following - - - - ); } diff --git a/examples/react-native/src/utils/Deferred.ts b/examples/react-native/src/utils/Deferred.ts new file mode 100644 index 0000000000..94765a03ea --- /dev/null +++ b/examples/react-native/src/utils/Deferred.ts @@ -0,0 +1,15 @@ +/** + * Unwraps the promise to allow resolving/rejecting outside the Promise constructor + */ +export class Deferred { + readonly promise: Promise; + resolve!: (value: T) => void; + reject!: (reason?: unknown) => void; + + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } +} diff --git a/examples/react-native/src/utils/bindings.ts b/examples/react-native/src/utils/bindings.ts new file mode 100644 index 0000000000..6b819dd3d6 --- /dev/null +++ b/examples/react-native/src/utils/bindings.ts @@ -0,0 +1,28 @@ +import { JsonRpcProvider, JsonRpcSigner, Web3Provider } from '@ethersproject/providers'; +import { IBindings } from '@lens-protocol/react-native'; +import { IProvider } from '@walletconnect/modal-react-native'; + +export function bindings(providerPromise: Promise): IBindings { + return { + getProvider: async (): Promise => { + const provider = await providerPromise; + + if (!provider) { + throw new Error('Provider not defined'); + } + + return new Web3Provider(provider); + }, + getSigner: async (): Promise => { + const provider = await providerPromise; + + if (!provider) { + throw new Error('Provider not defined'); + } + + const ethersProvider = new Web3Provider(provider); + + return ethersProvider.getSigner(); + }, + }; +} diff --git a/examples/react-native/src/utils/environment.ts b/examples/react-native/src/utils/environment.ts index 07cac3a942..33da028817 100644 --- a/examples/react-native/src/utils/environment.ts +++ b/examples/react-native/src/utils/environment.ts @@ -1,6 +1,5 @@ import { EnvironmentConfig, development, production } from '@lens-protocol/react-native'; import Config from 'react-native-config'; -import { polygon, polygonAmoy } from 'viem/chains'; const environment = Config.ENVIRONMENT || 'development'; @@ -25,14 +24,3 @@ export function getLensEnvironment(): EnvironmentConfig { throw new Error(`Unknown environment ${environment}`); } } - -export function getViemChain() { - switch (environment) { - case 'production': - return polygon; - case 'development': - return polygonAmoy; - default: - throw new Error(`Unknown environment ${environment}`); - } -} diff --git a/examples/react-native/src/utils/wallet.ts b/examples/react-native/src/utils/wallet.ts deleted file mode 100644 index 4c2ab6d5df..0000000000 --- a/examples/react-native/src/utils/wallet.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { JsonRpcProvider, Web3Provider } from '@ethersproject/providers'; -import { IBindings } from '@lens-protocol/react-native'; -import { WalletClient } from 'viem'; - -function clientToProvider(client: WalletClient): JsonRpcProvider { - if (!client.chain) { - throw new Error('Chain not defined'); - } - - const network = { - chainId: client.chain.id, - name: client.chain.name, - ensAddress: client.chain.contracts?.ensRegistry?.address ?? '', - }; - - if (!client.chain) { - return new JsonRpcProvider(client.transport.url as string); - } - - return new JsonRpcProvider(client.transport.url as string, network); -} - -function clientToSigner(client: WalletClient) { - const provider = new Web3Provider(client.transport, 'any'); - - return provider.getSigner(client.account?.address); -} - -export function bindings(client: WalletClient): IBindings { - return { - getProvider: async () => clientToProvider(client), - getSigner: async () => clientToSigner(client), - }; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ccee6bdc05..860798ede8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -227,9 +227,6 @@ importers: react-native-windows: specifier: ^0.73.11 version: 0.73.11(@babel/core@7.24.4)(@babel/preset-env@7.24.4)(react-native@0.73.7)(react@18.2.0) - viem: - specifier: ^2.9.26 - version: 2.9.26(typescript@5.4.5) devDependencies: '@babel/core': specifier: ^7.24.4 @@ -8004,7 +8001,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 18.18.12 + '@types/node': 20.12.7 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -8124,7 +8121,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.20 - '@types/node': 18.18.12 + '@types/node': 20.12.7 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -12455,7 +12452,7 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 18.18.12 + '@types/node': 20.12.7 '@types/responselike': 1.0.3 dev: true @@ -12468,7 +12465,7 @@ packages: /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 /@types/debug@4.1.12: resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -12497,7 +12494,7 @@ packages: /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 dev: true /@types/har-format@1.2.15: @@ -12564,7 +12561,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 dev: true /@types/level-errors@3.0.2: @@ -12693,7 +12690,7 @@ packages: /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 dev: true /@types/scheduler@0.16.8: @@ -12702,7 +12699,7 @@ packages: /@types/secp256k1@4.0.6: resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 /@types/seedrandom@3.0.1: resolution: {integrity: sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==} @@ -12748,12 +12745,12 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 18.18.12 + '@types/node': 20.12.7 dev: true /@types/yargs-parser@21.0.3: @@ -20988,7 +20985,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.18.12 + '@types/node': 20.12.7 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -21149,7 +21146,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 18.18.12 + '@types/node': 20.12.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -21269,7 +21266,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.18.12 + '@types/node': 20.12.7 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -21300,7 +21297,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.18.12 + '@types/node': 20.12.7 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -21387,7 +21384,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.18.12 + '@types/node': 20.12.7 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -24664,7 +24661,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 18.18.12 + '@types/node': 20.12.7 long: 5.2.3 /proxy-compare@2.5.1: @@ -28394,29 +28391,6 @@ packages: - zod dev: false - /viem@2.9.26(typescript@5.4.5): - resolution: {integrity: sha512-WWYsZfxDsvVsbQF9v3i0M7A2TYTtQl+pwiF5UP8/5dr15XEMGB0MJDhH3esU7jJnBd/JMjkJH/DQRAKuqYS23Q==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@adraffy/ens-normalize': 1.10.0 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@scure/bip32': 1.3.2 - '@scure/bip39': 1.2.1 - abitype: 1.0.0(typescript@5.4.5) - isows: 1.0.3(ws@8.13.0) - typescript: 5.4.5 - ws: 8.13.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - dev: false - /vite-plugin-node-polyfills@0.9.0(vite@4.5.0): resolution: {integrity: sha512-+i+WPUuIBhJy+ODfxx6S6FTl28URCxUszbl/IL4GwrZvbqqY/8VDIp+zpjMS8Us/a7GwN4Iaqr/fVIBtkNQojQ==} peerDependencies: