diff --git a/mobile/README.md b/mobile/README.md
index 9114550..9709f23 100644
--- a/mobile/README.md
+++ b/mobile/README.md
@@ -125,3 +125,34 @@ make android
# to start Metro Bundler:
make start
```
+
+## Inter App communication
+
+dSocial and Gnokey mobile app are using `expo-linking` to exchange data.
+So that way you can signin or sign a transaction using Gnokey mobile app.
+
+### Sign in
+
+Example of dSocial asking for sign in
+```
+land.gno.gnokey://tologin?callback=tech.berty.dsocial%3A%2F%2Flogin-callback
+```
+- Base url: `land.gno.gnokey://tologin`
+- Parameters:
+ - callback: the url that Gnokey mobile will call after the user selecting the account.
+
+
+### Sign a transaction
+Example of dSocial asking Gnokey Mobile to sign a transaction:
+```
+land.gno.gnokey://tosign?tx=%257B%2522msg%2522%253A%255B%257B%2522%2540type%2522%253A%2522%252Fvm.m_call%2522%252C%2522caller%2522%253A%2522g1gl0hrpuegawx6pv24xjq8jjmufzp5r5mnn896w%2522%252C%2522send%2522%253A%2522%2522%252C%2522pkg_path%2522%253A%2522gno.land%252Fr%252Fberty%252Fsocial%2522%252C%2522func%2522%253A%2522PostMessage%2522%252C%2522args%2522%253A%255B%2522Test%25203%2522%255D%257D%255D%252C%2522fee%2522%253A%257B%2522gas_wanted%2522%253A%252210000000%2522%252C%2522gas_fee%2522%253A%25221000000ugnot%2522%257D%252C%2522signatures%2522%253Anull%252C%2522memo%2522%253A%2522%2522%257D&address=g1gl0hrpuegawx6pv24xjq8jjmufzp5r5mnn896w&client_name=dSocial&reason=Post%20a%20message&callback=tech.berty.dsocial%253A%252F%252Fpost
+```
+
+- Base url: `land.gno.gnokey://tosign`
+- Parameters:
+ - tx: the json result of `gnonative.makeCallTx(...)`
+ - address: bech32 address of whoever you want to sign the transaction.
+ - client_name: the name of the application that is calling the Gnokey mobile application. It will be displayed to the user.
+ - reason: the reason behind this action. It will be displayed to the user.
+ - callback: the callback URL that will be called from Gnokey mobile after signing the tx.
+
diff --git a/mobile/app/(app)/home/home.tsx b/mobile/app/(app)/home/home.tsx
index d01ca58..31118dd 100644
--- a/mobile/app/(app)/home/home.tsx
+++ b/mobile/app/(app)/home/home.tsx
@@ -3,7 +3,7 @@ import { FlatList, TouchableOpacity, View } from "react-native";
import { useNavigation, useRouter } from "expo-router";
import { Layout } from "@/components/index";
import Text from "@/components/text";
-import { selectMasterPassword, selectTxInput, useAppDispatch, useAppSelector } from "@/redux";
+import { selectMasterPassword, useAppDispatch, useAppSelector } from "@/redux";
import { KeyInfo, useGnoNativeContext } from "@gnolang/gnonative";
import Octicons from '@expo/vector-icons/Octicons';
import TextInput from "@/components/textinput";
@@ -22,7 +22,6 @@ export default function Page() {
const { gnonative } = useGnoNativeContext();
const navigation = useNavigation();
const dispatch = useAppDispatch();
- const txInput = useAppSelector(selectTxInput);
const masterPassword = useAppSelector(selectMasterPassword)
useEffect(() => {
diff --git a/mobile/app/(app)/tologin/index.tsx b/mobile/app/(app)/tologin/index.tsx
index e162d00..5f083cb 100644
--- a/mobile/app/(app)/tologin/index.tsx
+++ b/mobile/app/(app)/tologin/index.tsx
@@ -3,10 +3,10 @@ import Button from "@/components/button";
import VaultListItem from "@/components/list/vault-list/VaultListItem";
import Spacer from "@/components/spacer";
import Text from "@/components/text";
-import { selectCallback, sendAddressToSoliciting, useAppDispatch, useAppSelector } from "@/redux";
+import { clearLinking, selectCallback, sendAddressToSoliciting, useAppDispatch, useAppSelector } from "@/redux";
import { KeyInfo, useGnoNativeContext } from "@gnolang/gnonative";
import { router, useNavigation } from "expo-router";
-import { useCallback, useEffect, useMemo, useState } from "react";
+import { useCallback, useEffect, useState } from "react";
import { FlatList } from "react-native";
export default function Page() {
@@ -41,6 +41,11 @@ export default function Page() {
router.push("/home")
}, [callback]);
+ const onCancel = () => {
+ dispatch(clearLinking())
+ router.push("/home")
+ }
+
return (
<>
@@ -58,7 +63,7 @@ export default function Page() {
ListEmptyComponent={There are no items to list.}
/>
)}
- router.push("/home")}>
+
>
diff --git a/mobile/app/(app)/tosign/index.tsx b/mobile/app/(app)/tosign/index.tsx
index 3dbad3b..3dbd978 100644
--- a/mobile/app/(app)/tosign/index.tsx
+++ b/mobile/app/(app)/tosign/index.tsx
@@ -2,7 +2,7 @@ import { Layout } from "@/components";
import Button from "@/components/button";
import Spacer from "@/components/spacer";
import Text from "@/components/text";
-import { selectClientName, selectBech32Address, selectTxInput, signTx, useAppDispatch, useAppSelector, reasonSelector, selectCallback, selectKeyInfo } from "@/redux";
+import { selectClientName, selectBech32Address, selectTxInput, signTx, useAppDispatch, useAppSelector, reasonSelector, selectCallback, selectKeyInfo, clearLinking } from "@/redux";
import { useGnoNativeContext } from "@gnolang/gnonative";
import { router } from "expo-router";
import { useEffect, useState } from "react";
@@ -48,6 +48,11 @@ export default function Page() {
router.push("/home")
}
+ const onCancel = () => {
+ dispatch(clearLinking());
+ router.push("/home")
+ }
+
return (
<>
@@ -66,7 +71,7 @@ export default function Page() {
- router.push("/home")}>
+
>
diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx
index 7be6264..19d7887 100644
--- a/mobile/app/index.tsx
+++ b/mobile/app/index.tsx
@@ -3,7 +3,7 @@ import { ScrollView, View } from "react-native";
import { useRouter } from "expo-router";
import { Layout } from "@/components/index";
import Text from "@/components/text";
-import { getInitialState, selectInitialized, selectMasterPassword, selectPath, signIn, signUp, useAppDispatch, useAppSelector } from "@/redux";
+import { getInitialState, selectAction, selectInitialized, selectMasterPassword, signIn, signUp, useAppDispatch, useAppSelector } from "@/redux";
import * as Application from "expo-application";
import SignInView from "@/views/signin";
import SignUpView from "@/views/signup";
@@ -19,7 +19,7 @@ export default function Root() {
const appInitialized = useAppSelector(selectInitialized)
const hasMasterPassword = useAppSelector(selectMasterPassword)
- const path = useAppSelector(selectPath);
+ const action = useAppSelector(selectAction);
useEffect(() => {
dispatch(getInitialState())
@@ -50,9 +50,8 @@ export default function Root() {
};
const naviateTo = () => {
- console.log("path", path);
- if (path) {
- route.replace(path as string);
+ if (action) {
+ route.replace(action);
} else {
route.replace("/home");
}
diff --git a/mobile/package.json b/mobile/package.json
index 52963ba..813aa4f 100644
--- a/mobile/package.json
+++ b/mobile/package.json
@@ -1,7 +1,7 @@
{
"name": "gnokey",
"version": "0.0.1",
- "main": "expo-router/entry",
+ "main": "index.ts",
"scripts": {
"start": "expo start -d",
"android": "expo run:android",
diff --git a/mobile/redux/features/linkingSlice.ts b/mobile/redux/features/linkingSlice.ts
index 4e3c9ea..9ddfd6a 100644
--- a/mobile/redux/features/linkingSlice.ts
+++ b/mobile/redux/features/linkingSlice.ts
@@ -14,6 +14,7 @@ interface CounterState {
callback?: string;
/* The path of the requested screen */
path?: string | 'tologin';
+ hostname?: string;
}
const initialState: CounterState = {
@@ -23,6 +24,7 @@ const initialState: CounterState = {
txInput: undefined,
callback: undefined,
path: undefined,
+ hostname: undefined,
};
/**
@@ -76,6 +78,7 @@ interface SetLinkResponse {
callback?: string;
path: string;
keyinfo?: KeyInfo;
+ hostname?: string;
}
export const setLinkingData = createAsyncThunk("linking/setLinkingData", async (parsedURL, thunkAPI) => {
@@ -98,12 +101,13 @@ export const setLinkingData = createAsyncThunk {
+ console.log("clearing linking data");
+ state = { ...initialState };
+ },
+ },
extraReducers: (builder) => {
builder.addCase(setLinkingData.fulfilled, (state, action) => {
state.reason = action.payload.reason;
@@ -121,6 +130,7 @@ export const linkingSlice = createSlice({
state.callback = action.payload.callback;
state.path = action.payload.path;
state.keyinfo = action.payload.keyinfo;
+ state.hostname = action.payload.hostname;
})
},
selectors: {
@@ -131,7 +141,14 @@ export const linkingSlice = createSlice({
selectClientName: (state) => state.clientName,
selectKeyInfo: (state) => state.keyinfo,
reasonSelector: (state) => state.reason,
+ isToLoginSelector: (state) => state.hostname === 'tologin',
+ selectAction: (state) => state.hostname !== expo_default ? state.hostname : undefined,
},
});
-export const { selectTxInput, selectCallback, selectPath, selectBech32Address, selectClientName, reasonSelector, selectKeyInfo } = linkingSlice.selectors;
+// Expo default hostname
+const expo_default = 'expo-development-client';
+
+export const { clearLinking } = linkingSlice.actions;
+
+export const { selectTxInput, selectCallback, selectPath, selectBech32Address, selectClientName, reasonSelector, selectKeyInfo, isToLoginSelector, selectAction } = linkingSlice.selectors;