mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 09:50:15 +01:00
ADD: display bip47 payment code contact on tx details screen
This commit is contained in:
parent
1384c8453f
commit
438a671299
@ -591,6 +591,10 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
|
|||||||
tx.value += new BigNumber(vout.value).multipliedBy(100000000).toNumber();
|
tx.value += new BigNumber(vout.value).multipliedBy(100000000).toNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.allowBIP47() && this.isBIP47Enabled()) {
|
||||||
|
tx.counterparty = this.getBip47CounterpartyByTx(tx);
|
||||||
|
}
|
||||||
ret.push(tx);
|
ret.push(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1557,16 +1561,28 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return BIP47 payment code of the counterparty of this transaction (someone paid us, or we paid someone)
|
* return BIP47 payment code of the counterparty of this transaction (someone who paid us, or someone we paid)
|
||||||
* or false if it was a non-BIP47 transaction
|
* or undefined if it was a non-BIP47 transaction
|
||||||
*/
|
*/
|
||||||
getSenderByTxid(txid: string): string | false {
|
getBip47CounterpartyByTxid(txid: string): string | undefined {
|
||||||
|
const foundTx = this.getTransactions().find(tx => tx.txid === txid);
|
||||||
|
if (foundTx) {
|
||||||
|
return this.getBip47CounterpartyByTx(foundTx);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return BIP47 payment code of the counterparty of this transaction (someone who paid us, or someone we paid)
|
||||||
|
* or undefined if it was a non-BIP47 transaction
|
||||||
|
*/
|
||||||
|
getBip47CounterpartyByTx(tx: Transaction): string | undefined {
|
||||||
for (const pc of Object.keys(this._txs_by_payment_code_index)) {
|
for (const pc of Object.keys(this._txs_by_payment_code_index)) {
|
||||||
// iterating all payment codes
|
// iterating all payment codes
|
||||||
|
|
||||||
for (const txs of Object.values(this._txs_by_payment_code_index[pc])) {
|
for (const txs of Object.values(this._txs_by_payment_code_index[pc])) {
|
||||||
for (const tx of txs) {
|
for (const tx2 of txs) {
|
||||||
if (tx.txid === txid) {
|
if (tx2.txid === tx.txid) {
|
||||||
return pc; // found it!
|
return pc; // found it!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1576,19 +1592,17 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
|
|||||||
// checking txs we sent to counterparties
|
// checking txs we sent to counterparties
|
||||||
|
|
||||||
for (const pc of this._send_payment_codes) {
|
for (const pc of this._send_payment_codes) {
|
||||||
for (const tx of this.getTransactions().filter(transaction => transaction.txid === txid)) {
|
for (const out of tx.outputs) {
|
||||||
for (const out of tx.outputs) {
|
for (const address of out.scriptPubKey?.addresses ?? []) {
|
||||||
for (const address of out.scriptPubKey?.addresses ?? []) {
|
if (this._addresses_by_payment_code_send[pc] && Object.values(this._addresses_by_payment_code_send[pc]).includes(address)) {
|
||||||
if (this._addresses_by_payment_code_send[pc] && Object.values(this._addresses_by_payment_code_send[pc]).includes(address)) {
|
// found it!
|
||||||
// found it!
|
return pc;
|
||||||
return pc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // found nothing
|
return undefined; // found nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
createBip47NotificationTransaction(utxos: CreateTransactionUtxo[], receiverPaymentCode: string, feeRate: number, changeAddress: string) {
|
createBip47NotificationTransaction(utxos: CreateTransactionUtxo[], receiverPaymentCode: string, feeRate: number, changeAddress: string) {
|
||||||
|
@ -78,6 +78,17 @@ export type TransactionOutput = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type LightningTransaction = {
|
||||||
|
memo?: string;
|
||||||
|
type?: 'user_invoice' | 'payment_request' | 'bitcoind_tx' | 'paid_invoice';
|
||||||
|
payment_hash?: string | { data: string };
|
||||||
|
category?: 'receive';
|
||||||
|
timestamp?: number;
|
||||||
|
expire_time?: number;
|
||||||
|
ispaid?: boolean;
|
||||||
|
walletID?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type Transaction = {
|
export type Transaction = {
|
||||||
txid: string;
|
txid: string;
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -94,6 +105,11 @@ export type Transaction = {
|
|||||||
blocktime: number;
|
blocktime: number;
|
||||||
received?: number;
|
received?: number;
|
||||||
value?: number;
|
value?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if known, who is on the other end of the transaction (BIP47 payment code)
|
||||||
|
*/
|
||||||
|
counterparty?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TWallet =
|
export type TWallet =
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/* eslint react/prop-types: "off" */
|
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import React, { useState, useMemo, useCallback, useContext, useEffect, useRef } from 'react';
|
|
||||||
import { Linking, StyleSheet, View } from 'react-native';
|
import { Linking, StyleSheet, View } from 'react-native';
|
||||||
import Clipboard from '@react-native-clipboard/clipboard';
|
import Clipboard from '@react-native-clipboard/clipboard';
|
||||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
@ -20,8 +19,15 @@ import TransactionPendingIcon from '../components/icons/TransactionPendingIcon';
|
|||||||
import { useTheme } from './themes';
|
import { useTheme } from './themes';
|
||||||
import ListItem from './ListItem';
|
import ListItem from './ListItem';
|
||||||
import { useSettings } from './Context/SettingsContext';
|
import { useSettings } from './Context/SettingsContext';
|
||||||
|
import { LightningTransaction, Transaction } from '../class/wallets/types';
|
||||||
|
|
||||||
export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, walletID }) => {
|
interface TransactionListItemProps {
|
||||||
|
itemPriceUnit: BitcoinUnit;
|
||||||
|
walletID: string;
|
||||||
|
item: Transaction & LightningTransaction; // using type intersection to have less issues with ts
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TransactionListItem: React.FC<TransactionListItemProps> = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, walletID }) => {
|
||||||
const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1);
|
const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1);
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const { navigate } = useNavigation();
|
const { navigate } = useNavigation();
|
||||||
@ -39,17 +45,22 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
[colors.lightBorder],
|
[colors.lightBorder],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const shortenContactName = (addr: string): string => {
|
||||||
|
return addr.substr(0, 5) + '...' + addr.substr(addr.length - 4, 4);
|
||||||
|
};
|
||||||
|
|
||||||
const title = useMemo(() => {
|
const title = useMemo(() => {
|
||||||
if (item.confirmations === 0) {
|
if (item.confirmations === 0) {
|
||||||
return loc.transactions.pending;
|
return loc.transactions.pending;
|
||||||
} else {
|
} else {
|
||||||
return transactionTimeToReadable(item.received);
|
return transactionTimeToReadable(item.received!);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [item.confirmations, item.received, language]);
|
}, [item.confirmations, item.received, language]);
|
||||||
const txMemo = txMetadata[item.hash]?.memo ?? '';
|
|
||||||
|
const txMemo = (item.counterparty ? `[${shortenContactName(item.counterparty)}] ` : '') + (txMetadata[item.hash]?.memo ?? '');
|
||||||
const subtitle = useMemo(() => {
|
const subtitle = useMemo(() => {
|
||||||
let sub = item.confirmations < 7 ? loc.formatString(loc.transactions.list_conf, { number: item.confirmations }) : '';
|
let sub = Number(item.confirmations) < 7 ? loc.formatString(loc.transactions.list_conf, { number: item.confirmations }) : '';
|
||||||
if (sub !== '') sub += ' ';
|
if (sub !== '') sub += ' ';
|
||||||
sub += txMemo;
|
sub += txMemo;
|
||||||
if (item.memo) sub += item.memo;
|
if (item.memo) sub += item.memo;
|
||||||
@ -58,12 +69,12 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
|
|
||||||
const rowTitle = useMemo(() => {
|
const rowTitle = useMemo(() => {
|
||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
if (isNaN(item.value)) {
|
if (isNaN(Number(item.value))) {
|
||||||
item.value = '0';
|
item.value = 0;
|
||||||
}
|
}
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
const invoiceExpiration = item.timestamp! + item.expire_time!;
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
if (invoiceExpiration > now) {
|
||||||
return formatBalanceWithoutSuffix(item.value && item.value, itemPriceUnit, true).toString();
|
return formatBalanceWithoutSuffix(item.value && item.value, itemPriceUnit, true).toString();
|
||||||
@ -86,7 +97,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
if (item.type === 'user_invoice' || item.type === 'payment_request') {
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
const invoiceExpiration = item.timestamp! + item.expire_time!;
|
||||||
|
|
||||||
if (invoiceExpiration > now) {
|
if (invoiceExpiration > now) {
|
||||||
color = colors.successColor;
|
color = colors.successColor;
|
||||||
@ -97,7 +108,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
color = '#9AA0AA';
|
color = '#9AA0AA';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item.value / 100000000 < 0) {
|
} else if (item.value! / 100000000 < 0) {
|
||||||
color = colors.foregroundColor;
|
color = colors.foregroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +123,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
|
|
||||||
const avatar = useMemo(() => {
|
const avatar = useMemo(() => {
|
||||||
// is it lightning refill tx?
|
// is it lightning refill tx?
|
||||||
if (item.category === 'receive' && item.confirmations < 3) {
|
if (item.category === 'receive' && item.confirmations! < 3) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.iconWidth}>
|
<View style={styles.iconWidth}>
|
||||||
<TransactionPendingIcon />
|
<TransactionPendingIcon />
|
||||||
@ -140,7 +151,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
if (!item.ispaid) {
|
if (!item.ispaid) {
|
||||||
const currentDate = new Date();
|
const currentDate = new Date();
|
||||||
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
const now = (currentDate.getTime() / 1000) | 0; // eslint-disable-line no-bitwise
|
||||||
const invoiceExpiration = item.timestamp + item.expire_time;
|
const invoiceExpiration = item.timestamp! + item.expire_time!;
|
||||||
if (invoiceExpiration < now) {
|
if (invoiceExpiration < now) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.iconWidth}>
|
<View style={styles.iconWidth}>
|
||||||
@ -163,7 +174,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
<TransactionPendingIcon />
|
<TransactionPendingIcon />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
} else if (item.value < 0) {
|
} else if (item.value! < 0) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.iconWidth}>
|
<View style={styles.iconWidth}>
|
||||||
<TransactionOutgoingIcon />
|
<TransactionOutgoingIcon />
|
||||||
@ -183,8 +194,10 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
}, [subtitle]);
|
}, [subtitle]);
|
||||||
|
|
||||||
const onPress = useCallback(async () => {
|
const onPress = useCallback(async () => {
|
||||||
menuRef?.current?.dismissMenu();
|
// @ts-ignore: idk how to fix
|
||||||
|
menuRef?.current?.dismissMenu?.();
|
||||||
if (item.hash) {
|
if (item.hash) {
|
||||||
|
// @ts-ignore: idk how to fix
|
||||||
navigate('TransactionStatus', { hash: item.hash, walletID });
|
navigate('TransactionStatus', { hash: item.hash, walletID });
|
||||||
} else if (item.type === 'user_invoice' || item.type === 'payment_request' || item.type === 'paid_invoice') {
|
} else if (item.type === 'user_invoice' || item.type === 'payment_request' || item.type === 'paid_invoice') {
|
||||||
const lightningWallet = wallets.filter(wallet => wallet?.getID() === item.walletID);
|
const lightningWallet = wallets.filter(wallet => wallet?.getID() === item.walletID);
|
||||||
@ -192,13 +205,14 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
try {
|
try {
|
||||||
// is it a successful lnurl-pay?
|
// is it a successful lnurl-pay?
|
||||||
const LN = new Lnurl(false, AsyncStorage);
|
const LN = new Lnurl(false, AsyncStorage);
|
||||||
let paymentHash = item.payment_hash;
|
let paymentHash = item.payment_hash!;
|
||||||
if (typeof paymentHash === 'object') {
|
if (typeof paymentHash === 'object') {
|
||||||
paymentHash = Buffer.from(paymentHash.data).toString('hex');
|
paymentHash = Buffer.from(paymentHash.data).toString('hex');
|
||||||
}
|
}
|
||||||
const loaded = await LN.loadSuccessfulPayment(paymentHash);
|
const loaded = await LN.loadSuccessfulPayment(paymentHash);
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
NavigationService.navigate('ScanLndInvoiceRoot', {
|
NavigationService.navigate('ScanLndInvoiceRoot', {
|
||||||
|
// @ts-ignore: idk how to fix
|
||||||
screen: 'LnurlPaySuccess',
|
screen: 'LnurlPaySuccess',
|
||||||
params: {
|
params: {
|
||||||
paymentHash,
|
paymentHash,
|
||||||
@ -212,6 +226,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore: idk how to fix
|
||||||
navigate('LNDViewInvoice', {
|
navigate('LNDViewInvoice', {
|
||||||
invoice: item,
|
invoice: item,
|
||||||
walletID: lightningWallet[0].getID(),
|
walletID: lightningWallet[0].getID(),
|
||||||
@ -244,18 +259,18 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
}, [item.hash]);
|
}, [item.hash]);
|
||||||
|
|
||||||
const onToolTipPress = useCallback(
|
const onToolTipPress = useCallback(
|
||||||
id => {
|
(id: any) => {
|
||||||
if (id === TransactionListItem.actionKeys.CopyAmount) {
|
if (id === actionKeys.CopyAmount) {
|
||||||
handleOnCopyAmountTap();
|
handleOnCopyAmountTap();
|
||||||
} else if (id === TransactionListItem.actionKeys.CopyNote) {
|
} else if (id === actionKeys.CopyNote) {
|
||||||
handleOnCopyNote();
|
handleOnCopyNote();
|
||||||
} else if (id === TransactionListItem.actionKeys.OpenInBlockExplorer) {
|
} else if (id === actionKeys.OpenInBlockExplorer) {
|
||||||
handleOnViewOnBlockExplorer();
|
handleOnViewOnBlockExplorer();
|
||||||
} else if (id === TransactionListItem.actionKeys.ExpandNote) {
|
} else if (id === actionKeys.ExpandNote) {
|
||||||
handleOnExpandNote();
|
handleOnExpandNote();
|
||||||
} else if (id === TransactionListItem.actionKeys.CopyBlockExplorerLink) {
|
} else if (id === actionKeys.CopyBlockExplorerLink) {
|
||||||
handleCopyOpenInBlockExplorerPress();
|
handleCopyOpenInBlockExplorerPress();
|
||||||
} else if (id === TransactionListItem.actionKeys.CopyTXID) {
|
} else if (id === actionKeys.CopyTXID) {
|
||||||
handleOnCopyTransactionID();
|
handleOnCopyTransactionID();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -273,36 +288,36 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
const actions = [];
|
const actions = [];
|
||||||
if (rowTitle !== loc.lnd.expired) {
|
if (rowTitle !== loc.lnd.expired) {
|
||||||
actions.push({
|
actions.push({
|
||||||
id: TransactionListItem.actionKeys.CopyAmount,
|
id: actionKeys.CopyAmount,
|
||||||
text: loc.transactions.details_copy_amount,
|
text: loc.transactions.details_copy_amount,
|
||||||
icon: TransactionListItem.actionIcons.Clipboard,
|
icon: actionIcons.Clipboard,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subtitle) {
|
if (subtitle) {
|
||||||
actions.push({
|
actions.push({
|
||||||
id: TransactionListItem.actionKeys.CopyNote,
|
id: actionKeys.CopyNote,
|
||||||
text: loc.transactions.details_copy_note,
|
text: loc.transactions.details_copy_note,
|
||||||
icon: TransactionListItem.actionIcons.Clipboard,
|
icon: actionIcons.Clipboard,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (item.hash) {
|
if (item.hash) {
|
||||||
actions.push(
|
actions.push(
|
||||||
{
|
{
|
||||||
id: TransactionListItem.actionKeys.CopyTXID,
|
id: actionKeys.CopyTXID,
|
||||||
text: loc.transactions.details_copy_txid,
|
text: loc.transactions.details_copy_txid,
|
||||||
icon: TransactionListItem.actionIcons.Clipboard,
|
icon: actionIcons.Clipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: TransactionListItem.actionKeys.CopyBlockExplorerLink,
|
id: actionKeys.CopyBlockExplorerLink,
|
||||||
text: loc.transactions.details_copy_block_explorer_link,
|
text: loc.transactions.details_copy_block_explorer_link,
|
||||||
icon: TransactionListItem.actionIcons.Clipboard,
|
icon: actionIcons.Clipboard,
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: TransactionListItem.actionKeys.OpenInBlockExplorer,
|
id: actionKeys.OpenInBlockExplorer,
|
||||||
text: loc.transactions.details_show_in_block_explorer,
|
text: loc.transactions.details_show_in_block_explorer,
|
||||||
icon: TransactionListItem.actionIcons.Link,
|
icon: actionIcons.Link,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -311,9 +326,9 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
if (subtitle && subtitleNumberOfLines === 1) {
|
if (subtitle && subtitleNumberOfLines === 1) {
|
||||||
actions.push([
|
actions.push([
|
||||||
{
|
{
|
||||||
id: TransactionListItem.actionKeys.ExpandNote,
|
id: actionKeys.ExpandNote,
|
||||||
text: loc.transactions.expand_note,
|
text: loc.transactions.expand_note,
|
||||||
icon: TransactionListItem.actionIcons.Note,
|
icon: actionIcons.Note,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -326,6 +341,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<ToolTipMenu ref={menuRef} actions={toolTipActions} onPressMenuItem={onToolTipPress} onPress={onPress}>
|
<ToolTipMenu ref={menuRef} actions={toolTipActions} onPressMenuItem={onToolTipPress} onPress={onPress}>
|
||||||
<ListItem
|
<ListItem
|
||||||
|
// @ts-ignore wtf
|
||||||
leftAvatar={avatar}
|
leftAvatar={avatar}
|
||||||
title={title}
|
title={title}
|
||||||
subtitleNumberOfLines={subtitleNumberOfLines}
|
subtitleNumberOfLines={subtitleNumberOfLines}
|
||||||
@ -342,7 +358,7 @@ export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUn
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
TransactionListItem.actionKeys = {
|
const actionKeys = {
|
||||||
CopyTXID: 'copyTX_ID',
|
CopyTXID: 'copyTX_ID',
|
||||||
CopyBlockExplorerLink: 'copy_blockExplorer',
|
CopyBlockExplorerLink: 'copy_blockExplorer',
|
||||||
ExpandNote: 'expandNote',
|
ExpandNote: 'expandNote',
|
||||||
@ -351,7 +367,7 @@ TransactionListItem.actionKeys = {
|
|||||||
CopyNote: 'copyNote',
|
CopyNote: 'copyNote',
|
||||||
};
|
};
|
||||||
|
|
||||||
TransactionListItem.actionIcons = {
|
const actionIcons = {
|
||||||
Eye: {
|
Eye: {
|
||||||
iconType: 'SYSTEM',
|
iconType: 'SYSTEM',
|
||||||
iconValue: 'eye',
|
iconValue: 'eye',
|
||||||
|
@ -373,6 +373,8 @@
|
|||||||
"status_cancel": "Cancel Transaction",
|
"status_cancel": "Cancel Transaction",
|
||||||
"transactions_count": "Transactions Count",
|
"transactions_count": "Transactions Count",
|
||||||
"txid": "Transaction ID",
|
"txid": "Transaction ID",
|
||||||
|
"from": "From: {counterparty}",
|
||||||
|
"to": "To: {counterparty}",
|
||||||
"updating": "Updating..."
|
"updating": "Updating..."
|
||||||
},
|
},
|
||||||
"wallets": {
|
"wallets": {
|
||||||
|
@ -426,7 +426,14 @@ const TransactionsStatus = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shortenCounterpartyName = (addr: string): string => {
|
||||||
|
if (addr.length < 20) return addr;
|
||||||
|
return addr.substr(0, 10) + '...' + addr.substr(addr.length - 10, 10);
|
||||||
|
};
|
||||||
|
|
||||||
const renderTXMetadata = () => {
|
const renderTXMetadata = () => {
|
||||||
|
const counterparty = tx.counterparty ? shortenCounterpartyName(tx.counterparty) : false;
|
||||||
|
|
||||||
if (txMetadata[tx.hash]) {
|
if (txMetadata[tx.hash]) {
|
||||||
if (txMetadata[tx.hash].memo) {
|
if (txMetadata[tx.hash].memo) {
|
||||||
return (
|
return (
|
||||||
@ -434,6 +441,20 @@ const TransactionsStatus = () => {
|
|||||||
<Text selectable style={styles.memoText}>
|
<Text selectable style={styles.memoText}>
|
||||||
{txMetadata[tx.hash].memo}
|
{txMetadata[tx.hash].memo}
|
||||||
</Text>
|
</Text>
|
||||||
|
{counterparty ? (
|
||||||
|
<View>
|
||||||
|
<BlueSpacing10 />
|
||||||
|
<Text selectable style={styles.memoText}>
|
||||||
|
{tx.value < 0
|
||||||
|
? loc.formatString(loc.transactions.to, {
|
||||||
|
counterparty,
|
||||||
|
})
|
||||||
|
: loc.formatString(loc.transactions.from, {
|
||||||
|
counterparty,
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -207,7 +207,7 @@ describe('Bech32 Segwit HD (BIP84) with BIP47', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
w.getSenderByTxid('64058a49bb75481fc0bebbb0d84a4aceebe319f9d32929e73cefb21d83342e9f'),
|
w.getBip47CounterpartyByTxid('64058a49bb75481fc0bebbb0d84a4aceebe319f9d32929e73cefb21d83342e9f'),
|
||||||
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
||||||
); // we got paid
|
); // we got paid
|
||||||
|
|
||||||
@ -240,8 +240,22 @@ describe('Bech32 Segwit HD (BIP84) with BIP47', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
w.getSenderByTxid('73a2ac70858c5b306b101a861d582f40c456a692096a4e4805aa739258c4400d'),
|
w.getBip47CounterpartyByTxid('73a2ac70858c5b306b101a861d582f40c456a692096a4e4805aa739258c4400d'),
|
||||||
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
||||||
); // we paid sparrow
|
); // we paid sparrow
|
||||||
|
|
||||||
|
let txWithCounterparty = w.getTransactions().find(tx => tx.txid === '73a2ac70858c5b306b101a861d582f40c456a692096a4e4805aa739258c4400d');
|
||||||
|
assert(txWithCounterparty);
|
||||||
|
assert.strictEqual(
|
||||||
|
txWithCounterparty.counterparty,
|
||||||
|
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
||||||
|
);
|
||||||
|
|
||||||
|
txWithCounterparty = w.getTransactions().find(tx => tx.txid === '64058a49bb75481fc0bebbb0d84a4aceebe319f9d32929e73cefb21d83342e9f');
|
||||||
|
assert(txWithCounterparty);
|
||||||
|
assert.strictEqual(
|
||||||
|
txWithCounterparty.counterparty,
|
||||||
|
'PM8TJi1RuCrgSHTzGMoayUf8xUW6zYBGXBPSWwTiMhMMwqto7G6NA4z9pN5Kn8Pbhryo2eaHMFRRcidCGdB3VCDXJD4DdPD2ZyG3ScLMEvtStAetvPMo',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user