|
1 | 1 | import { Layout } from "@/components";
|
2 | 2 | import Button from "@/components/button";
|
3 | 3 | import Text from "@/components/text";
|
4 |
| -import { selectClientName, selectBech32Address, selectTxInput, signTx, useAppDispatch, useAppSelector, reasonSelector, selectCallback, selectKeyInfo, clearLinking, selectChainId, selectRemote } from "@/redux"; |
| 4 | +import { |
| 5 | + estimateGasWanted, |
| 6 | + selectClientName, |
| 7 | + selectBech32Address, |
| 8 | + selectTxInput, |
| 9 | + signTx, |
| 10 | + useAppDispatch, |
| 11 | + useAppSelector, |
| 12 | + reasonSelector, |
| 13 | + selectCallback, |
| 14 | + selectKeyInfo, |
| 15 | + clearLinking, |
| 16 | + selectChainId, |
| 17 | + selectRemote, |
| 18 | +} from "@/redux"; |
5 | 19 | import { useGnoNativeContext } from "@gnolang/gnonative";
|
6 | 20 | import { router } from "expo-router";
|
7 | 21 | import { useEffect, useState } from "react";
|
8 |
| -import * as Linking from 'expo-linking'; |
| 22 | +import * as Linking from "expo-linking"; |
9 | 23 | import { View } from "react-native";
|
10 | 24 | import { Spacer } from "@/modules/ui-components";
|
11 | 25 |
|
12 | 26 | export default function Page() {
|
13 |
| - |
14 |
| - const dispatch = useAppDispatch(); |
15 |
| - const { gnonative } = useGnoNativeContext(); |
16 |
| - const [accountName, setAccountName] = useState<string | undefined>(undefined); |
17 |
| - const clientName = useAppSelector(selectClientName); |
18 |
| - |
19 |
| - const reason = useAppSelector(reasonSelector); |
20 |
| - const bech32Address = useAppSelector(selectBech32Address); |
21 |
| - const txInput = useAppSelector(selectTxInput); |
22 |
| - const callback = useAppSelector(selectCallback); |
23 |
| - const keyInfo = useAppSelector(selectKeyInfo); |
24 |
| - const chainId = useAppSelector(selectChainId); |
25 |
| - const remote = useAppSelector(selectRemote); |
26 |
| - |
27 |
| - console.log('txInput', txInput); |
28 |
| - console.log('bech32Address', bech32Address); |
29 |
| - console.log('clientName', clientName); |
30 |
| - console.log('reason', reason); |
31 |
| - |
32 |
| - useEffect(() => { |
33 |
| - (async () => { |
34 |
| - |
35 |
| - if (!chainId || !remote) throw new Error("No chainId or remote found."); |
36 |
| - gnonative.setChainID(chainId); |
37 |
| - gnonative.setRemote(remote); |
38 |
| - |
39 |
| - const accountNameStr = await gnonative.qEval("gno.land/r/sys/users", `ResolveAddress("${bech32Address}").Name()`); |
40 |
| - setAccountName(accountNameStr); |
41 |
| - })(); |
42 |
| - }, [bech32Address]); |
43 |
| - |
44 |
| - const signTxAndReturnToRequester = async () => { |
45 |
| - console.log('onChangeAccountHandler', keyInfo); |
| 27 | + const dispatch = useAppDispatch(); |
| 28 | + const { gnonative } = useGnoNativeContext(); |
| 29 | + const [accountName, setAccountName] = useState<string | undefined>(undefined); |
| 30 | + const clientName = useAppSelector(selectClientName); |
| 31 | + const [signedTx, setSignedTx] = useState<string | undefined>(undefined); |
| 32 | + const [gasWanted, setGasWanted] = useState<bigint>(BigInt(0)); |
| 33 | + |
| 34 | + const reason = useAppSelector(reasonSelector); |
| 35 | + const bech32Address = useAppSelector(selectBech32Address); |
| 36 | + const txInput = useAppSelector(selectTxInput); |
| 37 | + const callback = useAppSelector(selectCallback); |
| 38 | + const keyInfo = useAppSelector(selectKeyInfo); |
| 39 | + const chainId = useAppSelector(selectChainId); |
| 40 | + const remote = useAppSelector(selectRemote); |
| 41 | + |
| 42 | + console.log("txInput", txInput); |
| 43 | + console.log("bech32Address", bech32Address); |
| 44 | + console.log("clientName", clientName); |
| 45 | + console.log("reason", reason); |
| 46 | + |
| 47 | + useEffect(() => { |
| 48 | + (async () => { |
| 49 | + if (!chainId || !remote) throw new Error("No chainId or remote found."); |
| 50 | + gnonative.setChainID(chainId); |
| 51 | + gnonative.setRemote(remote); |
| 52 | + |
| 53 | + const accountNameStr = await gnonative.qEval("gno.land/r/sys/users", `ResolveAddress("${bech32Address}").Name()`); |
| 54 | + setAccountName(accountNameStr); |
| 55 | + })(); |
| 56 | + }, [bech32Address]); |
| 57 | + |
| 58 | + useEffect(() => { |
| 59 | + (async () => { |
| 60 | + try { |
| 61 | + console.log("onChangeAccountHandler", keyInfo); |
46 | 62 |
|
47 | 63 | if (!txInput || !keyInfo) {
|
48 |
| - throw new Error("No transaction input or keyInfo found."); |
| 64 | + throw new Error("No transaction input or keyInfo found."); |
49 | 65 | }
|
50 | 66 |
|
51 |
| - const signedTx = await dispatch(signTx({ keyInfo })).unwrap(); |
52 |
| - |
53 |
| - const path = callback ? callback : 'tech.berty.dsocial://post'; |
54 |
| - const url = `${path}?tx=${encodeURIComponent(signedTx.signedTxJson)}`; |
55 |
| - console.log("response URL " + url); |
56 |
| - Linking.openURL(url); |
| 67 | + const { gasWanted } = await dispatch(estimateGasWanted({ keyInfo, updateTx: true })).unwrap(); |
57 | 68 |
|
58 |
| - router.push("/home") |
| 69 | + const signedTx = await dispatch(signTx({ keyInfo })).unwrap(); |
| 70 | + setSignedTx(signedTx.signedTxJson); |
| 71 | + setGasWanted(gasWanted); |
| 72 | + } catch (error: unknown | Error) { |
| 73 | + console.error(error); |
| 74 | + } |
| 75 | + })(); |
| 76 | + }, [txInput, keyInfo]); |
| 77 | + |
| 78 | + const returnSignedTxToRequester = async () => { |
| 79 | + if (!signedTx) { |
| 80 | + throw new Error("No signedTx found."); |
59 | 81 | }
|
60 | 82 |
|
61 |
| - const onCancel = () => { |
62 |
| - dispatch(clearLinking()); |
63 |
| - if (callback) { |
64 |
| - Linking.openURL(`${callback}?status=cancelled`); // callback to requester |
65 |
| - } |
66 |
| - router.replace("/home"); |
67 |
| - } |
| 83 | + const path = callback ? callback : "tech.berty.dsocial://post"; |
| 84 | + const url = `${path}?tx=${encodeURIComponent(signedTx)}&gaswanted=${gasWanted.toString()}`; |
| 85 | + console.log("response URL " + url); |
| 86 | + Linking.openURL(url); |
68 | 87 |
|
69 |
| - return ( |
70 |
| - <> |
71 |
| - <Layout.Container> |
72 |
| - <Layout.BodyAlignedBotton> |
73 |
| - <Text.Title>{clientName} is requiring permission to {reason}.</Text.Title> |
74 |
| - <Spacer space={16} /> |
75 |
| - |
76 |
| - <Spacer space={16} /> |
77 |
| - <Text.Body>reason: {reason}</Text.Body> |
78 |
| - <Text.Body>callback: {callback}</Text.Body> |
79 |
| - <Text.Body>client_name: {clientName}</Text.Body> |
80 |
| - <Text.Body>accountName: {accountName}</Text.Body> |
81 |
| - <View style={{ flexDirection: 'row', alignItems:'center' }}> |
82 |
| - <Text.Body>Address:</Text.Body> |
83 |
| - <Text.Caption1>{bech32Address}</Text.Caption1> |
84 |
| - </View> |
85 |
| - <View style={{ flexDirection: 'row', alignItems:'center' }}> |
86 |
| - <Text.Body>Keyinfo:</Text.Body> |
87 |
| - <Text.Caption1>{keyInfo?.name}</Text.Caption1> |
88 |
| - </View> |
89 |
| - <Text.Body>remote: {remote}</Text.Body> |
90 |
| - <Text.Body>chainId: {chainId}</Text.Body> |
91 |
| - |
92 |
| - <Spacer space={16} /> |
93 |
| - |
94 |
| - <Button.TouchableOpacity title="Approve" variant="primary" onPress={signTxAndReturnToRequester}></Button.TouchableOpacity> |
95 |
| - <Button.TouchableOpacity title="Cancel" variant="primary-red" onPress={onCancel}></Button.TouchableOpacity> |
96 |
| - </Layout.BodyAlignedBotton> |
97 |
| - </Layout.Container> |
98 |
| - </> |
99 |
| - ) |
| 88 | + router.push("/home"); |
| 89 | + }; |
100 | 90 |
|
| 91 | + const onCancel = () => { |
| 92 | + dispatch(clearLinking()); |
| 93 | + if (callback) { |
| 94 | + Linking.openURL(`${callback}?status=cancelled`); // callback to requester |
| 95 | + } |
| 96 | + router.replace("/home"); |
| 97 | + }; |
| 98 | + |
| 99 | + return ( |
| 100 | + <> |
| 101 | + <Layout.Container> |
| 102 | + <Layout.BodyAlignedBotton> |
| 103 | + <Text.Title> |
| 104 | + {clientName} is requiring permission to {reason}. |
| 105 | + </Text.Title> |
| 106 | + <Spacer space={16} /> |
| 107 | + |
| 108 | + <Spacer space={16} /> |
| 109 | + <Text.Body>reason: {reason}</Text.Body> |
| 110 | + <Text.Body>callback: {callback}</Text.Body> |
| 111 | + <Text.Body>client_name: {clientName}</Text.Body> |
| 112 | + <Text.Body>accountName: {accountName}</Text.Body> |
| 113 | + <View style={{ flexDirection: "row", alignItems: "center" }}> |
| 114 | + <Text.Body>Address:</Text.Body> |
| 115 | + <Text.Caption1>{bech32Address}</Text.Caption1> |
| 116 | + </View> |
| 117 | + <View style={{ flexDirection: "row", alignItems: "center" }}> |
| 118 | + <Text.Body>Keyinfo:</Text.Body> |
| 119 | + <Text.Caption1>{keyInfo?.name}</Text.Caption1> |
| 120 | + </View> |
| 121 | + <View style={{ flexDirection: "row", alignItems: "center" }}> |
| 122 | + <Text.Body>Gas Wanted:</Text.Body> |
| 123 | + <Text.Caption1>{gasWanted?.toString()}</Text.Caption1> |
| 124 | + </View> |
| 125 | + <Text.Body>remote: {remote}</Text.Body> |
| 126 | + <Text.Body>chainId: {chainId}</Text.Body> |
| 127 | + |
| 128 | + <Spacer space={16} /> |
| 129 | + |
| 130 | + <Button.TouchableOpacity |
| 131 | + title="Approve" |
| 132 | + variant="primary" |
| 133 | + onPress={returnSignedTxToRequester} |
| 134 | + ></Button.TouchableOpacity> |
| 135 | + <Button.TouchableOpacity title="Cancel" variant="primary-red" onPress={onCancel}></Button.TouchableOpacity> |
| 136 | + </Layout.BodyAlignedBotton> |
| 137 | + </Layout.Container> |
| 138 | + </> |
| 139 | + ); |
101 | 140 | }
|
0 commit comments