import React, { Component } from 'react'; import { View, ScrollView, TouchableOpacity, Linking } from 'react-native'; import { BlueButton, SafeBlueArea, BlueCard, BlueText, BlueHeaderDefaultSub, BlueLoading, BlueSpacing20, BlueCopyToClipboardButton, BlueNavigationStyle, } from '../../BlueComponents'; 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) { console.log(tx); foundTx = tx; for (let input of foundTx.inputs) { from = from.concat(input.addresses); } for (let output of foundTx.outputs) { to = to.concat(output.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, }; } async componentDidMount() { console.log('transactions/details - componentDidMount'); this.setState({ isLoading: false, }); } render() { if (this.state.isLoading || !this.state.hasOwnProperty('tx')) { return ; } return ( {(() => { if (this.state.tx.confirmations === 0 && this.state.wallet && this.state.wallet.allowRBF()) { return ( this.props.navigation.navigate('RBF', { txid: this.state.tx.hash, }) } title="Replace-By-Fee (RBF)" /> ); } })()} {(() => { 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://live.blockcypher.com/btc/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('confirmations') && this.state.tx.confirmations > 0 && ( Confirmations {this.state.tx.confirmations} )} {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, }), }), }), };