diff --git a/mobile/app/[account]/remove.tsx b/mobile/app/[account]/remove.tsx index 63d96764..7a1205c9 100644 --- a/mobile/app/[account]/remove.tsx +++ b/mobile/app/[account]/remove.tsx @@ -2,10 +2,11 @@ import { selectFollowers } from "redux/features/profileSlice"; import { logedOut, useAppDispatch, useAppSelector } from "@gno/redux"; import { User } from "@gno/types"; import RemoveAccountContent from "@gno/components/view/account/remove-account.tsx"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; + export default function Page() { - const gno = useGno(); + const gno = useGnoNativeContext(); const dispatch = useAppDispatch(); const data = useAppSelector(selectFollowers); diff --git a/mobile/app/_layout.tsx b/mobile/app/_layout.tsx index d0bca23a..45dba56e 100644 --- a/mobile/app/_layout.tsx +++ b/mobile/app/_layout.tsx @@ -10,21 +10,29 @@ import { Provider } from "react-redux"; import { DefaultTheme, ThemeProvider } from "@react-navigation/native"; import { store } from "@gno/redux"; import { Guard } from "@gno/components/auth/guard"; +import { GnoNativeProvider } from "@gnolang/gnonative"; + +const gnoDefaultConfig = { + remote: process.env.EXPO_PUBLIC_GNO_REMOTE!, + chain_id: process.env.EXPO_PUBLIC_GNO_CHAIN_ID!, +}; export default function AppLayout() { return ( - - - - - - - + + + + + + + + + ); } diff --git a/mobile/app/home/feed.tsx b/mobile/app/home/feed.tsx index b44196fd..077a1614 100644 --- a/mobile/app/home/feed.tsx +++ b/mobile/app/home/feed.tsx @@ -28,8 +28,8 @@ export default function Page() { setError(undefined); setIsLoading(true); try { - const total = await feed.fetchCount(); - setTotalPosts(total); + // const total = await feed.fetchCount(); + // setTotalPosts(total); } catch (error) { console.error(error); } finally { diff --git a/mobile/app/home/profile.tsx b/mobile/app/home/profile.tsx index 25e6a481..2130b370 100644 --- a/mobile/app/home/profile.tsx +++ b/mobile/app/home/profile.tsx @@ -1,7 +1,7 @@ import { StyleSheet, View } from "react-native"; import { router, useNavigation } from "expo-router"; import { useEffect, useState } from "react"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { logedOut, useAppDispatch } from "@gno/redux"; import Button from "@gno/components/button"; import useOnboarding from "@gno/hooks/use-onboarding"; @@ -19,7 +19,7 @@ export default function Page() { const [remote, setRemote] = useState(""); const [followersCount, setFollowersCount] = useState({ n_followers: 0, n_following: 0 }); - const gno = useGno(); + const gno = useGnoNativeContext(); const search = useSearch(); const navigation = useNavigation(); const dispatch = useAppDispatch(); diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx index 0d17492f..00eb3986 100644 --- a/mobile/app/index.tsx +++ b/mobile/app/index.tsx @@ -8,9 +8,9 @@ import ReenterPassword from "@gno/components/modal/reenter-password"; import { Spacer } from "@gno/components/row"; import Ruller from "@gno/components/row/Ruller"; import Text from "@gno/components/text"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; import { loggedIn, useAppDispatch } from "@gno/redux"; import { KeyInfo } from "@buf/gnolang_gnonative.bufbuild_es/gnonativetypes_pb"; +import { useGnoNativeContext } from "@gnolang/gnonative"; export default function Root() { const route = useRouter(); @@ -19,7 +19,7 @@ export default function Root() { const [loading, setLoading] = useState(undefined); const [reenterPassword, setReenterPassword] = useState(undefined); - const gno = useGno(); + const gno = useGnoNativeContext(); const navigation = useNavigation(); const dispatch = useAppDispatch(); @@ -51,7 +51,8 @@ export default function Root() { return; } - dispatch(loggedIn(keyInfo)); + const bech32 = await gno.addressToBech32(keyInfo.address); + await dispatch(loggedIn({ keyInfo, bech32 })); setTimeout(() => route.replace("/home"), 500); } catch (error: unknown | Error) { setLoading(error?.toString()); @@ -61,7 +62,8 @@ export default function Root() { const onCloseReenterPassword = async (sucess: boolean) => { if (sucess && reenterPassword) { - dispatch(loggedIn(reenterPassword)); + const bech32 = await gno.addressToBech32(reenterPassword.address); + await dispatch(loggedIn({ keyInfo: reenterPassword, bech32 })); setTimeout(() => route.replace("/home"), 500); } setReenterPassword(undefined); diff --git a/mobile/app/post/[post_id].tsx b/mobile/app/post/[post_id].tsx index b5c84cd2..56e7f159 100644 --- a/mobile/app/post/[post_id].tsx +++ b/mobile/app/post/[post_id].tsx @@ -7,7 +7,7 @@ import TextInput from "@gno/components/textinput"; import Button from "@gno/components/button"; import Spacer from "@gno/components/spacer"; import Alert from "@gno/components/alert"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { Tweet } from "@gno/components/feed/tweet"; import { FlatList } from "react-native"; import { Post } from "@gno/types"; @@ -20,7 +20,7 @@ function Page() { const post = useAppSelector(selectPostToReply); const thread = useAppSelector(selectReplyThread); const router = useRouter(); - const gno = useGno(); + const gno = useGnoNativeContext(); const onPressReply = async () => { if (!post) return; diff --git a/mobile/app/post/index.tsx b/mobile/app/post/index.tsx index 90329dbf..49974040 100644 --- a/mobile/app/post/index.tsx +++ b/mobile/app/post/index.tsx @@ -5,18 +5,17 @@ import Layout from "@gno/components/layout"; import Spacer from "@gno/components/spacer"; import Text from "@gno/components/text"; import TextInput from "@gno/components/textinput"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { Stack, useNavigation, useRouter } from "expo-router"; import { useEffect, useState } from "react"; -import { ScrollView, StyleSheet, View } from "react-native"; +import { StyleSheet } from "react-native"; export default function Search() { const [postContent, setPostContent] = useState(""); const [error, setError] = useState(undefined); const [loading, setLoading] = useState(false); - const [account, setAccount] = useState(undefined); - const gno = useGno(); + const gno = useGnoNativeContext(); const navigation = useNavigation(); const router = useRouter(); @@ -26,7 +25,6 @@ export default function Search() { try { const response = await gno.getActiveAccount(); if (!response.key) throw new Error("No active account"); - setAccount(response.key); } catch (error: unknown | Error) { console.log(error); } diff --git a/mobile/app/sign-up.tsx b/mobile/app/sign-up.tsx index 44d8b453..6ecfbf1f 100644 --- a/mobile/app/sign-up.tsx +++ b/mobile/app/sign-up.tsx @@ -5,11 +5,11 @@ import TextInput from "components/textinput"; import Button from "components/button"; import Spacer from "components/spacer"; import * as Clipboard from "expo-clipboard"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; import { useAppDispatch, loggedIn } from "@gno/redux"; import Alert from "@gno/components/alert"; import useOnboarding from "@gno/hooks/use-onboarding"; import Layout from "@gno/components/layout"; +import { useGnoNativeContext } from "@gnolang/gnonative"; export default function Page() { const [name, setName] = useState(""); @@ -21,7 +21,7 @@ export default function Page() { const inputRef = useRef(null); const navigation = useNavigation(); - const gno = useGno(); + const gno = useGnoNativeContext(); const dispatch = useAppDispatch(); const onboarding = useOnboarding(); @@ -63,20 +63,15 @@ export default function Page() { try { setLoading(true); - const response = await gno.createAccount(name, phrase, password); - if (!response) throw new Error("Failed to create account"); - console.log("createAccount response: " + JSON.stringify(response)); + const newAccount = await gno.createAccount(name, phrase, password); + if (!newAccount) throw new Error("Failed to create account"); + console.log("createAccount response: " + JSON.stringify(newAccount)); await gno.selectAccount(name); await gno.setPassword(password); - - await gno.selectAccount(name); - await gno.setPassword(password); - await onboarding.onboard(response.name, response.address); - - dispatch(loggedIn(response)); - - await dispatch(loggedIn(response)); + await onboarding.onboard(newAccount.name, newAccount.address); + const bech32 = await gno.addressToBech32(newAccount.address); + await dispatch(loggedIn({ keyInfo: newAccount, bech32})); router.push("/home"); } catch (error) { setError("" + error); diff --git a/mobile/components/modal/reenter-password.tsx b/mobile/components/modal/reenter-password.tsx index 7f6cac2d..1f98e097 100644 --- a/mobile/components/modal/reenter-password.tsx +++ b/mobile/components/modal/reenter-password.tsx @@ -12,7 +12,7 @@ import { GRPCError } from "@gnolang/gnonative/src/grpc/error"; import { ErrCode } from "@buf/gnolang_gnonative.bufbuild_es/rpc_pb"; import Alert from "@gno/components/alert"; import { Spacer } from "@gno/components/row"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { ModalView } from "."; import TextInput from "../textinput"; import Text from "../text"; @@ -25,7 +25,7 @@ export type Props = { }; const ReenterPassword = ({ visible, accountName, onClose }: Props) => { - const gno = useGno(); + const gno = useGnoNativeContext(); const [password, setPassword] = useState(""); const [error, setError] = useState(undefined); diff --git a/mobile/components/settings/account/account-balance.tsx b/mobile/components/settings/account/account-balance.tsx index 546d9a8b..f8fa69e1 100644 --- a/mobile/components/settings/account/account-balance.tsx +++ b/mobile/components/settings/account/account-balance.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from "react"; import { KeyInfo } from "@buf/gnolang_gnonative.bufbuild_es/gnonativetypes_pb"; import Text from "@gno/components/text"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { useSearch } from "@gno/hooks/use-search"; interface Props { @@ -12,7 +12,7 @@ export function AccountBalance({ activeAccount }: Props) { const [address, setAddress] = useState(undefined); const [balance, setBalance] = useState(undefined); - const gno = useGno(); + const gno = useGnoNativeContext(); const account = useSearch(); useEffect(() => { diff --git a/mobile/redux/features/accountSlice.ts b/mobile/redux/features/accountSlice.ts index 92b7d43a..976269db 100644 --- a/mobile/redux/features/accountSlice.ts +++ b/mobile/redux/features/accountSlice.ts @@ -1,7 +1,7 @@ import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; import { User } from "@gno/types"; import { KeyInfo } from "@buf/gnolang_gnonative.bufbuild_es/gnonativetypes_pb"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; export interface CounterState { account?: User; @@ -11,10 +11,8 @@ const initialState: CounterState = { account: undefined, }; -export const loggedIn = createAsyncThunk("user/loggedIn", async (keyInfo: KeyInfo, thunkAPI) => { - const gno = useGno(); - - const bech32 = await gno.addressToBech32(keyInfo.address); +export const loggedIn = createAsyncThunk("user/loggedIn", async (param: { keyInfo: KeyInfo; bech32: string }, _) => { + const { keyInfo, bech32 } = param; const user: User = { address: bech32, name: keyInfo.name }; @@ -34,6 +32,9 @@ export const accountSlice = createSlice({ builder.addCase(loggedIn.fulfilled, (state, action) => { state.account = action.payload; }); + builder.addCase(loggedIn.rejected, (_, action) => { + console.error("loggedIn.rejected", action); + }); }, selectors: { diff --git a/mobile/src/hooks/use-feed.ts b/mobile/src/hooks/use-feed.ts index 19a40ea6..b377c095 100644 --- a/mobile/src/hooks/use-feed.ts +++ b/mobile/src/hooks/use-feed.ts @@ -1,10 +1,10 @@ import { Post, User } from "@gno/types"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; import { useUserCache } from "./use-user-cache"; import useGnoJsonParser from "./use-gno-json-parser"; export const useFeed = () => { - const gno = useGno(); + const gno = useGnoNativeContext(); const cache = useUserCache(); const parser = useGnoJsonParser(); diff --git a/mobile/src/hooks/use-onboarding.ts b/mobile/src/hooks/use-onboarding.ts index aedf3826..6850b00e 100644 --- a/mobile/src/hooks/use-onboarding.ts +++ b/mobile/src/hooks/use-onboarding.ts @@ -1,7 +1,7 @@ -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; const useOnboarding = () => { - const gno = useGno(); + const gno = useGnoNativeContext(); const onboard = async (name: string, address: Uint8Array) => { const address_bech32 = await gno.addressToBech32(address); @@ -16,7 +16,8 @@ const useOnboarding = () => { return; } - await sendCoins(address_bech32); + const response = await sendCoins(address_bech32); + console.log("sent coins %s", response); await registerAccount(name); } catch (error) { diff --git a/mobile/src/hooks/use-search.ts b/mobile/src/hooks/use-search.ts index d75e2d13..dcee6857 100644 --- a/mobile/src/hooks/use-search.ts +++ b/mobile/src/hooks/use-search.ts @@ -1,10 +1,10 @@ -import { Following, GetJsonFollowersResult, GetJsonFollowingResult, User } from "@gno/types"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { GetJsonFollowersResult, GetJsonFollowingResult, User } from "@gno/types"; +import { useGnoNativeContext } from "@gnolang/gnonative"; const MAX_RESULT = 10; export const useSearch = () => { - const gno = useGno(); + const gno = useGnoNativeContext(); async function Follow(address: string) { checkActiveAccount(); @@ -84,7 +84,7 @@ export const useSearch = () => { } async function convertToJson(result: string | undefined) { - if (result === "(\"\" string)") return undefined; + if (result === '("" string)') return undefined; if (!result || !(result.startsWith("(") && result.endsWith(" string)"))) throw new Error("Malformed GetThreadPosts response"); const quoted = result.substring(1, result.length - " string)".length); @@ -102,7 +102,7 @@ export const useSearch = () => { return { searchUser, getJsonUserByName, - GetJsonFollowersCount, + GetJsonFollowersCount, GetJsonFollowing, GetJsonFollowers, Follow, diff --git a/mobile/src/hooks/use-user-cache.ts b/mobile/src/hooks/use-user-cache.ts index 6c82d998..62494eff 100644 --- a/mobile/src/hooks/use-user-cache.ts +++ b/mobile/src/hooks/use-user-cache.ts @@ -1,10 +1,10 @@ import { User } from "@gno/types"; -import { useGno } from "@gnolang/gnonative/src/hooks/use-gno"; +import { useGnoNativeContext } from "@gnolang/gnonative"; const usersCache = new Map(); export const useUserCache = () => { - const gno = useGno(); + const gno = useGnoNativeContext(); async function getUser(bech32: string): Promise { if (usersCache.has(bech32)) {