import React, { Component } from 'react'; import { View, ScrollView, TouchableOpacity, Linking } from 'react-native'; import { SafeBlueArea, BlueCard, BlueText, BlueHeaderDefaultSub, BlueLoading, BlueSpacing20, BlueCopyToClipboardButton, BlueNavigationStyle, } from '../../BlueComponents'; import HandoffSettings from '../../class/handoff'; import Handoff from 'react-native-handoff'; import PropTypes from 'prop-types'; /** @type {AppStorage} */ let BlueApp = require('../../BlueApp'); let loc = require('../../loc'); const dayjs = require('dayjs'); function onlyUnique(value, index, self) { return self.indexOf(value) === index; } function arrDiff(a1, a2) { let ret = []; for (let v of a2) { if (a1.indexOf(v) === -1) { ret.push(v); } } return ret; } export default class TransactionsDetails extends Component { static navigationOptions = () => ({ ...BlueNavigationStyle(), }); constructor(props) { super(props); let hash = props.navigation.state.params.hash; let foundTx = {}; let from = []; let to = []; for (let tx of BlueApp.getTransactions()) { if (tx.hash === hash) { foundTx = tx; for (let input of foundTx.inputs) { from = from.concat(input.addresses); } for (let output of foundTx.outputs) { if (output.addresses) to = to.concat(output.addresses); if (output.scriptPubKey && output.scriptPubKey.addresses) to = to.concat(output.scriptPubKey.addresses); } } } let wallet = false; for (let w of BlueApp.getWallets()) { for (let t of w.getTransactions()) { if (t.hash === hash) { console.log('tx', hash, 'belongs to', w.getLabel()); wallet = w; } } } this.state = { isLoading: true, tx: foundTx, from, to, wallet, isHandOffUseEnabled: false, }; } async componentDidMount() { console.log('transactions/details - componentDidMount'); const isHandOffUseEnabled = await HandoffSettings.isHandoffUseEnabled(); this.setState({ isLoading: false, isHandOffUseEnabled, }); } render() { if (this.state.isLoading || !this.state.hasOwnProperty('tx')) { return ; } return ( {this.state.isHandOffUseEnabled && ( )} {(() => { if (BlueApp.tx_metadata[this.state.tx.hash]) { if (BlueApp.tx_metadata[this.state.tx.hash]['memo']) { return ( {BlueApp.tx_metadata[this.state.tx.hash]['memo']} ); } } })()} {this.state.hasOwnProperty('from') && ( {loc.transactions.details.from} {this.state.from.filter(onlyUnique).join(', ')} )} {this.state.hasOwnProperty('to') && ( {loc.transactions.details.to} {arrDiff(this.state.from, this.state.to.filter(onlyUnique)).join(', ')} )} {this.state.tx.hasOwnProperty('fee') && ( {loc.send.create.fee} {this.state.tx.fee + ' sats'} )} {this.state.tx.hasOwnProperty('hash') && ( Txid {this.state.tx.hash} { const url = `https://blockstream.info/tx/${this.state.tx.hash}`; Linking.canOpenURL(url).then(supported => { if (supported) { Linking.openURL(url); } }); }} > {loc.transactions.details.show_in_block_explorer} )} {this.state.tx.hasOwnProperty('received') && ( Received {dayjs(this.state.tx.received).format('MM/DD/YYYY h:mm A')} )} {this.state.tx.hasOwnProperty('block_height') && this.state.tx.block_height > 0 && ( Block Height {this.state.tx.block_height} )} {this.state.tx.hasOwnProperty('inputs') && ( Inputs {this.state.tx.inputs.length} )} {this.state.tx.hasOwnProperty('outputs') && this.state.tx.outputs.length > 0 && ( Outputs {this.state.tx.outputs.length} )} ); } } TransactionsDetails.propTypes = { navigation: PropTypes.shape({ goBack: PropTypes.func, navigate: PropTypes.func, state: PropTypes.shape({ params: PropTypes.shape({ hash: PropTypes.string, }), }), }), };