diff --git a/cashtab/src/components/Alias/Alias.js b/cashtab/src/components/Alias/Alias.js
--- a/cashtab/src/components/Alias/Alias.js
+++ b/cashtab/src/components/Alias/Alias.js
@@ -68,9 +68,10 @@
isAliasServerOnline,
} = ContextValue;
const walletState = getWalletState(wallet);
- const { balances, nonSlpUtxos } = walletState;
+ const { balances } = walletState;
const [formData, setFormData] = useState({
aliasName: '',
+ aliasAddress: '',
});
const [isValidAliasInput, setIsValidAliasInput] = useState(false); // tracks whether to activate the registration button
const [aliasValidationError, setAliasValidationError] = useState(false);
@@ -97,6 +98,13 @@
}
passLoadingStatus(true);
+ // Set address of active wallet to default alias registration address
+ // Use formdata approach as we will later add a form field for aliasAddress
+ setFormData(formData => ({
+ ...formData,
+ aliasAddress: wallet.Path1899.cashAddress,
+ }));
+
// check whether the address is attached to an onchain alias on page load
const walletHasAlias = isAddressRegistered(
wallet,
@@ -151,6 +159,7 @@
// note: input already validated via handleAliasNameInput()
const aliasInput = formData.aliasName;
+ const aliasAddress = formData.aliasAddress;
// check if the user is trying to essentially register chicken.xec.xec
const doubleExtensionInput = isAliasFormat(aliasInput);
@@ -184,16 +193,16 @@
`Alias ${aliasInput} is available. Broadcasting registration transaction.`,
);
try {
- const link = await registerNewAlias(
+ const result = await registerNewAlias(
chronik,
wallet,
- nonSlpUtxos,
currency.defaultFee,
aliasInput,
- fromSatoshisToXec(registrationFee),
+ aliasAddress,
+ registrationFee,
);
- registerAliasNotification(link, aliasInput);
+ registerAliasNotification(result.explorerLink, aliasInput);
// allow alias server to process the pending alias
const delay = ms => new Promise(res => setTimeout(res, ms));
@@ -306,7 +315,9 @@
onCancel={handleCancel}
>
- {`Are you sure you want to register the alias '${formData.aliasName}' for ${fromSatoshisToXec(aliasFee)} XECs?`}
+ {`Are you sure you want to register the alias '${
+ formData.aliasName
+ }' for ${fromSatoshisToXec(aliasFee)} XECs?`}
@@ -380,7 +391,9 @@
setIsModalVisible(true)}
+ onClick={() =>
+ setIsModalVisible(true)
+ }
>
Register Alias
diff --git a/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap b/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
--- a/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
+++ b/cashtab/src/components/Send/__tests__/__snapshots__/Send.test.js.snap
@@ -1,4 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+// @generated
exports[`Wallet with BCH balances 1`] = `
Array [
@@ -197,7 +198,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
@@ -787,7 +788,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
@@ -1382,7 +1383,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
@@ -1973,7 +1974,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
@@ -2558,7 +2559,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
diff --git a/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap b/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
--- a/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
+++ b/cashtab/src/components/Send/__tests__/__snapshots__/SendToken.test.js.snap
@@ -1,4 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+// @generated
exports[`Wallet with BCH balances and tokens 1`] = `null`;
@@ -101,7 +102,7 @@
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
- placeholder="Address"
+ placeholder="Address or Alias"
required={true}
style={null}
type="text"
diff --git a/cashtab/src/utils/__mocks__/registerNewAliasMocks.js b/cashtab/src/utils/__mocks__/registerNewAliasMocks.js
new file mode 100644
--- /dev/null
+++ b/cashtab/src/utils/__mocks__/registerNewAliasMocks.js
@@ -0,0 +1,608 @@
+// @generated
+
+export const aliasRegisteringWallet = {
+ mnemonic:
+ 'cheese purpose sphere member afford orbit aisle bundle shoe save delay poverty',
+ name: '[burned]aliasRegTest',
+ Path245: {
+ publicKey:
+ '033a8335572ad5877fb4691d702dc276e965e3dfc61b7ddb1266e56ee9e63b07c7',
+ hash160: '260ad4f88031bf90191db87956a141a4caee41b9',
+ cashAddress: 'ecash:qqnq448csqcmlyqerku8j44pgxjv4mjphyvf4q7ku5',
+ fundingWif: 'L2z9MWRYBdajS1JUvry8ef3H4dMoJiQpL7H9gh9QY9uN4tTW5sty',
+ },
+ Path145: {
+ publicKey:
+ '03bb8d0f9b479bbbf17025f1c58c34c9831ad4ac16f1707fb3e19bf4a990eed517',
+ hash160: '7774bdf6dc5f88dcbafc9876ddda68d6ef9f5079',
+ cashAddress: 'ecash:qpmhf00km30c3h96ljv8dhw6drtwl86s0ysn32vngq',
+ fundingWif: 'Kwhw5NivkPBigRCsRFeab2W62yWHH3aNAK8PBAeK4cW13Sk3NM98',
+ },
+ Path1899: {
+ publicKey:
+ '036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ hash160: '20edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ cashAddress: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ fundingWif: 'L3NFW2e1T92cF6YZydoEtpmYSm1hhmUzJ9fXgBAzF8ts4Eugno2D',
+ },
+ state: {
+ balances: {
+ totalBalanceInSatoshis: '10000000',
+ totalBalance: '100000',
+ },
+ slpUtxos: [],
+ nonSlpUtxos: [
+ {
+ outpoint: {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ outIdx: 0,
+ },
+ blockHeight: 790294,
+ isCoinbase: false,
+ value: '10000000',
+ network: 'XEC',
+ address: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ },
+ ],
+ tokens: [],
+ parsedTxHistory: [
+ {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '88fec8beeda59c72b06b6d5d9531a03e4ecb46a0097501565361900f9dcc280a',
+ outIdx: 1,
+ },
+ inputScript:
+ '47304402206bb74db30b624d62b51e00f1f4a309ad7c037c55c45ac38425a63e4b168e92ad022034e464b5f6136bb63345a32e40aa0c3224fcfb6ad4bb7449094b84f36a331e294121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '8849259',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '1c0b5e632601d041a4423e05aa9824c8d368eb01c8a9aaefc506233879349404',
+ outIdx: 3,
+ },
+ inputScript:
+ '4730440220097633057fd28fb098c11012e63e05850b4f172f37dd58373c14ef80fdc790cb02203f0d5f44b92f3e659c605faac2c6743eacf223f695d1ce7cfd07796ff0a241694121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '5000',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '179f65e21f4bb3ee3bf9d0433b7a6df7ed6e5a795b2c1aea47902e1fb0e39fe3',
+ outIdx: 1,
+ },
+ inputScript:
+ '473044022062f6dcddca0d477dedd0024cabf0b4e22f2b213231f385e0b68e9e5f41eb04e602201597c7df3495bab6093612d2628b8c30554c27a24d452bc11e3a51fd37727f264121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '1100674',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '9da7445bb061944175710efcb5a22118aceb6c23c8bc82d4afeddddd410ea2b5',
+ outIdx: 2,
+ },
+ inputScript:
+ '47304402207d591fe5f8f6d71e120634be09674e36074122c3291c00c18e6807397ecac323022021e7e9c2c0fb724e99a74e0dd5dba453d292a1cd32f55e18a33fcf515b50e9784121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '9998848',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '10000000',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ },
+ {
+ value: '9952434',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790294,
+ hash: '0000000000000000084fe051052cbbe8778135f254076b3e20e9f08387654b2f',
+ timestamp: '1683047794',
+ },
+ timeFirstSeen: '1683047404',
+ size: 666,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: true,
+ xecAmount: '100000',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr',
+ aliasFlag: false,
+ },
+ },
+ ],
+ },
+};
+export const aliasRegisteringWalletAfterTx = {
+ mnemonic:
+ 'cheese purpose sphere member afford orbit aisle bundle shoe save delay poverty',
+ name: '[burned]aliasRegTest',
+ Path245: {
+ publicKey:
+ '033a8335572ad5877fb4691d702dc276e965e3dfc61b7ddb1266e56ee9e63b07c7',
+ hash160: '260ad4f88031bf90191db87956a141a4caee41b9',
+ cashAddress: 'ecash:qqnq448csqcmlyqerku8j44pgxjv4mjphyvf4q7ku5',
+ fundingWif: 'L2z9MWRYBdajS1JUvry8ef3H4dMoJiQpL7H9gh9QY9uN4tTW5sty',
+ },
+ Path145: {
+ publicKey:
+ '03bb8d0f9b479bbbf17025f1c58c34c9831ad4ac16f1707fb3e19bf4a990eed517',
+ hash160: '7774bdf6dc5f88dcbafc9876ddda68d6ef9f5079',
+ cashAddress: 'ecash:qpmhf00km30c3h96ljv8dhw6drtwl86s0ysn32vngq',
+ fundingWif: 'Kwhw5NivkPBigRCsRFeab2W62yWHH3aNAK8PBAeK4cW13Sk3NM98',
+ },
+ Path1899: {
+ publicKey:
+ '036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ hash160: '20edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ cashAddress: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ fundingWif: 'L3NFW2e1T92cF6YZydoEtpmYSm1hhmUzJ9fXgBAzF8ts4Eugno2D',
+ },
+ state: {
+ balances: {
+ totalBalanceInSatoshis: '9998994',
+ totalBalance: '99989.94',
+ },
+ slpUtxos: [],
+ nonSlpUtxos: [
+ {
+ outpoint: {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ outIdx: 2,
+ },
+ blockHeight: 790297,
+ isCoinbase: false,
+ value: '9998994',
+ network: 'XEC',
+ address: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ },
+ ],
+ tokens: [],
+ parsedTxHistory: [
+ {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ outIdx: 0,
+ },
+ inputScript:
+ '483045022100dd79c2a3e8773e7d4963ad3f6f03b54aca569e8e383c5cdc285afa601ee50829022058dfcdc905ec8f45d7418644ccfdf45cd8db41aade2d57d455c50e1a181cf7bb4121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ value: '10000000',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '0',
+ outputScript:
+ '6a042e78656300086e65777465737431150020edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ },
+ {
+ value: '551',
+ outputScript:
+ '76a914638568e36d0b5d7d49a6e99854caa27d9772b09388ac',
+ },
+ {
+ value: '9998994',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790297,
+ hash: '000000000000000016920644c8c4abcf1681a6ca9068e532410554e901848d41',
+ timestamp: '1683049955',
+ },
+ timeFirstSeen: '1683049080',
+ size: 273,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: false,
+ xecAmount: '5.51',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ aliasFlag: true,
+ },
+ },
+ {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '88fec8beeda59c72b06b6d5d9531a03e4ecb46a0097501565361900f9dcc280a',
+ outIdx: 1,
+ },
+ inputScript:
+ '47304402206bb74db30b624d62b51e00f1f4a309ad7c037c55c45ac38425a63e4b168e92ad022034e464b5f6136bb63345a32e40aa0c3224fcfb6ad4bb7449094b84f36a331e294121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '8849259',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '1c0b5e632601d041a4423e05aa9824c8d368eb01c8a9aaefc506233879349404',
+ outIdx: 3,
+ },
+ inputScript:
+ '4730440220097633057fd28fb098c11012e63e05850b4f172f37dd58373c14ef80fdc790cb02203f0d5f44b92f3e659c605faac2c6743eacf223f695d1ce7cfd07796ff0a241694121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '5000',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '179f65e21f4bb3ee3bf9d0433b7a6df7ed6e5a795b2c1aea47902e1fb0e39fe3',
+ outIdx: 1,
+ },
+ inputScript:
+ '473044022062f6dcddca0d477dedd0024cabf0b4e22f2b213231f385e0b68e9e5f41eb04e602201597c7df3495bab6093612d2628b8c30554c27a24d452bc11e3a51fd37727f264121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '1100674',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '9da7445bb061944175710efcb5a22118aceb6c23c8bc82d4afeddddd410ea2b5',
+ outIdx: 2,
+ },
+ inputScript:
+ '47304402207d591fe5f8f6d71e120634be09674e36074122c3291c00c18e6807397ecac323022021e7e9c2c0fb724e99a74e0dd5dba453d292a1cd32f55e18a33fcf515b50e9784121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '9998848',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '10000000',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ spentBy: {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ outIdx: 0,
+ },
+ },
+ {
+ value: '9952434',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790294,
+ hash: '0000000000000000084fe051052cbbe8778135f254076b3e20e9f08387654b2f',
+ timestamp: '1683047794',
+ },
+ timeFirstSeen: '1683047404',
+ size: 666,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: true,
+ xecAmount: '100000',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr',
+ aliasFlag: false,
+ },
+ },
+ ],
+ },
+};
+export const aliasRegisteringWalletAfterTwoTxs = {
+ mnemonic:
+ 'cheese purpose sphere member afford orbit aisle bundle shoe save delay poverty',
+ name: '[burned]aliasRegTest',
+ Path245: {
+ publicKey:
+ '033a8335572ad5877fb4691d702dc276e965e3dfc61b7ddb1266e56ee9e63b07c7',
+ hash160: '260ad4f88031bf90191db87956a141a4caee41b9',
+ cashAddress: 'ecash:qqnq448csqcmlyqerku8j44pgxjv4mjphyvf4q7ku5',
+ fundingWif: 'L2z9MWRYBdajS1JUvry8ef3H4dMoJiQpL7H9gh9QY9uN4tTW5sty',
+ },
+ Path145: {
+ publicKey:
+ '03bb8d0f9b479bbbf17025f1c58c34c9831ad4ac16f1707fb3e19bf4a990eed517',
+ hash160: '7774bdf6dc5f88dcbafc9876ddda68d6ef9f5079',
+ cashAddress: 'ecash:qpmhf00km30c3h96ljv8dhw6drtwl86s0ysn32vngq',
+ fundingWif: 'Kwhw5NivkPBigRCsRFeab2W62yWHH3aNAK8PBAeK4cW13Sk3NM98',
+ },
+ Path1899: {
+ publicKey:
+ '036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ hash160: '20edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ cashAddress: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ fundingWif: 'L3NFW2e1T92cF6YZydoEtpmYSm1hhmUzJ9fXgBAzF8ts4Eugno2D',
+ },
+ state: {
+ balances: {
+ totalBalanceInSatoshis: '9997988',
+ totalBalance: '99979.88',
+ },
+ slpUtxos: [],
+ nonSlpUtxos: [
+ {
+ outpoint: {
+ txid: '912582a1dc11b568f14f8ebae15cbb0ce53bdb973e137e7dc7c9b261327e6cab',
+ outIdx: 2,
+ },
+ blockHeight: 790312,
+ isCoinbase: false,
+ value: '9997988',
+ network: 'XEC',
+ address: 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ },
+ ],
+ tokens: [],
+ parsedTxHistory: [
+ {
+ txid: '912582a1dc11b568f14f8ebae15cbb0ce53bdb973e137e7dc7c9b261327e6cab',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ outIdx: 2,
+ },
+ inputScript:
+ '47304402205cf1941bd0ed8c49319189973feebd14e8d7faf6c5a3cdc6c16f676bd62c63ac022068c10726326e37f960433a92894609f7f0b65946d8104038110e2104d973c8e24121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ value: '9998994',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '0',
+ outputScript:
+ '6a042e78656300157477656e74796f6e6562797465616c696173726567150020edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ },
+ {
+ value: '551',
+ outputScript:
+ '76a914638568e36d0b5d7d49a6e99854caa27d9772b09388ac',
+ },
+ {
+ value: '9997988',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790312,
+ hash: '0000000000000000170185a5ef34ce2d9eaa9eebc540dadac15eb154c8c7aedd',
+ timestamp: '1683063775',
+ },
+ timeFirstSeen: '1683063315',
+ size: 285,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: false,
+ xecAmount: '5.51',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ aliasFlag: true,
+ },
+ },
+ {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ outIdx: 0,
+ },
+ inputScript:
+ '483045022100dd79c2a3e8773e7d4963ad3f6f03b54aca569e8e383c5cdc285afa601ee50829022058dfcdc905ec8f45d7418644ccfdf45cd8db41aade2d57d455c50e1a181cf7bb4121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ value: '10000000',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '0',
+ outputScript:
+ '6a042e78656300086e65777465737431150020edc8389101aed204b9c17b7d64a00ead0e8cfc',
+ },
+ {
+ value: '551',
+ outputScript:
+ '76a914638568e36d0b5d7d49a6e99854caa27d9772b09388ac',
+ },
+ {
+ value: '9998994',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ spentBy: {
+ txid: '912582a1dc11b568f14f8ebae15cbb0ce53bdb973e137e7dc7c9b261327e6cab',
+ outIdx: 0,
+ },
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790297,
+ hash: '000000000000000016920644c8c4abcf1681a6ca9068e532410554e901848d41',
+ timestamp: '1683049955',
+ },
+ timeFirstSeen: '1683049080',
+ size: 273,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: false,
+ xecAmount: '5.51',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ aliasFlag: true,
+ },
+ },
+ {
+ txid: '879e64ba90c09d957f6b7043776cd5c171ee2c7c82e728bd1fe97899f42d9c04',
+ version: 2,
+ inputs: [
+ {
+ prevOut: {
+ txid: '88fec8beeda59c72b06b6d5d9531a03e4ecb46a0097501565361900f9dcc280a',
+ outIdx: 1,
+ },
+ inputScript:
+ '47304402206bb74db30b624d62b51e00f1f4a309ad7c037c55c45ac38425a63e4b168e92ad022034e464b5f6136bb63345a32e40aa0c3224fcfb6ad4bb7449094b84f36a331e294121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '8849259',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '1c0b5e632601d041a4423e05aa9824c8d368eb01c8a9aaefc506233879349404',
+ outIdx: 3,
+ },
+ inputScript:
+ '4730440220097633057fd28fb098c11012e63e05850b4f172f37dd58373c14ef80fdc790cb02203f0d5f44b92f3e659c605faac2c6743eacf223f695d1ce7cfd07796ff0a241694121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '5000',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '179f65e21f4bb3ee3bf9d0433b7a6df7ed6e5a795b2c1aea47902e1fb0e39fe3',
+ outIdx: 1,
+ },
+ inputScript:
+ '473044022062f6dcddca0d477dedd0024cabf0b4e22f2b213231f385e0b68e9e5f41eb04e602201597c7df3495bab6093612d2628b8c30554c27a24d452bc11e3a51fd37727f264121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '1100674',
+ sequenceNo: 4294967295,
+ },
+ {
+ prevOut: {
+ txid: '9da7445bb061944175710efcb5a22118aceb6c23c8bc82d4afeddddd410ea2b5',
+ outIdx: 2,
+ },
+ inputScript:
+ '47304402207d591fe5f8f6d71e120634be09674e36074122c3291c00c18e6807397ecac323022021e7e9c2c0fb724e99a74e0dd5dba453d292a1cd32f55e18a33fcf515b50e9784121020d867a730bb6b55078d4eaf36fbf06d2a3867f81c20ad54925bcdd02ec914cbb',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ value: '9998848',
+ sequenceNo: 4294967295,
+ },
+ ],
+ outputs: [
+ {
+ value: '10000000',
+ outputScript:
+ '76a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac',
+ spentBy: {
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ outIdx: 0,
+ },
+ },
+ {
+ value: '9952434',
+ outputScript:
+ '76a9147f6df05119aa77f34cc54c8c3c0698bb5505f9f388ac',
+ },
+ ],
+ lockTime: 0,
+ block: {
+ height: 790294,
+ hash: '0000000000000000084fe051052cbbe8778135f254076b3e20e9f08387654b2f',
+ timestamp: '1683047794',
+ },
+ timeFirstSeen: '1683047404',
+ size: 666,
+ isCoinbase: false,
+ network: 'XEC',
+ parsed: {
+ incoming: true,
+ xecAmount: '100000',
+ isEtokenTx: false,
+ airdropFlag: false,
+ airdropTokenId: '',
+ opReturnMessage: '',
+ isCashtabMessage: false,
+ isEncryptedMessage: false,
+ decryptionSuccess: false,
+ replyAddress:
+ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr',
+ aliasFlag: false,
+ },
+ },
+ ],
+ },
+};
diff --git a/cashtab/src/utils/__tests__/transactions.test.js b/cashtab/src/utils/__tests__/transactions.test.js
--- a/cashtab/src/utils/__tests__/transactions.test.js
+++ b/cashtab/src/utils/__tests__/transactions.test.js
@@ -1,5 +1,10 @@
/* eslint-disable no-native-reassign */
import sendBCHMock from '../__mocks__/sendBCH';
+import {
+ aliasRegisteringWallet,
+ aliasRegisteringWalletAfterTx,
+ aliasRegisteringWalletAfterTwoTxs,
+} from '../__mocks__/registerNewAliasMocks';
import createTokenMock from '../__mocks__/createToken';
import { burnTokenWallet } from '../__mocks__/burnToken';
import { currency } from '../../components/Common/Ticker';
@@ -11,6 +16,7 @@
burnToken,
createToken,
getRecipientPublicKey,
+ registerNewAlias,
} from 'utils/transactions';
describe('Cashtab transaction broadcasting functions', () => {
@@ -99,6 +105,89 @@
).toBe(`${currency.blockExplorerUrl}/tx/${expectedTxId}`);
});
+ it('Broadcasts a v0 alias registration tx for an 8-byte alias to a p2pkh address', async () => {
+ const chronik = new ChronikClient(
+ 'https://FakeChronikUrlToEnsureMocksOnly.com',
+ );
+
+ const mockTxid =
+ '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0';
+
+ chronik.broadcastTx = jest.fn().mockResolvedValue({ txid: mockTxid });
+
+ const expectedResult = {
+ explorerLink:
+ 'https://explorer.e.cash/tx/1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ rawTxHex:
+ '0200000001049c2df49978e91fbd28e7827c2cee71c1d56c7743706b7f959dc090ba649e87000000006b483045022100dd79c2a3e8773e7d4963ad3f6f03b54aca569e8e383c5cdc285afa601ee50829022058dfcdc905ec8f45d7418644ccfdf45cd8db41aade2d57d455c50e1a181cf7bb4121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6ffffffff030000000000000000266a042e78656300086e65777465737431150020edc8389101aed204b9c17b7d64a00ead0e8cfc27020000000000001976a914638568e36d0b5d7d49a6e99854caa27d9772b09388ac92929800000000001976a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac00000000',
+ txid: '1272c4a9bf5829c9dba1efb252e753ed20e3cdd49b6e75a778befc7a87eaf7d0',
+ };
+ expect(
+ await registerNewAlias(
+ chronik,
+ aliasRegisteringWallet,
+ currency.defaultFee,
+ 'newtest1',
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ 551,
+ ),
+ ).toStrictEqual(expectedResult);
+ });
+ it('Broadcasts a v0 alias registration tx for a 21-byte alias to a p2pkh address', async () => {
+ const chronik = new ChronikClient(
+ 'https://FakeChronikUrlToEnsureMocksOnly.com',
+ );
+
+ const mockTxid =
+ '912582a1dc11b568f14f8ebae15cbb0ce53bdb973e137e7dc7c9b261327e6cab';
+
+ chronik.broadcastTx = jest.fn().mockResolvedValue({ txid: mockTxid });
+
+ const expectedResult = {
+ explorerLink: `${currency.blockExplorerUrl}/tx/${mockTxid}`,
+ txid: mockTxid,
+ rawTxHex:
+ '0200000001d0f7ea877afcbe78a7756e9bd4cde320ed53e752b2efa1dbc92958bfa9c47212020000006a47304402205cf1941bd0ed8c49319189973feebd14e8d7faf6c5a3cdc6c16f676bd62c63ac022068c10726326e37f960433a92894609f7f0b65946d8104038110e2104d973c8e24121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6ffffffff030000000000000000336a042e78656300157477656e74796f6e6562797465616c696173726567150020edc8389101aed204b9c17b7d64a00ead0e8cfc27020000000000001976a914638568e36d0b5d7d49a6e99854caa27d9772b09388aca48e9800000000001976a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac00000000',
+ };
+ expect(
+ await registerNewAlias(
+ chronik,
+ aliasRegisteringWalletAfterTx,
+ currency.defaultFee,
+ 'twentyonebytealiasreg',
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ 551,
+ ),
+ ).toStrictEqual(expectedResult);
+ });
+ it('Broadcasts a v0 alias registration tx for a 16-byte alias to a p2pkh address', async () => {
+ const chronik = new ChronikClient(
+ 'https://FakeChronikUrlToEnsureMocksOnly.com',
+ );
+
+ const mockTxid =
+ '8783d7064ce22e8390c9fa94ef9a4d5bb0184e401ef5a9fbf60b68294e275c80';
+
+ chronik.broadcastTx = jest.fn().mockResolvedValue({ txid: mockTxid });
+
+ const expectedResult = {
+ explorerLink: `${currency.blockExplorerUrl}/tx/${mockTxid}`,
+ txid: mockTxid,
+ rawTxHex:
+ '0200000001ab6c7e3261b2c9c77d7e133e97db3be50cbb5ce1ba8e4ff168b511dca1822591020000006b483045022100d0bd27e798ac38de8b4c654c6670386c68d8bfac4bf5fe26a185d8250bd7ae7e02206acfe247b95ee9879080e6e413d7f28734aa498046e7363a638a537fc657c50e4121036ea648569566fa0843b914f67e54ebcfa6921208acd6408d2881488809403ac6ffffffff0300000000000000002e6a042e78656300107768796e6f7474687265657465737473150020edc8389101aed204b9c17b7d64a00ead0e8cfc27020000000000001976a914638568e36d0b5d7d49a6e99854caa27d9772b09388acb68a9800000000001976a91420edc8389101aed204b9c17b7d64a00ead0e8cfc88ac00000000',
+ };
+ expect(
+ await registerNewAlias(
+ chronik,
+ aliasRegisteringWalletAfterTwoTxs,
+ currency.defaultFee,
+ 'whynotthreetests',
+ 'ecash:qqswmjpcjyq6a5syh8qhklty5q826r5vlsh7a7uqtq',
+ 551,
+ ),
+ ).toStrictEqual(expectedResult);
+ });
+
it(`Throws error if called trying to send one base unit ${currency.ticker} more than available in utxo set`, async () => {
const chronik = new ChronikClient(
'https://FakeChronikUrlToEnsureMocksOnly.com',
diff --git a/cashtab/src/utils/transactions.js b/cashtab/src/utils/transactions.js
--- a/cashtab/src/utils/transactions.js
+++ b/cashtab/src/utils/transactions.js
@@ -12,6 +12,8 @@
getChangeAddressFromInputUtxos,
toHash160,
getMessageByteSize,
+ generateAliasOpReturnScript,
+ fromSatoshisToXec,
} from 'utils/cashMethods';
import ecies from 'ecies-lite';
import * as utxolib from '@bitgo/utxo-lib';
@@ -328,67 +330,57 @@
export const registerNewAlias = async (
chronik,
wallet,
- utxos,
feeInSatsPerByte,
aliasName,
- registrationFee,
+ aliasAddress,
+ registrationFeeSats,
) => {
try {
+ // Instantiate new txBuilder
let txBuilder = utxolib.bitgo.createTransactionBuilderForNetwork(
utxolib.networks.ecash,
);
- const satoshisToSend = fromXecToSatoshis(registrationFee);
+ // Create this transaction with nonSlpUtxos
+ const utxos = wallet.state.nonSlpUtxos;
- // Throw validation error if fromXecToSatoshis returns false
- if (!satoshisToSend) {
- throw new Error(`Invalid alias registration fee`);
- }
+ // Build opReturnData for alias tx per spec
+ const opReturnData = generateAliasOpReturnScript(
+ aliasName,
+ aliasAddress,
+ );
- // Start of building the OP_RETURN output.
- // only build the OP_RETURN output if the user supplied it
- if (
- aliasName &&
- typeof aliasName !== 'undefined' &&
- aliasName.trim() !== ''
- ) {
- const opReturnData = generateOpReturnScript(
- aliasName,
- false, // encryption use
- false, // airdrop use
- null, // airdrop use
- null, // encrypted use
- true, // alias registration flag
- );
- txBuilder.addOutput(opReturnData, 0);
- }
+ // Add opReturn as output with 0 satoshis of XEC spent
+ txBuilder.addOutput(opReturnData, 0);
// generate the tx inputs and add to txBuilder instance
// returns the updated txBuilder, txFee, totalInputUtxoValue and inputUtxos
let txInputObj = generateTxInput(
- false, // not one to many
+ false, // not a one to many tx
utxos,
txBuilder,
- null, // one to many array
- satoshisToSend,
+ null, // no one-to-many array
+ registrationFeeSats,
feeInSatsPerByte,
);
+ // Get the change address
const changeAddress = getChangeAddressFromInputUtxos(
txInputObj.inputUtxos,
wallet,
);
+
txBuilder = txInputObj.txBuilder; // update the local txBuilder with the generated tx inputs
// generate the tx outputs and add to txBuilder instance
// returns the updated txBuilder
const txOutputObj = generateTxOutput(
- false, // not one to many
- registrationFee,
- satoshisToSend,
+ false, // not a one-to-many tx
+ fromSatoshisToXec(registrationFeeSats), // TODO fix this oversight param req in generateTxOutput
+ registrationFeeSats,
txInputObj.totalInputUtxoValue,
currency.aliasSettings.aliasPaymentAddress,
- null, // one to many address array
+ null, // no one-to-many address array
changeAddress,
txInputObj.txFee,
txBuilder,
@@ -417,8 +409,9 @@
throw err;
}
+ const explorerLink = `${currency.blockExplorerUrl}/tx/${broadcastResponse.txid}`;
// return the explorer link for the broadcasted tx
- return `${currency.blockExplorerUrl}/tx/${broadcastResponse.txid}`;
+ return { explorerLink, txid: broadcastResponse.txid, rawTxHex };
} catch (err) {
if (err.error === 'insufficient priority (code 66)') {
err.code = SEND_XEC_ERRORS.INSUFFICIENT_PRIORITY;
@@ -533,9 +526,13 @@
let opReturnByteCount;
if (optionalOpReturnMsg) {
- opReturnByteCount = getMessageByteSize(optionalOpReturnMsg, encryptionFlag, encryptedEj);
+ opReturnByteCount = getMessageByteSize(
+ optionalOpReturnMsg,
+ encryptionFlag,
+ encryptedEj,
+ );
}
-
+
// generate the tx inputs and add to txBuilder instance
// returns the updated txBuilder, txFee, totalInputUtxoValue and inputUtxos
let txInputObj = generateTxInput(