eToken
@@ -396,7 +396,7 @@
exports[`Wallet without BCH balance 1`] = `
Array [
XEC
eToken
diff --git a/web/cashtab/src/hooks/__mocks__/mockParsedTxs.js b/web/cashtab/src/hooks/__mocks__/mockParsedTxs.js
--- a/web/cashtab/src/hooks/__mocks__/mockParsedTxs.js
+++ b/web/cashtab/src/hooks/__mocks__/mockParsedTxs.js
@@ -9,6 +9,7 @@
'bitcoincash:qphpmfj0qn7znklqhrfn5dq7qh36l3vxavu346vqcl',
height: 674993,
outgoingTx: true,
+ isCashtabMessage: false,
opReturnMessage: '',
tokenTx: false,
txid: '089f2188d5771a7de0589def2b8d6c1a1f33f45b6de26d9a0ef32782f019ecf1',
@@ -25,6 +26,7 @@
'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9',
height: 672077,
outgoingTx: false,
+ isCashtabMessage: false,
opReturnMessage: '',
tokenTx: false,
txid: '42d39fbe068a40fe691f987b22fdf04b80f94d71d2fec20a58125e7b1a06d2a9',
@@ -41,6 +43,7 @@
'bitcoincash:qzj5zu6fgg8v2we82gh76xnrk9njcregluzgaztm45',
height: 674444,
outgoingTx: true,
+ isCashtabMessage: false,
opReturnMessage: '',
tokenTx: true,
txid: 'ffe3a7500dbcc98021ad581c98d9947054d1950a7f3416664715066d3d20ad72',
@@ -56,6 +59,7 @@
'bitcoincash:qpmytrdsakt0axrrlswvaj069nat3p9s7ct4lsf8k9',
height: 674143,
outgoingTx: false,
+ isCashtabMessage: false,
opReturnMessage: '',
tokenTx: true,
txid: '618d0dd8c0c5fa5a34c6515c865dd72bb76f8311cd6ee9aef153bab20dabc0e6',
@@ -72,6 +76,7 @@
opReturnMessage: new Buffer('testing message 12'),
outgoingTx: false,
tokenTx: false,
+ isCashtabMessage: true,
txid: 'dd35690b0cefd24dcc08acba8694ecd49293f365a81372cb66c8f1c1291d97c5',
},
];
@@ -86,6 +91,7 @@
opReturnMessage: new Buffer('testing message 13'),
outgoingTx: false,
tokenTx: false,
+ isCashtabMessage: true,
txid: '5adc33b5c0509b31c6da359177b19467c443bdc4dd37c283c0f87244c0ad63af',
},
];
diff --git a/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js b/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js
--- a/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js
+++ b/web/cashtab/src/hooks/__mocks__/mockTxDataWithPassthrough.js
@@ -789,7 +789,7 @@
value: 0,
n: 0,
scriptPubKey: {
- asm: 'OP_RETURN 621 74657374696e67206d657373616765203132',
+ asm: 'OP_RETURN 1130 1650553856 74657374696e67206d657373616765203132',
hex: '6a026d021274657374696e67206d657373616765203132',
type: 'nulldata',
},
@@ -840,7 +840,7 @@
value: 0,
n: 0,
scriptPubKey: {
- asm: 'OP_RETURN 621 74657374696e67206d657373616765203133',
+ asm: 'OP_RETURN 1130 1650553856 74657374696e67206d657373616765203133',
hex: '6a026d021274657374696e67206d657373616765203133',
type: 'nulldata',
},
diff --git a/web/cashtab/src/hooks/__tests__/useBCH.test.js b/web/cashtab/src/hooks/__tests__/useBCH.test.js
--- a/web/cashtab/src/hooks/__tests__/useBCH.test.js
+++ b/web/cashtab/src/hooks/__tests__/useBCH.test.js
@@ -1,5 +1,5 @@
/* eslint-disable no-native-reassign */
-import useBCH from '../useBCH';
+import useBCH, { removeOpReturnPrefixes } from '../useBCH';
import mockReturnGetHydratedUtxoDetails from '../__mocks__/mockReturnGetHydratedUtxoDetails';
import mockReturnGetSlpBalancesAndUtxos from '../__mocks__/mockReturnGetSlpBalancesAndUtxos';
import mockReturnGetHydratedUtxoDetailsWithZeroBalance from '../__mocks__/mockReturnGetHydratedUtxoDetailsWithZeroBalance';
@@ -414,4 +414,31 @@
mockReceivedOpReturnMessageTx,
);
});
+
+ it(`Correctly removes an OP_RETURN message prefix from an ASM substring`, () => {
+ const { removeOpReturnPrefixes } = useBCH();
+ expect(
+ removeOpReturnPrefixes('OP_RETURN 1130 REMAINDER'),
+ ).toStrictEqual('OP_RETURN REMAINDER');
+ });
+
+ it(`Correctly returns an eToken OP_RETURN message prefix untouched`, () => {
+ const { removeOpReturnPrefixes } = useBCH();
+ expect(
+ removeOpReturnPrefixes(
+ 'OP_RETURN 5262419 1 1145980243 69b8431ddecf775393b1b36aa1d0ddcd7b342f1157b9671a03747378ed35ea0d 00000000000000e6 000000000000010e',
+ ),
+ ).toStrictEqual(
+ 'OP_RETURN 5262419 1 1145980243 69b8431ddecf775393b1b36aa1d0ddcd7b342f1157b9671a03747378ed35ea0d 00000000000000e6 000000000000010e',
+ );
+ });
+
+ it(`Correctly returns an invalid OP_RETURN message prefix untouched`, () => {
+ const { removeOpReturnPrefixes } = useBCH();
+ expect(
+ removeOpReturnPrefixes(
+ 'OP_RETURN not a message its just gibberish REMAINDER',
+ ),
+ ).toStrictEqual('OP_RETURN not a message its just gibberish REMAINDER');
+ });
});
diff --git a/web/cashtab/src/hooks/useBCH.js b/web/cashtab/src/hooks/useBCH.js
--- a/web/cashtab/src/hooks/useBCH.js
+++ b/web/cashtab/src/hooks/useBCH.js
@@ -33,9 +33,10 @@
// filter out prefixes for OP_RETURN encoded messages
// Note: only for use with encoded message strings
const removeOpReturnPrefixes = asmStr => {
- if (asmStr.includes(' 621')) {
- //strip out the 621 (6d02) prefix if exists
- asmStr = asmStr.replace(' 621', '');
+ let msgPrefix = ' ' + currency.opReturn.opreturnMessagePrefixAsm;
+ if (asmStr.includes(msgPrefix)) {
+ //strip out the message prefix if exists
+ asmStr = asmStr.replace(msgPrefix, '');
}
return asmStr;
};
@@ -126,6 +127,7 @@
let amountSent = 0;
let amountReceived = 0;
let opReturnMessage = '';
+ let isCashtabMessage = false;
// Assume an incoming transaction
let outgoingTx = false;
let tokenTx = false;
@@ -148,7 +150,9 @@
!Object.keys(thisOutput.scriptPubKey).includes('addresses')
) {
let asm = thisOutput.scriptPubKey.asm;
- if (asm.includes('OP_RETURN 5262419')) {
+ let eTokenSubstring =
+ 'OP_RETURN ' + currency.opReturn.eTokenPrefixAsm;
+ if (asm.includes(eTokenSubstring)) {
// assume this is an eToken tx for now
// future diffs will add additional NFT parsing logic in this segment
tokenTx = true;
@@ -156,9 +160,23 @@
// if this is not an eToken tx and does not contain addresses, then assume encoded message
asm = removeOpReturnPrefixes(asm);
let msgBody = asm.substr(asm.indexOf(' ') + 1); // extract everything after the OP_RETURN opcode
+
try {
- opReturnMessage = Buffer.from(msgBody, 'hex');
+ if (
+ msgBody.split(' ')[0] ===
+ currency.opReturn.cashtabPrefixAsm
+ ) {
+ // this is a Cashtab.com generated message
+ opReturnMessage = Buffer.from(
+ msgBody.substr(msgBody.indexOf(' ') + 1),
+ 'hex',
+ ); // extract everything after the Cashtab prefix
+ isCashtabMessage = true;
+ } else {
+ opReturnMessage = Buffer.from(msgBody, 'hex');
+ }
} catch (err) {
+ // if an unexpected or invalid hex is encountered
opReturnMessage = '';
}
}
@@ -186,7 +204,7 @@
parsedTx.outgoingTx = outgoingTx;
parsedTx.destinationAddress = destinationAddress;
parsedTx.opReturnMessage = opReturnMessage;
-
+ parsedTx.isCashtabMessage = isCashtabMessage;
parsedTxHistory.push(parsedTx);
}
return parsedTxHistory;
@@ -990,7 +1008,12 @@
) {
const script = [
BCH.Script.opcodes.OP_RETURN,
- Buffer.from('6d02', 'hex'),
+ Buffer.from(
+ currency.opReturn.opReturnPrefixHex +
+ currency.opReturn.opReturnPushDataHex,
+ 'hex',
+ ),
+ Buffer.from(currency.opReturn.cashtabPrefixHex, 'hex'),
Buffer.from(optionalOpReturnMsg),
];
const data = BCH.Script.encode(script);
@@ -1132,5 +1155,6 @@
sendToken,
createToken,
getTokenStats,
+ removeOpReturnPrefixes,
};
}