Skip to content

Commit

Permalink
Set up creating and sending transactions (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
dguenther authored Sep 23, 2024
1 parent 27845e9 commit 42b1e23
Show file tree
Hide file tree
Showing 20 changed files with 1,039 additions and 220 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ public class IronfishNativeModule: Module {
throw error
}
}

AsyncFunction("hashTransaction") { (transaction: Data) -> Data in
return hashTransaction(transaction: transaction)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/ironfish-native-module/rust_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
blake3 = "1.5.0"
const-hex = "1.12.0"
ironfish = { path = "../ironfish/ironfish-rust" }
num = "0.4.1"
Expand Down
7 changes: 7 additions & 0 deletions packages/ironfish-native-module/rust_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,10 @@ pub fn create_transaction(
.map_err(|e| EnumError::Error { msg: e.to_string() })?;
Ok(buffer)
}

#[uniffi::export]
pub fn hash_transaction(
transaction: Vec<u8>,
) -> Vec<u8> {
blake3::hash(&transaction).as_bytes().to_vec()
}
4 changes: 4 additions & 0 deletions packages/ironfish-native-module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,7 @@ export function createTransaction(
spendingKey,
);
}

export function hashTransaction(transaction: Uint8Array): Promise<Uint8Array> {
return IronfishNativeModule.hashTransaction(transaction);
}
7 changes: 6 additions & 1 deletion packages/mobile-app/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ export default function Balances() {
<Text>You're currently on Testnet</Text>
{getAccountResult.data && (
<>
<Text>{`${getAccountResult.data.balances.iron.confirmed}`}</Text>
<Text>
{getAccountResult.data.balances.iron.confirmed ===
getAccountResult.data.balances.iron.available
? `${getAccountResult.data.balances.iron.confirmed}`
: `${getAccountResult.data.balances.iron.confirmed} (${getAccountResult.data.balances.iron.available} available to spend)`}
</Text>
{getIronAsset.data && (
<Text>{`${getIronAsset.data.verification.status === "verified" ? `${getIronAsset.data.verification.symbol} (Verified)` : `${getIronAsset.data.name} (Unverified)`}`}</Text>
)}
Expand Down
5 changes: 5 additions & 0 deletions packages/mobile-app/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import { useEffect, useState } from "react";
import { ColorScheme } from "@ironfish/tackle-box";

const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
mutationCache: new MutationCache({
onSuccess: async () => {
await queryClient.invalidateQueries();
Expand Down
30 changes: 28 additions & 2 deletions packages/mobile-app/app/account-settings/account-name.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
import { StatusBar } from "expo-status-bar";
import { Button, StyleSheet, Text, TextInput, View } from "react-native";
import { useRouter } from "expo-router";
import { useFacade } from "../../data/facades";
import { useState } from "react";

export default function AccountName() {
const router = useRouter();
const facade = useFacade();

const [newName, setNewName] = useState("");

const activeAccount = facade.getAccount.useQuery({});

const renameAccount = facade.renameAccount.useMutation();

return (
<View style={styles.container}>
<Button title="Back" onPress={() => router.dismiss()} />

<View>
<Text>Account Name</Text>
<TextInput placeholder="Account 1" />
<Text>Current name: {activeAccount.data?.name}</Text>
<TextInput
placeholder="New Name"
value={newName}
onChangeText={setNewName}
/>
</View>
<Button title="Save" />
<Button
title="Save"
onPress={async () => {
if (!activeAccount.data) {
return;
}
await renameAccount.mutateAsync({
name: activeAccount.data?.name,
newName: newName,
});
router.dismissAll();
}}
/>
<StatusBar style="auto" />
</View>
);
Expand Down
3 changes: 3 additions & 0 deletions packages/mobile-app/app/menu/debug/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useFacade } from "../../../data/facades";
import { Network } from "../../../data/constants";
import { wallet } from "../../../data/wallet/wallet";
import { reverseScan } from "../../../data/debug/reverseScan";
import { LinkButton } from "../../../components/LinkButton";

export default function MenuDebug() {
const facade = useFacade();
Expand All @@ -17,6 +18,8 @@ export default function MenuDebug() {

return (
<View style={styles.container}>
<LinkButton title="Pending Transactions" href="/menu/debug/pending/" />
<LinkButton title="Unspent Notes" href="/menu/debug/unspent/" />
<View>
{walletStatus.data && (
<>
Expand Down
73 changes: 73 additions & 0 deletions packages/mobile-app/app/menu/debug/pending.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { StatusBar } from "expo-status-bar";
import { Button, ScrollView, StyleSheet, Text, View } from "react-native";
import { Network } from "../../../data/constants";
import { wallet } from "../../../data/wallet/wallet";
import * as Uint8ArrayUtils from "../../../utils/uint8Array";
import { useState } from "react";

export default function MenuDebugPending() {
const [transactions, setTransactions] = useState<
{
hash: Uint8Array;
}[]
>();

const refreshTransactions = async () => {
if (wallet.state.type !== "STARTED") {
return;
}
const account = await wallet.getActiveAccountWithHeadAndBalances(
Network.TESTNET,
);
if (!account) {
return;
}
const txns = await wallet.state.db.getPendingTransactions(
account.id,
Network.TESTNET,
);
console.log(`txns: ${txns.length}`);

setTransactions(txns);
};

return (
<View style={styles.container}>
<View>
<Button
onPress={async () => {
await refreshTransactions();
}}
title="Get Pending Transactions"
/>
</View>
<ScrollView>
{transactions?.map((txn, i) => (
<View key={i} style={{ marginVertical: 5 }}>
<Text>{Uint8ArrayUtils.toHex(txn.hash)}</Text>
<Button
onPress={async () => {
if (wallet.state.type !== "STARTED") {
return;
}
await wallet.state.db.removePendingTransaction(txn.hash);
await refreshTransactions();
}}
title="Delete"
/>
</View>
))}
</ScrollView>
<StatusBar style="auto" />
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
99 changes: 99 additions & 0 deletions packages/mobile-app/app/menu/debug/unspent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { StatusBar } from "expo-status-bar";
import { Button, ScrollView, StyleSheet, Text, View } from "react-native";
import { Network } from "../../../data/constants";
import { wallet } from "../../../data/wallet/wallet";
import { Blockchain } from "../../../data/blockchain";
import * as Uint8ArrayUtils from "../../../utils/uint8Array";
import { useState } from "react";

export default function MenuDebugUnspentNotes() {
const [notes, setNotes] = useState<
{
assetId: Uint8Array;
value: string;
}[]
>();

const [balances, setBalances] = useState<
{
assetId: Uint8Array;
confirmed: string;
unconfirmed: string;
pending: string;
available: string;
}[]
>();

const sum =
notes?.reduce((prev, cur) => {
console.log(BigInt(cur.value).toString());
return prev + BigInt(cur.value);
}, BigInt(0)) ?? BigInt(0);

return (
<View style={styles.container}>
<View>
<Button
onPress={async () => {
if (wallet.state.type !== "STARTED") {
return;
}
const account = await wallet.getActiveAccountWithHeadAndBalances(
Network.TESTNET,
);
if (!account) {
return;
}
setBalances(account.balances);
const seq = await Blockchain.getLatestBlock(Network.TESTNET);
const notes = await wallet.state.db.getUnspentNotes(
seq.sequence,
2,
account?.id,
Uint8ArrayUtils.fromHex(
"51f33a2f14f92735e562dc658a5639279ddca3d5079a6d1242b2a588a9cbf44c",
),
Network.TESTNET,
);
setNotes(notes);
}}
title="Get Notes"
/>
</View>
<View>
{balances?.map((balance, i) => (
<View key={i}>
<Text>{Uint8ArrayUtils.toHex(balance.assetId)}</Text>
<Text>Confirmed: {balance.confirmed}</Text>
<Text>Unconfirmed: {balance.unconfirmed}</Text>
<Text>Pending: {balance.pending}</Text>
<Text>Available: {balance.available}</Text>
</View>
))}
{notes && (
<Text>
Total: {sum.toString()} ({notes?.length ?? 0} notes)
</Text>
)}
</View>
<ScrollView>
{notes?.map((note, i) => (
<View key={i} style={{ marginVertical: 5 }}>
<Text>{note.value}</Text>
<Text>{Uint8ArrayUtils.toHex(note.assetId)}</Text>
</View>
))}
</ScrollView>
<StatusBar style="auto" />
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
2 changes: 1 addition & 1 deletion packages/mobile-app/app/send/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function Send() {
<View style={styles.container}>
<Text>Select asset</Text>
<Button
title={`IRON (${getAccountResult.data?.balances.iron.confirmed ?? 0}) ${selectedAssetId === "51f33a2f14f92735e562dc658a5639279ddca3d5079a6d1242b2a588a9cbf44c" ? "(selected)" : ""}`}
title={`IRON (${getAccountResult.data?.balances.iron.available ?? 0}) ${selectedAssetId === "51f33a2f14f92735e562dc658a5639279ddca3d5079a6d1242b2a588a9cbf44c" ? "(selected)" : ""}`}
onPress={() =>
setSelectedAssetId(
"51f33a2f14f92735e562dc658a5639279ddca3d5079a6d1242b2a588a9cbf44c",
Expand Down
12 changes: 4 additions & 8 deletions packages/mobile-app/data/facades/wallet/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,8 @@ export const walletHandlers = f.facade<WalletHandlers>({
assetId: Uint8ArrayUtils.toHex(b.assetId),
confirmed: b.confirmed,
unconfirmed: b.unconfirmed,
// TODO: Implement pending balance in Wallet
pending: "0",
// TODO: Implement available balance in Wallet
available: "0",
pending: b.pending,
available: b.available,
};
});

Expand Down Expand Up @@ -147,10 +145,8 @@ export const walletHandlers = f.facade<WalletHandlers>({
assetId: Uint8ArrayUtils.toHex(b.assetId),
confirmed: b.confirmed,
unconfirmed: b.unconfirmed,
// TODO: Implement pending balance in Wallet
pending: "0",
// TODO: Implement available balance in Wallet
available: "0",
pending: b.pending,
available: b.available,
};
});

Expand Down
Loading

0 comments on commit 42b1e23

Please sign in to comment.