diff --git a/package.json b/package.json index 5fdf7b3..392281c 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "buffer": "^6.0.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "crypto-js": "^4.2.0", "currency-list": "^1.0.8", "dayjs": "^1.11.10", "expo": "~51.0.34", @@ -67,6 +68,7 @@ "@babel/preset-typescript": "^7.24.7", "@testing-library/react-hooks": "^8.0.1", "@testing-library/react-native": "^12.7.2", + "@types/crypto-js": "^4.2.2", "@types/jest": "^29.5.13", "@types/react": "~18.2.45", "jest": "^29.7.0", diff --git a/pages/Transaction.tsx b/pages/Transaction.tsx index 6c8808f..6b031a9 100644 --- a/pages/Transaction.tsx +++ b/pages/Transaction.tsx @@ -2,7 +2,7 @@ import { Nip47Transaction } from "@getalby/sdk/dist/NWCClient"; import dayjs from "dayjs"; import { useLocalSearchParams } from "expo-router"; import React from "react"; -import { View, TouchableOpacity } from "react-native"; +import { View, TouchableOpacity, ScrollView } from "react-native"; import Screen from "~/components/Screen"; import { MoveDownLeft, MoveUpRight } from "~/components/Icons"; import { Text } from "~/components/ui/text"; @@ -10,6 +10,29 @@ import { useGetFiatAmount } from "~/hooks/useGetFiatAmount"; import { cn } from "~/lib/utils"; import * as Clipboard from "expo-clipboard"; import Toast from "react-native-toast-message"; +import Hex from "crypto-js/enc-hex"; +import Utf8 from "crypto-js/enc-utf8"; + +type TLVRecord = { + type: number; + value: string; +}; + +type Boostagram = { + app_name: string; + name: string; + podcast: string; + url: string; + episode?: string; + itemID?: string; + ts?: string; + message?: string; + sender_id: string; + sender_name: string; + time: string; + action: string; + value_msat_total: number; +} export function Transaction() { const { transactionJSON } = useLocalSearchParams() as unknown as { @@ -17,75 +40,91 @@ export function Transaction() { }; const transaction: Nip47Transaction = JSON.parse(transactionJSON); const getFiatAmount = useGetFiatAmount(); + const rawMetadata = transaction.metadata; + let boostagram: Boostagram | undefined; + + try { + const tlvRecord = (rawMetadata?.tlv_records as TLVRecord[])?.find(record => record.type === 7629169); + if (tlvRecord) { + boostagram = JSON.parse(Utf8.stringify(Hex.parse(tlvRecord.value))) + } + } catch (e) { + console.error(e); + } return ( - + - - - {transaction.type === "incoming" && ( - + + + {transaction.type === "incoming" && ( + + )} + {transaction.type === "outgoing" && ( + + )} + + + {transaction.type === "incoming" ? "Received" : "Sent"} + + + + + {transaction.type === "incoming" ? "+" : "-"} {Math.floor(transaction.amount / 1000)} + + sats + + {getFiatAmount && ( + + {getFiatAmount(Math.floor(transaction.amount / 1000))} + + )} + + + + + + {boostagram && } + + + + - )} - {transaction.type === "outgoing" && ( - - )} - - - {transaction.type === "incoming" ? "Received" : "Sent"} - - - - - {transaction.type === "incoming" ? "+" : "-"} {Math.floor(transaction.amount / 1000)} - - sats - {getFiatAmount && ( - - {getFiatAmount(Math.floor(transaction.amount / 1000))} - - )} - - - - - - - - + ); } @@ -117,3 +156,62 @@ function TransactionDetailRow(props: { ); } + +function PodcastingInfo({ boost }: { boost: Boostagram }) { + return ( + <> + {boost.message && ( + + )} + {boost.podcast && ( + + )} + {boost.episode && ( + + )} + {boost.action && ( + + )} + {boost.ts && ( + + )} + {boost.value_msat_total && ( + + )} + {boost.sender_name && ( + + )} + {boost.app_name && ( + + )} + + ); +} + +export default PodcastingInfo; diff --git a/yarn.lock b/yarn.lock index 7b4dac3..bf91668 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2797,6 +2797,11 @@ resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== +"@types/crypto-js@^4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.2.2.tgz#771c4a768d94eb5922cc202a3009558204df0cea" + integrity sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ== + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -4010,6 +4015,11 @@ crypt@0.0.2, crypt@~0.0.1: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== +crypto-js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"