Skip to content

Commit 4764237

Browse files
committed
merge main
2 parents 6e51632 + 997b97b commit 4764237

File tree

14 files changed

+2160
-461
lines changed

14 files changed

+2160
-461
lines changed

package-lock.json

Lines changed: 1857 additions & 363 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ironfish-native-module/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"prepublishOnly": "expo-module prepublishOnly",
1616
"expo-module": "expo-module",
1717
"cargo-ios": "tsx scripts/cargo-ios.ts",
18+
"cargo-ios-native": "tsx scripts/cargo-ios.ts --target=ios",
1819
"cargo-ios-sim": "tsx scripts/cargo-ios.ts --target=ios-sim",
1920
"cargo-android": "tsx scripts/cargo-android.ts",
2021
"build-rust": "npm run cargo-android && npm run cargo-ios -- --target=ios-sim",

packages/mobile-app/app.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"expo": {
3-
"name": "mobile-app",
4-
"slug": "mobile-app",
3+
"name": "Iron Fish",
4+
"slug": "ironfishwallet",
55
"scheme": "ironfishwallet",
66
"version": "1.0.0",
77
"orientation": "portrait",
@@ -10,11 +10,12 @@
1010
"splash": {
1111
"image": "./assets/splash.png",
1212
"resizeMode": "contain",
13-
"backgroundColor": "#ffffff"
13+
"backgroundColor": "#de83f0"
1414
},
1515
"assetBundlePatterns": ["**/*"],
1616
"ios": {
17-
"bundleIdentifier": "com.ironfish.mobileapp",
17+
"icon": "./assets/icon.png",
18+
"bundleIdentifier": "network.ironfish.mobilewallet",
1819
"infoPlist": {
1920
"NSAppTransportSecurity": {
2021
"NSAllowsArbitraryLoads": false,
@@ -39,9 +40,9 @@
3940
"android": {
4041
"adaptiveIcon": {
4142
"foregroundImage": "./assets/adaptive-icon.png",
42-
"backgroundColor": "#ffffff"
43+
"backgroundColor": "#de83f0"
4344
},
44-
"package": "com.ironfish.mobileapp"
45+
"package": "network.ironfish.mobilewallet"
4546
},
4647
"plugins": ["expo-router", "expo-secure-store", "expo-font", "expo-sqlite"]
4748
}

packages/mobile-app/app/(drawer)/account/bridge/index.tsx

Lines changed: 181 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
import { WebView } from "react-native-webview";
2-
import {
3-
Button,
4-
Modal,
5-
SafeAreaView,
6-
StyleSheet,
7-
Text,
8-
View,
9-
} from "react-native";
2+
import { StyleSheet, View } from "react-native";
3+
import { Button, Card, Layout, Text } from "@ui-kitten/components";
104
import { oreoWallet } from "@/data/wallet/oreowalletWallet";
115
import { Network } from "@/data/constants";
12-
import { useRef, useState } from "react";
6+
import { useCallback, useRef, useState } from "react";
137
import * as Uint8ArrayUtils from "@/utils/uint8Array";
148
import { useFacade } from "@/data/facades";
159
import { Output } from "@/data/facades/wallet/types";
1610
import SendTransactionModal from "@/components/browser/SendTransactionModal";
11+
import { Image } from "expo-image";
1712
import Stack from "expo-router/stack";
13+
import {
14+
BottomSheetModal,
15+
BottomSheetView,
16+
BottomSheetModalProvider,
17+
BottomSheetBackdrop,
18+
} from "@gorhom/bottom-sheet";
19+
import { SettingsKey } from "@/data/settings/db";
1820

1921
type Message = {
2022
id: number;
@@ -112,6 +114,15 @@ class MessageHandler {
112114
data: { address },
113115
}),
114116
);
117+
} else if (message.type === "disconnect") {
118+
this.updateActiveAccount(null);
119+
postMessage?.(
120+
JSON.stringify({
121+
id: message.id,
122+
type: "disconnect",
123+
data: null,
124+
}),
125+
);
115126
} else if (message.type === "getBalances") {
116127
if (oreoWallet.state.type !== "STARTED" || !this.activeAccount) {
117128
console.error("Wallet not started");
@@ -191,13 +202,44 @@ export default function MenuDebugBrowser() {
191202
const webref = useRef<WebView | null>(null);
192203
const messageHandler = useRef(new MessageHandler());
193204
const facade = useFacade();
205+
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
206+
207+
const settings = facade.getAppSettings.useQuery(undefined);
208+
const network = settings.data
209+
? BRIDGE_URLS[settings.data[SettingsKey.Network]]
210+
: null;
194211

195212
const [accountModalVisible, setAccountModalVisible] = useState(false);
196213
const [sendTransactionData, setSendTransactionData] =
197214
useState<GeneralTransactionData | null>(null);
198-
const accounts = facade.getAccounts.useQuery(undefined, {
199-
enabled: accountModalVisible,
200-
});
215+
const account = facade.getAccount.useQuery(
216+
{},
217+
{
218+
enabled: accountModalVisible,
219+
},
220+
);
221+
222+
const handlePresentModalPress = useCallback(() => {
223+
bottomSheetModalRef.current?.present();
224+
setAccountModalVisible(true);
225+
}, []);
226+
227+
const handleDismissModalPress = useCallback(() => {
228+
bottomSheetModalRef.current?.dismiss();
229+
setAccountModalVisible(false);
230+
}, []);
231+
232+
const renderBackdrop = useCallback(
233+
(props: any) => (
234+
<BottomSheetBackdrop
235+
{...props}
236+
disappearsOnIndex={-1}
237+
appearsOnIndex={0}
238+
opacity={0.5}
239+
/>
240+
),
241+
[],
242+
);
201243

202244
const js = `
203245
window.addEventListener('message', (event) => {
@@ -215,6 +257,8 @@ export default function MenuDebugBrowser() {
215257
216258
if (message.type === "connect") {
217259
window.rpccalls[message.id].resolve(message.data.address);
260+
} else if (message.type === "disconnect") {
261+
window.rpccalls[message.id].resolve(null);
218262
} else if (message.type === "getBalances") {
219263
window.rpccalls[message.id].resolve(message.data.balances);
220264
} else if (message.type === "generalTransaction") {
@@ -252,6 +296,20 @@ export default function MenuDebugBrowser() {
252296
console.log(result);
253297
return result;
254298
}
299+
async disconnect() {
300+
const id = window.rpccounter++;
301+
window.ReactNativeWebView.postMessage(JSON.stringify({
302+
id,
303+
type: "disconnect",
304+
data: null,
305+
}));
306+
const result = await new Promise((resolve, reject) => {
307+
window.rpccalls[id] = { resolve, reject };
308+
});
309+
this.#address = null;
310+
console.log("Disconnected");
311+
return null;
312+
}
255313
async getBalances() {
256314
if (!this.#address) {
257315
throw new Error("Connect first");
@@ -306,89 +364,134 @@ export default function MenuDebugBrowser() {
306364
`;
307365

308366
return (
309-
<>
367+
<BottomSheetModalProvider>
310368
<Stack.Screen
311369
options={{
312370
headerTitle: "Bridge",
313371
headerBackTitle: "Back",
314372
}}
315373
/>
316-
<View style={styles.container}>
317-
<Modal
318-
animationType="slide"
319-
visible={accountModalVisible}
320-
onRequestClose={() => {
321-
messageHandler.current.updateActiveAccount(null);
322-
setAccountModalVisible(false);
323-
}}
324-
>
325-
<SafeAreaView>
326-
<View style={{ paddingTop: 40, paddingHorizontal: 4 }}>
327-
<Text style={{ fontSize: 20, textAlign: "center" }}>
328-
This website would like to connect to your wallet.
329-
</Text>
330-
<Text style={{ textAlign: "center" }}>
331-
Choose an account to connect, or click Cancel.
374+
{network && (
375+
<View style={styles.container}>
376+
<BottomSheetModal
377+
ref={bottomSheetModalRef}
378+
snapPoints={["50%"]}
379+
enablePanDownToClose
380+
backdropComponent={renderBackdrop}
381+
onDismiss={() => {
382+
messageHandler.current.updateActiveAccount(null);
383+
setAccountModalVisible(false);
384+
}}
385+
backgroundStyle={styles.bottomSheetModal}
386+
>
387+
<BottomSheetView style={styles.bottomSheetContent}>
388+
<Layout style={{ flexDirection: "row", gap: 8 }}>
389+
<Image
390+
source={network + "favicon.ico"}
391+
style={{ width: 48, height: 48 }}
392+
/>
393+
<Layout style={{ gap: 2 }}>
394+
<Text category="h5">Iron Fish Bridge</Text>
395+
<Text category="s2" appearance="hint">
396+
{network}
397+
</Text>
398+
</Layout>
399+
</Layout>
400+
<Text style={styles.modalSubtitle}>
401+
Allow this site to view your account's balances and
402+
transactions?
332403
</Text>
333-
{accounts.data?.map((a) => (
404+
<Card>
405+
<Text category="h6">{account.data?.name}</Text>
406+
<Text category="s2" appearance="hint">
407+
{account.data?.publicAddress}
408+
</Text>
409+
</Card>
410+
<Layout
411+
style={{ flexDirection: "row", gap: 8, marginBottom: 32 }}
412+
>
334413
<Button
335-
key={a.name}
336414
onPress={() => {
415+
if (!account.data) {
416+
console.error("No account loaded");
417+
return;
418+
}
337419
messageHandler.current.updateActiveAccount({
338-
name: a.name,
339-
address: a.publicAddress,
420+
name: account.data.name,
421+
address: account.data.publicAddress,
340422
});
341-
setAccountModalVisible(false);
423+
handleDismissModalPress();
342424
}}
343-
title={`${a.name} (${a.balances.iron.confirmed} $IRON)`}
344-
/>
345-
))}
346-
<Button
347-
onPress={() => {
348-
messageHandler.current.updateActiveAccount(null);
349-
setAccountModalVisible(false);
350-
}}
351-
title="Cancel"
352-
/>
353-
</View>
354-
</SafeAreaView>
355-
</Modal>
356-
<SendTransactionModal
357-
sendTransactionData={sendTransactionData}
358-
cancel={() => {
359-
messageHandler.current.rejectSendTransactionRequest();
360-
setSendTransactionData(null);
361-
}}
362-
success={(hash) => {
363-
messageHandler.current.resolveSendTransactionRequest(hash);
364-
setSendTransactionData(null);
365-
}}
366-
/>
367-
<WebView
368-
source={{ uri: BRIDGE_URLS[Network.MAINNET] }}
369-
ref={(r) => (webref.current = r)}
370-
injectedJavaScriptBeforeContentLoaded={js}
371-
onMessage={(event) => {
372-
messageHandler.current.handleMessage(
373-
event.nativeEvent.data,
374-
() => {
375-
setAccountModalVisible(true);
376-
},
377-
(data) => {
378-
setSendTransactionData(data);
379-
},
380-
webref.current?.postMessage,
381-
);
382-
}}
383-
webviewDebuggingEnabled
384-
/>
385-
</View>
386-
</>
425+
style={{ flex: 1 }}
426+
>
427+
Confirm
428+
</Button>
429+
<Button
430+
onPress={() => {
431+
messageHandler.current.updateActiveAccount(null);
432+
handleDismissModalPress();
433+
}}
434+
style={{ flex: 1 }}
435+
appearance="outline"
436+
>
437+
Cancel
438+
</Button>
439+
</Layout>
440+
</BottomSheetView>
441+
</BottomSheetModal>
442+
<SendTransactionModal
443+
sendTransactionData={sendTransactionData}
444+
cancel={() => {
445+
messageHandler.current.rejectSendTransactionRequest();
446+
setSendTransactionData(null);
447+
}}
448+
success={(hash) => {
449+
messageHandler.current.resolveSendTransactionRequest(hash);
450+
setSendTransactionData(null);
451+
}}
452+
/>
453+
<WebView
454+
source={{ uri: network }}
455+
ref={(r) => (webref.current = r)}
456+
injectedJavaScriptBeforeContentLoaded={js}
457+
onMessage={(event) => {
458+
messageHandler.current.handleMessage(
459+
event.nativeEvent.data,
460+
handlePresentModalPress,
461+
(data) => {
462+
setSendTransactionData(data);
463+
},
464+
webref.current?.postMessage,
465+
);
466+
}}
467+
webviewDebuggingEnabled
468+
/>
469+
</View>
470+
)}
471+
</BottomSheetModalProvider>
387472
);
388473
}
389474

390475
const styles = StyleSheet.create({
391476
container: {
392477
flex: 1,
393478
},
479+
bottomSheetModal: {
480+
shadowColor: "#000",
481+
shadowOffset: {
482+
width: 0,
483+
height: 6,
484+
},
485+
shadowOpacity: 0.37,
486+
shadowRadius: 7.49,
487+
488+
elevation: 12,
489+
},
490+
bottomSheetContent: {
491+
padding: 16,
492+
gap: 16,
493+
},
494+
modalSubtitle: {
495+
textAlign: "center",
496+
},
394497
});

0 commit comments

Comments
 (0)