diff --git a/cashtab/src/assets/agora-tx.svg b/cashtab/src/assets/agora-tx.svg deleted file mode 100644 --- a/cashtab/src/assets/agora-tx.svg +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<svg width="128pt" height="128pt" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"> - <path d="m43.836 65.574h9.8086v62.426h-9.8086z" fill="#00abe6"/> - <path d="m74.363 65.574h9.8086v62.426h-9.8086z" fill="#00abe6"/> - <path d="m84.23 51.031h-40.449l-5.1133-9.3125h50.676z" fill="#00abe6"/> - <path d="m43.898 65.574h9.8086v62.426h-9.8086z" fill="#00abe6"/> - <path d="m74.363 65.574h9.8086v62.426h-9.8086z" fill="#00abe6"/> - <path d="m38.656 24.594h50.68v12.906h-50.68z" fill="#00abe6"/> - <path d="m43.836 55.254h40.336v6.0977h-40.336z" fill="#00abe6"/> - <path d="m59.102 65.574h9.8086v62.426h-9.8086z" fill="#00abe6"/> - <path d="m84.219 51.031h-40.449l-5.1133-9.3125h50.676z" fill="#00abe6"/> -</svg> diff --git a/cashtab/src/assets/tokensend.svg b/cashtab/src/assets/tokensend.svg new file mode 100644 --- /dev/null +++ b/cashtab/src/assets/tokensend.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="128pt" height="128pt" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"> + <path d="m34.664 16c-4.2695 0-8.1914 2.4219-10.102 6.2383-2.7656 5.5234-5.5234 11.051-8.2852 16.574-0.16406 0.34375-0.25391 0.72656-0.26953 0.95312-0.003906 0.023437-0.011718 58.895-0.011718 58.895 0 7.3359 6 13.336 13.336 13.336h69.328c7.3359 0 13.336-6 13.336-13.336l-0.011719-58.887c-0.003906-0.21875-0.09375-0.60938-0.26953-0.96484-2.7617-5.5234-5.5195-11.051-8.2852-16.574-1.9102-3.8203-5.8281-6.2383-10.102-6.2383zm0 5.3359h26.672v16h-38.355l6.3555-12.711c1.0117-2.0234 3.0664-3.2891 5.3281-3.2891zm32 0h26.672c2.2656 0 4.3203 1.2656 5.3281 3.2891l6.3555 12.711h-38.355zm18.672 42.664c0.70312 0 1.3867 0.28125 1.8867 0.78125l8 8c1.0391 1.0469 1.0391 2.7305 0 3.7695l-8 8c-1.0469 1.0469-2.7305 1.0469-3.7695 0-1.0469-1.0391-1.0469-2.7266 0-3.7695l3.4453-3.4453h-52.23c-1.4688 0-2.6641-1.1953-2.6641-2.6719 0-1.4688 1.1953-2.6641 2.6641-2.6641h52.23l-3.4453-3.4492c-1.0469-1.0391-1.0469-2.7266 0-3.7695 0.5-0.5 1.1758-0.78125 1.8867-0.78125z" fill="#00abe6"/> +</svg> diff --git a/cashtab/src/chronik/fixtures/mocks.js b/cashtab/src/chronik/fixtures/mocks.js --- a/cashtab/src/chronik/fixtures/mocks.js +++ b/cashtab/src/chronik/fixtures/mocks.js @@ -7279,6 +7279,8 @@ 'ecash:qr689ree3wukyetgqv6xld9vghthvpq69cg04xjp57', 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', ], + appActions: [], + parsedTokenEntries: [], }, }; @@ -7338,6 +7340,9 @@ stackArray: [], xecTxType: 'Received', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + replyAddress: 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', + appActions: [], + parsedTokenEntries: [], }, }; @@ -7397,6 +7402,8 @@ stackArray: [], xecTxType: 'Sent', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + appActions: [], + parsedTokenEntries: [], }, }; @@ -7465,6 +7472,44 @@ ], xecTxType: 'Sent', recipients: ['ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07'], + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + address: 'ecash:qqxuz9rkvw2g7rw0kqxvgpld5sd3y9cn45tv669kqz', + alias: 'bug2', + }, + }, + ], + parsedTokenEntries: [], + }, +}; +export const invalidAliasRegistration = { + tx: { + ...aliasRegistration.tx, + outputs: [ + { + ...aliasRegistration.tx.outputs[0], + outputScript: + '6a042e786563010104627567321500dc1147663948f0dcfb00cc407eda41b121713ad3', + }, + ...aliasRegistration.tx.outputs.slice(1), + ], + }, + parsed: { + appActions: [{ app: 'alias', isValid: false, lokadId: '2e786563' }], + parsedTokenEntries: [], + recipients: ['ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07'], + satoshisSent: 555, + stackArray: [ + '2e786563', + '01', + '62756732', + '00dc1147663948f0dcfb00cc407eda41b121713ad3', + ], + xecTxType: 'Sent', }, }; @@ -7610,6 +7655,17 @@ ], xecTxType: 'Received', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + replyAddress: 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'SEND', + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + tokenSatoshis: '12', + }, + ], }, }; @@ -7755,6 +7811,16 @@ ], xecTxType: 'Sent', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'SEND', + tokenId: + '4bd147fc5d5ff26249a9299c46b80920c0b81f59a60e05428262160ebee0b0c3', + tokenSatoshis: '17', + }, + ], }, }; @@ -7846,6 +7912,16 @@ ], xecTxType: 'Sent', recipients: [], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'GENESIS', + tokenId: + 'cf601c56b58bc05a39a95374a4a865f0a8b56544ea937b30fb46315441717c50', + tokenSatoshis: '7777777777', + }, + ], }, }; @@ -7983,6 +8059,17 @@ ], xecTxType: 'Received', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'SEND', + tokenId: + 'acba1d7f354c6d4d001eb99d31de174e5cea8a31d692afd6e7eb8474ad541f55', + tokenSatoshis: '123456789', + }, + ], + replyAddress: 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', }, }; @@ -8583,8 +8670,23 @@ 'ecash:qq0rwc6wv6f7y2yqrsv5c3tsr4y6r5fw9squdmajds', 'ecash:qp36z7k8xt7k4l5xnxeypg5mfqeyvvyduu04m37fwd', ], + appActions: [ + { + action: { + msg: 'evc token service holders air drop🥇🌐🥇❤👌🛬🛬🍗🤴', + tokenId: + 'bdb3b4215ca0622e0c4c07655522c376eaa891838a82f0217fa453bb0595a37c', + }, + isValid: true, + app: '🪂Airdrop', + lokadId: '64726f70', + }, + ], + parsedTokenEntries: [], + replyAddress: 'ecash:qp36z7k8xt7k4l5xnxeypg5mfqeyvvyduu04m37fwd', }, }; + export const onSpecAirdropTxNoMsg = { tx: { txid: '298c3d1a5bd00bd86d92d48ec5695c25a0a86093964d9f53eb19b46dc472b9f5', @@ -9183,7 +9285,254 @@ timestamp: 1711102691, }, }, - parsed: {}, + sendingHash: '2a96944d06700882bbd984761d9c9e4215f2d78e', + parsed: { + appActions: [ + { + action: { + msg: 'ATTENTION GRUMPY PEOPLE! 😾 You can now deposit $GRP to the eToken bot at t.me/eCashPlay to top up your Casino Credits! 1m $GRP = 1 Credit. Play Casino games and win XEC! ', + tokenId: + 'fb4233e8a568993976ed38a81c2671587c5ad09552dedefa78760deed6ff87aa', + }, + isValid: true, + app: '🪂Airdrop', + lokadId: '64726f70', + }, + ], + parsedTokenEntries: [], + recipients: [ + 'ecash:qp2kre7s2ja5mqwcvt7uvazjtskuxdavd5e5vrcxel', + 'ecash:qqtms0966jq55hryqrjp3mrf72vk8g5qtqpwysa6na', + 'ecash:qqhp20z0cc7u40cw39ymyrw6ktpa7acya55l0hgyrd', + 'ecash:qzvkd5cjsz6n78ptshuhtyvwkvprk2qlsc4yrkjum8', + 'ecash:qzla829ez2ne3zqfpyx72ej36369z55t5y75969dkn', + 'ecash:qpllgmsgq7cd8fte0ht9h6hxelxz6q09dcpuhyzzr9', + 'ecash:qpv9ajuqwf5ew77zrgdze4whcnl3z58ffyulr5hxmz', + 'ecash:qqxmqltt0904le050ef64vj64src6g5lsy9t0vws7c', + 'ecash:qqlj8cn954c83tywva0h3024922eg098aq90dtfspf', + 'ecash:qz3nkdrq6saeufapv5v9k2rrk8my6svdsg9wj4s4hl', + 'ecash:qrsqdhs9prwt7f9wq32u5w6kvhks23248sz7x0vz03', + 'ecash:qp03a3ka95pvr73jkxzgrzl9vydwvaxlqv4nuyqll2', + 'ecash:qpz9crr5qsvn2lws8jf6x5wxnmklgva7gcx4qsn5sw', + 'ecash:qr40el0vmxxdaxf780sp4xk3zk8a86mh8ypwtuycl9', + 'ecash:qqpr5uy8a6dl40rh2j8utu9rtxhfht8hhstayxwwfm', + 'ecash:qrk76dvgz6frgsq0w4t2gza0sz8paj8t75yz9dg9aa', + 'ecash:qqdrx6zzp8vh369uzs7xlndh74hrys7uachl0rwq7d', + 'ecash:qpyxe0ctlw3m0592uy97clcdggnwdcg0jctx6mfrz4', + 'ecash:qzqvwt004vkfnncexswvpc5e93je6ssesuzzjzad2z', + 'ecash:qzs4mw9zf7dnwspc8yn6r4u8hfmmxjmr4qa2pvqwvr', + 'ecash:qq36zdqdh0ndahcu6vwd7y0ctv6y9n7c9qwg9xyccn', + 'ecash:qq0yvnyd9quhdhwp87n82eeklre6qp5l0qcy78a7x6', + 'ecash:qredshz087mcc8vhyl02wd5scu5p2atw9vxhhp6t7d', + 'ecash:qrv8ywknhmxygdtzvl5dqvfkjtzf8l3tmukugtcl6d', + 'ecash:qqtpet5n3mqjr0vewqcywe5xtxglaq9xxqukk4u9q0', + 'ecash:qzgwc35u54xwjctzst02nq9rnu8yhxn2hyu2mn9e97', + 'ecash:qzecdv04nd0s8dz5w80jzn2877446jqqxq8d2rppc4', + 'ecash:qrfw4xap5zgu9t0sz9k6f5krmhpu7ufy4ynpmajugh', + 'ecash:qzvydd4n3lm3xv62cx078nu9rg0e3srmqq0knykfed', + 'ecash:qpgn0x4kzy58vkxfu8q0nrcf9xka6k30r534m2j2ca', + 'ecash:qqe0cv6phqleq23kpjaljxsga2vu9ymn85q3uuvpdu', + 'ecash:qpvljwpehgj2h45edd6689yxdywagpnqhcd5fngx3n', + 'ecash:qpe77979h864r6hr7w604hmply72uhn2agr5z20769', + 'ecash:qp5sqwvcctpj4jqe2xugg94f59wl8gve9yvt7h4vj0', + 'ecash:qpwaqsgl5cq6hqhu66yffj2ex3se5jvjqcmn6tp9gn', + 'ecash:qpf5c3q8am48ujuv8mta4ewtfgjnn0hdnyx7nqk7y8', + 'ecash:qprlsm6ywgwg6zavycmqyutlcy9smfymnupv08w52e', + 'ecash:qzz3f8x423t5qxk5v3w9fwrv4gxwp48stu7zk0lhxv', + 'ecash:qrc27ws5z8k5nzdlt3zxg8p6sm288tly2y3m6nwxww', + 'ecash:qztnm9f7zhtz8qajf6lr6u7sreac80vcju4tk6j75z', + 'ecash:qrdd7dxda8rhflwkxsxd9yt2nww96470gv48s4f9j0', + 'ecash:qpx797ee7zw3gjf0f4qwp7m8pfp275zudvk3ym56ad', + 'ecash:qr7h7485jm9dkzmd8npqdmsf3w4jn02mhu7n4g6whr', + 'ecash:qz646fl9p9gq47zjgd3zxs72nc74fgzr3gw9u8p7tc', + 'ecash:qp284wa258z7jtkdu4gur07mngh9g49cxqxs2pmdgc', + 'ecash:qq8kn2f3g6vp26hw30dedgm0rcy0rwsk35ln6cazck', + 'ecash:qp59q64mfnnfcrjedjqta0j9dua707gyl5q5p2a5py', + 'ecash:qpr6kemj5374tdmynwplzp0atnwra23z4y7mt4d46q', + 'ecash:qp36z7k8xt7k4l5xnxeypg5mfqeyvvyduu04m37fwd', + 'ecash:qzm5es2p37kj9lswkzl02uyzmxpk52f5psl90kzl6t', + 'ecash:qr3n7laxk8qr669zsavvrme6t7nnyt90hvy5esczyf', + 'ecash:qz3sz5adwwa90dhn0sssgd0yq7ah5d52t56s78jsfa', + 'ecash:qq2qfhrm2j4hw6yrwu579mlq2gg95nzqty3fpaxcpk', + 'ecash:qztvmtsvsgzzdt5rzgtdv2fc8hd8aedd4v8rxttrt0', + 'ecash:qqfvfjp2435fdktwmcuwhytttqv6gmyq8gq4a6tsj2', + 'ecash:qpaa7n5pjg2uel5n0f3n4c52ut5a82kuqcunkfhuhj', + 'ecash:qphzk6xg0wrw67dcdgyuvtz8vtt7gvduegnh0l7gcn', + 'ecash:qrn6turzu59rt43elsthxuug8ygeuc28t5ux5hqnl0', + 'ecash:qz35jcyk8kn7qtslqdtnykv9gada495aauxyeljy8s', + 'ecash:qzwcdzwupqfa5n6jqgj7awutsryr2tky553a8ddw9p', + 'ecash:qz75ekume8d7y83tn0wn89d7x5xc4wlpd5wkjutg7a', + 'ecash:qqkh24v4294s7cju28fz80yy5kklcaajqcajx2tv7k', + 'ecash:qrwsrk79tv87nceuadcqknzy2gqshk66zchyqqakmd', + 'ecash:qqyrns594r2m22f5c2x553dpsdwaghc22vkfgfhqn5', + 'ecash:qq7a367d7rjdv4cj5u3lyg6kw5ckdpm3vv8hkvlk26', + 'ecash:qzt557ajdtp0v2lkpfn47hcqyjngnspa055p5p0k3e', + 'ecash:qr6lws9uwmjkkaau4w956lugs9nlg9hudqs26lyxkv', + 'ecash:qrwwkvr2wdvzu5kyxqjl0mk4sfaxm85juq4wa28f2e', + 'ecash:qrunq208tyej03dcvn4x39hvlkj0l7m2hqz0s0zjys', + 'ecash:qqrzpf7l9crr00yd8haxv0yhns26vuwluszxw5x0wv', + 'ecash:qpuy0lnswzlvs4nm86qs74pl97qvc0srhc665724p7', + 'ecash:qzphvp80l4rsl2468czyuznufe4g5lhgccw7fd7qw6', + 'ecash:qqk77gg5xw8sh6dzd9tr0rhuuc8p0dvqkvvp76ut5u', + 'ecash:qzptzhmgr220a8m2c2waacs560wc3a2mlsxt0wkmsc', + 'ecash:qpu0g0hxk8jhwv5uplyuk3lhgdv4f6hgrusukd6cwl', + 'ecash:qrq605fdmhr2xped7zw0tc9qpm8pnrxgcyrwkrjedn', + 'ecash:qz7vajm78ewnln97uvs3f99dxg20j8x8fu2a6jt5fk', + 'ecash:qrauj3smamqd0qc99ssvn98lk38yvpqa2y8stcekhf', + 'ecash:qz55hqtk62xttdwrq8cshdzmmv7kurp80580x8h5zl', + 'ecash:qzvnu6lw7a85a5xrleg6lz27gakwxlpk9v55jr2p46', + 'ecash:qqhv22qcvn7f38dt2sas2333e9crsztgncmtgdrcm2', + 'ecash:qpvph4dusdwv0z9ajzj0duxfcg0tzu6h9cyaag2pwn', + 'ecash:qq5v4wmfhclzqur4wnt6phwxt2qpk6h9nyesy04fn0', + 'ecash:qzut8s3dsfuycflqyf8a328l2jdx06245vra9q3458', + 'ecash:qzu270ek398w0ejk83njw98eadrueqafuy098ueasq', + 'ecash:qrayn7v0kf0ghpxwyyxsduzj4mvgctz0nqysm47axp', + 'ecash:qpsng33a73pkh7xxv2myj9mppa3l5hvfaunm762526', + 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', + 'ecash:qzelsrygyg838qspwq4y6rqr8vjgqk0umsa2rsz35w', + 'ecash:qzkhavkghz869cl4zk9nnzjfhunhgqvcfce9c7mvdc', + 'ecash:qp45whpmdrlcgy09cse8rmwyunexmlyq9gaduqlm6p', + 'ecash:qrhgew49vsk3chg679grahdx54gyf6qsdcurky8xms', + 'ecash:qplr7p624c7vnxn0fzujsqywh9zcv9dk4ytfcrvql0', + 'ecash:qqypd75zeegzrpc6ldhmmj28qu20ha78a57269a645', + 'ecash:qqfwq959a6szyfdw85749zccftsdk533gv3lc4mfrp', + ], + satoshisSent: 199975, + stackArray: [ + '64726f70', + 'fb4233e8a568993976ed38a81c2671587c5ad09552dedefa78760deed6ff87aa', + '415454454e54494f4e204752554d50592050454f504c452120f09f98be20596f752063616e206e6f77206465706f736974202447525020746f207468652065546f6b656e20626f7420617420742e6d652f6543617368506c617920746f20746f7020757020796f757220436173696e6f20437265646974732120316d2024475250203d2031204372656469742e20506c617920436173696e6f2067616d657320616e642077696e205845432120', + ], + xecTxType: 'Sent', + }, +}; + +export const offSpecAirdropTx = { + tx: { + ...onSpecAirdropTxNoMsg.tx, + outputs: [ + { + ...onSpecAirdropTxNoMsg.tx.outputs[0], + outputScript: + '6a0464726f701ffb4233e8a568993976ed38a81c2671587c5ad09552dedefa78760deed6ff87', + }, + ...onSpecAirdropTxNoMsg.tx.outputs.slice(1), + ], + }, + sendingHash: '2a96944d06700882bbd984761d9c9e4215f2d78e', + parsed: { + appActions: [ + { + app: '🪂Airdrop', + isValid: false, + lokadId: '64726f70', + }, + ], + parsedTokenEntries: [], + recipients: [ + 'ecash:qp2kre7s2ja5mqwcvt7uvazjtskuxdavd5e5vrcxel', + 'ecash:qqtms0966jq55hryqrjp3mrf72vk8g5qtqpwysa6na', + 'ecash:qqhp20z0cc7u40cw39ymyrw6ktpa7acya55l0hgyrd', + 'ecash:qzvkd5cjsz6n78ptshuhtyvwkvprk2qlsc4yrkjum8', + 'ecash:qzla829ez2ne3zqfpyx72ej36369z55t5y75969dkn', + 'ecash:qpllgmsgq7cd8fte0ht9h6hxelxz6q09dcpuhyzzr9', + 'ecash:qpv9ajuqwf5ew77zrgdze4whcnl3z58ffyulr5hxmz', + 'ecash:qqxmqltt0904le050ef64vj64src6g5lsy9t0vws7c', + 'ecash:qqlj8cn954c83tywva0h3024922eg098aq90dtfspf', + 'ecash:qz3nkdrq6saeufapv5v9k2rrk8my6svdsg9wj4s4hl', + 'ecash:qrsqdhs9prwt7f9wq32u5w6kvhks23248sz7x0vz03', + 'ecash:qp03a3ka95pvr73jkxzgrzl9vydwvaxlqv4nuyqll2', + 'ecash:qpz9crr5qsvn2lws8jf6x5wxnmklgva7gcx4qsn5sw', + 'ecash:qr40el0vmxxdaxf780sp4xk3zk8a86mh8ypwtuycl9', + 'ecash:qqpr5uy8a6dl40rh2j8utu9rtxhfht8hhstayxwwfm', + 'ecash:qrk76dvgz6frgsq0w4t2gza0sz8paj8t75yz9dg9aa', + 'ecash:qqdrx6zzp8vh369uzs7xlndh74hrys7uachl0rwq7d', + 'ecash:qpyxe0ctlw3m0592uy97clcdggnwdcg0jctx6mfrz4', + 'ecash:qzqvwt004vkfnncexswvpc5e93je6ssesuzzjzad2z', + 'ecash:qzs4mw9zf7dnwspc8yn6r4u8hfmmxjmr4qa2pvqwvr', + 'ecash:qq36zdqdh0ndahcu6vwd7y0ctv6y9n7c9qwg9xyccn', + 'ecash:qq0yvnyd9quhdhwp87n82eeklre6qp5l0qcy78a7x6', + 'ecash:qredshz087mcc8vhyl02wd5scu5p2atw9vxhhp6t7d', + 'ecash:qrv8ywknhmxygdtzvl5dqvfkjtzf8l3tmukugtcl6d', + 'ecash:qqtpet5n3mqjr0vewqcywe5xtxglaq9xxqukk4u9q0', + 'ecash:qzgwc35u54xwjctzst02nq9rnu8yhxn2hyu2mn9e97', + 'ecash:qzecdv04nd0s8dz5w80jzn2877446jqqxq8d2rppc4', + 'ecash:qrfw4xap5zgu9t0sz9k6f5krmhpu7ufy4ynpmajugh', + 'ecash:qzvydd4n3lm3xv62cx078nu9rg0e3srmqq0knykfed', + 'ecash:qpgn0x4kzy58vkxfu8q0nrcf9xka6k30r534m2j2ca', + 'ecash:qqe0cv6phqleq23kpjaljxsga2vu9ymn85q3uuvpdu', + 'ecash:qpvljwpehgj2h45edd6689yxdywagpnqhcd5fngx3n', + 'ecash:qpe77979h864r6hr7w604hmply72uhn2agr5z20769', + 'ecash:qp5sqwvcctpj4jqe2xugg94f59wl8gve9yvt7h4vj0', + 'ecash:qpwaqsgl5cq6hqhu66yffj2ex3se5jvjqcmn6tp9gn', + 'ecash:qpf5c3q8am48ujuv8mta4ewtfgjnn0hdnyx7nqk7y8', + 'ecash:qprlsm6ywgwg6zavycmqyutlcy9smfymnupv08w52e', + 'ecash:qzz3f8x423t5qxk5v3w9fwrv4gxwp48stu7zk0lhxv', + 'ecash:qrc27ws5z8k5nzdlt3zxg8p6sm288tly2y3m6nwxww', + 'ecash:qztnm9f7zhtz8qajf6lr6u7sreac80vcju4tk6j75z', + 'ecash:qrdd7dxda8rhflwkxsxd9yt2nww96470gv48s4f9j0', + 'ecash:qpx797ee7zw3gjf0f4qwp7m8pfp275zudvk3ym56ad', + 'ecash:qr7h7485jm9dkzmd8npqdmsf3w4jn02mhu7n4g6whr', + 'ecash:qz646fl9p9gq47zjgd3zxs72nc74fgzr3gw9u8p7tc', + 'ecash:qp284wa258z7jtkdu4gur07mngh9g49cxqxs2pmdgc', + 'ecash:qq8kn2f3g6vp26hw30dedgm0rcy0rwsk35ln6cazck', + 'ecash:qp59q64mfnnfcrjedjqta0j9dua707gyl5q5p2a5py', + 'ecash:qpr6kemj5374tdmynwplzp0atnwra23z4y7mt4d46q', + 'ecash:qp36z7k8xt7k4l5xnxeypg5mfqeyvvyduu04m37fwd', + 'ecash:qzm5es2p37kj9lswkzl02uyzmxpk52f5psl90kzl6t', + 'ecash:qr3n7laxk8qr669zsavvrme6t7nnyt90hvy5esczyf', + 'ecash:qz3sz5adwwa90dhn0sssgd0yq7ah5d52t56s78jsfa', + 'ecash:qq2qfhrm2j4hw6yrwu579mlq2gg95nzqty3fpaxcpk', + 'ecash:qztvmtsvsgzzdt5rzgtdv2fc8hd8aedd4v8rxttrt0', + 'ecash:qqfvfjp2435fdktwmcuwhytttqv6gmyq8gq4a6tsj2', + 'ecash:qpaa7n5pjg2uel5n0f3n4c52ut5a82kuqcunkfhuhj', + 'ecash:qphzk6xg0wrw67dcdgyuvtz8vtt7gvduegnh0l7gcn', + 'ecash:qrn6turzu59rt43elsthxuug8ygeuc28t5ux5hqnl0', + 'ecash:qz35jcyk8kn7qtslqdtnykv9gada495aauxyeljy8s', + 'ecash:qzwcdzwupqfa5n6jqgj7awutsryr2tky553a8ddw9p', + 'ecash:qz75ekume8d7y83tn0wn89d7x5xc4wlpd5wkjutg7a', + 'ecash:qqkh24v4294s7cju28fz80yy5kklcaajqcajx2tv7k', + 'ecash:qrwsrk79tv87nceuadcqknzy2gqshk66zchyqqakmd', + 'ecash:qqyrns594r2m22f5c2x553dpsdwaghc22vkfgfhqn5', + 'ecash:qq7a367d7rjdv4cj5u3lyg6kw5ckdpm3vv8hkvlk26', + 'ecash:qzt557ajdtp0v2lkpfn47hcqyjngnspa055p5p0k3e', + 'ecash:qr6lws9uwmjkkaau4w956lugs9nlg9hudqs26lyxkv', + 'ecash:qrwwkvr2wdvzu5kyxqjl0mk4sfaxm85juq4wa28f2e', + 'ecash:qrunq208tyej03dcvn4x39hvlkj0l7m2hqz0s0zjys', + 'ecash:qqrzpf7l9crr00yd8haxv0yhns26vuwluszxw5x0wv', + 'ecash:qpuy0lnswzlvs4nm86qs74pl97qvc0srhc665724p7', + 'ecash:qzphvp80l4rsl2468czyuznufe4g5lhgccw7fd7qw6', + 'ecash:qqk77gg5xw8sh6dzd9tr0rhuuc8p0dvqkvvp76ut5u', + 'ecash:qzptzhmgr220a8m2c2waacs560wc3a2mlsxt0wkmsc', + 'ecash:qpu0g0hxk8jhwv5uplyuk3lhgdv4f6hgrusukd6cwl', + 'ecash:qrq605fdmhr2xped7zw0tc9qpm8pnrxgcyrwkrjedn', + 'ecash:qz7vajm78ewnln97uvs3f99dxg20j8x8fu2a6jt5fk', + 'ecash:qrauj3smamqd0qc99ssvn98lk38yvpqa2y8stcekhf', + 'ecash:qz55hqtk62xttdwrq8cshdzmmv7kurp80580x8h5zl', + 'ecash:qzvnu6lw7a85a5xrleg6lz27gakwxlpk9v55jr2p46', + 'ecash:qqhv22qcvn7f38dt2sas2333e9crsztgncmtgdrcm2', + 'ecash:qpvph4dusdwv0z9ajzj0duxfcg0tzu6h9cyaag2pwn', + 'ecash:qq5v4wmfhclzqur4wnt6phwxt2qpk6h9nyesy04fn0', + 'ecash:qzut8s3dsfuycflqyf8a328l2jdx06245vra9q3458', + 'ecash:qzu270ek398w0ejk83njw98eadrueqafuy098ueasq', + 'ecash:qrayn7v0kf0ghpxwyyxsduzj4mvgctz0nqysm47axp', + 'ecash:qpsng33a73pkh7xxv2myj9mppa3l5hvfaunm762526', + 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', + 'ecash:qzelsrygyg838qspwq4y6rqr8vjgqk0umsa2rsz35w', + 'ecash:qzkhavkghz869cl4zk9nnzjfhunhgqvcfce9c7mvdc', + 'ecash:qp45whpmdrlcgy09cse8rmwyunexmlyq9gaduqlm6p', + 'ecash:qrhgew49vsk3chg679grahdx54gyf6qsdcurky8xms', + 'ecash:qplr7p624c7vnxn0fzujsqywh9zcv9dk4ytfcrvql0', + 'ecash:qqypd75zeegzrpc6ldhmmj28qu20ha78a57269a645', + 'ecash:qqfwq959a6szyfdw85749zccftsdk533gv3lc4mfrp', + ], + satoshisSent: 199975, + stackArray: [ + '64726f70', + 'fb4233e8a568993976ed38a81c2671587c5ad09552dedefa78760deed6ff87', + ], + xecTxType: 'Sent', + }, }; export const outgoingEncryptedMsg = { @@ -9250,6 +9599,10 @@ ], xecTxType: 'Sent', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + appActions: [ + { app: 'Cashtab Encrypted (deprecated)', lokadId: '65746162' }, + ], + parsedTokenEntries: [], }, }; @@ -9317,6 +9670,11 @@ ], xecTxType: 'Received', recipients: ['ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6'], + replyAddress: 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', + appActions: [ + { app: 'Cashtab Encrypted (deprecated)', lokadId: '65746162' }, + ], + parsedTokenEntries: [], }, }; @@ -9455,6 +9813,16 @@ ], xecTxType: 'Sent', recipients: [], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'BURN', + tokenId: + '4db25a4b2f0b57415ce25fab6d9cb3ac2bbb444ff493dc16d0615a11ad06c875', + tokenSatoshis: '12', + }, + ], }, }; @@ -9569,690 +9937,658 @@ ], xecTxType: 'Sent', recipients: [], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'BURN', + tokenId: + '7443f7c831cdf2b2b04d5f0465ed0bcf348582675b0e4f17906438c232c22f3d', + tokenSatoshis: '1234567', + }, + ], }, }; -export const eCashChatAuthenticationTx = { +export const swapTx = { tx: { - txid: '61838af28ae42e3b6a5fd037e112fe0df936dabf2a6417091abce6a3d830b078', - version: 2, + txid: 'baed6358b9ea2e354e384d2e31a576ffa25fcceaf796e711e8306f9c8086b00f', + version: 1, inputs: [ { prevOut: { - txid: 'f9323576b17aebd302272652ee9990b2a1347da7e3270d19b8d32ae60a0dec2f', - outIdx: 0, + txid: '8b55a382501b538296cd13269b341f7a964366a705a45f89f56e0d783240f3a4', + outIdx: 2, }, inputScript: - '413fb023c886471d0f7eefcd3e5bf2cdbc0f537edd20b9f515d32da7c80b519b7cdc2da3e6696220addd232ebd8c10d53c092965d6bcce262b1a8745a61a18f3a54121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', - value: 3377, + '41256f3c091df7dea2bb9d74241b47116364d7b0035dfe1c5d1d398d8e92e99f4d5f3dd747f8e81ca99ddaf5630399ef18e26b6a3bf9b763cdd25225e68f7bbd2d41210304222c88e9936a195762fc4ee41a082e906a0e8434df43a03bfcdf1f9d2c1b8d', + value: 546, sequenceNo: 4294967295, outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', + '76a91493472d56ba91581ed473225a765dd14a2db5d9d888ac', }, - ], - outputs: [ { - value: 0, + prevOut: { + txid: '8b55a382501b538296cd13269b341f7a964366a705a45f89f56e0d783240f3a4', + outIdx: 3, + }, + inputScript: + '418ab02f08273afd67c4db840f09429d7c76c0a71b28dbaef5c63f277944a168819d72bedd14e78b327a237f6070b0519ef8456efbfe206bae0c60d3b5f328faea412103df543832906a1f5fc8f201bb99454f350b1906375d522f735bd357cbda11ab5b', + value: 2565, + sequenceNo: 4294967295, outputScript: - '6a0461757468140644ad85a538657c033e36ce5a3c8cf26076591f', + '76a9149ea00e6c2ef24026719421e4790e1a694c94381b88ac', }, + ], + outputs: [ { - value: 550, + value: 0, outputScript: - '76a914b20298c1b5d6a82a61f6c8cd708fa87a1ce1a97a88ac', + '6a045357500001010101209e0a9d4720782cf661beaea6c5513f1972e0f3b1541ba4c83f4c87ef65f843dc0453454c4c0631323831323301002039c6db26912f34352d50fdfd8d75d1c16cb8a669f3ae05000a6c8c74d14839a50101063132383132330437383035', }, { - value: 2314, + value: 2656, outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', + '76a91493472d56ba91581ed473225a765dd14a2db5d9d888ac', + spentBy: { + txid: '47f7a2189eb65e9a2288f81640351cc80ada49288b09973bcaa7aef1e423faa8', + outIdx: 1, + }, }, ], lockTime: 0, - timeFirstSeen: 1723372560, - size: 255, + timeFirstSeen: 1712535539, + size: 439, isCoinbase: false, tokenEntries: [], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 857308, - hash: '000000000000000020801fb91e3685a03a8d8f967cd048f58059bda0800a8402', - timestamp: 1723373699, - }, - parsed: { - xecTxType: 'Sent', - satoshisSent: 550, - stackArray: [ - '61757468', - '0644ad85a538657c033e36ce5a3c8cf26076591f', - ], - recipients: ['ecash:qzeq9xxpkht2s2np7myv6uy04papecdf0g0zly33v5'], + height: 839523, + hash: '00000000000000000c61b358a9681170b9387790370bf3ca18a402bc50264fc0', + timestamp: 1712536759, }, }, + parsed: { + satoshisSent: 0, + stackArray: [ + '53575000', + '01', + '01', + '9e0a9d4720782cf661beaea6c5513f1972e0f3b1541ba4c83f4c87ef65f843dc', + '53454c4c', + '313238313233', + '00', + '39c6db26912f34352d50fdfd8d75d1c16cb8a669f3ae05000a6c8c74d14839a5', + '01', + '313238313233', + '37383035', + ], + xecTxType: 'Received', + appActions: [{ app: 'SWaP', lokadId: '53575000' }], + parsedTokenEntries: [], + recipients: ['ecash:qzf5wt2kh2g4s8k5wv395aja699zmdwemq05vg6h92'], + replyAddress: 'ecash:qzf5wt2kh2g4s8k5wv395aja699zmdwemq05vg6h92', + }, }; -export const agoraAdSetupTxSlpNft = { +export const PayButtonNoDataYesNonce = { tx: { - txid: '972fd1322542740835a3f7e6d0917e5ac1ab6f20c5bfb40edbfb4ca73a144194', + txid: 'f2ca747f0780c6cda32a43418b4dd55112b709577f64436d80ab1a38e4f2787a', version: 2, inputs: [ { prevOut: { - txid: 'c886d9d73b0c2592fb2df95cf0bb832c8077ff8adec132ee3cff5ba576f4ed1e', - outIdx: 1, - }, - inputScript: - '419d3ac0b32abebc181c55e5a45c25d5050f73ba1269348829f4d5677131e3c627f73a552bf003de5d86423ce3f47fd4fd116eba837be72a3cef6f002158b0482a412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - { - prevOut: { - txid: '03672250bda1410ffa9b1c2cf3dc8c456bcb7a54e8dff0a7686bcce6ba82cf1b', + txid: '00bfb4625325fe6e6a3ce34eb3ed7214167644e2eca892db207a44ea3262effc', outIdx: 2, }, inputScript: - '41f444904158cb70106321dc09161d7bf3dde584e541c73d21f46a19c176c10e1c3ea79252e52878a0f11f5c6b896d8adc5c75d1c6039e750c31ab07114d2f3bca412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 1748, - sequenceNo: 4294967295, + '411b57cfa0bcc8e1f1c02f0dfed248688bf1e337e75d9c2775324e55b5d6d2085260303c3f77437d7bc0f1533ea816e7c8e4b77175ff3c9e61ce2e21b5e1dc95014121027a70b0f8b59cbb83a64cacbf4fca79e5c9a4f655f325d0936ed4eebced3cb8aa', + value: 7146, + sequenceNo: 4294967294, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a91403c63d3a52cde136da8858e9d0ffaa810cb6639288ac', }, ], outputs: [ { value: 0, + outputScript: '6a0450415900000008d980190d13019567', + }, + { + value: 1800, outputScript: - '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000001', + '76a914f66d2760b20dc7a47d9cf1a2b2f49749bf7093f688ac', }, { - value: 860, - outputScript: 'a91463b7313157fb1d054919364c837d8af927fa569987', - token: { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, + value: 3876, + outputScript: + '76a91401bfce4ff373b108bd65b4da08de621ade85adb588ac', spentBy: { - txid: 'c7fe7ac1f29c34e0795786b609622f6439cfde52246f31cba89aa0b28c8542ee', + txid: '566a7c12364e3f362fbc738bf209527d3074ce0a2d19b797d3ca34a3482e3386', outIdx: 0, }, }, - { - value: 1012, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, ], lockTime: 0, - timeFirstSeen: 1729632267, - size: 422, + timeFirstSeen: 0, + size: 245, isCoinbase: false, - tokenEntries: [ - { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, - groupTokenId: - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', - }, - ], + tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 867731, - hash: '000000000000000023e84eda63a1c6cce9c8e1d8b6484ee3dba0bf13b38d9116', - timestamp: 1729632495, + height: 828922, + hash: '0000000000000000018b4f795d767bce0438dedf67d2904e35da7d746065af1a', + timestamp: 1706323334, }, }, parsed: { - satoshisSent: 860, - stackArray: [ - '534c5000', - '41', - '53454e44', - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - '0000000000000001', - ], - xecTxType: 'Sent', - recipients: ['ecash:pp3mwvf32la36p2frymyeqma3tuj07jknyhljj09qd'], - }, - // 1 Nile Kinnick - cache: [ - [ - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + satoshisSent: 1800, + stackArray: ['50415900', '00', '00', 'd980190d13019567'], + xecTxType: 'Received', + appActions: [ { - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - timeFirstSeen: 1713828197, - genesisInfo: { - tokenTicker: 'NK', - tokenName: 'Nile Kinnick', - url: 'cashtab.com', - decimals: 0, - hash: 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - }, - block: { - height: 841418, - hash: '000000000000000015c94349a2ec777da460e8d8d48a220bbf9d6a6e6e9df66f', - timestamp: 1713829166, - }, - genesisSupply: '1', - genesisOutputScripts: [ - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - ], - genesisMintBatons: 0, + action: { data: '', nonce: 'd980190d13019567' }, + isValid: true, + app: 'PayButton', + lokadId: '50415900', }, ], - ], + parsedTokenEntries: [], + recipients: ['ecash:qqqmlnj07demzz9avk6d5zx7vgddapddk5k05jys53'], + replyAddress: 'ecash:qqpuv0f62tx7zdk63pvwn58l42qsednrjgnt0czndd', + }, }; -// 8880046b7b34da75f405abf8e76237082ed83f6a6293b378f83629320bf57097 -// buy from 76458db0ed96fe9863fc1ccec9fa2cfab884b0f6 -// sale for 95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d -export const agoraOneshotSaleTx = { +export const PayButtonYesDataYesNonce = { tx: { - txid: '8880046b7b34da75f405abf8e76237082ed83f6a6293b378f83629320bf57097', + txid: '952dd66d7145330d8d3b2f09abbee33344e8aa65b7483cfaa9d278ec55379e29', version: 2, inputs: [ { prevOut: { - txid: 'c7fe7ac1f29c34e0795786b609622f6439cfde52246f31cba89aa0b28c8542ee', - outIdx: 1, - }, - inputScript: - '2102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd879540c4da30dce1304b58ad7e2b8f87729d2b7c5f7c2390e8bbc33bebcc7c80503c992801df01dad963adb737892e0d3499875b99477f65786c45e9146610a219fe104c5aee42858cb2a09aa8cb316f2452decf39642f6209b6865779e0349cf2c17afec70100000001ac2202000000000000ffffffffc996989ea840ccd9e2f0324dc0accbe26a32c3c8bd5d710ce18f68acaafdb3d300000000c10000004422020000000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac7a3d160c000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac514cb0634c6b0000000000000000406a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df30800000000000000000800000000000000013ea74b04000000001976a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac7c7eaa7801327f7701207f7588520144807c7ea86f7bbb7501c17e7c672103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba668abac', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: 'a914dec4855b83573e56312d9f3852697a48c09ee6b087', - }, - { - prevOut: { - txid: 'd8a564b6aa82861ea16864ef83d0ec81ecf8cb13c0a59c2737a444c7b880368d', - outIdx: 3, - }, - inputScript: - '414964793d1de39477192d9ee1491c49973303b18b594b249cfb0b9b752826f0ccc9da5ebf1dde9de63f5e5825b3e7257f48e1310920e30e28e83beada1f21be58412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 19360, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: '4fdcf99a029298ca1e3a692c4485711d22e7eb6aeb76d58354666e0a87260a4a', - outIdx: 1, - }, - inputScript: - '41c60f1f0f70dd45780f5b5a48e7e8e823ab04ae5f2b652c68d36856d7999e65423c88f4315bde6eeebe1c263e27b5275453a52c33962eddd704ec63330482cbde412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 11007, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: '9191385318562f9b9491cb51dd336054ff48086effdb603ce4d070ec27b0a310', - outIdx: 1, - }, - inputScript: - '418a65da44dc054c90c718cafe5a8eb1a58a40f1c2864a356152eadb6ad439f66f7e457f09821fb53b07bd50d68baa64abed6134f98d18c2da4050496c54341a4c412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 5235, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: 'e85c851664f633ac3888908be544d379b6a300ecd7e3ba3b7d8895ff4bcd2907', - outIdx: 1, - }, - inputScript: - '41db37e18dda29041f7f931bb895777ec8bea1f6341dc48a144a2deac2545519892c19c050bfe8eb32143a5860ef4343079cb0b6705f2b72e8555f3b96badd3e82412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 4201, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: '2bec8ef2b93a4cc859d2b5eef36516d5e559ed6c8ba14437ebd910d7110e8e7b', - outIdx: 2, - }, - inputScript: - '41f5ad3937e27b09550dfac33838bb0acfe61bf69378c3fbd6fb145ce48cf0cd9fc7e2b4abfcb17616dedecd33e84a860c5f2ceea50ea0e59a59e7fa4e87b478ce412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 19901, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: '528fc61b8fe7131dcba81c99a4604c409aafe6faaf4286e21da07cae92bdf586', - outIdx: 2, - }, - inputScript: - '41346e924f1a559129de3bb6f8bfb9358aae0401ab6dcc49c9e974bed7b94b246f001ec19ed7c682d945426882abce9f5bebdd984845b2c127c0f2549fcee5aec9412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 12964, - sequenceNo: 4294967295, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - }, - { - prevOut: { - txid: '5963aebb41910aee8014cbbf2e2fb487dcbecb8b4a66b26e07f5b6542355bbf7', - outIdx: 1, + txid: '37a740f89ab6c212f211150f35fb1e12cd80f287b825126eed262999ea4264b8', + outIdx: 0, }, inputScript: - '41f5295566cdf6a64102474a4cf1a90c0be1f734a01a7c553d28d79543de93991633b67473c7cd859f14f4682942ea08b8f399abc3d9aba4d3017931ae61f677d4412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 274781657, - sequenceNo: 4294967295, + '41fc1401150778a0d47d5279ccdaa13298cfa43e25d8d37d37570291207a92098beefa8fb25b8fb9cb2c4d7b5f98b7ff377c54932e0e67f4db2fc127ed86e01b1a4121024b60abfca9302b9bf5731faca03fd4f0b06391621a4cd1d57fffd6f1179bb9ba', + value: 3403110, + sequenceNo: 4294967294, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a914e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000000080000000000000001', - }, - { - value: 72066878, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '6a04504159000008f09f9882f09f918d0869860643e4dc4c88', }, { - value: 546, + value: 3392102, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - token: { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, + '76a914e573dd89a61f8daeb56bf5b5fb5d7cd86e31ab2e88ac', + spentBy: { + txid: '8b2a86aabae90c0f9e8a111e220c85b52fc54b15c6d46cbbbca89020318714a4', + outIdx: 0, }, }, { - value: 202784122, + value: 9490, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a914697ae72b062557fa69f9d4d09182529da368ab6988ac', + spentBy: { + txid: '1b3165e7edef19369880f032d8f4d19cc41e9ebf2bfb657518ae99075aa2b471', + outIdx: 0, + }, }, ], lockTime: 0, - timeFirstSeen: 1729713477, - size: 1654, + timeFirstSeen: 0, + size: 253, isCoinbase: false, - tokenEntries: [ + tokenEntries: [], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', + block: { + height: 828920, + hash: '00000000000000000d6a683b11a6bdaab4b79b15f100daa9361d02207667de1d', + timestamp: 1706323234, + }, + }, + parsed: { + satoshisSent: 3401592, + stackArray: ['50415900', '00', 'f09f9882f09f918d', '69860643e4dc4c88'], + xecTxType: 'Sent', + recipients: [ + 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', + 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + ], + appActions: [ { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, + action: { + data: '😂👍', + nonce: '69860643e4dc4c88', }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, - groupTokenId: - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + isValid: true, + lokadId: '50415900', + app: 'PayButton', }, ], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + parsedTokenEntries: [], }, - parsed: { - recipients: ['ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035'], - satoshisSent: 72066878, - stackArray: [ - '534c5000', - '41', - '53454e44', - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - '0000000000000000', - '0000000000000001', +}; + +// No data no payment id +const PayButtonEmptyTx = JSON.parse( + JSON.stringify(PayButtonYesDataYesNonce.tx), +); +// Create a tx with 00 in paymentId and nonce spaces +PayButtonEmptyTx.outputs[0].outputScript = '6a0450415900000000'; +export const PayButtonEmpty = { + tx: PayButtonEmptyTx, + parsed: { + satoshisSent: 3401592, + stackArray: ['50415900', '00', '00', '00'], + xecTxType: 'Sent', + recipients: [ + 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', + 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', ], + appActions: [ + { + action: { + data: '', + nonce: '', + }, + isValid: true, + lokadId: '50415900', + app: 'PayButton', + }, + ], + parsedTokenEntries: [], + }, +}; +// data and no payment id +const PayButtonYesDataNoNonceTx = JSON.parse( + JSON.stringify(PayButtonYesDataYesNonce.tx), +); +// Create a tx with 00 in paymentId and nonce spaces +PayButtonYesDataNoNonceTx.outputs[0].outputScript = + '6a0450415900000e6f6e6c792064617461206865726500'; +export const PayButtonYesDataNoNonce = { + tx: PayButtonYesDataNoNonceTx, + parsed: { + satoshisSent: 3401592, + stackArray: ['50415900', '00', '6f6e6c7920646174612068657265', '00'], xecTxType: 'Sent', + recipients: [ + 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', + 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + ], + appActions: [ + { + action: { + data: 'only data here', + nonce: '', + }, + app: 'PayButton', + isValid: true, + lokadId: '50415900', + }, + ], + parsedTokenEntries: [], }, - cache: agoraAdSetupTxSlpNft.cache, }; -// e9d594e054bf9a7cead11cdc31953f0e45782c97c6298513f41b70eb408aa1a8 -export const agoraPartialCancelTx = { +// Off spec paybutton tx +const PayButtonOffSpecTx = JSON.parse( + JSON.stringify(PayButtonYesDataYesNonce.tx), +); +// Create a tx with 3 pushes instead of expected 4 +PayButtonOffSpecTx.outputs[0].outputScript = '6a04504159000008f09f9882f09f918d'; +export const PayButtonOffSpec = { + tx: PayButtonOffSpecTx, + parsed: { + satoshisSent: 3401592, + stackArray: ['50415900', '00', 'f09f9882f09f918d'], + xecTxType: 'Sent', + recipients: [ + 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', + 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + ], + appActions: [ + { + app: 'PayButton', + isValid: false, + lokadId: '50415900', + }, + ], + parsedTokenEntries: [], + }, +}; + +// Unsupported version paybutton tx +const PayButtonBadVersionTx = JSON.parse( + JSON.stringify(PayButtonYesDataYesNonce.tx), +); +// Force a version 1 tx +PayButtonBadVersionTx.outputs[0].outputScript = + '6a0450415900010108f09f9882f09f918d0869860643e4dc4c88'; +export const PayButtonBadVersion = { + tx: PayButtonBadVersionTx, + parsed: { + satoshisSent: 3401592, + stackArray: ['50415900', '01', 'f09f9882f09f918d', '69860643e4dc4c88'], + xecTxType: 'Sent', + recipients: [ + 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', + 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + ], + appActions: [ + { + app: 'PayButton', + isValid: false, + lokadId: '50415900', + }, + ], + parsedTokenEntries: [], + }, +}; + +export const MsgFromElectrum = { tx: { - txid: 'e9d594e054bf9a7cead11cdc31953f0e45782c97c6298513f41b70eb408aa1a8', + txid: 'd0c4c5b86016b7a021470180cb4afd1f8456fcf683a19d8b061b2225abd71be4', version: 2, inputs: [ { prevOut: { - txid: '58ec58688cef1d0abe2ee30c15f84af51833e61e998841fac3ecbcadafc31233', - outIdx: 2, + txid: '7e439e4a1dde6f4380ed1afddbd5f484db80b00f26c85b3f10f6ccb245da5800', + outIdx: 4, }, inputScript: - '41fd18138ab17386e9599e54d9d5f1994d1c4add3af860b1ece44b71d04bc7e7cd799e1234e2959236cd38558713d7fdb797a894c527906b0235a38519ad63fbea4121024f624d04900c2e3b7ea6014cb257f525b6d229db274bceeadbb1f06c07776e82', - value: 975251, - sequenceNo: 4294967295, + '416d2f67c38b81b6fdd13f4cb2c2d0a9194800e98b80a1054ca83b1ea3d739e70f9c4e2c8a61050b40161a0d741db9a6e71d155cf61623b9279739b50446d3ec6a4121026769c23182aaa572c16c82121caff660a7c13befd0d20c263e577ca01c4f029e', + value: 81319, + sequenceNo: 4294967294, outputScript: - '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', - }, - // Note that the p2sh is not necessarily input 0 for an agora partial cancel tx - { - prevOut: { - txid: '0c580a7dbfb7f160f0e4623faa24eb0475b2220704c8c46f279a479a477433f8', - outIdx: 1, - }, - inputScript: - '0441475230075041525449414c4113bb98283dc7a2f69957940bb3a45f4ec6050b61bcc1b1134d786727e379c8793107bf0d0b0e051665ab3eed2cca34901646cf564a1ab52cb32668da229eef0b41004d5f014c766a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8080000000000000000030276a4000000000000e815000000000000a24a2600000000004b4a343a024f624d04900c2e3b7ea6014cb257f525b6d229db274bceeadbb1f06c07776e8208948eff7f00000000ab7b63817b6ea2697603a24a26a269760376a4009700887d94527901377f75789263587e780376a400965580bc030000007e7e68587e52790376a400965580bc030000007e7e825980bc7c7e0200007e7b02e7159302e8159656807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702dd007f5c7f7701207f547f75044b4a343a886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - amount: '855738679296', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: 'a914cb61d733f8e99b1b40d40a53a59aca8a08368a6f87', + '76a914eff9a0ba847ae97697a9f97c05887aba2b41060e88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f808000000c73e000000', + '6a1774657374696e672061206d736720666f72206572726f72', }, { - value: 546, + value: 80213, outputScript: - '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', - token: { - tokenId: - '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - amount: '855738679296', - isMintBaton: false, - entryIdx: 0, + '76a914731fbd873b3603e8dafd62923b954d38571e10fc88ac', + spentBy: { + txid: 'b817870c8ae5ec94d639089e37763daee271f412ab478705a29b036ba0b00f3d', + outIdx: 55, }, }, { - value: 973723, + value: 600, outputScript: - '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', + '76a9144e532257c01b310b3b5c1fd947c79a72addf852388ac', + spentBy: { + txid: 'dc06ab36c9a7e365f319c0e918324af9778cb29b82c07ff87e2ec80eb6e4e6fe', + outIdx: 9, + }, }, ], lockTime: 0, - timeFirstSeen: 1729789538, - size: 760, + timeFirstSeen: 1709353270, + size: 253, isCoinbase: false, - tokenEntries: [ - { - tokenId: - '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, - }, - ], + tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 867971, - hash: '000000000000000013f3d459ae121dc1494e7e9fe57c2e60cf393184d7ab6dc9', - timestamp: 1729793460, + height: 833968, + hash: '000000000000000020f276cf59fc4e53672500ca5b5896502d0a50500174c27c', + timestamp: 1709354653, }, }, parsed: { - recipients: [], - satoshisSent: 974269, - stackArray: [ - '534c5000', - '01', - '53454e44', - '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', - '000000c73e000000', - ], - xecTxType: 'Sent', - }, - cache: [ - [ - '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + satoshisSent: 600, + stackArray: ['74657374696e672061206d736720666f72206572726f72'], + xecTxType: 'Received', + appActions: [ { - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - genesisInfo: { - tokenTicker: 'VSP', - tokenName: 'Vespene Gas', - url: 'https://simple.wikipedia.org/wiki/StarCraft#Gameplay', - decimals: 9, - hash: '', - }, - timeFirstSeen: 0, - genesisSupply: '3000000000.000000000', - genesisOutputScripts: [ - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - ], - genesisMintBatons: 0, - block: { - height: 763087, - hash: '0000000000000000015abcebc15e74036598855a9fdd976868ad99bb23b87a89', - timestamp: 1666631359, + action: { + decoded: 'testing a msg for error', + stack: '74657374696e672061206d736720666f72206572726f72', }, + lokadId: '', + app: 'none', }, ], - ], + parsedTokenEntries: [], + recipients: ['ecash:qpe3l0v88vmq86x6l43fywu4f5u9w8sslsga0tcn4t'], + replyAddress: 'ecash:qrhlng96s3awja5h48uhcpvg02azksgxpce6nvshln', + }, }; -// 6c6b32e7d68f5743dceec779c61ebe45dc1e8ca7562821ae974c71ef8d2450a7 -export const agoraPartialBuxBuyTx = { +export const unknownAppTx = { tx: { - txid: '6c6b32e7d68f5743dceec779c61ebe45dc1e8ca7562821ae974c71ef8d2450a7', + txid: '4cd528a95263714b8f748d58df30c44956158825924e3385b5c5c511129d1b3a', version: 2, inputs: [ { prevOut: { - txid: 'f696ae69fb2d7f7253f1fc98aba1a6312c92e98dd691d9825f633aaf7b0f2417', + txid: '9ca28926f8ec125dce0b7084468bd595b27bd73991b48461ac994cacff47a21d', outIdx: 1, }, inputScript: - '0441475230075041525449414c21023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1400c2c91f9168505022957e651ce0d876ec90a483dec8eb83f9a2897cd0b1640962dcab03e0df52f086db75351d10c01386ff2dcf4e774ee09b5dcf6b96ced6b254422020000000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688acc5728209000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac4d280117240f7baf3a635f82d991d68de9922c31a6a1ab98fcf153727f2dfb69ae96f601000000cf7b63817b6ea269760460368f02a2697602c6109700887d94527901377f75789263587e7802c610965880bc007e7e68587e527902c610965880bc007e7e825980bc7c7e007e7b5d935e9658807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702cf007f5c7f7701207f547f750443840647886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c880441475230872202000000000000ffffffffb0f7a847759b44cb4dd22554924cf5dae4d946b5aa04372b20eb218d43210b4243840647c10000000422ad0024514d51014c766a04534c500001010453454e44207e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e50800000000000000000000c6100000000000000e0000000000000060368f020000000043840647037f1729ee682b22da2b5dd8a11779ec7b80739c4b5d4b48f83c35d83fbb40a21208c09ef87f00000000ab7b63817b6ea269760460368f02a2697602c6109700887d94527901377f75789263587e7802c610965880bc007e7e68587e527902c610965880bc007e7e825980bc7c7e007e7b5d935e9658807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702cf007f5c7f7701207f547f750443840647886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', - value: 546, + '483045022100b50fac4b810ac6b10ce35f25fcc1a6b1f87b1209e8ee5973732d983395199de102204f860238b12ba3e7adfc432e331405f751fef1aa494c2d0122b7aaa522158933412102188904278ebf33059093f596a2697cf3668b3bec9a3a0c6408a455147ab3db93', + value: 3725, sequenceNo: 4294967295, - token: { - tokenId: - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + outputScript: + '76a914d18b7b500f17c5db64303fec630f9dbb85aa959688ac', + }, + ], + outputs: [ + { + value: 0, + outputScript: + '6a4cd43336616533642d4d45524f4e2d57494e227d2c7b226e616d65223a2277616c61222c226d657373616765223a223635396661313133373065333136663265613336616533642d57414c412d57494e227d5d2c227465726d73223a5b7b226e616d65223a22726566657265655075624b6579222c2274797065223a226279746573222c2276616c7565223a22303231383839303432373865626633333035393039336635393661323639376366333636386233626563396133613063363430386134353531343761623364623933227d5d7d7d7d7d', + }, + { + value: 3308, + outputScript: + '76a914d18b7b500f17c5db64303fec630f9dbb85aa959688ac', + spentBy: { + txid: 'e5b4912fa19d93db9b6b9586ad9ab3a7f9bc3514325c71e36816e4b047a9f6b8', + outIdx: 0, + }, + }, + ], + lockTime: 0, + timeFirstSeen: 0, + size: 416, + isCoinbase: false, + tokenEntries: [], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', + block: { + height: 826662, + hash: '00000000000000001d45441094ec7a93f42f3beb564684aba68250b016feefb4', + timestamp: 1704961725, + }, + }, + parsed: { + satoshisSent: 3308, + stackArray: [ + '3336616533642d4d45524f4e2d57494e227d2c7b226e616d65223a2277616c61222c226d657373616765223a223635396661313133373065333136663265613336616533642d57414c412d57494e227d5d2c227465726d73223a5b7b226e616d65223a22726566657265655075624b6579222c2274797065223a226279746573222c2276616c7565223a22303231383839303432373865626633333035393039336635393661323639376366333636386233626563396133613063363430386134353531343761623364623933227d5d7d7d7d7d', + ], + xecTxType: 'Sent', + recipients: [], + appActions: [ + { + action: { + decoded: + '36ae3d-MERON-WIN"},{"name":"wala","message":"659fa11370e316f2ea36ae3d-WALA-WIN"}],"terms":[{"name":"refereePubKey","type":"bytes","value":"02188904278ebf33059093f596a2697cf3668b3bec9a3a0c6408a455147ab3db93"}]}}}}', + stack: '3336616533642d4d45524f4e2d57494e227d2c7b226e616d65223a2277616c61222c226d657373616765223a223635396661313133373065333136663265613336616533642d57414c412d57494e227d5d2c227465726d73223a5b7b226e616d65223a22726566657265655075624b6579222c2274797065223a226279746573222c2276616c7565223a22303231383839303432373865626633333035393039336635393661323639376366333636386233626563396133613063363430386134353531343761623364623933227d5d7d7d7d7d', + }, + app: 'none', + lokadId: '', + }, + ], + parsedTokenEntries: [], + }, +}; + +export const AlpTx = { + tx: { + txid: '791c460c6d5b513283b98b92b83f0e6fa662fc279f39fd00bd27047370ba4647', + version: 1, + inputs: [ + { + prevOut: { + txid: '927bf59fee669509ffee3f3cad5d283694adaf8e44e37e2ae62df53e51116052', + outIdx: 1, + }, + inputScript: + '41482340e636feab0d15efb309e72eac0f559d0b85eb1799e0a1419430e95448a6a5c1e3961c92861e653dde4428e6e3a79c90d10911b045e7469f7beeae62fc56c1210378d370d2cd269a77ac2f37c28d98b392e5b9892f3b3406bfec8794c82244b039', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - amount: '500000', + amount: '49756', isMintBaton: false, entryIdx: 0, }, - outputScript: 'a9149c2c40a0a571b35e2e6cca5c224d0c948096a36b87', + outputScript: + '76a914575116c8adf5817c99fc5bdac8db18d10c25703d88ac', }, { prevOut: { - txid: '20d870129eab4418cf8917731ba9f240d5ac6a938d0570af2912f3ed77162d34', + txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', outIdx: 2, }, inputScript: - '41fb428d1c14340d4ef10c55202db803232018f0ae41777503c4a9cb78b4659fad4540f27314c74b9247a1c88937c5594ef908f5e916dddd5b054f290c5a8807a4412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 32055, + '4152ed9a66a0c40759e400a1484df1a1d2b152c9d6917abf3beaf974f21a935d60853490ae5a07c237531016ceae6c1f01cce9cf2a1417b2b2bcbbc4737ea2fe35412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', + value: 1000, sequenceNo: 4294967295, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', }, { prevOut: { - txid: '2cd92dbce9696b704ae7235e31d0840d728ad11217631dee849d49624f91ffd4', - outIdx: 0, + txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', + outIdx: 3, }, inputScript: - '4102e2c50dc6e3c3d8151c950075bc997dbe4762b1c59bcbe3cdd124566d1925bcecb466d21d32133b68fb8579b79e538f4b8dd61832374f2f713f328c3fc850ab412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 3300, + '412a65517b4df68bb03ba2b7cd85e70af662503bbc8be209e7fbf18bb0950ff7e0d589f0b3e8119b5e67314fbedd856968890556593d97db58c78e86d2417f27d7412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', + value: 1000, sequenceNo: 4294967295, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', }, { prevOut: { - txid: '874d3ddb44d022952d3686d39d219c7fdf21327eaa852d2d249102bec026ec4a', - outIdx: 3, + txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', + outIdx: 4, }, inputScript: - '412f68bc4b72f9df1435d4046719b793556295fbe02d80c8752acf587afac49d09f160ba04f2dfd5c1fa9ae5e294e31d5b8efc331074cefa08bfe7e2106e46b34a412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 202656827, + '412c9a66d04d341b1f0c3a15689265729a18f5605269909ad9f7b842ea03d96f8540e1b5b272ddc9db5f2d392a8e0569428a7ba4b5d99bbc707168898399f00da7412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', + value: 1000, sequenceNo: 4294967295, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', + }, + { + prevOut: { + txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', + outIdx: 5, + }, + inputScript: + '41f2ffdbd5f3694669d448899d3f6d939a8165d70cba6be2eaa8416847d56d4630a7b3ac8a35641705e4eb583b391a46c204920641dd85e2b7e04dd18553422651412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', + value: 1000, + sequenceNo: 4294967295, + outputScript: + '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001010453454e44207e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5080000000000000000080000000000057ba508000000000002257b', + '6a503d534c5032000453454e4445e1f25de444e399b6d46fa66e3424c04549a85a14b12bc9a4ddc9cdcdcdcdcd038a02000000003e3000000000948f00000000', }, { - value: 43144579, + value: 546, outputScript: '76a914dee50f576362377dd2f031453c0bb09009acaf8188ac', - }, - { - value: 546, - outputScript: 'a914502ed21ca74bde03d7fb672ed9c996eab92e72fd87', token: { tokenId: - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - amount: '359333', + amount: '650', isMintBaton: false, entryIdx: 0, }, }, { - value: 546, - outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + value: 1960, + outputScript: 'a914b0bfb87508e5203803490c2f3891d040f772ba0f87', token: { tokenId: - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - amount: '140667', + amount: '12350', isMintBaton: false, entryIdx: 0, }, }, { - value: 159544005, + value: 546, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', - spentBy: { - txid: '40c5a257a9797bf9cb44f0f1fe7ee08d732a151c70f1a038487bac4a431b7787', - outIdx: 1, + '76a914575116c8adf5817c99fc5bdac8db18d10c25703d88ac', + token: { + tokenId: + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, + }, + amount: '36756', + isMintBaton: false, + entryIdx: 0, }, }, ], - lockTime: 1191609411, - timeFirstSeen: 1729812060, - size: 1518, + lockTime: 0, + timeFirstSeen: 1710439161, + size: 888, isCoinbase: false, tokenEntries: [ { tokenId: - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, txType: 'SEND', isInvalid: false, @@ -10266,165 +10602,135 @@ tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', block: { - height: 867988, - hash: '000000000000000029b0040b966ade65e7217457758ef4c1a9f524bacc30baf5', - timestamp: 1729813559, + height: 835924, + hash: '00000000000000000cb5f7d96ddff0d04096c405a0361196bcbe60622ea0e44f', + timestamp: 1710440413, }, }, parsed: { - recipients: [ - 'ecash:qr0w2r6hvd3rwlwj7qc520qtkzgqnt90sypk26yd2u', - 'ecash:ppgza5su5a9auq7hldnjakwfjm4tjtnjl54xmlf83s', - ], - satoshisSent: 43145125, + satoshisSent: 546, stackArray: [ - '534c5000', - '01', - '53454e44', - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', - '0000000000000000', - '0000000000057ba5', - '000000000002257b', + '50', + '534c5032000453454e4445e1f25de444e399b6d46fa66e3424c04549a85a14b12bc9a4ddc9cdcdcdcdcd038a02000000003e3000000000948f00000000', ], - xecTxType: 'Sent', - }, - cache: [ - [ - '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + xecTxType: 'Received', + appActions: [], + parsedTokenEntries: [ { - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - genesisInfo: { - tokenTicker: 'BUX', - tokenName: 'Badger Universal Token', - url: 'https://bux.digital', - decimals: 4, - hash: '', - }, - timeFirstSeen: 0, - genesisSupply: '0.0000', - genesisOutputScripts: [ - 'a91420d151c5ab4ca4154407626069eaafd8ce6306fc87', - ], - genesisMintBatons: 1, - block: { - height: 726564, - hash: '000000000000000010ea35897b2b7373261fdfbca3d02e4f9a6eeb79dc914315', - timestamp: 1644797123, - }, + renderedTokenType: 'ALP', + renderedTxType: 'SEND', + tokenId: + 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + tokenSatoshis: '650', }, ], - ], + recipients: [ + 'ecash:pzctlwr4prjjqwqrfyxz7wy36pq0wu46pud7n9ffz3', + 'ecash:qpt4z9kg4h6czlyel3da4jxmrrgscfts859gzp2zuu', + ], + replyAddress: 'ecash:qpt4z9kg4h6czlyel3da4jxmrrgscfts859gzp2zuu', + }, }; -// 3ada11ca38e5da8bfda9b045ab7412cecff5b788aad8e49673183010e725099e -export const partialBuyBull = { +export const SlpNftParentFanTx = { tx: { - txid: '3ada11ca38e5da8bfda9b045ab7412cecff5b788aad8e49673183010e725099e', + txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', version: 2, inputs: [ { prevOut: { - txid: '20469a4316506e0fea99ad0673d6663f2f546c0aad84b741e08c4d0f9248b18c', + txid: '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', outIdx: 1, }, inputScript: - '0441475230075041525449414c21023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1404799ed59b763768b8e7385a35c0a357e624e1725154d4c3240f38edc021527b267881f2078be11f89221f6c8036c156274742dae00ce8a88bb6ee527bc18dc744422020000000000001976a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac4d420100000000001976a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac4d32018cb148920f4d8ce041b784ad0a6c542f3f66d67306ad99ea0f6e5016439a462001000000d97b63817b6ea26976046de4ff17a26976033b62109700887d94527901377f75789263587e78033b6210965880bc007e7e68587e5279033b6210965880bc007e7e825980bc7c7e01007e7b03288f009303298f009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d9007f5c7f7701207f547f7504f3282c4e886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c880441475230872202000000000000ffffffffca3033eea929796cc020b87c909e38d37943502aa69486f2d97d56daa454e28df3282c4ec1000000046de4ff17514d5b014c766a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f89608000000000000000000013b62100000000000298f0000000000006de4ff1700000000f3282c4e03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba608f06cff7f00000000ab7b63817b6ea26976046de4ff17a26976033b62109700887d94527901377f75789263587e78033b6210965880bc007e7e68587e5279033b6210965880bc007e7e825980bc7c7e01007e7b03288f009303298f009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d9007f5c7f7701207f547f7504f3282c4e886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', + '483045022100a5e4824f76bad8f224412fca2442c11598d6dd29848b67ae0e8c6f74a5a80b2c022049ee636ac6b951eba8273f300bcab8ffc31525f4d96ca738cfbb62e73769bf3a412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', value: 546, sequenceNo: 4294967295, token: { tokenId: - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - amount: '2000', + amount: '4', isMintBaton: false, entryIdx: 0, }, - plugins: { - agora: { - groups: [ - '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - '5401d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', - '4601d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', - ], - data: [ - '5041525449414c', - '00', - '01', - '3b62100000000000', - '298f000000000000', - '6de4ff1700000000', - 'f3282c4e', - ], - }, - }, - outputScript: 'a914563178ea073228709397a2c98baf10677e683e6687', + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, { prevOut: { - txid: 'bfce47f2403031f5465982b821e8e14c78deff2dd5986ca0c21cebb5ed946b4d', - outIdx: 2, + txid: '73c8333ffbf94d14a52c0284a67a7e0cb71dac08d6ae9da989f7c3b97339df7f', + outIdx: 3, }, inputScript: - '41866f21d34e5b061cf7cb9ce4a6ce4df037628b72765db893675eae909ddad9d7ea7593d1a510fee1d80887699410b4330e9214efd5668dd51644d7ffce498ac94121039f0061726e4fed07061f705d34707b7f9c2f175bfa2ca7fe7df0a81e9efe1e8b', - value: 2898252, + '483045022100dfe70b028211bf747a9d634f03f6f024264f75ef37f9dd4b40c8d8dfddfeff9702205ccb832e674c5c865353707fc46c5b4206dd807797d6b64f146441fa2d85bf94412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 32771801, sequenceNo: 4294967295, outputScript: - '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896080000000000000000080000000000000659080000000000000177', + '6a04534c500001810453454e442012a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3080000000000000001080000000000000001080000000000000001080000000000000001', }, { - value: 2812672, + value: 546, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + token: { + tokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, spentBy: { - txid: '5d934ade992707fe126bcd393ad4358b2c10118b635df4b97e3e3f30ca7cc781', - outIdx: 1, + txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', + outIdx: 0, }, }, { value: 546, - outputScript: 'a91451d609999740085f16cfbee2f9791d6ae6ac678d87', - plugins: { - agora: { - groups: [ - '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - '5401d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', - '4601d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', - ], - data: [ - '5041525449414c', - '00', - '01', - '3b62100000000000', - '298f000000000000', - '6de4ff1700000000', - 'f3282c4e', - ], + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + token: { + tokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, + amount: '1', + isMintBaton: false, + entryIdx: 0, }, + }, + { + value: 546, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - amount: '1625', + amount: '1', isMintBaton: false, entryIdx: 0, }, @@ -10432,46 +10738,42 @@ { value: 546, outputScript: - '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - amount: '375', + amount: '1', isMintBaton: false, entryIdx: 0, }, - spentBy: { - txid: 'f0e450b41d1c15b32478efb668bc562fa341a40fa799db7747228350295f84d4', - outIdx: 0, - }, }, { - value: 82509, + value: 32769023, outputScript: - '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', spentBy: { - txid: '3a7a8971392e74fd542498c055509ace4f4853b981d87d73ba045f77100dad1e', + txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', outIdx: 1, }, }, ], - lockTime: 1311516915, - timeFirstSeen: 1730860384, - size: 1256, + lockTime: 0, + timeFirstSeen: 1713825841, + size: 567, isCoinbase: false, tokenEntries: [ { tokenId: - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, txType: 'SEND', isInvalid: false, @@ -10485,108 +10787,117 @@ tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', block: { - height: 869782, - hash: '0000000000000000178954cd24752cd8fb8aa980c36012a16cec251d8c2f68d6', - timestamp: 1730861016, + height: 841414, + hash: '00000000000000000e074b0e1067d96e33a0b4df2a352dab1abbb6f28645563a', + timestamp: 1713826095, }, }, parsed: { - recipients: [ - 'ecash:ppgavzvejaqqshcke7lw97ter44wdtr835rs9eedxc', - 'ecash:qq4t5d7kxewnu4cv4he76e093tj26ag6xql82hcgru', - ], - satoshisSent: 2812672, + recipients: [], + satoshisSent: 32771207, stackArray: [ '534c5000', - '01', + '81', '53454e44', - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', - '0000000000000000', - '0000000000000659', - '0000000000000177', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '0000000000000001', + '0000000000000001', + '0000000000000001', + '0000000000000001', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + nftFanInputsCreated: 4, + renderedTokenType: 'Collection', + renderedTxType: 'Fan Out', + tokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + tokenSatoshis: '0', + }, ], - xecTxType: 'Received', }, - sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', + // 3 The Four Half-Coins of Jin-qua (4HC) cache: [ [ - '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', { tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, + timeFirstSeen: 1713551159, genesisInfo: { - tokenTicker: 'BULL', - tokenName: 'Bull', - url: 'https://cashtab.com/', + tokenTicker: '4HC', + tokenName: 'The Four Half-Coins of Jin-qua', + url: 'en.wikipedia.org/wiki/Tai-Pan_(novel)', decimals: 0, - hash: '', + hash: '2a6585a404fae1c33a43322b723b9dbd926cb07244ae9bea888add8f471511e0', }, - timeFirstSeen: 0, - genesisSupply: '21000000', + block: { + height: 840791, + hash: '00000000000000000be1576bcb0bf1c035bba940d5c696d7bb8a0d53c16076c5', + timestamp: 1713551526, + }, + genesisSupply: '4', genesisOutputScripts: [ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', ], genesisMintBatons: 0, - block: { - height: 835482, - hash: '0000000000000000133bf16cb7fdab5c6ff64a874632eb2fe80265e34a6ad99f', - timestamp: 1710174132, - }, }, ], ], }; -// 1e68af94c0117223511e3d7f7b6f0f6c2ffa07972844ff6d04f7f37d36ad5b50 -export const agoraPartialCancelTwo = { +export const SlpNftMint = { tx: { - txid: '1e68af94c0117223511e3d7f7b6f0f6c2ffa07972844ff6d04f7f37d36ad5b50', + txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', version: 2, inputs: [ { prevOut: { - txid: 'ea28b2d3db0d4972eb56f2f20473fe821a6d46f328ecc5e97c4c3e353ff22a52', - outIdx: 3, - }, - inputScript: - '415ece5326f001de92ce37d34b6ada073c3f60b52231b8291e1d4900c4813b93379dfc3e11ed417c58fce9fc1ead27b5754d4d2c8ff3d6949e694a9529afea0f4c412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 661543961, - sequenceNo: 4294967295, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - { - prevOut: { - txid: '44aa224b6eb5058717d1403d7376ef48e0eae2e4065303f0f9452782aad9f541', - outIdx: 2, + txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', + outIdx: 1, }, inputScript: - '0441475230075041525449414c4195484212249b53096fa43b1dc39559f9671cd305b4715c063c486b2fc30eec194685f027c560742da8746b61aacfb05dd039d8e519fa7ca065d7fe3188fa63df41004d5a014c766a04534c500001010453454e4420b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc0800000000000000000001f588410000000000f980000000000000f588410000000000bbbcb84f03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba608bbd1b77e00000000ab7b63817b6ea2697603f58841a2697603f588419700887d94527901377f75789263587e7803f58841965880bc007e7e68587e527903f58841965880bc007e7e825980bc7c7e01007e7b03f880009303f980009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d8007f5c7f7701207f547f7504bbbcb84f886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', + '483045022100939d517c889174bdcaf9755390165ce1e2ba7f47d1490dbf48bbf2f4146c84360220172aeb2fe8eca8a0c59e68ca6b2ab1a8fd0bdded8410212c5d34d936cadcf734412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', value: 546, sequenceNo: 4294967295, token: { tokenId: - 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - amount: '495', + amount: '1', isMintBaton: false, - entryIdx: 0, + entryIdx: 1, }, - outputScript: 'a914b069fa99f084a259a6a31cc8cf33edb8a853fbb587', + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, + { + prevOut: { + txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', + outIdx: 5, + }, + inputScript: + '483045022100da6101ab8d02141d6745b3985d4c1ba5481cb2c470acff8d40e66fa654e3f14402200906d6a511dda0c5bc243f82217a03fe40c3cfc0a407b2d1e6f971de1ae70316412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 32769023, + sequenceNo: 4294967295, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001010453454e4420b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc0800000000000001ef', + '6a04534c500001410747454e45534953035746430c57752046616e672043686f690b636173687461622e636f6d20ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a297308385501004c00080000000000000001', }, { value: 546, @@ -10594,727 +10905,1505 @@ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, }, - amount: '495', + amount: '1', isMintBaton: false, entryIdx: 0, }, }, { - value: 661543206, + value: 32768070, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], lockTime: 0, - timeFirstSeen: 1729825975, - size: 755, + timeFirstSeen: 1713828197, + size: 474, isCoinbase: false, tokenEntries: [ { tokenId: - 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, }, - txType: 'SEND', + txType: 'GENESIS', isInvalid: false, burnSummary: '', failedColorings: [], actualBurnAmount: '0', intentionalBurn: '0', burnsMintBatons: false, - }, + groupTokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + }, + { + tokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, + }, + txType: 'NONE', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + }, ], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', }, - sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { - recipients: ['ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035'], - satoshisSent: 0, + recipients: [], + satoshisSent: 32768616, stackArray: [ '534c5000', - '01', - '53454e44', - 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', - '00000000000001ef', + '41', + '47454e45534953', + '574643', + '57752046616e672043686f69', + '636173687461622e636f6d', + 'ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a2973083855', + '00', + '', + '0000000000000001', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'NFT', + renderedTxType: 'GENESIS', + tokenId: + 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', + tokenSatoshis: '1', + }, + { + renderedTokenType: 'Collection', + renderedTxType: 'NONE', // this type occurs when we burn a 1-qty collection token to mint an NFT + tokenId: + '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + tokenSatoshis: '0', + }, ], - xecTxType: 'Received', }, + // 1 Wu Fang Choi (WFC) cache: [ [ - 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', { tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, }, + timeFirstSeen: 1713828197, genesisInfo: { - tokenTicker: 'CTD', - tokenName: 'Cashtab Dark', - url: 'https://cashtab.com/', + tokenTicker: 'WFC', + tokenName: 'Wu Fang Choi', + url: 'cashtab.com', decimals: 0, - hash: '', + hash: 'ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a2973083855', }, - timeFirstSeen: 0, - genesisSupply: '10000', + block: { + height: 841418, + hash: '000000000000000015c94349a2ec777da460e8d8d48a220bbf9d6a6e6e9df66f', + timestamp: 1713829166, + }, + genesisSupply: '1', genesisOutputScripts: [ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', ], genesisMintBatons: 0, - block: { - height: 726043, - hash: '00000000000000000182db32e000171006b7b7820181676b5fd8f29cc90d2b9c', - timestamp: 1644455332, - }, }, ], ], }; -// Canceling an agora oneshot NFT listing slp1 -// a57b6b00b328f0c6a916f6469dcc4e05ab202e7eca82f4cda5dbd736064910d9 -export const AgoraOneshotCancelTx = { +export const SlpParentGenesisTxMock = { tx: { - txid: 'a57b6b00b328f0c6a916f6469dcc4e05ab202e7eca82f4cda5dbd736064910d9', + txid: 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', version: 2, inputs: [ { prevOut: { - txid: '9dad6def1241cea3ef1942e53ed0a34163da41fc726feb304fbd4d27482ce063', - outIdx: 1, - }, - inputScript: - '419b8ec92ca5701691d9f5e75d525532cbec6ed9d9ed81f8f982b5af76090289d001ce2022ec82ba096c99beb00b0d9b0a92f2ef8da269a7967e6856170796beac41004cb0634c6b0000000000000000406a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df308000000000000000008000000000000000164594e05000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac7c7eaa7801327f7701207f7588520144807c7ea86f7bbb7501c17e7c672102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd879568abac', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: 'a91451a5d608ff31c1585d7aba3a2afcd2ae02898abd87', - }, - { - prevOut: { - txid: '9cf904c798295bfee43670162dc816e25d129ae9a0b13a41f11560cf7dbbb5b8', - outIdx: 3, + txid: '5d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a2228326', + outIdx: 2, }, inputScript: - '41ccbca2638a68145ecc38c8a96c058dff2619b8d495360e0b5866de555f1c6b621ef147df1a9e0f5bee006d1db94e1e2670915265d38f3ba801114037ed0d441d412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', - value: 1153, + '483045022100eb2e68c7d02eda2dd64c22a079d832c5c85f34f1ced264cd3b37658d4cd0b89e02203e204cd625a05c8ba59291567bc14d0bfa193a9a37cbc00aec804a224dc910d1412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 32766028, sequenceNo: 4294967295, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000001', + '6a04534c500001810747454e455349530348534d0b54686520486569736d616e2c68747470733a2f2f656e2e77696b6970656469612e6f72672f77696b692f486569736d616e5f54726f7068792073229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb97601004c00080000000000000059', }, { value: 546, outputScript: - '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - amount: '1', + amount: '89', isMintBaton: false, entryIdx: 0, }, + spentBy: { + txid: '1f2f9a37767586320a8af6afadda56bdf5446034910e27d537f26777ad95e0d5', + outIdx: 0, + }, + }, + { + value: 32764762, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + spentBy: { + txid: '1f2f9a37767586320a8af6afadda56bdf5446034910e27d537f26777ad95e0d5', + outIdx: 1, + }, }, ], lockTime: 0, - timeFirstSeen: 1729720346, - size: 535, + timeFirstSeen: 1714048251, + size: 358, isCoinbase: false, tokenEntries: [ { tokenId: - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', tokenType: { protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, }, - txType: 'SEND', + txType: 'GENESIS', isInvalid: false, burnSummary: '', failedColorings: [], actualBurnAmount: '0', intentionalBurn: '0', burnsMintBatons: false, - groupTokenId: - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', }, ], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 841852, + hash: '00000000000000000cea344b4130a2de214200266ad0d67253eea01eeb34a48d', + timestamp: 1714048284, + }, }, parsed: { - recipients: ['ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj'], - satoshisSent: 0, + recipients: [], + satoshisSent: 32765308, stackArray: [ '534c5000', - '41', - '53454e44', - 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', - '0000000000000001', + '81', + '47454e45534953', + '48534d', + '54686520486569736d616e', + '68747470733a2f2f656e2e77696b6970656469612e6f72672f77696b692f486569736d616e5f54726f706879', + '73229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb976', + '00', + '', + '0000000000000059', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'Collection', + renderedTxType: 'GENESIS', + tokenId: + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + tokenSatoshis: '89', + }, ], - xecTxType: 'Received', }, - cache: agoraAdSetupTxSlpNft.cache, + cache: [ + [ + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + { + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 129, + }, + timeFirstSeen: 1714048251, + genesisInfo: { + tokenTicker: 'HSM', + tokenName: 'The Heisman', + url: 'https://en.wikipedia.org/wiki/Heisman_Trophy', + decimals: 0, + hash: '73229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb976', + }, + block: { + height: 841852, + hash: '00000000000000000cea344b4130a2de214200266ad0d67253eea01eeb34a48d', + timestamp: 1714048284, + }, + genesisSupply: '89', + genesisOutputScripts: [ + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + ], + genesisMintBatons: 0, + }, + ], + ], }; -export const paywallPaymentTx = { +export const oneOutputReceivedTx = { tx: { - txid: 'e9692335fdb3b75f2e319cbda1396f7f32c02c3d172e58148abeb2952c7e2460', + txid: '0edd96775cc1dbc4c36dbf5f1773f937de3bdadd572265ad78bae931fec3f431', version: 2, inputs: [ { prevOut: { - txid: '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', - outIdx: 1, + txid: 'cd5731b4f5ec4ff2e12fe3187e37ce3dc544f5419df8f6c36f649e1236d7dcee', + outIdx: 0, }, inputScript: - '483045022100a58e1087f128d676d4b5839c795df15b88b87b47b0c8f382d39811ee5df21cf6022022727ede00178347e0ab0dd3df91959378c25a29f902a4f8b4f1c79ddd7cf15241210216794b896521c52b0b156d886652859d1e4e03a9cd8f3894f4b1e1853092a3c7', - value: 550, - sequenceNo: 4294967295, + '41246058dcfab4114536db638d064612e12e0cfff613b568535c278e544ec68ec3e02ffc94d09a0ffe0f4e6fd9ff9608b01aad46cad3765059c3fe45ea09898abe4121029bd5d9d9565b734188493dfd3b0fe985ccd55bb6bc1544cf6ed25a46076f045f', + value: 45553900000, + sequenceNo: 4294967294, outputScript: - '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', + '76a914bb3f3669824acaf67902cbc8477f75ae5b139a0f88ac', }, { prevOut: { - txid: '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', - outIdx: 2, + txid: '3719ef3aa2739da328a1a2916a422931fb7b0fa897183f3fd8f3c26864285e34', + outIdx: 0, }, inputScript: - '483045022100856c2d015d7384a094d0c17dde0ec29ee37ddf64c914a6c1d12c9bd92724bc52022027d9f6525c49786e5454615e605d1af0aa4fa0860eea39e927316042ba3557f141210216794b896521c52b0b156d886652859d1e4e03a9cd8f3894f4b1e1853092a3c7', - value: 27419, - sequenceNo: 4294967295, + '415d1ee0074f11a0adf5c35039167a731d008656eb0a33b5eec9144dd8614419e88866779cce3da0de8c9f839ddbb8d8ee8d24c82526a8900730ea8af8ef102c6d4121020b5c467c0276678df5f50cc932e81abf259f40477f815ed11f4d0fecab39f2d6', + value: 100000000, + sequenceNo: 4294967294, outputScript: - '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', + '76a91409c388abff6922c7e97ef8ea58e9697b6637910c88ac', }, ], outputs: [ { - value: 0, - outputScript: - '6a0470617977204d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', - }, - { - value: 15000, + value: 45653899320, outputScript: - '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', + '76a914601efc2aa406fe9eaedd41d2b5d95d1f4db9041d88ac', spentBy: { - txid: '84d75fe93ab918e74e58c1a12a982d0cc8d1db1bb102f02068772723891711b3', - outIdx: 0, + txid: 'b9aab1e26381457b390ad689c7577962cef1ec48de3a83d87db68968afb7e4cf', + outIdx: 54, }, }, - { - value: 12056, - outputScript: - '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', - }, ], lockTime: 0, - timeFirstSeen: 1716474827, - size: 454, + timeFirstSeen: 1714138690, + size: 326, isCoinbase: false, tokenEntries: [], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 845901, - hash: '00000000000000001da9291a7aa6fa8f9fa5f99413faa951e3f5777a082f911e', - timestamp: 1716475087, - }, - parsed: { - xecTxType: 'Sent', - satoshisSent: 27056, - stackArray: [ - '70617977', - '34643761363265626237663036666437613836663836313238303835336536666365336331313763373335393866653238343139303236306162643564646334', - ], - recipients: [], + height: 842022, + hash: '00000000000000000c331ba563d903d20ff670b18afd0d6cd4aadca854d294a6', + timestamp: 1714139968, }, }, + parsed: { + appActions: [], + parsedTokenEntries: [], + recipients: [], + replyAddress: 'ecash:qzan7dnfsf9v4aneqt9us3mlwkh9kyu6pufd42k3cf', + satoshisSent: 45653899320, + stackArray: [], + xecTxType: 'Received', + }, }; -export const swapTx = { +export const eCashChatAuthenticationTx = { tx: { - txid: 'baed6358b9ea2e354e384d2e31a576ffa25fcceaf796e711e8306f9c8086b00f', - version: 1, + txid: '61838af28ae42e3b6a5fd037e112fe0df936dabf2a6417091abce6a3d830b078', + version: 2, inputs: [ { prevOut: { - txid: '8b55a382501b538296cd13269b341f7a964366a705a45f89f56e0d783240f3a4', - outIdx: 2, - }, - inputScript: - '41256f3c091df7dea2bb9d74241b47116364d7b0035dfe1c5d1d398d8e92e99f4d5f3dd747f8e81ca99ddaf5630399ef18e26b6a3bf9b763cdd25225e68f7bbd2d41210304222c88e9936a195762fc4ee41a082e906a0e8434df43a03bfcdf1f9d2c1b8d', - value: 546, - sequenceNo: 4294967295, - outputScript: - '76a91493472d56ba91581ed473225a765dd14a2db5d9d888ac', - }, - { - prevOut: { - txid: '8b55a382501b538296cd13269b341f7a964366a705a45f89f56e0d783240f3a4', - outIdx: 3, + txid: 'f9323576b17aebd302272652ee9990b2a1347da7e3270d19b8d32ae60a0dec2f', + outIdx: 0, }, inputScript: - '418ab02f08273afd67c4db840f09429d7c76c0a71b28dbaef5c63f277944a168819d72bedd14e78b327a237f6070b0519ef8456efbfe206bae0c60d3b5f328faea412103df543832906a1f5fc8f201bb99454f350b1906375d522f735bd357cbda11ab5b', - value: 2565, + '413fb023c886471d0f7eefcd3e5bf2cdbc0f537edd20b9f515d32da7c80b519b7cdc2da3e6696220addd232ebd8c10d53c092965d6bcce262b1a8745a61a18f3a54121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', + value: 3377, sequenceNo: 4294967295, outputScript: - '76a9149ea00e6c2ef24026719421e4790e1a694c94381b88ac', + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', }, ], outputs: [ { value: 0, outputScript: - '6a045357500001010101209e0a9d4720782cf661beaea6c5513f1972e0f3b1541ba4c83f4c87ef65f843dc0453454c4c0631323831323301002039c6db26912f34352d50fdfd8d75d1c16cb8a669f3ae05000a6c8c74d14839a50101063132383132330437383035', + '6a0461757468140644ad85a538657c033e36ce5a3c8cf26076591f', }, { - value: 2656, + value: 550, outputScript: - '76a91493472d56ba91581ed473225a765dd14a2db5d9d888ac', - spentBy: { - txid: '47f7a2189eb65e9a2288f81640351cc80ada49288b09973bcaa7aef1e423faa8', - outIdx: 1, - }, + '76a914b20298c1b5d6a82a61f6c8cd708fa87a1ce1a97a88ac', + }, + { + value: 2314, + outputScript: + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', }, ], lockTime: 0, - timeFirstSeen: 1712535539, - size: 439, + timeFirstSeen: 1723372560, + size: 255, isCoinbase: false, tokenEntries: [], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 839523, - hash: '00000000000000000c61b358a9681170b9387790370bf3ca18a402bc50264fc0', - timestamp: 1712536759, + height: 857308, + hash: '000000000000000020801fb91e3685a03a8d8f967cd048f58059bda0800a8402', + timestamp: 1723373699, + }, + parsed: { + xecTxType: 'Sent', + satoshisSent: 550, + stackArray: [ + '61757468', + '0644ad85a538657c033e36ce5a3c8cf26076591f', + ], + recipients: ['ecash:qzeq9xxpkht2s2np7myv6uy04papecdf0g0zly33v5'], }, }, + sendingHash: '14582d09f61c6580b8a2b6c8af8d6a13c9128b6f', parsed: { - satoshisSent: 0, - stackArray: [ - '53575000', - '01', - '01', - '9e0a9d4720782cf661beaea6c5513f1972e0f3b1541ba4c83f4c87ef65f843dc', - '53454c4c', - '313238313233', - '00', - '39c6db26912f34352d50fdfd8d75d1c16cb8a669f3ae05000a6c8c74d14839a5', - '01', - '313238313233', - '37383035', - ], - xecTxType: 'Received', - recipients: ['ecash:qzf5wt2kh2g4s8k5wv395aja699zmdwemq05vg6h92'], + appActions: [{ isValid: true, lokadId: '61757468', app: 'Auth' }], + parsedTokenEntries: [], + recipients: ['ecash:qzeq9xxpkht2s2np7myv6uy04papecdf0g0zly33v5'], + satoshisSent: 550, + stackArray: ['61757468', '0644ad85a538657c033e36ce5a3c8cf26076591f'], + xecTxType: 'Sent', }, }; -export const PayButtonNoDataYesNonce = { +export const MsgFromEcashChat = { tx: { - txid: 'f2ca747f0780c6cda32a43418b4dd55112b709577f64436d80ab1a38e4f2787a', + txid: 'a3b3e23eb564920c10b1b6278a1e00dcec0c8b1593fc0d7f2e514cf20416255c', version: 2, inputs: [ { prevOut: { - txid: '00bfb4625325fe6e6a3ce34eb3ed7214167644e2eca892db207a44ea3262effc', - outIdx: 2, + txid: '5eff401088014f551d5fce6340d9fa09ff3082b58cf5a3d8e20c5c14a0b4200e', + outIdx: 0, }, inputScript: - '411b57cfa0bcc8e1f1c02f0dfed248688bf1e337e75d9c2775324e55b5d6d2085260303c3f77437d7bc0f1533ea816e7c8e4b77175ff3c9e61ce2e21b5e1dc95014121027a70b0f8b59cbb83a64cacbf4fca79e5c9a4f655f325d0936ed4eebced3cb8aa', - value: 7146, - sequenceNo: 4294967294, + '483045022100b7af7b05bb2fd4c743724175ddb4ed00030954f35adabe5e4dd77c1cb3125a7e02204186b77fcb0ce296a2ece2a0aa942933401bc269ea19f85434cdffe21bfea85d412103def4b1f77431c9825632ac5da7433b6eaa5281a90aabd9b597af4f16f6cccf51', + value: 3000, + sequenceNo: 4294967295, outputScript: - '76a91403c63d3a52cde136da8858e9d0ffaa810cb6639288ac', + '76a9140536f99c447acb2ab26b91db741975b6e0bd981788ac', }, ], outputs: [ { value: 0, - outputScript: '6a0450415900000008d980190d13019567', + outputScript: + '6a04636861741a68656c6c6f2066726f6d206543617368204368617420f09f918d', }, { - value: 1800, + value: 1000, outputScript: - '76a914f66d2760b20dc7a47d9cf1a2b2f49749bf7093f688ac', + '76a9140b7d35fda03544a08e65464d54cfae4257eb6db788ac', }, { - value: 3876, + value: 1461, outputScript: - '76a91401bfce4ff373b108bd65b4da08de621ade85adb588ac', - spentBy: { - txid: '566a7c12364e3f362fbc738bf209527d3074ce0a2d19b797d3ca34a3482e3386', - outIdx: 0, - }, + '76a9140536f99c447acb2ab26b91db741975b6e0bd981788ac', }, ], lockTime: 0, - timeFirstSeen: 0, - size: 245, + timeFirstSeen: 1711788850, + size: 268, isCoinbase: false, tokenEntries: [], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 828922, - hash: '0000000000000000018b4f795d767bce0438dedf67d2904e35da7d746065af1a', - timestamp: 1706323334, - }, }, parsed: { - satoshisSent: 1800, - stackArray: ['50415900', '00', '00', 'd980190d13019567'], + satoshisSent: 1000, + xecTxType: 'Received', + stackArray: [ + '63686174', + '68656c6c6f2066726f6d206543617368204368617420f09f918d', + ], + appActions: [ + { + action: { + msg: 'hello from eCash Chat 👍', + }, + isValid: true, + lokadId: '63686174', + app: 'eCashChat', + }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qqznd7vug3avk24jdwgakaqewkmwp0vczu5u9man9y'], + replyAddress: 'ecash:qqznd7vug3avk24jdwgakaqewkmwp0vczu5u9man9y', + }, +}; +export const offSpecEcashChat = { + tx: { + ...MsgFromEcashChat.tx, + outputs: [ + { + ...MsgFromEcashChat.tx.outputs[0], + outputScript: '6a0463686174', + }, + ...MsgFromEcashChat.tx.outputs.slice(1), + ], + }, + parsed: { + appActions: [{ app: 'eCashChat', isValid: false, lokadId: '63686174' }], + parsedTokenEntries: [], + recipients: ['ecash:qqznd7vug3avk24jdwgakaqewkmwp0vczu5u9man9y'], + replyAddress: 'ecash:qqznd7vug3avk24jdwgakaqewkmwp0vczu5u9man9y', + satoshisSent: 1000, + stackArray: ['63686174'], xecTxType: 'Received', - recipients: ['ecash:qqqmlnj07demzz9avk6d5zx7vgddapddk5k05jys53'], }, }; -export const PayButtonYesDataYesNonce = { +export const SlpV1Mint = { tx: { - txid: '952dd66d7145330d8d3b2f09abbee33344e8aa65b7483cfaa9d278ec55379e29', + txid: '4b5b2a0f8bcacf6bccc7ef49e7f82a894c9c599589450eaeaf423e0f5926c38e', version: 2, inputs: [ { prevOut: { - txid: '37a740f89ab6c212f211150f35fb1e12cd80f287b825126eed262999ea4264b8', + txid: 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + outIdx: 2, + }, + inputScript: + '473044022038242777df76cf81fea627fad7c8a4f67ddb2dd68defcdb8d45dbc7e0f90c62102206f5c9a5b79f10cb6ac93d46a084666b810d12871c02182f9097b1ac72643dab6412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '0', + isMintBaton: true, + entryIdx: 0, + }, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, + { + prevOut: { + txid: '89b922392753498ea1c6f8f29c9c9c2d7768fcaa36c34b931dbdcedf094cd283', outIdx: 0, }, inputScript: - '41fc1401150778a0d47d5279ccdaa13298cfa43e25d8d37d37570291207a92098beefa8fb25b8fb9cb2c4d7b5f98b7ff377c54932e0e67f4db2fc127ed86e01b1a4121024b60abfca9302b9bf5731faca03fd4f0b06391621a4cd1d57fffd6f1179bb9ba', - value: 3403110, - sequenceNo: 4294967294, + '47304402206d2c4bada7e705e12f7e8e21b2bfb7a6cf0b02dcb7ffc6b21f1a866dc0e7c7a10220667c1d970506cdae180a78888cf10cf9ada6800b4db22f06a8f4ae5c40aeea16412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 3300, + sequenceNo: 4294967295, outputScript: - '76a914e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc88ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04504159000008f09f9882f09f918d0869860643e4dc4c88', + '6a04534c50000101044d494e5420aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb10102080000000000000064', }, { - value: 3392102, + value: 546, outputScript: - '76a914e573dd89a61f8daeb56bf5b5fb5d7cd86e31ab2e88ac', - spentBy: { - txid: '8b2a86aabae90c0f9e8a111e220c85b52fc54b15c6d46cbbbca89020318714a4', - outIdx: 0, + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + token: { + tokenId: + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '100', + isMintBaton: false, + entryIdx: 0, }, }, { - value: 9490, + value: 546, outputScript: - '76a914697ae72b062557fa69f9d4d09182529da368ab6988ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + token: { + tokenId: + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '0', + isMintBaton: true, + entryIdx: 0, + }, spentBy: { - txid: '1b3165e7edef19369880f032d8f4d19cc41e9ebf2bfb657518ae99075aa2b471', + txid: 'dd9018d0037fee4094c2445b23ed9eef65d456db3f2b9c053ad39ee6505fca44', outIdx: 0, }, }, + { + value: 2280, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, ], lockTime: 0, - timeFirstSeen: 0, - size: 253, + timeFirstSeen: 1711861819, + size: 472, isCoinbase: false, - tokenEntries: [], + tokenEntries: [ + { + tokenId: + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + txType: 'MINT', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + }, + ], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', + tokenStatus: 'TOKEN_STATUS_NORMAL', block: { - height: 828920, - hash: '00000000000000000d6a683b11a6bdaab4b79b15f100daa9361d02207667de1d', - timestamp: 1706323234, + height: 838323, + hash: '000000000000000011466b30b743ea02424347838273e890d6a9f1afbc16f66e', + timestamp: 1711868662, }, }, parsed: { - satoshisSent: 3401592, - stackArray: ['50415900', '00', 'f09f9882f09f918d', '69860643e4dc4c88'], - xecTxType: 'Sent', - recipients: [ - 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', - 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', - ], - }, -}; - -// No data no payment id -const PayButtonEmptyTx = JSON.parse( - JSON.stringify(PayButtonYesDataYesNonce.tx), -); -// Create a tx with 00 in paymentId and nonce spaces -PayButtonEmptyTx.outputs[0].outputScript = '6a0450415900000000'; -export const PayButtonEmpty = { - tx: PayButtonEmptyTx, - parsed: { - satoshisSent: 3401592, - stackArray: ['50415900', '00', '00', '00'], - xecTxType: 'Sent', - recipients: [ - 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', - 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', - ], - }, -}; -// data and no payment id -const PayButtonYesDataNoNonceTx = JSON.parse( - JSON.stringify(PayButtonYesDataYesNonce.tx), -); -// Create a tx with 00 in paymentId and nonce spaces -PayButtonYesDataNoNonceTx.outputs[0].outputScript = - '6a0450415900000e6f6e6c792064617461206865726500'; -export const PayButtonYesDataNoNonce = { - tx: PayButtonYesDataNoNonceTx, - parsed: { - satoshisSent: 3401592, - stackArray: ['50415900', '00', '6f6e6c7920646174612068657265', '00'], - xecTxType: 'Sent', - recipients: [ - 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', - 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', - ], - }, -}; - -// Off spec paybutton tx -const PayButtonOffSpecTx = JSON.parse( - JSON.stringify(PayButtonYesDataYesNonce.tx), -); -// Create a tx with 3 pushes instead of expected 4 -PayButtonOffSpecTx.outputs[0].outputScript = '6a04504159000008f09f9882f09f918d'; -export const PayButtonOffSpec = { - tx: PayButtonOffSpecTx, - parsed: { - satoshisSent: 3401592, - stackArray: ['50415900', '00', 'f09f9882f09f918d'], - xecTxType: 'Sent', - recipients: [ - 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', - 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + satoshisSent: 3372, + stackArray: [ + '534c5000', + '01', + '4d494e54', + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + '02', + '0000000000000064', ], - }, -}; - -// Unsupported version paybutton tx -const PayButtonBadVersionTx = JSON.parse( - JSON.stringify(PayButtonYesDataYesNonce.tx), -); -// Force a version 1 tx -PayButtonBadVersionTx.outputs[0].outputScript = - '6a0450415900010108f09f9882f09f918d0869860643e4dc4c88'; -export const PayButtonBadVersion = { - tx: PayButtonBadVersionTx, - parsed: { - satoshisSent: 3401592, - stackArray: ['50415900', '01', 'f09f9882f09f918d', '69860643e4dc4c88'], xecTxType: 'Sent', - recipients: [ - 'ecash:qrjh8hvf5c0cmt44d06mt76a0nvxuvdt9cmj39zxwm', - 'ecash:qp5h4eetqcj407nfl82dpyvz22w6x69tdyxpprn8zg', + recipients: [], + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'MINT', + tokenId: + 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + tokenSatoshis: '100', + }, ], }, }; -export const MsgFromEcashChat = { +export const agoraAdSetupTxSlpNft = { tx: { - txid: 'a3b3e23eb564920c10b1b6278a1e00dcec0c8b1593fc0d7f2e514cf20416255c', + txid: '972fd1322542740835a3f7e6d0917e5ac1ab6f20c5bfb40edbfb4ca73a144194', version: 2, inputs: [ { prevOut: { - txid: '5eff401088014f551d5fce6340d9fa09ff3082b58cf5a3d8e20c5c14a0b4200e', - outIdx: 0, + txid: 'c886d9d73b0c2592fb2df95cf0bb832c8077ff8adec132ee3cff5ba576f4ed1e', + outIdx: 1, }, inputScript: - '483045022100b7af7b05bb2fd4c743724175ddb4ed00030954f35adabe5e4dd77c1cb3125a7e02204186b77fcb0ce296a2ece2a0aa942933401bc269ea19f85434cdffe21bfea85d412103def4b1f77431c9825632ac5da7433b6eaa5281a90aabd9b597af4f16f6cccf51', - value: 3000, + '419d3ac0b32abebc181c55e5a45c25d5050f73ba1269348829f4d5677131e3c627f73a552bf003de5d86423ce3f47fd4fd116eba837be72a3cef6f002158b0482a412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 546, sequenceNo: 4294967295, + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, outputScript: - '76a9140536f99c447acb2ab26b91db741975b6e0bd981788ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, + { + prevOut: { + txid: '03672250bda1410ffa9b1c2cf3dc8c456bcb7a54e8dff0a7686bcce6ba82cf1b', + outIdx: 2, + }, + inputScript: + '41f444904158cb70106321dc09161d7bf3dde584e541c73d21f46a19c176c10e1c3ea79252e52878a0f11f5c6b896d8adc5c75d1c6039e750c31ab07114d2f3bca412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 1748, + sequenceNo: 4294967295, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04636861741a68656c6c6f2066726f6d206543617368204368617420f09f918d', + '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000001', }, { - value: 1000, - outputScript: - '76a9140b7d35fda03544a08e65464d54cfae4257eb6db788ac', + value: 860, + outputScript: 'a91463b7313157fb1d054919364c837d8af927fa569987', + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, + spentBy: { + txid: 'c7fe7ac1f29c34e0795786b609622f6439cfde52246f31cba89aa0b28c8542ee', + outIdx: 0, + }, }, { - value: 1461, + value: 1012, outputScript: - '76a9140536f99c447acb2ab26b91db741975b6e0bd981788ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], lockTime: 0, - timeFirstSeen: 1711788850, - size: 268, + timeFirstSeen: 1729632267, + size: 422, isCoinbase: false, - tokenEntries: [], + tokenEntries: [ + { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + groupTokenId: + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + }, + ], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', + tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 867731, + hash: '000000000000000023e84eda63a1c6cce9c8e1d8b6484ee3dba0bf13b38d9116', + timestamp: 1729632495, + }, }, parsed: { - satoshisSent: 1000, - xecTxType: 'Received', + satoshisSent: 860, stackArray: [ - '63686174', - '68656c6c6f2066726f6d206543617368204368617420f09f918d', + '534c5000', + '41', + '53454e44', + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + '0000000000000001', ], - recipients: ['ecash:qqznd7vug3avk24jdwgakaqewkmwp0vczu5u9man9y'], - }, -}; -export const CashtabMsg = { - tx: { - txid: '1ce6c307b4083fcfc065287a00f0a582cf88bf33de34845db4c49387d4532b8a', - version: 2, - inputs: [ + xecTxType: 'Sent', + recipients: ['ecash:pp3mwvf32la36p2frymyeqma3tuj07jknyhljj09qd'], + appActions: [], + parsedTokenEntries: [ { - prevOut: { - txid: '01d4b064a4e17f77e5712cb13b488e65d39b33b54475b78debee1fe1d9d9acb1', - outIdx: 1, - }, - inputScript: - '483045022100eccfc2e23d49fb7e72a35123c807f4feef2f379313673295f36611d725e877b002207b1df4c142c590a54d371fe2f04c05769ecf778e0d28fc50a671e5c5d8b277854121028c1fc90b3fa6e5be985032b061b5ca6db41a6878a9c8b442747b820ca74010db', - value: 3001592, - sequenceNo: 4294967295, - outputScript: - '76a914e6309418b6e60b8119928ec45b8ba87de8e735f788ac', + renderedTokenType: 'NFT', + renderedTxType: 'Agora Offer', + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenSatoshis: '1', }, ], - outputs: [ - { - value: 0, + }, + // 1 Nile Kinnick + cache: [ + [ + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + { + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + timeFirstSeen: 1713828197, + genesisInfo: { + tokenTicker: 'NK', + tokenName: 'Nile Kinnick', + url: 'cashtab.com', + decimals: 0, + hash: 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + }, + block: { + height: 841418, + hash: '000000000000000015c94349a2ec777da460e8d8d48a220bbf9d6a6e6e9df66f', + timestamp: 1713829166, + }, + genesisSupply: '1', + genesisOutputScripts: [ + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + ], + genesisMintBatons: 0, + }, + ], + ], +}; + +// 8880046b7b34da75f405abf8e76237082ed83f6a6293b378f83629320bf57097 +// buy from 76458db0ed96fe9863fc1ccec9fa2cfab884b0f6 +// sale for 95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d +export const agoraOneshotBuyTx = { + tx: { + txid: '8880046b7b34da75f405abf8e76237082ed83f6a6293b378f83629320bf57097', + version: 2, + inputs: [ + { + prevOut: { + txid: 'c7fe7ac1f29c34e0795786b609622f6439cfde52246f31cba89aa0b28c8542ee', + outIdx: 1, + }, + inputScript: + '2102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd879540c4da30dce1304b58ad7e2b8f87729d2b7c5f7c2390e8bbc33bebcc7c80503c992801df01dad963adb737892e0d3499875b99477f65786c45e9146610a219fe104c5aee42858cb2a09aa8cb316f2452decf39642f6209b6865779e0349cf2c17afec70100000001ac2202000000000000ffffffffc996989ea840ccd9e2f0324dc0accbe26a32c3c8bd5d710ce18f68acaafdb3d300000000c10000004422020000000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac7a3d160c000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac514cb0634c6b0000000000000000406a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df30800000000000000000800000000000000013ea74b04000000001976a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac7c7eaa7801327f7701207f7588520144807c7ea86f7bbb7501c17e7c672103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba668abac', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, + outputScript: 'a914dec4855b83573e56312d9f3852697a48c09ee6b087', + }, + { + prevOut: { + txid: 'd8a564b6aa82861ea16864ef83d0ec81ecf8cb13c0a59c2737a444c7b880368d', + outIdx: 3, + }, + inputScript: + '414964793d1de39477192d9ee1491c49973303b18b594b249cfb0b9b752826f0ccc9da5ebf1dde9de63f5e5825b3e7257f48e1310920e30e28e83beada1f21be58412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 19360, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: '4fdcf99a029298ca1e3a692c4485711d22e7eb6aeb76d58354666e0a87260a4a', + outIdx: 1, + }, + inputScript: + '41c60f1f0f70dd45780f5b5a48e7e8e823ab04ae5f2b652c68d36856d7999e65423c88f4315bde6eeebe1c263e27b5275453a52c33962eddd704ec63330482cbde412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 11007, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: '9191385318562f9b9491cb51dd336054ff48086effdb603ce4d070ec27b0a310', + outIdx: 1, + }, + inputScript: + '418a65da44dc054c90c718cafe5a8eb1a58a40f1c2864a356152eadb6ad439f66f7e457f09821fb53b07bd50d68baa64abed6134f98d18c2da4050496c54341a4c412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 5235, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: 'e85c851664f633ac3888908be544d379b6a300ecd7e3ba3b7d8895ff4bcd2907', + outIdx: 1, + }, + inputScript: + '41db37e18dda29041f7f931bb895777ec8bea1f6341dc48a144a2deac2545519892c19c050bfe8eb32143a5860ef4343079cb0b6705f2b72e8555f3b96badd3e82412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 4201, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: '2bec8ef2b93a4cc859d2b5eef36516d5e559ed6c8ba14437ebd910d7110e8e7b', + outIdx: 2, + }, + inputScript: + '41f5ad3937e27b09550dfac33838bb0acfe61bf69378c3fbd6fb145ce48cf0cd9fc7e2b4abfcb17616dedecd33e84a860c5f2ceea50ea0e59a59e7fa4e87b478ce412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 19901, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: '528fc61b8fe7131dcba81c99a4604c409aafe6faaf4286e21da07cae92bdf586', + outIdx: 2, + }, + inputScript: + '41346e924f1a559129de3bb6f8bfb9358aae0401ab6dcc49c9e974bed7b94b246f001ec19ed7c682d945426882abce9f5bebdd984845b2c127c0f2549fcee5aec9412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 12964, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + { + prevOut: { + txid: '5963aebb41910aee8014cbbf2e2fb487dcbecb8b4a66b26e07f5b6542355bbf7', + outIdx: 1, + }, + inputScript: + '41f5295566cdf6a64102474a4cf1a90c0be1f734a01a7c553d28d79543de93991633b67473c7cd859f14f4682942ea08b8f399abc3d9aba4d3017931ae61f677d4412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 274781657, + sequenceNo: 4294967295, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + ], + outputs: [ + { + value: 0, + outputScript: + '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000000080000000000000001', + }, + { + value: 72066878, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, + { + value: 546, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, + }, + { + value: 202784122, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + ], + lockTime: 0, + timeFirstSeen: 1729713477, + size: 1654, + isCoinbase: false, + tokenEntries: [ + { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + groupTokenId: + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + }, + ], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NORMAL', + }, + sendingHash: '76458db0ed96fe9863fc1ccec9fa2cfab884b0f6', + parsed: { + recipients: ['ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035'], + satoshisSent: 72066878, + stackArray: [ + '534c5000', + '41', + '53454e44', + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + '0000000000000000', + '0000000000000001', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'NFT', + renderedTxType: 'Agora Buy', + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenSatoshis: '1', + }, + ], + }, + cache: agoraAdSetupTxSlpNft.cache, +}; +export const agoraOneshotSaleTx = { + tx: agoraOneshotBuyTx.tx, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', + parsed: { + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'NFT', + renderedTxType: 'Agora Sale', + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenSatoshis: '1', + }, + ], + recipients: ['ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj'], + replyAddress: 'ecash:pr0vfp2msdtnu4339k0ns5nf0fyvp8hxkqxcuyfhrp', + satoshisSent: 72066878, + stackArray: [ + '534c5000', + '41', + '53454e44', + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + '0000000000000000', + '0000000000000001', + ], + xecTxType: 'Received', + }, + cache: agoraOneshotBuyTx.cache, +}; + +// e9d594e054bf9a7cead11cdc31953f0e45782c97c6298513f41b70eb408aa1a8 +export const agoraPartialCancelTx = { + tx: { + txid: 'e9d594e054bf9a7cead11cdc31953f0e45782c97c6298513f41b70eb408aa1a8', + version: 2, + inputs: [ + { + prevOut: { + txid: '58ec58688cef1d0abe2ee30c15f84af51833e61e998841fac3ecbcadafc31233', + outIdx: 2, + }, + inputScript: + '41fd18138ab17386e9599e54d9d5f1994d1c4add3af860b1ece44b71d04bc7e7cd799e1234e2959236cd38558713d7fdb797a894c527906b0235a38519ad63fbea4121024f624d04900c2e3b7ea6014cb257f525b6d229db274bceeadbb1f06c07776e82', + value: 975251, + sequenceNo: 4294967295, + outputScript: + '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', + }, + // Note that the p2sh is not necessarily input 0 for an agora partial cancel tx + { + prevOut: { + txid: '0c580a7dbfb7f160f0e4623faa24eb0475b2220704c8c46f279a479a477433f8', + outIdx: 1, + }, + inputScript: + '0441475230075041525449414c4113bb98283dc7a2f69957940bb3a45f4ec6050b61bcc1b1134d786727e379c8793107bf0d0b0e051665ab3eed2cca34901646cf564a1ab52cb32668da229eef0b41004d5f014c766a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8080000000000000000030276a4000000000000e815000000000000a24a2600000000004b4a343a024f624d04900c2e3b7ea6014cb257f525b6d229db274bceeadbb1f06c07776e8208948eff7f00000000ab7b63817b6ea2697603a24a26a269760376a4009700887d94527901377f75789263587e780376a400965580bc030000007e7e68587e52790376a400965580bc030000007e7e825980bc7c7e0200007e7b02e7159302e8159656807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702dd007f5c7f7701207f547f75044b4a343a886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '855738679296', + isMintBaton: false, + entryIdx: 0, + }, + outputScript: 'a914cb61d733f8e99b1b40d40a53a59aca8a08368a6f87', + }, + ], + outputs: [ + { + value: 0, + outputScript: + '6a04534c500001010453454e442020a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f808000000c73e000000', + }, + { + value: 546, + outputScript: + '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', + token: { + tokenId: + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '855738679296', + isMintBaton: false, + entryIdx: 0, + }, + }, + { + value: 973723, + outputScript: + '76a9147847fe7070bec8567b3e810f543f2f80cc3e03be88ac', + }, + ], + lockTime: 0, + timeFirstSeen: 1729789538, + size: 760, + isCoinbase: false, + tokenEntries: [ + { + tokenId: + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + }, + ], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 867971, + hash: '000000000000000013f3d459ae121dc1494e7e9fe57c2e60cf393184d7ab6dc9', + timestamp: 1729793460, + }, + }, + parsed: { + recipients: [], + satoshisSent: 974269, + stackArray: [ + '534c5000', + '01', + '53454e44', + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + '000000c73e000000', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'Agora Cancel', + tokenId: + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + tokenSatoshis: '855738679296', + }, + ], + }, + cache: [ + [ + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + { + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + genesisInfo: { + tokenTicker: 'VSP', + tokenName: 'Vespene Gas', + url: 'https://simple.wikipedia.org/wiki/StarCraft#Gameplay', + decimals: 9, + hash: '', + }, + timeFirstSeen: 0, + genesisSupply: '3000000000.000000000', + genesisOutputScripts: [ + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + ], + genesisMintBatons: 0, + block: { + height: 763087, + hash: '0000000000000000015abcebc15e74036598855a9fdd976868ad99bb23b87a89', + timestamp: 1666631359, + }, + }, + ], + ], +}; + +// 3ada11ca38e5da8bfda9b045ab7412cecff5b788aad8e49673183010e725099e +export const partialBuyBull = { + tx: { + txid: '3ada11ca38e5da8bfda9b045ab7412cecff5b788aad8e49673183010e725099e', + version: 2, + inputs: [ + { + prevOut: { + txid: '20469a4316506e0fea99ad0673d6663f2f546c0aad84b741e08c4d0f9248b18c', + outIdx: 1, + }, + inputScript: + '0441475230075041525449414c21023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1404799ed59b763768b8e7385a35c0a357e624e1725154d4c3240f38edc021527b267881f2078be11f89221f6c8036c156274742dae00ce8a88bb6ee527bc18dc744422020000000000001976a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac4d420100000000001976a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac4d32018cb148920f4d8ce041b784ad0a6c542f3f66d67306ad99ea0f6e5016439a462001000000d97b63817b6ea26976046de4ff17a26976033b62109700887d94527901377f75789263587e78033b6210965880bc007e7e68587e5279033b6210965880bc007e7e825980bc7c7e01007e7b03288f009303298f009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d9007f5c7f7701207f547f7504f3282c4e886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c880441475230872202000000000000ffffffffca3033eea929796cc020b87c909e38d37943502aa69486f2d97d56daa454e28df3282c4ec1000000046de4ff17514d5b014c766a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f89608000000000000000000013b62100000000000298f0000000000006de4ff1700000000f3282c4e03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba608f06cff7f00000000ab7b63817b6ea26976046de4ff17a26976033b62109700887d94527901377f75789263587e78033b6210965880bc007e7e68587e5279033b6210965880bc007e7e825980bc7c7e01007e7b03288f009303298f009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d9007f5c7f7701207f547f7504f3282c4e886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '2000', + isMintBaton: false, + entryIdx: 0, + }, + plugins: { + agora: { + groups: [ + '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '5401d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '4601d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + ], + data: [ + '5041525449414c', + '00', + '01', + '3b62100000000000', + '298f000000000000', + '6de4ff1700000000', + 'f3282c4e', + ], + }, + }, + outputScript: 'a914563178ea073228709397a2c98baf10677e683e6687', + }, + { + prevOut: { + txid: 'bfce47f2403031f5465982b821e8e14c78deff2dd5986ca0c21cebb5ed946b4d', + outIdx: 2, + }, + inputScript: + '41866f21d34e5b061cf7cb9ce4a6ce4df037628b72765db893675eae909ddad9d7ea7593d1a510fee1d80887699410b4330e9214efd5668dd51644d7ffce498ac94121039f0061726e4fed07061f705d34707b7f9c2f175bfa2ca7fe7df0a81e9efe1e8b', + value: 2898252, + sequenceNo: 4294967295, outputScript: - '6a04007461624cbe4d6572636920706f7572206c65207072697820657420626f6e6e6520636f6e74696e756174696f6e2064616e7320766f732070726f6a6574732064652064c3a976656c6f70706575722e2e2e204a27616920c3a974c3a92063656e737572c3a92073c3bb722074c3a96cc3a96772616d6d65206a7573717527617520313520417672696c20323032342e2052c3a97061726572206c6520627567206f6273657276c3a920737572206c6120706167652065546f6b656e204661756365743f', + '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', }, + ], + outputs: [ { - value: 550, + value: 0, outputScript: - '76a9143c28745097b1e32b343c50a8d4a7697fe7ad8aff88ac', + '6a04534c500001010453454e442001d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896080000000000000000080000000000000659080000000000000177', }, { - value: 3000609, + value: 2812672, outputScript: - '76a914e6309418b6e60b8119928ec45b8ba87de8e735f788ac', + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + spentBy: { + txid: '5d934ade992707fe126bcd393ad4358b2c10118b635df4b97e3e3f30ca7cc781', + outIdx: 1, + }, + }, + { + value: 546, + outputScript: 'a91451d609999740085f16cfbee2f9791d6ae6ac678d87', + plugins: { + agora: { + groups: [ + '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '5401d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '4601d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + ], + data: [ + '5041525449414c', + '00', + '01', + '3b62100000000000', + '298f000000000000', + '6de4ff1700000000', + 'f3282c4e', + ], + }, + }, + token: { + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '1625', + isMintBaton: false, + entryIdx: 0, + }, + }, + { + value: 546, + outputScript: + '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', + token: { + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + amount: '375', + isMintBaton: false, + entryIdx: 0, + }, + spentBy: { + txid: 'f0e450b41d1c15b32478efb668bc562fa341a40fa799db7747228350295f84d4', + outIdx: 0, + }, + }, + { + value: 82509, + outputScript: + '76a9142aba37d6365d3e570cadf3ed65e58ae4ad751a3088ac', + spentBy: { + txid: '3a7a8971392e74fd542498c055509ace4f4853b981d87d73ba045f77100dad1e', + outIdx: 1, + }, + }, + ], + lockTime: 1311516915, + timeFirstSeen: 1730860384, + size: 1256, + isCoinbase: false, + tokenEntries: [ + { + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + }, + ], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 869782, + hash: '0000000000000000178954cd24752cd8fb8aa980c36012a16cec251d8c2f68d6', + timestamp: 1730861016, + }, + }, + sendingHash: '2aba37d6365d3e570cadf3ed65e58ae4ad751a30', + parsed: { + recipients: [ + 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', + 'ecash:ppgavzvejaqqshcke7lw97ter44wdtr835rs9eedxc', + ], + satoshisSent: 2813218, + stackArray: [ + '534c5000', + '01', + '53454e44', + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '0000000000000000', + '0000000000000659', + '0000000000000177', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'Agora Buy', + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenSatoshis: '375', + }, + ], + }, + cache: [ + [ + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + { + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + genesisInfo: { + tokenTicker: 'BULL', + tokenName: 'Bull', + url: 'https://cashtab.com/', + decimals: 0, + hash: '', + }, + timeFirstSeen: 0, + genesisSupply: '21000000', + genesisOutputScripts: [ + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + ], + genesisMintBatons: 0, + block: { + height: 835482, + hash: '0000000000000000133bf16cb7fdab5c6ff64a874632eb2fe80265e34a6ad99f', + timestamp: 1710174132, + }, + }, + ], + ], +}; + +export const partialSellBull = { + tx: partialBuyBull.tx, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88', + parsed: { + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'Agora Sale', + tokenId: + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + tokenSatoshis: '375', }, ], - lockTime: 0, - timeFirstSeen: 1712616513, - size: 433, - isCoinbase: false, - tokenEntries: [], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 839618, - hash: '00000000000000000e63e39951cc745db046aa7f57f811b68846ade8ad100293', - timestamp: 1712616969, - }, + recipients: [ + 'ecash:ppgavzvejaqqshcke7lw97ter44wdtr835rs9eedxc', + 'ecash:qq4t5d7kxewnu4cv4he76e093tj26ag6xql82hcgru', + ], + replyAddress: 'ecash:pptrz782quezsuynj73vnza0zpnhu6p7vcj7g5qlfr', + satoshisSent: 2812672, + stackArray: [ + '534c5000', + '01', + '53454e44', + '01d63c4f4cb496829a6743f7b1805d086ea3877a1dd34b3f92ffba2c9c99f896', + '0000000000000000', + '0000000000000659', + '0000000000000177', + ], + xecTxType: 'Received', }, - parsed: {}, + cache: partialBuyBull.cache, }; -export const SlpV1Mint = { +// 1e68af94c0117223511e3d7f7b6f0f6c2ffa07972844ff6d04f7f37d36ad5b50 +export const agoraPartialCancelTwo = { tx: { - txid: '4b5b2a0f8bcacf6bccc7ef49e7f82a894c9c599589450eaeaf423e0f5926c38e', + txid: '1e68af94c0117223511e3d7f7b6f0f6c2ffa07972844ff6d04f7f37d36ad5b50', version: 2, inputs: [ { prevOut: { - txid: 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', - outIdx: 2, + txid: 'ea28b2d3db0d4972eb56f2f20473fe821a6d46f328ecc5e97c4c3e353ff22a52', + outIdx: 3, }, inputScript: - '473044022038242777df76cf81fea627fad7c8a4f67ddb2dd68defcdb8d45dbc7e0f90c62102206f5c9a5b79f10cb6ac93d46a084666b810d12871c02182f9097b1ac72643dab6412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, + '415ece5326f001de92ce37d34b6ada073c3f60b52231b8291e1d4900c4813b93379dfc3e11ed417c58fce9fc1ead27b5754d4d2c8ff3d6949e694a9529afea0f4c412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 661543961, sequenceNo: 4294967295, - token: { - tokenId: - 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_FUNGIBLE', - number: 1, - }, - amount: '0', - isMintBaton: true, - entryIdx: 0, - }, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, { prevOut: { - txid: '89b922392753498ea1c6f8f29c9c9c2d7768fcaa36c34b931dbdcedf094cd283', - outIdx: 0, + txid: '44aa224b6eb5058717d1403d7376ef48e0eae2e4065303f0f9452782aad9f541', + outIdx: 2, }, inputScript: - '47304402206d2c4bada7e705e12f7e8e21b2bfb7a6cf0b02dcb7ffc6b21f1a866dc0e7c7a10220667c1d970506cdae180a78888cf10cf9ada6800b4db22f06a8f4ae5c40aeea16412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 3300, - sequenceNo: 4294967295, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - ], - outputs: [ - { - value: 0, - outputScript: - '6a04534c50000101044d494e5420aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb10102080000000000000064', - }, - { + '0441475230075041525449414c4195484212249b53096fa43b1dc39559f9671cd305b4715c063c486b2fc30eec194685f027c560742da8746b61aacfb05dd039d8e519fa7ca065d7fe3188fa63df41004d5a014c766a04534c500001010453454e4420b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc0800000000000000000001f588410000000000f980000000000000f588410000000000bbbcb84f03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba608bbd1b77e00000000ab7b63817b6ea2697603f58841a2697603f588419700887d94527901377f75789263587e7803f58841965880bc007e7e68587e527903f58841965880bc007e7e825980bc7c7e01007e7b03f880009303f980009657807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702d8007f5c7f7701207f547f7504bbbcb84f886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', value: 546, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + sequenceNo: 4294967295, token: { tokenId: - 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_FUNGIBLE', number: 1, }, - amount: '100', + amount: '495', isMintBaton: false, entryIdx: 0, }, + outputScript: 'a914b069fa99f084a259a6a31cc8cf33edb8a853fbb587', + }, + ], + outputs: [ + { + value: 0, + outputScript: + '6a04534c500001010453454e4420b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc0800000000000001ef', }, { value: 546, @@ -11322,41 +12411,37 @@ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_FUNGIBLE', number: 1, }, - amount: '0', - isMintBaton: true, + amount: '495', + isMintBaton: false, entryIdx: 0, }, - spentBy: { - txid: 'dd9018d0037fee4094c2445b23ed9eef65d456db3f2b9c053ad39ee6505fca44', - outIdx: 0, - }, }, { - value: 2280, + value: 661543206, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, ], lockTime: 0, - timeFirstSeen: 1711861819, - size: 472, + timeFirstSeen: 1729825975, + size: 755, isCoinbase: false, tokenEntries: [ { tokenId: - 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_FUNGIBLE', number: 1, }, - txType: 'MINT', + txType: 'SEND', isInvalid: false, burnSummary: '', failedColorings: [], @@ -11367,263 +12452,272 @@ ], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', - block: { - height: 838323, - hash: '000000000000000011466b30b743ea02424347838273e890d6a9f1afbc16f66e', - timestamp: 1711868662, - }, }, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { - satoshisSent: 3372, + recipients: ['ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035'], + satoshisSent: 0, stackArray: [ '534c5000', '01', - '4d494e54', - 'aed861a31b96934b88c0252ede135cb9700d7649f69191235087a3030e553cb1', - '02', - '0000000000000064', + '53454e44', + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + '00000000000001ef', ], - xecTxType: 'Sent', - recipients: [], - }, -}; - -export const MsgFromElectrum = { - tx: { - txid: 'd0c4c5b86016b7a021470180cb4afd1f8456fcf683a19d8b061b2225abd71be4', - version: 2, - inputs: [ + xecTxType: 'Received', + appActions: [], + parsedTokenEntries: [ { - prevOut: { - txid: '7e439e4a1dde6f4380ed1afddbd5f484db80b00f26c85b3f10f6ccb245da5800', - outIdx: 4, - }, - inputScript: - '416d2f67c38b81b6fdd13f4cb2c2d0a9194800e98b80a1054ca83b1ea3d739e70f9c4e2c8a61050b40161a0d741db9a6e71d155cf61623b9279739b50446d3ec6a4121026769c23182aaa572c16c82121caff660a7c13befd0d20c263e577ca01c4f029e', - value: 81319, - sequenceNo: 4294967294, - outputScript: - '76a914eff9a0ba847ae97697a9f97c05887aba2b41060e88ac', + renderedTokenType: 'SLP', + renderedTxType: 'Agora Cancel', + tokenId: + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', + tokenSatoshis: '495', }, ], - outputs: [ - { - value: 0, - outputScript: - '6a1774657374696e672061206d736720666f72206572726f72', - }, + replyAddress: 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', + }, + cache: [ + [ + 'b8f2a9e767a0be7b80c7e414ef2534586d4da72efddb39a4e70e501ab73375cc', { - value: 80213, - outputScript: - '76a914731fbd873b3603e8dafd62923b954d38571e10fc88ac', - spentBy: { - txid: 'b817870c8ae5ec94d639089e37763daee271f412ab478705a29b036ba0b00f3d', - outIdx: 55, + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, }, - }, - { - value: 600, - outputScript: - '76a9144e532257c01b310b3b5c1fd947c79a72addf852388ac', - spentBy: { - txid: 'dc06ab36c9a7e365f319c0e918324af9778cb29b82c07ff87e2ec80eb6e4e6fe', - outIdx: 9, + genesisInfo: { + tokenTicker: 'CTD', + tokenName: 'Cashtab Dark', + url: 'https://cashtab.com/', + decimals: 0, + hash: '', + }, + timeFirstSeen: 0, + genesisSupply: '10000', + genesisOutputScripts: [ + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + ], + genesisMintBatons: 0, + block: { + height: 726043, + hash: '00000000000000000182db32e000171006b7b7820181676b5fd8f29cc90d2b9c', + timestamp: 1644455332, }, }, ], - lockTime: 0, - timeFirstSeen: 1709353270, - size: 253, - isCoinbase: false, - tokenEntries: [], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 833968, - hash: '000000000000000020f276cf59fc4e53672500ca5b5896502d0a50500174c27c', - timestamp: 1709354653, - }, - }, - parsed: { - satoshisSent: 600, - stackArray: ['74657374696e672061206d736720666f72206572726f72'], - xecTxType: 'Received', - recipients: ['ecash:qpe3l0v88vmq86x6l43fywu4f5u9w8sslsga0tcn4t'], - }, + ], }; -export const unknownAppTx = { +// Canceling an agora oneshot NFT listing slp1 +// a57b6b00b328f0c6a916f6469dcc4e05ab202e7eca82f4cda5dbd736064910d9 +export const AgoraOneshotCancelTx = { tx: { - txid: '4cd528a95263714b8f748d58df30c44956158825924e3385b5c5c511129d1b3a', + txid: 'a57b6b00b328f0c6a916f6469dcc4e05ab202e7eca82f4cda5dbd736064910d9', version: 2, inputs: [ { prevOut: { - txid: '9ca28926f8ec125dce0b7084468bd595b27bd73991b48461ac994cacff47a21d', + txid: '9dad6def1241cea3ef1942e53ed0a34163da41fc726feb304fbd4d27482ce063', outIdx: 1, }, inputScript: - '483045022100b50fac4b810ac6b10ce35f25fcc1a6b1f87b1209e8ee5973732d983395199de102204f860238b12ba3e7adfc432e331405f751fef1aa494c2d0122b7aaa522158933412102188904278ebf33059093f596a2697cf3668b3bec9a3a0c6408a455147ab3db93', - value: 3725, + '419b8ec92ca5701691d9f5e75d525532cbec6ed9d9ed81f8f982b5af76090289d001ce2022ec82ba096c99beb00b0d9b0a92f2ef8da269a7967e6856170796beac41004cb0634c6b0000000000000000406a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df308000000000000000008000000000000000164594e05000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac7c7eaa7801327f7701207f7588520144807c7ea86f7bbb7501c17e7c672102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd879568abac', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, + outputScript: 'a91451a5d608ff31c1585d7aba3a2afcd2ae02898abd87', + }, + { + prevOut: { + txid: '9cf904c798295bfee43670162dc816e25d129ae9a0b13a41f11560cf7dbbb5b8', + outIdx: 3, + }, + inputScript: + '41ccbca2638a68145ecc38c8a96c058dff2619b8d495360e0b5866de555f1c6b621ef147df1a9e0f5bee006d1db94e1e2670915265d38f3ba801114037ed0d441d412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 1153, sequenceNo: 4294967295, outputScript: - '76a914d18b7b500f17c5db64303fec630f9dbb85aa959688ac', + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + }, + ], + outputs: [ + { + value: 0, + outputScript: + '6a04534c500001410453454e4420f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3080000000000000001', + }, + { + value: 546, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + token: { + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, + }, + amount: '1', + isMintBaton: false, + entryIdx: 0, + }, }, ], - outputs: [ - { - value: 0, - outputScript: - '6a4cd43336616533642d4d45524f4e2d57494e227d2c7b226e616d65223a2277616c61222c226d657373616765223a223635396661313133373065333136663265613336616533642d57414c412d57494e227d5d2c227465726d73223a5b7b226e616d65223a22726566657265655075624b6579222c2274797065223a226279746573222c2276616c7565223a22303231383839303432373865626633333035393039336635393661323639376366333636386233626563396133613063363430386134353531343761623364623933227d5d7d7d7d7d', - }, + lockTime: 0, + timeFirstSeen: 1729720346, + size: 535, + isCoinbase: false, + tokenEntries: [ { - value: 3308, - outputScript: - '76a914d18b7b500f17c5db64303fec630f9dbb85aa959688ac', - spentBy: { - txid: 'e5b4912fa19d93db9b6b9586ad9ab3a7f9bc3514325c71e36816e4b047a9f6b8', - outIdx: 0, + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 65, }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + groupTokenId: + 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', }, ], - lockTime: 0, - timeFirstSeen: 0, - size: 416, - isCoinbase: false, - tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 826662, - hash: '00000000000000001d45441094ec7a93f42f3beb564684aba68250b016feefb4', - timestamp: 1704961725, - }, + tokenStatus: 'TOKEN_STATUS_NORMAL', }, parsed: { - satoshisSent: 3308, + recipients: ['ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj'], + satoshisSent: 0, stackArray: [ - '3336616533642d4d45524f4e2d57494e227d2c7b226e616d65223a2277616c61222c226d657373616765223a223635396661313133373065333136663265613336616533642d57414c412d57494e227d5d2c227465726d73223a5b7b226e616d65223a22726566657265655075624b6579222c2274797065223a226279746573222c2276616c7565223a22303231383839303432373865626633333035393039336635393661323639376366333636386233626563396133613063363430386134353531343761623364623933227d5d7d7d7d7d', + '534c5000', + '41', + '53454e44', + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + '0000000000000001', ], - xecTxType: 'Sent', - recipients: [], + xecTxType: 'Received', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'NFT', + renderedTxType: 'Agora Cancel', + tokenId: + 'f09ec0e8e5f37ab8aebe8e701a476b6f2085f8d9ea10ddc8ef8d64e7ad377df3', + tokenSatoshis: '1', + }, + ], + replyAddress: 'ecash:ppg6t4sglucuzkza02ar52hu62hq9zv2h5jjktp2kp', }, + cache: agoraAdSetupTxSlpNft.cache, }; -// TODO you are here. Get the parseTx unit tests to match mocks by updating mocks. -// You will need integration tests for rendering of different OP_RETURN types -export const AlpTx = { +// 6c6b32e7d68f5743dceec779c61ebe45dc1e8ca7562821ae974c71ef8d2450a7 +export const agoraPartialBuxBuyTx = { tx: { - txid: '791c460c6d5b513283b98b92b83f0e6fa662fc279f39fd00bd27047370ba4647', - version: 1, + txid: '6c6b32e7d68f5743dceec779c61ebe45dc1e8ca7562821ae974c71ef8d2450a7', + version: 2, inputs: [ { prevOut: { - txid: '927bf59fee669509ffee3f3cad5d283694adaf8e44e37e2ae62df53e51116052', + txid: 'f696ae69fb2d7f7253f1fc98aba1a6312c92e98dd691d9825f633aaf7b0f2417', outIdx: 1, }, inputScript: - '41482340e636feab0d15efb309e72eac0f559d0b85eb1799e0a1419430e95448a6a5c1e3961c92861e653dde4428e6e3a79c90d10911b045e7469f7beeae62fc56c1210378d370d2cd269a77ac2f37c28d98b392e5b9892f3b3406bfec8794c82244b039', + '0441475230075041525449414c21023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1400c2c91f9168505022957e651ce0d876ec90a483dec8eb83f9a2897cd0b1640962dcab03e0df52f086db75351d10c01386ff2dcf4e774ee09b5dcf6b96ced6b254422020000000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688acc5728209000000001976a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac4d280117240f7baf3a635f82d991d68de9922c31a6a1ab98fcf153727f2dfb69ae96f601000000cf7b63817b6ea269760460368f02a2697602c6109700887d94527901377f75789263587e7802c610965880bc007e7e68587e527902c610965880bc007e7e825980bc7c7e007e7b5d935e9658807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702cf007f5c7f7701207f547f750443840647886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c880441475230872202000000000000ffffffffb0f7a847759b44cb4dd22554924cf5dae4d946b5aa04372b20eb218d43210b4243840647c10000000422ad0024514d51014c766a04534c500001010453454e44207e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e50800000000000000000000c6100000000000000e0000000000000060368f020000000043840647037f1729ee682b22da2b5dd8a11779ec7b80739c4b5d4b48f83c35d83fbb40a21208c09ef87f00000000ab7b63817b6ea269760460368f02a2697602c6109700887d94527901377f75789263587e7802c610965880bc007e7e68587e527902c610965880bc007e7e825980bc7c7e007e7b5d935e9658807e041976a914707501557f77a97e0288ac7e7e6b7d02220258800317a9147e024c7672587d807e7e7e01ab7e537901257f7702cf007f5c7f7701207f547f750443840647886b7ea97e01877e7c92647500687b8292697e6c6c7b7eaa88520144807c7ea86f7bbb7501c17e7c677501557f7768ad075041525449414c88044147523087', value: 546, sequenceNo: 4294967295, token: { tokenId: - 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, }, - amount: '49756', + amount: '500000', isMintBaton: false, entryIdx: 0, }, - outputScript: - '76a914575116c8adf5817c99fc5bdac8db18d10c25703d88ac', + outputScript: 'a9149c2c40a0a571b35e2e6cca5c224d0c948096a36b87', }, { prevOut: { - txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', + txid: '20d870129eab4418cf8917731ba9f240d5ac6a938d0570af2912f3ed77162d34', outIdx: 2, }, inputScript: - '4152ed9a66a0c40759e400a1484df1a1d2b152c9d6917abf3beaf974f21a935d60853490ae5a07c237531016ceae6c1f01cce9cf2a1417b2b2bcbbc4737ea2fe35412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', - value: 1000, - sequenceNo: 4294967295, - outputScript: - '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', - }, - { - prevOut: { - txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', - outIdx: 3, - }, - inputScript: - '412a65517b4df68bb03ba2b7cd85e70af662503bbc8be209e7fbf18bb0950ff7e0d589f0b3e8119b5e67314fbedd856968890556593d97db58c78e86d2417f27d7412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', - value: 1000, + '41fb428d1c14340d4ef10c55202db803232018f0ae41777503c4a9cb78b4659fad4540f27314c74b9247a1c88937c5594ef908f5e916dddd5b054f290c5a8807a4412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 32055, sequenceNo: 4294967295, outputScript: - '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', }, { prevOut: { - txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', - outIdx: 4, + txid: '2cd92dbce9696b704ae7235e31d0840d728ad11217631dee849d49624f91ffd4', + outIdx: 0, }, inputScript: - '412c9a66d04d341b1f0c3a15689265729a18f5605269909ad9f7b842ea03d96f8540e1b5b272ddc9db5f2d392a8e0569428a7ba4b5d99bbc707168898399f00da7412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', - value: 1000, + '4102e2c50dc6e3c3d8151c950075bc997dbe4762b1c59bcbe3cdd124566d1925bcecb466d21d32133b68fb8579b79e538f4b8dd61832374f2f713f328c3fc850ab412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 3300, sequenceNo: 4294967295, outputScript: - '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', }, { prevOut: { - txid: 'd848d41122437eb049f75142674bb5ec810815955ed2a85a9cfc6142c72e7d00', - outIdx: 5, + txid: '874d3ddb44d022952d3686d39d219c7fdf21327eaa852d2d249102bec026ec4a', + outIdx: 3, }, inputScript: - '41f2ffdbd5f3694669d448899d3f6d939a8165d70cba6be2eaa8416847d56d4630a7b3ac8a35641705e4eb583b391a46c204920641dd85e2b7e04dd18553422651412102f49a7fd4e0c6cea6401aed57b76b2fb358e1ebbb65fc5782e3c2165c9e850b31', - value: 1000, + '412f68bc4b72f9df1435d4046719b793556295fbe02d80c8752acf587afac49d09f160ba04f2dfd5c1fa9ae5e294e31d5b8efc331074cefa08bfe7e2106e46b34a412102c237f49dd4c812f27b09d69d4c8a4da12744fda8ad63ce151fed2a3f41fd8795', + value: 202656827, sequenceNo: 4294967295, outputScript: - '76a9148b9b3ba9199d98e131b762081c0c31754fb904c288ac', + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', }, ], outputs: [ { value: 0, outputScript: - '6a503d534c5032000453454e4445e1f25de444e399b6d46fa66e3424c04549a85a14b12bc9a4ddc9cdcdcdcdcd038a02000000003e3000000000948f00000000', + '6a04534c500001010453454e44207e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5080000000000000000080000000000057ba508000000000002257b', }, { - value: 546, + value: 43144579, outputScript: '76a914dee50f576362377dd2f031453c0bb09009acaf8188ac', - token: { - tokenId: - 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '650', - isMintBaton: false, - entryIdx: 0, - }, }, { - value: 1960, - outputScript: 'a914b0bfb87508e5203803490c2f3891d040f772ba0f87', + value: 546, + outputScript: 'a914502ed21ca74bde03d7fb672ed9c996eab92e72fd87', token: { tokenId: - 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, }, - amount: '12350', + amount: '359333', isMintBaton: false, entryIdx: 0, }, @@ -11631,89 +12725,178 @@ { value: 546, outputScript: - '76a914575116c8adf5817c99fc5bdac8db18d10c25703d88ac', + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', token: { tokenId: - 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, }, - amount: '36756', + amount: '140667', isMintBaton: false, entryIdx: 0, }, }, + { + value: 159544005, + outputScript: + '76a91476458db0ed96fe9863fc1ccec9fa2cfab884b0f688ac', + spentBy: { + txid: '40c5a257a9797bf9cb44f0f1fe7ee08d732a151c70f1a038487bac4a431b7787', + outIdx: 1, + }, + }, ], - lockTime: 0, - timeFirstSeen: 1710439161, - size: 888, + lockTime: 1191609411, + timeFirstSeen: 1729812060, + size: 1518, isCoinbase: false, tokenEntries: [ { tokenId: - 'cdcdcdcdcdc9dda4c92bb1145aa84945c024346ea66fd4b699e344e45df2e145', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + txType: 'SEND', + isInvalid: false, + burnSummary: '', + failedColorings: [], + actualBurnAmount: '0', + intentionalBurn: '0', + burnsMintBatons: false, + }, + ], + tokenFailedParsings: [], + tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 867988, + hash: '000000000000000029b0040b966ade65e7217457758ef4c1a9f524bacc30baf5', + timestamp: 1729813559, + }, + }, + sendingHash: '76458db0ed96fe9863fc1ccec9fa2cfab884b0f6', + parsed: { + recipients: [ + 'ecash:qr0w2r6hvd3rwlwj7qc520qtkzgqnt90sypk26yd2u', + 'ecash:ppgza5su5a9auq7hldnjakwfjm4tjtnjl54xmlf83s', + ], + satoshisSent: 43145125, + stackArray: [ + '534c5000', + '01', + '53454e44', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + '0000000000000000', + '0000000000057ba5', + '000000000002257b', + ], + xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'Agora Buy', + tokenId: + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + tokenSatoshis: '140667', + }, + ], + }, + cache: [ + [ + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + { + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + genesisInfo: { + tokenTicker: 'BUX', + tokenName: 'Badger Universal Token', + url: 'https://bux.digital', + decimals: 4, + hash: '', + }, + timeFirstSeen: 0, + genesisSupply: '0.0000', + genesisOutputScripts: [ + 'a91420d151c5ab4ca4154407626069eaafd8ce6306fc87', + ], + genesisMintBatons: 1, + block: { + height: 726564, + hash: '000000000000000010ea35897b2b7373261fdfbca3d02e4f9a6eeb79dc914315', + timestamp: 1644797123, }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, }, ], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', - block: { - height: 835924, - hash: '00000000000000000cb5f7d96ddff0d04096c405a0361196bcbe60622ea0e44f', - timestamp: 1710440413, - }, - }, + ], +}; + +export const agoraPartialBuxSellTx = { + tx: agoraPartialBuxBuyTx.tx, + sendingHash: 'dee50f576362377dd2f031453c0bb09009acaf81', parsed: { - satoshisSent: 546, - stackArray: [ - '50', - '534c5032000453454e4445e1f25de444e399b6d46fa66e3424c04549a85a14b12bc9a4ddc9cdcdcdcdcd038a02000000003e3000000000948f00000000', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'Agora Sale', + tokenId: + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + tokenSatoshis: '140667', + }, ], - xecTxType: 'Received', recipients: [ - 'ecash:pzctlwr4prjjqwqrfyxz7wy36pq0wu46pud7n9ffz3', - 'ecash:qpt4z9kg4h6czlyel3da4jxmrrgscfts859gzp2zuu', + 'ecash:ppgza5su5a9auq7hldnjakwfjm4tjtnjl54xmlf83s', + 'ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj', + ], + replyAddress: 'ecash:pzwzcs9q54cmxh3wdn99cgjdpj2gp94rdvy2wuu50y', + satoshisSent: 43144579, + stackArray: [ + '534c5000', + '01', + '53454e44', + '7e7dacd72dcdb14e00a03dd3aff47f019ed51a6f1f4e4f532ae50692f62bc4e5', + '0000000000000000', + '0000000000057ba5', + '000000000002257b', ], + xecTxType: 'Received', }, + cache: agoraPartialBuxBuyTx.cache, }; -export const SlpNftParentFanTx = { +export const SlpNftParentMintTx = { tx: { - txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', + txid: 'af8d9508e488e7c9462cb9bb9d9b68f246cec6394676d1f660331bfe1f4e1fd2', version: 2, inputs: [ { prevOut: { - txid: '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', - outIdx: 1, + txid: '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', + outIdx: 2, }, inputScript: - '483045022100a5e4824f76bad8f224412fca2442c11598d6dd29848b67ae0e8c6f74a5a80b2c022049ee636ac6b951eba8273f300bcab8ffc31525f4d96ca738cfbb62e73769bf3a412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '413bcbae418f71ecbc9b5a2ecbe9d7d7bd61a7473399ccfe4176e62fe51fe4cdba2dc8cb42088207ee4daf8c4a618e7e4a9773f969e681c8e2b552b13fc8ddc8e8412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', value: 546, sequenceNo: 4294967295, token: { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_NFT1_GROUP', number: 129, }, - amount: '4', - isMintBaton: false, + amount: '0', + isMintBaton: true, entryIdx: 0, }, outputScript: @@ -11721,12 +12904,12 @@ }, { prevOut: { - txid: '73c8333ffbf94d14a52c0284a67a7e0cb71dac08d6ae9da989f7c3b97339df7f', - outIdx: 3, + txid: '607b7bb1a4d95efbeee42d98fc7b3b2fd3ed3dcfc6aea192f56839b405982889', + outIdx: 2, }, inputScript: - '483045022100dfe70b028211bf747a9d634f03f6f024264f75ef37f9dd4b40c8d8dfddfeff9702205ccb832e674c5c865353707fc46c5b4206dd807797d6b64f146441fa2d85bf94412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 32771801, + '41f5fe8b075e9f9ab3b3c69b8e5621c9de49c4daffb698097149bdb57f4d472e0d1a9692df4d07ec64d4102c10a76bdc6bc6ef9df630061b34a1d19f50f1e97ef4412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 71580707, sequenceNo: 4294967295, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', @@ -11736,28 +12919,7 @@ { value: 0, outputScript: - '6a04534c500001810453454e442012a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3080000000000000001080000000000000001080000000000000001080000000000000001', - }, - { - value: 546, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - token: { - tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, - spentBy: { - txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', - outIdx: 0, - }, + '6a04534c50000181044d494e54205a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f86200102080000000000000001', }, { value: 546, @@ -11765,7 +12927,7 @@ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_NFT1_GROUP', @@ -11782,58 +12944,41 @@ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_NFT1_GROUP', number: 129, }, - amount: '1', - isMintBaton: false, + amount: '0', + isMintBaton: true, entryIdx: 0, }, - }, - { - value: 546, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - token: { - tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, + spentBy: { + txid: '5d934ade992707fe126bcd393ad4358b2c10118b635df4b97e3e3f30ca7cc781', + outIdx: 0, }, }, { - value: 32769023, + value: 71579701, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - spentBy: { - txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', - outIdx: 1, - }, }, ], lockTime: 0, - timeFirstSeen: 1713825841, - size: 567, + timeFirstSeen: 1730953527, + size: 460, isCoinbase: false, tokenEntries: [ { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_NFT1_GROUP', number: 129, }, - txType: 'SEND', + txType: 'MINT', isInvalid: false, burnSummary: '', failedColorings: [], @@ -11845,96 +12990,105 @@ tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', block: { - height: 841414, - hash: '00000000000000000e074b0e1067d96e33a0b4df2a352dab1abbb6f28645563a', - timestamp: 1713826095, + height: 869927, + hash: '00000000000000001d5912840b0d830c3d491f273b15ac9f5bcd0234456dfb5a', + timestamp: 1730954146, }, }, + sendingHash: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', parsed: { recipients: [], - satoshisSent: 32771207, + satoshisSent: 71580793, stackArray: [ '534c5000', '81', - '53454e44', - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', - '0000000000000001', - '0000000000000001', - '0000000000000001', + '4d494e54', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', + '02', '0000000000000001', ], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'Collection', + renderedTxType: 'MINT', + tokenId: + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', + tokenSatoshis: '1', + }, + ], }, - // 3 The Four Half-Coins of Jin-qua (4HC) cache: [ [ - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', { tokenType: { protocol: 'SLP', type: 'SLP_TOKEN_TYPE_NFT1_GROUP', number: 129, }, - timeFirstSeen: 1713551159, genesisInfo: { - tokenTicker: '4HC', - tokenName: 'The Four Half-Coins of Jin-qua', - url: 'en.wikipedia.org/wiki/Tai-Pan_(novel)', + tokenTicker: 'MASCOTS', + tokenName: 'Mascots', + url: 'cashtab.com', decimals: 0, - hash: '2a6585a404fae1c33a43322b723b9dbd926cb07244ae9bea888add8f471511e0', - }, - block: { - height: 840791, - hash: '00000000000000000be1576bcb0bf1c035bba940d5c696d7bb8a0d53c16076c5', - timestamp: 1713551526, + hash: '2d0f7be21838551f43872cddda2213659f6603d0aec566dd8f917e49e172f27d', }, - genesisSupply: '4', + timeFirstSeen: 1716324228, + genesisSupply: '100', genesisOutputScripts: [ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', ], - genesisMintBatons: 0, + genesisMintBatons: 1, + block: { + height: 845656, + hash: '00000000000000001c7f33318a0ac58f2256696b302c2047ab73315943c0c6d7', + timestamp: 1716327571, + }, }, ], ], }; -export const SlpNftMint = { +// 29b79f0f4302c43f6e6dd565e7e5829cf7f8a8fe1e95a58e3e87620a24c5bef9 +export const alpBurnTx = { tx: { - txid: 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', + txid: '29b79f0f4302c43f6e6dd565e7e5829cf7f8a8fe1e95a58e3e87620a24c5bef9', version: 2, inputs: [ { prevOut: { - txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', - outIdx: 1, + txid: '061459eea0e569392f0622c20e5917b5ca94ae38a77405cd3a5f01b41bba688b', + outIdx: 2, }, inputScript: - '483045022100939d517c889174bdcaf9755390165ce1e2ba7f47d1490dbf48bbf2f4146c84360220172aeb2fe8eca8a0c59e68ca6b2ab1a8fd0bdded8410212c5d34d936cadcf734412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '41eed3688821e81f77edcf70e877d6b270acbd1714b82ea9b58fe0239e3dfccd73da5a1dd5d2906a40624d172e1a4273eda5e2feb902d74b73e264f9ef469c0a99412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', value: 546, sequenceNo: 4294967295, token: { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - amount: '1', + amount: '99999', isMintBaton: false, - entryIdx: 1, + entryIdx: 0, }, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, { prevOut: { - txid: 'faaba128601942a858abcce56d0da002c1f1d95e8c49ba4105c3d08aa76959d8', - outIdx: 5, + txid: 'efb84d4aa3aec5636ae5fcbbc560d4c1bafbe1e9ed00661380bce4a9db2360e0', + outIdx: 1, }, inputScript: - '483045022100da6101ab8d02141d6745b3985d4c1ba5481cb2c470acff8d40e66fa654e3f14402200906d6a511dda0c5bc243f82217a03fe40c3cfc0a407b2d1e6f971de1ae70316412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 32769023, + '41bfbaae1e96b3a3d7fbbe24c2cd9ac07e48b7340e24635a8005be1b94563bc0e020d073d8a88e9af4a5a067ff9dcd6601f35611399d70f2958ff7ce22770792a7412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 2812672, sequenceNo: 4294967295, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', @@ -11944,7 +13098,7 @@ { value: 0, outputScript: - '6a04534c500001410747454e45534953035746430c57752046616e672043686f690b636173687461622e636f6d20ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a297308385501004c00080000000000000001', + '6a5030534c503200044255524e3f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101000000000031534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11019e8601000000', }, { value: 546, @@ -11952,130 +13106,158 @@ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', token: { tokenId: - 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, - }, - { - value: 32768070, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - ], - lockTime: 0, - timeFirstSeen: 1713828197, - size: 474, - isCoinbase: false, - tokenEntries: [ - { - tokenId: - 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, - }, - txType: 'GENESIS', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, - groupTokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, + }, + amount: '99998', + isMintBaton: false, + entryIdx: 0, + }, + }, + { + value: 2812202, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, + ], + lockTime: 0, + timeFirstSeen: 1732374561, + size: 470, + isCoinbase: false, + tokenEntries: [ { tokenId: - '12a049d0da64652b4e8db68b6052ad0cda43cf0269190fe81040bed65ca926a3', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - txType: 'NONE', + txType: 'SEND', isInvalid: false, burnSummary: '', failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', + actualBurnAmount: '1', + intentionalBurn: '1', burnsMintBatons: false, }, ], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', + block: { + height: 872299, + hash: '000000000000000022478fad1745dbd1c8f57ad77b6627ba459720c2653cd086', + timestamp: 1732375055, + }, }, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { recipients: [], - satoshisSent: 32768616, + satoshisSent: 2812748, stackArray: [ - '534c5000', - '41', - '47454e45534953', - '574643', - '57752046616e672043686f69', - '636173687461622e636f6d', - 'ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a2973083855', - '00', - '', - '0000000000000001', + '50', + '534c503200044255524e3f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11010000000000', + '534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11019e8601000000', ], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'ALP', + renderedTxType: 'BURN', + tokenId: + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + tokenSatoshis: '1', + }, + ], }, - // 1 Wu Fang Choi (WFC) cache: [ [ - 'fcab9a929a15ef91b5c5ca38b638e4d3f5fc49deb36fbc5c63de1fa900c8bcda', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', { tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_CHILD', - number: 65, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - timeFirstSeen: 1713828197, genesisInfo: { - tokenTicker: 'WFC', - tokenName: 'Wu Fang Choi', + tokenTicker: 'TB', + tokenName: 'Tiberium', url: 'cashtab.com', decimals: 0, - hash: 'ec7ed5da3ed751a80a3ab857c50dce405f8e8f7a083fafea158a3a2973083855', - }, - block: { - height: 841418, - hash: '000000000000000015c94349a2ec777da460e8d8d48a220bbf9d6a6e6e9df66f', - timestamp: 1713829166, + authPubkey: + '03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', }, - genesisSupply: '1', + timeFirstSeen: 1732368999, + genesisSupply: '100000', genesisOutputScripts: [ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', ], - genesisMintBatons: 0, + genesisMintBatons: 1, + block: { + height: 872286, + hash: '00000000000000000714f249ab1ecd41eef595260c4f9e79fa49e7dc1bd45767', + timestamp: 1732369043, + }, }, ], ], }; -export const SlpParentGenesisTxMock = { +// cf7f6c07bd838dbc7f7b05f5f879d498789d087e6c76dde91fdedeb802230587 +export const alpAgoraListingTx = { tx: { - txid: 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + txid: 'cf7f6c07bd838dbc7f7b05f5f879d498789d087e6c76dde91fdedeb802230587', version: 2, inputs: [ { prevOut: { - txid: '5d9bff67b99e3f93c245a2d832ae40b67f39b79e5cf1daefe97fe6a8a2228326', + txid: '59a60227b112221130f11fd890100ba623944f8243cc8322e7f4c8fd17ab6ee2', outIdx: 2, }, inputScript: - '483045022100eb2e68c7d02eda2dd64c22a079d832c5c85f34f1ced264cd3b37658d4cd0b89e02203e204cd625a05c8ba59291567bc14d0bfa193a9a37cbc00aec804a224dc910d1412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 32766028, + '41063618b40515cc62f4c2802f4f76ae729cfe31351f419634560bff37fbb8fa3dce1efb084e12a5e983beb893e945854470f409c1ec1c8c48b2baf7f5d80cb5e1412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 546, + sequenceNo: 4294967295, + token: { + tokenId: + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, + }, + amount: '98082', + isMintBaton: false, + entryIdx: 0, + }, + outputScript: + '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + }, + { + prevOut: { + txid: 'cbded16a00885493d76e6534d932a58083f1918be220b8604897181c6b611609', + outIdx: 1, + }, + inputScript: + '41c143430106e44093436317fb23c3eb96e453ea500e47ea4d1952fdb917c4423abc52a51f0163e193704c6879fd0ff005423ae60ff4f75c7ff234cb6d45ef0391412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + value: 546, sequenceNo: 4294967295, + token: { + tokenId: + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, + }, + amount: '1024', + isMintBaton: false, + entryIdx: 0, + }, outputScript: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', }, @@ -12084,53 +13266,61 @@ { value: 0, outputScript: - '6a04534c500001810747454e455349530348534d0b54686520486569736d616e2c68747470733a2f2f656e2e77696b6970656469612e6f72672f77696b692f486569736d616e5f54726f7068792073229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb97601004c00080000000000000059', + '6a504b41475230075041525449414c0001a4540000000000009006000000000000a4540000000000006f67825703771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba631534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101228301000000', }, { value: 546, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + outputScript: 'a91410596364db3336ec723ce7eaa296e7fa7dbe070687', + plugins: { + agora: { + groups: [ + '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '54116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + '46116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + ], + data: [ + '5041525449414c', + '00', + '01', + 'a454000000000000', + '9006000000000000', + 'a454000000000000', + '6f678257', + ], + }, + }, token: { tokenId: - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - amount: '89', + amount: '99106', isMintBaton: false, entryIdx: 0, }, spentBy: { - txid: '1f2f9a37767586320a8af6afadda56bdf5446034910e27d537f26777ad95e0d5', - outIdx: 0, - }, - }, - { - value: 32764762, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - spentBy: { - txid: '1f2f9a37767586320a8af6afadda56bdf5446034910e27d537f26777ad95e0d5', + txid: 'a6d65d619bbb03c4490498f7fe1d5413e92df064915a3533a09e8a4ba1762255', outIdx: 1, }, }, ], lockTime: 0, - timeFirstSeen: 1714048251, - size: 358, + timeFirstSeen: 1732642801, + size: 461, isCoinbase: false, tokenEntries: [ { tokenId: - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - txType: 'GENESIS', + txType: 'SEND', isInvalid: false, burnSummary: '', failedColorings: [], @@ -12142,118 +13332,182 @@ tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', block: { - height: 841852, - hash: '00000000000000000cea344b4130a2de214200266ad0d67253eea01eeb34a48d', - timestamp: 1714048284, + height: 872745, + hash: '000000000000000017dce1ee0a66873715acd1987aa18d018cc94e2943c2608b', + timestamp: 1732642958, }, }, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { - recipients: [], - satoshisSent: 32765308, + recipients: ['ecash:pqg9jcmymvendmrj8nn74g5kula8m0s8qce724yjtn'], + satoshisSent: 546, stackArray: [ - '534c5000', - '81', - '47454e45534953', - '48534d', - '54686520486569736d616e', - '68747470733a2f2f656e2e77696b6970656469612e6f72672f77696b692f486569736d616e5f54726f706879', - '73229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb976', - '00', - '', - '0000000000000059', + '50', + '41475230075041525449414c0001a4540000000000009006000000000000a4540000000000006f67825703771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', + '534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101228301000000', ], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'ALP', + renderedTxType: 'Agora Offer', + tokenId: + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', + tokenSatoshis: '99106', + }, + ], }, cache: [ [ - 'd2bfffd48c289cd5d43920f4f95a88ac4b9572d39d54d874394682608f56bf4a', + '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', { tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 0, }, - timeFirstSeen: 1714048251, genesisInfo: { - tokenTicker: 'HSM', - tokenName: 'The Heisman', - url: 'https://en.wikipedia.org/wiki/Heisman_Trophy', + tokenTicker: 'TB', + tokenName: 'Tiberium', + url: 'cashtab.com', decimals: 0, - hash: '73229094743335d380cd7ce479fb38c9dfe77cdd97668aa0c4d9183855fcb976', - }, - block: { - height: 841852, - hash: '00000000000000000cea344b4130a2de214200266ad0d67253eea01eeb34a48d', - timestamp: 1714048284, + data: [], + authPubkey: + '03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', }, - genesisSupply: '89', + timeFirstSeen: 1732368999, + genesisSupply: '100000', genesisOutputScripts: [ '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', ], - genesisMintBatons: 0, + genesisMintBatons: 1, + block: { + height: 872286, + hash: '00000000000000000714f249ab1ecd41eef595260c4f9e79fa49e7dc1bd45767', + timestamp: 1732369043, + }, }, ], ], }; -export const oneOutputReceivedTx = { +export const paywallPaymentTx = { tx: { - txid: '0edd96775cc1dbc4c36dbf5f1773f937de3bdadd572265ad78bae931fec3f431', + txid: 'e9692335fdb3b75f2e319cbda1396f7f32c02c3d172e58148abeb2952c7e2460', version: 2, inputs: [ { prevOut: { - txid: 'cd5731b4f5ec4ff2e12fe3187e37ce3dc544f5419df8f6c36f649e1236d7dcee', - outIdx: 0, + txid: '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', + outIdx: 1, }, inputScript: - '41246058dcfab4114536db638d064612e12e0cfff613b568535c278e544ec68ec3e02ffc94d09a0ffe0f4e6fd9ff9608b01aad46cad3765059c3fe45ea09898abe4121029bd5d9d9565b734188493dfd3b0fe985ccd55bb6bc1544cf6ed25a46076f045f', - value: 45553900000, - sequenceNo: 4294967294, + '483045022100a58e1087f128d676d4b5839c795df15b88b87b47b0c8f382d39811ee5df21cf6022022727ede00178347e0ab0dd3df91959378c25a29f902a4f8b4f1c79ddd7cf15241210216794b896521c52b0b156d886652859d1e4e03a9cd8f3894f4b1e1853092a3c7', + value: 550, + sequenceNo: 4294967295, outputScript: - '76a914bb3f3669824acaf67902cbc8477f75ae5b139a0f88ac', + '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', }, { prevOut: { - txid: '3719ef3aa2739da328a1a2916a422931fb7b0fa897183f3fd8f3c26864285e34', - outIdx: 0, + txid: '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', + outIdx: 2, }, inputScript: - '415d1ee0074f11a0adf5c35039167a731d008656eb0a33b5eec9144dd8614419e88866779cce3da0de8c9f839ddbb8d8ee8d24c82526a8900730ea8af8ef102c6d4121020b5c467c0276678df5f50cc932e81abf259f40477f815ed11f4d0fecab39f2d6', - value: 100000000, - sequenceNo: 4294967294, + '483045022100856c2d015d7384a094d0c17dde0ec29ee37ddf64c914a6c1d12c9bd92724bc52022027d9f6525c49786e5454615e605d1af0aa4fa0860eea39e927316042ba3557f141210216794b896521c52b0b156d886652859d1e4e03a9cd8f3894f4b1e1853092a3c7', + value: 27419, + sequenceNo: 4294967295, outputScript: - '76a91409c388abff6922c7e97ef8ea58e9697b6637910c88ac', + '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', }, ], outputs: [ { - value: 45653899320, + value: 0, outputScript: - '76a914601efc2aa406fe9eaedd41d2b5d95d1f4db9041d88ac', + '6a0470617977204d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', + }, + { + value: 15000, + outputScript: + '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', spentBy: { - txid: 'b9aab1e26381457b390ad689c7577962cef1ec48de3a83d87db68968afb7e4cf', - outIdx: 54, + txid: '84d75fe93ab918e74e58c1a12a982d0cc8d1db1bb102f02068772723891711b3', + outIdx: 0, }, }, + { + value: 12056, + outputScript: + '76a91406e6281dfcffdd9db8304e81dcfa3820ab349ae488ac', + }, ], lockTime: 0, - timeFirstSeen: 1714138690, - size: 326, + timeFirstSeen: 1716474827, + size: 454, isCoinbase: false, tokenEntries: [], tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 842022, - hash: '00000000000000000c331ba563d903d20ff670b18afd0d6cd4aadca854d294a6', - timestamp: 1714139968, + height: 845901, + hash: '00000000000000001da9291a7aa6fa8f9fa5f99413faa951e3f5777a082f911e', + timestamp: 1716475087, + }, + parsed: { + xecTxType: 'Sent', + satoshisSent: 27056, + stackArray: [ + '70617977', + '34643761363265626237663036666437613836663836313238303835336536666365336331313763373335393866653238343139303236306162643564646334', + ], + recipients: [], }, }, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { - recipients: [], - satoshisSent: 45653899320, - stackArray: [], + appActions: [ + { + action: { + sharedArticleTxid: + '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', + }, + isValid: true, + app: 'Paywall', + lokadId: '70617977', + }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qqrwv2qalnlam8dcxp8grh868qs2kdy6usct6qpwew'], + replyAddress: 'ecash:qqrwv2qalnlam8dcxp8grh868qs2kdy6usct6qpwew', + satoshisSent: 0, + stackArray: [ + '70617977', + '4d7a62ebb7f06fd7a86f861280853e6fce3c117c73598fe284190260abd5ddc4', + ], + xecTxType: 'Received', + }, +}; +export const offSpecPaywallPaymentTx = { + tx: { + ...paywallPaymentTx.tx, + outputs: [ + { + ...paywallPaymentTx.tx.outputs[0], + outputScript: '6a0470617977', // no data after the paywall lokad ID + }, + ...paywallPaymentTx.tx.outputs.slice(1), + ], + }, + sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', + parsed: { + appActions: [{ app: 'Paywall', isValid: false, lokadId: '70617977' }], + parsedTokenEntries: [], + recipients: ['ecash:qqrwv2qalnlam8dcxp8grh868qs2kdy6usct6qpwew'], + replyAddress: 'ecash:qqrwv2qalnlam8dcxp8grh868qs2kdy6usct6qpwew', + satoshisSent: 0, + stackArray: ['70617977'], xecTxType: 'Received', }, }; @@ -20558,6 +21812,8 @@ satoshisSent: 1100, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -20610,6 +21866,9 @@ satoshisSent: 3300, stackArray: [], xecTxType: 'Received', + replyAddress: 'ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -20662,6 +21921,8 @@ satoshisSent: 1100, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -20714,6 +21975,9 @@ satoshisSent: 1100, stackArray: [], xecTxType: 'Received', + replyAddress: 'ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -20864,6 +22128,17 @@ '0000000000000008', ], xecTxType: 'Received', + replyAddress: 'ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'SEND', + tokenId: + '3fee3384150b030490b7bee095a63900f66a45f2d8e3002ae2cf17ce3ef4d109', + tokenSatoshis: '1', + }, + ], }, }, { @@ -20998,6 +22273,16 @@ '00038d5fad5b8e00', ], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [ + { + renderedTokenType: 'SLP', + renderedTxType: 'SEND', + tokenId: + '20a0b9337a78603c6681ed2bc541593375535dcd9979196620ce71f233f2f6f8', + tokenSatoshis: '33000000000', + }, + ], }, }, { @@ -21050,6 +22335,8 @@ satoshisSent: 100383, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -21102,6 +22389,8 @@ satoshisSent: 101053, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -21154,6 +22443,8 @@ satoshisSent: 101132, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, { @@ -21206,6 +22497,8 @@ satoshisSent: 101215, stackArray: [], xecTxType: 'Sent', + appActions: [], + parsedTokenEntries: [], }, }, ]; @@ -21418,642 +22711,338 @@ inputs: [ { prevOut: { - txid: '59daaab81418dff6acc6379d246d98348fdd2e7e10548877ffde73d5cf8d41ea', - outIdx: 1, - }, - inputScript: - '4145602aed278898b9892332953d7eb9212b8f4f842a3e761139baa5ec95d353d94ab3abcb7d62b79e190c6aca93e304555a87398fabda5b9141faec1596b9bcc84121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', - value: 600, - sequenceNo: 4294967295, - outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', - }, - { - prevOut: { - txid: '752ef889a8aff586d926344eb45dee03f56f57a0b08416f8a284903201f60fe6', - outIdx: 1, - }, - inputScript: - '41ec6df6abd70cdb718c19623173901a9471e9f52a5a4cd99d8093c4d5371bc2b0ce107866f1825a04646e6f7b51c883236eaefea50366e7c7074c140695f580014121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', - value: 600, - sequenceNo: 4294967295, - outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', - }, - { - prevOut: { - txid: '72f506669350eedc4b7643b6d3ca2c933137d303315a15c46042c31302c440f6', - outIdx: 2, - }, - inputScript: - '4131c3b37d72362a79618771e7ad737e462c0804367809fb79d2bac39b116663297a559327e747be37e70979ba2f2e6ea184bf616e1b11df72a27f8eaafabbc9c24121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', - value: 508087, - sequenceNo: 4294967295, - outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', - }, - ], - outputs: [ - { - value: 0, - outputScript: - '6a04626c6f6704726c6f6720fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b79922674c70697320796f7572207769666520746865206769726c667269656e642066726f6d207061727420313f20496620736f207468656e20736865277320796f757220736f756c6d6174652c206265747465722068616e67206f6e746f20686572206c696b6520796f7572205845432062616773', - }, - { - value: 550, - outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', - spentBy: { - txid: '29810f319e19c552a6646d96eb1de5f7587c9adc6bed80ea756fe5b8db1f3f34', - outIdx: 0, - }, - }, - { - value: 507394, - outputScript: - '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', - spentBy: { - txid: '29810f319e19c552a6646d96eb1de5f7587c9adc6bed80ea756fe5b8db1f3f34', - outIdx: 1, - }, - }, - ], - lockTime: 0, - timeFirstSeen: 1721558302, - size: 668, - isCoinbase: false, - tokenEntries: [], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 854251, - hash: '000000000000000000188bb36a8189d5612210ba2c6d1b8afa0f9d27e70ffe6f', - timestamp: 1721558514, - }, - parsed: { - xecTxType: 'Sent', - satoshisSent: 507944, - stackArray: [ - '626c6f67', - '726c6f67', - 'fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b7992267', - '697320796f7572207769666520746865206769726c667269656e642066726f6d207061727420313f20496620736f207468656e20736865277320796f757220736f756c6d6174652c206265747465722068616e67206f6e746f20686572206c696b6520796f7572205845432062616773', - ], - recipients: [], - }, - }, -}; -export const eCashChatArticleTx = { - tx: { - txid: 'ab32d18a8f52d57c31c0197a45a4f10ed9299df25d996ccd2b1792506d569836', - version: 2, - inputs: [ - { - prevOut: { - txid: 'cafc6799c3fd6712d2f94b4360c90c73edcb49c0d1030989b3b07223c4fc4aac', - outIdx: 2, - }, - inputScript: - '41f6b48f09d3d69002cb49049269d2e16c752b59357bf08c9a4a8513a69d6c87636db7acf09a6714663276d543584045b0796e76bfa3d67bd21a2fa680a89a375d412102f9e8383fe6fc81852f60909f5feb8a314949c3d2c9013c5e67563e3ba03e60ad', - value: 133153, - sequenceNo: 4294967295, - outputScript: - '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', - }, - ], - outputs: [ - { - value: 0, - outputScript: - '6a04626c6f672863666338633134326661323336303566366336343765333437636262613261356633363064383937', - }, - { - value: 550, - outputScript: - '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', - spentBy: { - txid: '9da106f4f05ba358b91486c5a233db096a57f40fa8134fddcc3ad2121857e47a', - outIdx: 0, - }, - }, - { - value: 132050, - outputScript: - '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', - spentBy: { - txid: '9da106f4f05ba358b91486c5a233db096a57f40fa8134fddcc3ad2121857e47a', - outIdx: 1, - }, - }, - ], - lockTime: 0, - timeFirstSeen: 1721543189, - size: 275, - isCoinbase: false, - tokenEntries: [], - tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NON_TOKEN', - block: { - height: 854224, - hash: '000000000000000017faf86eb0dc5a051ccc069b90c55653749311eca64c29e4', - timestamp: 1721543497, - }, - parsed: { - xecTxType: 'Sent', - satoshisSent: 132600, - stackArray: [ - '626c6f67', - '63666338633134326661323336303566366336343765333437636262613261356633363064383937', - ], - recipients: [], - }, - }, -}; -export const SlpNftParentMintTx = { - tx: { - txid: 'af8d9508e488e7c9462cb9bb9d9b68f246cec6394676d1f660331bfe1f4e1fd2', - version: 2, - inputs: [ - { - prevOut: { - txid: '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - outIdx: 2, + txid: '59daaab81418dff6acc6379d246d98348fdd2e7e10548877ffde73d5cf8d41ea', + outIdx: 1, }, inputScript: - '413bcbae418f71ecbc9b5a2ecbe9d7d7bd61a7473399ccfe4176e62fe51fe4cdba2dc8cb42088207ee4daf8c4a618e7e4a9773f969e681c8e2b552b13fc8ddc8e8412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, + '4145602aed278898b9892332953d7eb9212b8f4f842a3e761139baa5ec95d353d94ab3abcb7d62b79e190c6aca93e304555a87398fabda5b9141faec1596b9bcc84121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', + value: 600, sequenceNo: 4294967295, - token: { - tokenId: - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - amount: '0', - isMintBaton: true, - entryIdx: 0, + outputScript: + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', + }, + { + prevOut: { + txid: '752ef889a8aff586d926344eb45dee03f56f57a0b08416f8a284903201f60fe6', + outIdx: 1, }, + inputScript: + '41ec6df6abd70cdb718c19623173901a9471e9f52a5a4cd99d8093c4d5371bc2b0ce107866f1825a04646e6f7b51c883236eaefea50366e7c7074c140695f580014121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', + value: 600, + sequenceNo: 4294967295, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', }, { prevOut: { - txid: '607b7bb1a4d95efbeee42d98fc7b3b2fd3ed3dcfc6aea192f56839b405982889', + txid: '72f506669350eedc4b7643b6d3ca2c933137d303315a15c46042c31302c440f6', outIdx: 2, }, inputScript: - '41f5fe8b075e9f9ab3b3c69b8e5621c9de49c4daffb698097149bdb57f4d472e0d1a9692df4d07ec64d4102c10a76bdc6bc6ef9df630061b34a1d19f50f1e97ef4412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 71580707, + '4131c3b37d72362a79618771e7ad737e462c0804367809fb79d2bac39b116663297a559327e747be37e70979ba2f2e6ea184bf616e1b11df72a27f8eaafabbc9c24121030a06dd7429d8fce700b702a55a012a1f9d1eaa46825bde2d31252ee9cb30e536', + value: 508087, sequenceNo: 4294967295, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', }, ], outputs: [ { value: 0, outputScript: - '6a04534c50000181044d494e54205a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f86200102080000000000000001', - }, - { - value: 546, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - token: { - tokenId: - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - amount: '1', - isMintBaton: false, - entryIdx: 0, - }, + '6a04626c6f6704726c6f6720fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b79922674c70697320796f7572207769666520746865206769726c667269656e642066726f6d207061727420313f20496620736f207468656e20736865277320796f757220736f756c6d6174652c206265747465722068616e67206f6e746f20686572206c696b6520796f7572205845432062616773', }, { - value: 546, + value: 550, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - token: { - tokenId: - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - amount: '0', - isMintBaton: true, - entryIdx: 0, - }, + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', spentBy: { - txid: '5d934ade992707fe126bcd393ad4358b2c10118b635df4b97e3e3f30ca7cc781', + txid: '29810f319e19c552a6646d96eb1de5f7587c9adc6bed80ea756fe5b8db1f3f34', outIdx: 0, }, }, { - value: 71579701, + value: 507394, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a91414582d09f61c6580b8a2b6c8af8d6a13c9128b6f88ac', + spentBy: { + txid: '29810f319e19c552a6646d96eb1de5f7587c9adc6bed80ea756fe5b8db1f3f34', + outIdx: 1, + }, }, ], lockTime: 0, - timeFirstSeen: 1730953527, - size: 460, + timeFirstSeen: 1721558302, + size: 668, isCoinbase: false, - tokenEntries: [ - { - tokenId: - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - txType: 'MINT', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, - }, - ], + tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 869927, - hash: '00000000000000001d5912840b0d830c3d491f273b15ac9f5bcd0234456dfb5a', - timestamp: 1730954146, + height: 854251, + hash: '000000000000000000188bb36a8189d5612210ba2c6d1b8afa0f9d27e70ffe6f', + timestamp: 1721558514, + }, + parsed: { + xecTxType: 'Sent', + satoshisSent: 507944, + stackArray: [ + '626c6f67', + '726c6f67', + 'fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b7992267', + '697320796f7572207769666520746865206769726c667269656e642066726f6d207061727420313f20496620736f207468656e20736865277320796f757220736f756c6d6174652c206265747465722068616e67206f6e746f20686572206c696b6520796f7572205845432062616773', + ], + recipients: [], }, }, - sendingHash: '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', parsed: { - recipients: [], - satoshisSent: 71580793, + appActions: [ + { + action: { + msg: "is your wife the girlfriend from part 1? If so then she's your soulmate, better hang onto her like your XEC bags", + replyArticleTxid: + 'fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b7992267', + }, + app: 'eCashChat Article Reply', + isValid: true, + lokadId: '626c6f67', + }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qq29stgf7cwxtq9c52mv3tuddgfujy5tduaellf3wm'], + replyAddress: 'ecash:qq29stgf7cwxtq9c52mv3tuddgfujy5tduaellf3wm', + satoshisSent: 0, stackArray: [ - '534c5000', - '81', - '4d494e54', - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', - '02', - '0000000000000001', + '626c6f67', + '726c6f67', + 'fc1bec473c0c8de408b8587ead6d31ad1d8854835c19947488fa7b30b7992267', + '697320796f7572207769666520746865206769726c667269656e642066726f6d207061727420313f20496620736f207468656e20736865277320796f757220736f756c6d6174652c206265747465722068616e67206f6e746f20686572206c696b6520796f7572205845432062616773', ], - xecTxType: 'Sent', + xecTxType: 'Received', }, - cache: [ - [ - '5a9d91ae2730dffbd0795dd2f8bfda5a6ad905f374158c8df303ca5cc82f8620', +}; +export const offSpecEcashChatArticleReplyTx = { + tx: { + ...eCashChatArticleReplyTx.tx, + outputs: [ { - tokenType: { - protocol: 'SLP', - type: 'SLP_TOKEN_TYPE_NFT1_GROUP', - number: 129, - }, - genesisInfo: { - tokenTicker: 'MASCOTS', - tokenName: 'Mascots', - url: 'cashtab.com', - decimals: 0, - hash: '2d0f7be21838551f43872cddda2213659f6603d0aec566dd8f917e49e172f27d', - }, - timeFirstSeen: 1716324228, - genesisSupply: '100', - genesisOutputScripts: [ - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - ], - genesisMintBatons: 1, - block: { - height: 845656, - hash: '00000000000000001c7f33318a0ac58f2256696b302c2047ab73315943c0c6d7', - timestamp: 1716327571, - }, + ...eCashChatArticleReplyTx.tx.outputs[0], + outputScript: '6a04626c6f6704726c6f67', // no data after the article reply lokad ID i.e. stackArray !== 4 }, + ...eCashChatArticleReplyTx.tx.outputs.slice(1), ], - ], + }, + parsed: { + appActions: [ + { + app: 'eCashChat Article Reply', + isValid: false, + lokadId: '626c6f67', + }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qq29stgf7cwxtq9c52mv3tuddgfujy5tduaellf3wm'], + replyAddress: 'ecash:qq29stgf7cwxtq9c52mv3tuddgfujy5tduaellf3wm', + satoshisSent: 0, + stackArray: ['626c6f67', '726c6f67'], + xecTxType: 'Received', + }, }; - -// 29b79f0f4302c43f6e6dd565e7e5829cf7f8a8fe1e95a58e3e87620a24c5bef9 -export const alpBurnTx = { +export const eCashChatArticleTx = { tx: { - txid: '29b79f0f4302c43f6e6dd565e7e5829cf7f8a8fe1e95a58e3e87620a24c5bef9', + txid: 'ab32d18a8f52d57c31c0197a45a4f10ed9299df25d996ccd2b1792506d569836', version: 2, inputs: [ { prevOut: { - txid: '061459eea0e569392f0622c20e5917b5ca94ae38a77405cd3a5f01b41bba688b', + txid: 'cafc6799c3fd6712d2f94b4360c90c73edcb49c0d1030989b3b07223c4fc4aac', outIdx: 2, }, inputScript: - '41eed3688821e81f77edcf70e877d6b270acbd1714b82ea9b58fe0239e3dfccd73da5a1dd5d2906a40624d172e1a4273eda5e2feb902d74b73e264f9ef469c0a99412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '99999', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - { - prevOut: { - txid: 'efb84d4aa3aec5636ae5fcbbc560d4c1bafbe1e9ed00661380bce4a9db2360e0', - outIdx: 1, - }, - inputScript: - '41bfbaae1e96b3a3d7fbbe24c2cd9ac07e48b7340e24635a8005be1b94563bc0e020d073d8a88e9af4a5a067ff9dcd6601f35611399d70f2958ff7ce22770792a7412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 2812672, + '41f6b48f09d3d69002cb49049269d2e16c752b59357bf08c9a4a8513a69d6c87636db7acf09a6714663276d543584045b0796e76bfa3d67bd21a2fa680a89a375d412102f9e8383fe6fc81852f60909f5feb8a314949c3d2c9013c5e67563e3ba03e60ad', + value: 133153, sequenceNo: 4294967295, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', }, ], outputs: [ { value: 0, outputScript: - '6a5030534c503200044255524e3f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101000000000031534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11019e8601000000', + '6a04626c6f672863666338633134326661323336303566366336343765333437636262613261356633363064383937', }, { - value: 546, + value: 550, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - token: { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '99998', - isMintBaton: false, - entryIdx: 0, + '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', + spentBy: { + txid: '9da106f4f05ba358b91486c5a233db096a57f40fa8134fddcc3ad2121857e47a', + outIdx: 0, }, }, { - value: 2812202, + value: 132050, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - ], - lockTime: 0, - timeFirstSeen: 1732374561, - size: 470, - isCoinbase: false, - tokenEntries: [ - { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, + '76a914396addff64044d33431e0106b41c6903c7d0d28988ac', + spentBy: { + txid: '9da106f4f05ba358b91486c5a233db096a57f40fa8134fddcc3ad2121857e47a', + outIdx: 1, }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '1', - intentionalBurn: '1', - burnsMintBatons: false, }, ], + lockTime: 0, + timeFirstSeen: 1721543189, + size: 275, + isCoinbase: false, + tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 872299, - hash: '000000000000000022478fad1745dbd1c8f57ad77b6627ba459720c2653cd086', - timestamp: 1732375055, + height: 854224, + hash: '000000000000000017faf86eb0dc5a051ccc069b90c55653749311eca64c29e4', + timestamp: 1721543497, + }, + parsed: { + xecTxType: 'Sent', + satoshisSent: 132600, + stackArray: [ + '626c6f67', + '63666338633134326661323336303566366336343765333437636262613261356633363064383937', + ], + recipients: [], }, }, - sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', parsed: { - recipients: [], - satoshisSent: 2812748, + appActions: [ + { app: 'eCashChat Article', isValid: true, lokadId: '626c6f67' }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qquk4h0lvszy6v6rrcqsddqudypu05xj3yx7d0s32f'], + replyAddress: 'ecash:qquk4h0lvszy6v6rrcqsddqudypu05xj3yx7d0s32f', + satoshisSent: 0, stackArray: [ - '50', - '534c503200044255524e3f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11010000000000', - '534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e11019e8601000000', + '626c6f67', + '63666338633134326661323336303566366336343765333437636262613261356633363064383937', ], - xecTxType: 'Sent', + xecTxType: 'Received', }, - cache: [ - [ - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', +}; +export const offSpecEcashChatArticleTx = { + tx: { + ...eCashChatArticleTx.tx, + outputs: [ { - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - genesisInfo: { - tokenTicker: 'TB', - tokenName: 'Tiberium', - url: 'cashtab.com', - decimals: 0, - authPubkey: - '03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - }, - timeFirstSeen: 1732368999, - genesisSupply: '100000', - genesisOutputScripts: [ - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - ], - genesisMintBatons: 1, - block: { - height: 872286, - hash: '00000000000000000714f249ab1ecd41eef595260c4f9e79fa49e7dc1bd45767', - timestamp: 1732369043, - }, + ...eCashChatArticleTx.tx.outputs[0], + outputScript: '6a04626c6f67', // no data after the article lokad ID }, + ...eCashChatArticleTx.tx.outputs.slice(1), ], - ], + }, + parsed: { + appActions: [ + { app: 'eCashChat Article', isValid: false, lokadId: '626c6f67' }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qquk4h0lvszy6v6rrcqsddqudypu05xj3yx7d0s32f'], + replyAddress: 'ecash:qquk4h0lvszy6v6rrcqsddqudypu05xj3yx7d0s32f', + satoshisSent: 0, + stackArray: ['626c6f67'], + xecTxType: 'Received', + }, }; - -// cf7f6c07bd838dbc7f7b05f5f879d498789d087e6c76dde91fdedeb802230587 -export const alpAgoraListingTx = { +export const CashtabMsg = { tx: { - txid: 'cf7f6c07bd838dbc7f7b05f5f879d498789d087e6c76dde91fdedeb802230587', + txid: '1ce6c307b4083fcfc065287a00f0a582cf88bf33de34845db4c49387d4532b8a', version: 2, inputs: [ { prevOut: { - txid: '59a60227b112221130f11fd890100ba623944f8243cc8322e7f4c8fd17ab6ee2', - outIdx: 2, - }, - inputScript: - '41063618b40515cc62f4c2802f4f76ae729cfe31351f419634560bff37fbb8fa3dce1efb084e12a5e983beb893e945854470f409c1ec1c8c48b2baf7f5d80cb5e1412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, - sequenceNo: 4294967295, - token: { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '98082', - isMintBaton: false, - entryIdx: 0, - }, - outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - }, - { - prevOut: { - txid: 'cbded16a00885493d76e6534d932a58083f1918be220b8604897181c6b611609', + txid: '01d4b064a4e17f77e5712cb13b488e65d39b33b54475b78debee1fe1d9d9acb1', outIdx: 1, }, inputScript: - '41c143430106e44093436317fb23c3eb96e453ea500e47ea4d1952fdb917c4423abc52a51f0163e193704c6879fd0ff005423ae60ff4f75c7ff234cb6d45ef0391412103771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - value: 546, + '483045022100eccfc2e23d49fb7e72a35123c807f4feef2f379313673295f36611d725e877b002207b1df4c142c590a54d371fe2f04c05769ecf778e0d28fc50a671e5c5d8b277854121028c1fc90b3fa6e5be985032b061b5ca6db41a6878a9c8b442747b820ca74010db', + value: 3001592, sequenceNo: 4294967295, - token: { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '1024', - isMintBaton: false, - entryIdx: 0, - }, outputScript: - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', + '76a914e6309418b6e60b8119928ec45b8ba87de8e735f788ac', }, ], outputs: [ { value: 0, outputScript: - '6a504b41475230075041525449414c0001a4540000000000009006000000000000a4540000000000006f67825703771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba631534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101228301000000', + '6a04007461624cbe4d6572636920706f7572206c65207072697820657420626f6e6e6520636f6e74696e756174696f6e2064616e7320766f732070726f6a6574732064652064c3a976656c6f70706575722e2e2e204a27616920c3a974c3a92063656e737572c3a92073c3bb722074c3a96cc3a96772616d6d65206a7573717527617520313520417672696c20323032342e2052c3a97061726572206c6520627567206f6273657276c3a920737572206c6120706167652065546f6b656e204661756365743f', }, { - value: 546, - outputScript: 'a91410596364db3336ec723ce7eaa296e7fa7dbe070687', - plugins: { - agora: { - groups: [ - '5003771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - '54116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - '46116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - ], - data: [ - '5041525449414c', - '00', - '01', - 'a454000000000000', - '9006000000000000', - 'a454000000000000', - '6f678257', - ], - }, - }, - token: { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - amount: '99106', - isMintBaton: false, - entryIdx: 0, - }, - spentBy: { - txid: 'a6d65d619bbb03c4490498f7fe1d5413e92df064915a3533a09e8a4ba1762255', - outIdx: 1, - }, + value: 550, + outputScript: + '76a9143c28745097b1e32b343c50a8d4a7697fe7ad8aff88ac', }, - ], - lockTime: 0, - timeFirstSeen: 1732642801, - size: 461, - isCoinbase: false, - tokenEntries: [ { - tokenId: - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - txType: 'SEND', - isInvalid: false, - burnSummary: '', - failedColorings: [], - actualBurnAmount: '0', - intentionalBurn: '0', - burnsMintBatons: false, + value: 3000609, + outputScript: + '76a914e6309418b6e60b8119928ec45b8ba87de8e735f788ac', }, ], + lockTime: 0, + timeFirstSeen: 1712616513, + size: 433, + isCoinbase: false, + tokenEntries: [], tokenFailedParsings: [], - tokenStatus: 'TOKEN_STATUS_NORMAL', + tokenStatus: 'TOKEN_STATUS_NON_TOKEN', block: { - height: 872745, - hash: '000000000000000017dce1ee0a66873715acd1987aa18d018cc94e2943c2608b', - timestamp: 1732642958, + height: 839618, + hash: '00000000000000000e63e39951cc745db046aa7f57f811b68846ade8ad100293', + timestamp: 1712616969, }, }, - sendingHash: '95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d', + sendingHash: '3c28745097b1e32b343c50a8d4a7697fe7ad8aff', parsed: { - recipients: ['ecash:pqg9jcmymvendmrj8nn74g5kula8m0s8qce724yjtn'], - satoshisSent: 546, + appActions: [ + { + action: { + msg: "Merci pour le prix et bonne continuation dans vos projets de développeur... J'ai été censuré sûr télégramme jusqu'au 15 Avril 2024. Réparer le bug observé sur la page eToken Faucet?", + }, + app: 'Cashtab Msg', + isValid: true, + lokadId: '00746162', + }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qrnrp9qckmnqhqgej28vgkut4p773ee47u08xlygnr'], + replyAddress: 'ecash:qrnrp9qckmnqhqgej28vgkut4p773ee47u08xlygnr', + satoshisSent: 550, stackArray: [ - '50', - '41475230075041525449414c0001a4540000000000009006000000000000a4540000000000006f67825703771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - '534c5032000453454e443f93ce4cbff80c9cfc7647fe0c6d99b61248dce720a27f3723cd4737d35b6e1101228301000000', + '00746162', + '4d6572636920706f7572206c65207072697820657420626f6e6e6520636f6e74696e756174696f6e2064616e7320766f732070726f6a6574732064652064c3a976656c6f70706575722e2e2e204a27616920c3a974c3a92063656e737572c3a92073c3bb722074c3a96cc3a96772616d6d65206a7573717527617520313520417672696c20323032342e2052c3a97061726572206c6520627567206f6273657276c3a920737572206c6120706167652065546f6b656e204661756365743f', ], - xecTxType: 'Sent', + xecTxType: 'Received', }, - cache: [ - [ - '116e5bd33747cd23377fa220e7dc4812b6996d0cfe4776fc9c0cf8bf4cce933f', +}; +export const offSpecCashtabMsg = { + tx: { + ...CashtabMsg.tx, + outputs: [ { - tokenType: { - protocol: 'ALP', - type: 'ALP_TOKEN_TYPE_STANDARD', - number: 0, - }, - genesisInfo: { - tokenTicker: 'TB', - tokenName: 'Tiberium', - url: 'cashtab.com', - decimals: 0, - data: [], - authPubkey: - '03771805b54969a9bea4e3eb14a82851c67592156ddb5e52d3d53677d14a40fba6', - }, - timeFirstSeen: 1732368999, - genesisSupply: '100000', - genesisOutputScripts: [ - '76a91495e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d88ac', - ], - genesisMintBatons: 1, - block: { - height: 872286, - hash: '00000000000000000714f249ab1ecd41eef595260c4f9e79fa49e7dc1bd45767', - timestamp: 1732369043, - }, + ...CashtabMsg.tx.outputs[0], + outputScript: '6a0400746162', }, + ...CashtabMsg.tx.outputs.slice(1), ], - ], + }, + sendingHash: '3c28745097b1e32b343c50a8d4a7697fe7ad8aff', + parsed: { + appActions: [ + { app: 'Cashtab Msg', isValid: false, lokadId: '00746162' }, + ], + parsedTokenEntries: [], + recipients: ['ecash:qrnrp9qckmnqhqgej28vgkut4p773ee47u08xlygnr'], + replyAddress: 'ecash:qrnrp9qckmnqhqgej28vgkut4p773ee47u08xlygnr', + satoshisSent: 550, + stackArray: ['00746162'], + xecTxType: 'Received', + }, }; diff --git a/cashtab/src/chronik/fixtures/vectors.js b/cashtab/src/chronik/fixtures/vectors.js --- a/cashtab/src/chronik/fixtures/vectors.js +++ b/cashtab/src/chronik/fixtures/vectors.js @@ -11,11 +11,14 @@ incomingXec, outgoingXec, aliasRegistration, + invalidAliasRegistration, incomingEtoken, outgoingEtoken, genesisTx, incomingEtokenNineDecimals, legacyAirdropTx, + onSpecAirdropTxNoMsg, + offSpecAirdropTx, outgoingEncryptedMsg, incomingEncryptedMsg, tokenBurn, @@ -30,6 +33,8 @@ PayButtonYesDataNoNonce, MsgFromElectrum, MsgFromEcashChat, + offSpecEcashChat, + eCashChatAuthenticationTx, unknownAppTx, mockFlatTxHistoryNoUnconfirmed, mockSortedTxHistoryNoUnconfirmed, @@ -44,15 +49,26 @@ SlpParentGenesisTxMock, oneOutputReceivedTx, agoraAdSetupTxSlpNft, + agoraOneshotBuyTx, agoraOneshotSaleTx, AgoraOneshotCancelTx, agoraPartialCancelTx, agoraPartialBuxBuyTx, + agoraPartialBuxSellTx, agoraPartialCancelTwo, SlpNftParentMintTx, partialBuyBull, + partialSellBull, alpBurnTx, alpAgoraListingTx, + paywallPaymentTx, + offSpecPaywallPaymentTx, + eCashChatArticleTx, + offSpecEcashChatArticleTx, + eCashChatArticleReplyTx, + offSpecEcashChatArticleReplyTx, + CashtabMsg, + offSpecCashtabMsg, } from './mocks'; import { mockChronikUtxos, mockOrganizedUtxosByType } from './chronikUtxos'; import { getHashes } from 'wallet'; @@ -84,6 +100,12 @@ hashes: getHashes(mockAliasWallet), parsed: aliasRegistration.parsed, }, + { + description: 'Invalid alias registration', + tx: invalidAliasRegistration.tx, + hashes: getHashes(mockAliasWallet), + parsed: invalidAliasRegistration.parsed, + }, { description: 'Incoming eToken', tx: incomingEtoken.tx, @@ -114,6 +136,18 @@ hashes: getHashes(mockParseTxWalletAirdrop), parsed: legacyAirdropTx.parsed, }, + { + description: 'On spec airdrop tx no message', + tx: onSpecAirdropTxNoMsg.tx, + hashes: [onSpecAirdropTxNoMsg.sendingHash], + parsed: onSpecAirdropTxNoMsg.parsed, + }, + { + description: 'Off spec airdrop tx', + tx: offSpecAirdropTx.tx, + hashes: [offSpecAirdropTx.sendingHash], + parsed: offSpecAirdropTx.parsed, + }, { description: 'Outgoing encrypted msg (deprecated)', tx: outgoingEncryptedMsg.tx, @@ -168,12 +202,6 @@ hashes: ['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc'], parsed: PayButtonYesDataNoNonce.parsed, }, - { - description: 'PayButton tx with unsupported version number', - tx: PayButtonBadVersion.tx, - hashes: ['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc'], - parsed: PayButtonBadVersion.parsed, - }, { description: 'Paybutton tx that does not have spec number of pushes', @@ -181,6 +209,12 @@ hashes: ['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc'], parsed: PayButtonOffSpec.parsed, }, + { + description: 'PayButton tx with unsupported version number', + tx: PayButtonBadVersion.tx, + hashes: ['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc'], + parsed: PayButtonBadVersion.parsed, + }, { description: 'External msg received from Electrum', tx: MsgFromElectrum.tx, @@ -220,24 +254,36 @@ hashes: [SlpParentGenesisTxMock.tx.outputs[1].outputScript], parsed: SlpParentGenesisTxMock.parsed, }, + { + description: 'received xec tx with no change', + tx: oneOutputReceivedTx.tx, + hashes: ['601efc2aa406fe9eaedd41d2b5d95d1f4db9041d'], + parsed: oneOutputReceivedTx.parsed, + }, + { + description: 'eCash Chat authentication', + tx: eCashChatAuthenticationTx.tx, + hashes: [eCashChatAuthenticationTx.sendingHash], + parsed: eCashChatAuthenticationTx.parsed, + }, { description: 'External msg received from eCash Chat', tx: MsgFromEcashChat.tx, hashes: ['0b7d35fda03544a08e65464d54cfae4257eb6db7'], parsed: MsgFromEcashChat.parsed, }, + { + description: 'Off spec eCashChat', + tx: offSpecEcashChat.tx, + hashes: ['0b7d35fda03544a08e65464d54cfae4257eb6db7'], + parsed: offSpecEcashChat.parsed, + }, { description: 'slp v1 mint tx', tx: SlpV1Mint.tx, hashes: ['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d'], parsed: SlpV1Mint.parsed, }, - { - description: 'received xec tx with no change', - tx: oneOutputReceivedTx.tx, - hashes: ['601efc2aa406fe9eaedd41d2b5d95d1f4db9041d'], - parsed: oneOutputReceivedTx.parsed, - }, { description: 'SLP ad setup tx, NFT', tx: agoraAdSetupTxSlpNft.tx, @@ -247,27 +293,15 @@ }, { description: 'Agora one-shot buy', - tx: agoraOneshotSaleTx.tx, - hashes: ['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6'], - parsed: agoraOneshotSaleTx.parsed, + tx: agoraOneshotBuyTx.tx, + hashes: [agoraOneshotBuyTx.sendingHash], + parsed: agoraOneshotBuyTx.parsed, }, { description: 'Agora one-shot sale', tx: agoraOneshotSaleTx.tx, - hashes: ['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d'], - parsed: { - ...agoraOneshotSaleTx.parsed, - recipients: [ - 'ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj', - ], - xecTxType: 'Received', - }, - }, - { - description: 'Agora one-shot listing cancellation', - tx: AgoraOneshotCancelTx.tx, - hashes: ['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d'], - parsed: AgoraOneshotCancelTx.parsed, + hashes: [agoraOneshotSaleTx.sendingHash], + parsed: agoraOneshotSaleTx.parsed, }, { description: 'Agora partial listing cancellation', @@ -276,10 +310,16 @@ parsed: agoraPartialCancelTx.parsed, }, { - description: 'Buy 14 bux is rendered as buy 14', - tx: agoraPartialBuxBuyTx.tx, - hashes: ['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6'], - parsed: agoraPartialBuxBuyTx.parsed, + description: 'Another agora partial buy tx', + tx: partialBuyBull.tx, + hashes: [partialBuyBull.sendingHash], + parsed: partialBuyBull.parsed, + }, + { + description: 'Another agora partial sell tx', + tx: partialSellBull.tx, + hashes: [partialSellBull.sendingHash], + parsed: partialSellBull.parsed, }, { description: 'Another agora partial cancel', @@ -287,18 +327,30 @@ hashes: [agoraPartialCancelTwo.hash], parsed: agoraPartialCancelTwo.parsed, }, + { + description: 'Agora one-shot listing cancellation', + tx: AgoraOneshotCancelTx.tx, + hashes: ['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d'], + parsed: AgoraOneshotCancelTx.parsed, + }, + { + description: 'Buy 14 bux is rendered as buy 14', + tx: agoraPartialBuxBuyTx.tx, + hashes: [agoraPartialBuxBuyTx.sendingHash], + parsed: agoraPartialBuxBuyTx.parsed, + }, + { + description: 'Sell 14 bux is rendered as sell 14', + tx: agoraPartialBuxSellTx.tx, + hashes: [agoraPartialBuxSellTx.sendingHash], + parsed: agoraPartialBuxSellTx.parsed, + }, { description: 'SLP1 NFT Parent mint tx', tx: SlpNftParentMintTx.tx, hashes: [SlpNftParentMintTx.sendingHash], parsed: SlpNftParentMintTx.parsed, }, - { - description: 'Another agora partial buy tx', - tx: partialBuyBull.tx, - hashes: [partialBuyBull.sendingHash], - parsed: partialBuyBull.parsed, - }, { description: 'ALP burn tx', tx: alpBurnTx.tx, @@ -311,6 +363,54 @@ hashes: [alpAgoraListingTx.sendingHash], parsed: alpAgoraListingTx.parsed, }, + { + description: 'Paywall payment tx', + tx: paywallPaymentTx.tx, + hashes: [paywallPaymentTx.sendingHash], + parsed: paywallPaymentTx.parsed, + }, + { + description: 'Off spec paywall payment tx', + tx: offSpecPaywallPaymentTx.tx, + hashes: [paywallPaymentTx.sendingHash], + parsed: offSpecPaywallPaymentTx.parsed, + }, + { + description: 'eCashChat Article Reply', + tx: eCashChatArticleReplyTx.tx, + hashes: getHashes(mockParseTxWallet), + parsed: eCashChatArticleReplyTx.parsed, + }, + { + description: 'Off spec eCashChat Aricle Reply', + tx: offSpecEcashChatArticleReplyTx.tx, + hashes: getHashes(mockParseTxWallet), + parsed: offSpecEcashChatArticleReplyTx.parsed, + }, + { + description: 'eCashChat Article', + tx: eCashChatArticleTx.tx, + hashes: getHashes(mockParseTxWallet), + parsed: eCashChatArticleTx.parsed, + }, + { + description: 'off-spec eCashChat Article', + tx: offSpecEcashChatArticleTx.tx, + hashes: getHashes(mockParseTxWallet), + parsed: offSpecEcashChatArticleTx.parsed, + }, + { + description: 'Cashtab msg', + tx: CashtabMsg.tx, + hashes: [offSpecCashtabMsg.sendingHash], + parsed: CashtabMsg.parsed, + }, + { + description: 'Off spec Cashtab msg', + tx: offSpecCashtabMsg.tx, + hashes: [offSpecCashtabMsg.sendingHash], + parsed: offSpecCashtabMsg.parsed, + }, ], }, sortAndTrimChronikTxHistory: { diff --git a/cashtab/src/chronik/index.ts b/cashtab/src/chronik/index.ts --- a/cashtab/src/chronik/index.ts +++ b/cashtab/src/chronik/index.ts @@ -23,8 +23,14 @@ ScriptUtxo, Tx, BlockMetadata, + TokenTxType, } from 'chronik-client'; import { CashtabCachedTokenInfo } from 'config/CashtabCache'; +import appConfig from 'config/app'; +import { opReturn } from 'config/opreturn'; +import { scriptOps } from 'ecash-agora'; +import { Script, fromHex, OP_0 } from 'ecash-lib'; +import { getRenderedTokenType, RenderedTokenType } from 'token-protocols'; const CHRONIK_MAX_PAGE_SIZE = 200; @@ -244,92 +250,515 @@ Staking = 'Staking Reward', Coinbase = 'Coinbase Reward', } + +export enum ParsedTokenTxType { + AgoraOffer = 'Agora Offer', + AgoraCancel = 'Agora Cancel', + AgoraBuy = 'Agora Buy', + AgoraSale = 'Agora Sale', + FanOut = 'Fan Out', +} + +interface AliasAction { + alias: string; + address: string; +} +interface AirdropAction { + tokenId: string; + msg?: string; +} +interface PaybuttonAction { + data: string; + nonce: string; +} +interface EcashChatAction { + msg: string; +} +interface PaywallAction { + sharedArticleTxid: string; +} +interface EcashChatArticleReply { + replyArticleTxid: string; + msg: string; +} +interface CashtabMsgAction { + msg: string; +} +interface UnknownAction { + stack: string; + decoded: string; +} +interface AppAction { + lokadId: string; + app: string; + isValid?: boolean; + action?: + | AliasAction + | AirdropAction + | PaybuttonAction + | EcashChatAction + | PaywallAction + | EcashChatArticleReply + | CashtabMsgAction + | UnknownAction; +} + +/** + * Cashtab renders an action block for each token entry + * We get everything we need for the render in this function + * async and store in this interface so we keep rendering fast + */ +export interface ParsedTokenEntry { + /** + * tokenId for this token Entry + */ + tokenId: string; + /** + * See getRenderedTokenType in token-protocols + * Human-readable token type, i.e. "NFT" or "Collection" + */ + renderedTokenType: RenderedTokenType; + /** + * Same as txType from chronik-client, except we will + * occasionally overwrite SEND to be BURN if this + * token entry burns tokens + */ + renderedTxType: string; + /** + * The amount of tokenSatoshis associated with this tokenEntry + * e.g. the amount sent, or the amount minted, or the amount burned, + * or the amount purchased on agora, or the amount sold on agora + * + * Should be a bigint but jest can't stringify bigints, so we use a string + * simpler handling + */ + tokenSatoshis: string; + /** + * If this is a Collection token that is creating mint tokens, + * parse how many are created + */ + nftFanInputsCreated?: number; +} export interface ParsedTx { recipients: string[]; satoshisSent: number; stackArray: string[]; xecTxType: XecTxType; + appActions: AppAction[]; + replyAddress?: string; + /** + * Each token entry is associated with its own action, tokenId, token type, and quantity + * Same length as tokenEntries of this tx + */ + parsedTokenEntries: ParsedTokenEntry[]; } /** * Parse a Tx object for rendering in Cashtab - * TODO Potentially more efficient to do this calculation in the Tx.js component - * @param tx + * @param tx Tx object from chronik-client * @param hashes array of wallet hashes, one for each path */ export const parseTx = (tx: Tx, hashes: string[]): ParsedTx => { - const { inputs, outputs, isCoinbase } = tx; + const { inputs, outputs, isCoinbase, tokenEntries, txid } = tx; // Assign defaults let incoming = true; let stackArray = []; - // If it is not an incoming tx, make an educated guess about what addresses were sent to const destinationAddresses: Set<string> = new Set(); - // Iterate over inputs to see if this is an incoming tx (incoming === true) - for (const input of inputs) { - for (const hash of hashes) { - if ( + // Parse inputs for incoming/outgoing status + // Also parse for agora actions + for (const hash of hashes) { + // See if any of this txs inputs came from a hash in this wallet + const thisInputInThisWallet = inputs.find( + input => typeof input.outputScript !== 'undefined' && - input.outputScript.includes(hash) - ) { - // Then this is an outgoing tx - // Note: if the outputs also only send to inputs, then it is actually an incoming "self-send" tx - // For the purposes of rendering Cashtab tx history, self send txs are considered !incoming - incoming = false; + input.outputScript.includes(hash), + ); + if (typeof thisInputInThisWallet !== 'undefined') { + // If even one does, we call it an outgoing tx + incoming = false; + break; + } + } - // Break out of this for loop once you know this is (probably) an outgoing tx - break; + let isTokenTx = false; + let isAgoraCancel = false; + let isAgoraPurchase = false; + let isAgoraAdSetup = false; + let isAgoraOffer = false; + for (const input of inputs) { + if (typeof input.token !== 'undefined') { + // Flag if we have any token inputs for XecTxType assignment + isTokenTx = true; + // If this is a token tx, iterate over inputs for Agora info + try { + const { type } = cashaddr.getTypeAndHashFromOutputScript( + // we try..catch for this not existing + // not good practice but we are just implementing ts here now, refactor later + input.outputScript as string, + ); + if (type === 'p2sh') { + // Check if this is a cancellation + // See agora.ts from ecash-agora lib + // For now, I don't think it makes sense to have an 'isCanceled' method from ecash-agora + // This is a pretty specific application + const ops = scriptOps( + new Script(fromHex(input.inputScript)), + ); + // isCanceled is always the last pushop (before redeemScript) + const opIsCanceled = ops[ops.length - 2]; + + const isCanceled = opIsCanceled === OP_0; + + if (isCanceled) { + isAgoraCancel = true; + } else { + // We have a cashtab-created agora-offered input going to a Cashtab wallet + // Buy or sell depends on whether the XEC is sent or received + isAgoraPurchase = true; + } + } + } catch (err) { + console.error( + `Error in cashaddr.getTypeAndHashFromOutputScript(${input.outputScript}) from txid ${txid}`, + ); + // Do not parse it as an agora tx } + // We don't need to find any other inputs for this case + continue; } } - // Iterate over outputs to get the amount sent + // Parse outputs let change = 0; let outputSatoshis = 0; let receivedSatoshis = 0; - // A selfSendTx only sends to outputs in the wallet let selfSendTx = true; + for (const output of outputs) { const { outputScript, value } = output; - // outputSatoshis will have the total satoshis of all outputs outputSatoshis += value; if (outputScript.startsWith(opreturnConfig.opReturnPrefixHex)) { - // If this is an OP_RETURN output, get stackArray to store in parsed - // Note: we are assuming the tx only has one OP_RETURN output - // If it has more than one, then we will only parse the stackArray of the highest-index OP_RETURN - // For now, there is no need to handle the edge case of multiple OP_RETURNS in tx parsing stackArray = getStackArray(outputScript); - - // Continue to the next output, we do not parse value for OP_RETURN outputs continue; } - // Find amounts at your wallet's addresses let walletIncludesThisOutputScript = false; for (const hash of hashes) { if (outputScript.includes(hash)) { walletIncludesThisOutputScript = true; - // If incoming tx, this is amount received by the user's wallet - // if outgoing tx (incoming === false), then this is a change amount change += value; receivedSatoshis += value; } } if (!walletIncludesThisOutputScript) { - // See if this output script is a p2pkh or p2sh ecash address try { const destinationAddress = cashaddr.encodeOutputScript(outputScript); destinationAddresses.add(destinationAddress); } catch (err) { - // Do not render non-address recipients in tx history + // Skip non-address recipients } - - // If any output is at an outputScript that is not included in this wallet - // Then it is not a self-send tx selfSendTx = false; } } + + // Parse app action + const appActions = []; + if (stackArray.length !== 0) { + const lokadId = stackArray[0]; + switch (lokadId) { + case opReturn.appPrefixesHex.eToken: { + // slpv1 + // Do nothing, handle this in token actions + break; + } + case opReturn.opReserved: { + // EMPP + // For now, do nothing + // ALP will be parsed by tokenEntries below + // TODO parse EMPP app actions + break; + } + case opReturn.appPrefixesHex.aliasRegistration: { + const app = 'alias'; + // Magic numbers per spec + // https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/ecash-alias.md + if ( + stackArray[1] === '00' && + typeof stackArray[2] !== 'undefined' && + typeof stackArray[3] !== 'undefined' && + stackArray[3].length === 42 + ) { + const addressTypeByte = stackArray[3].slice(0, 2); + let addressType: 'p2pkh' | 'p2sh'; + if (addressTypeByte === '00') { + addressType = 'p2pkh'; + } else if (addressTypeByte === '08') { + addressType = 'p2sh'; + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + break; + } + const aliasAddress = cashaddr.encode( + 'ecash', + addressType, + stackArray[3].slice(1), + ); + appActions.push({ + app, + lokadId, + isValid: true, + action: { + alias: Buffer.from(stackArray[2], 'hex').toString( + 'utf8', + ), + address: aliasAddress, + }, + }); + break; + } + appActions.push({ app, lokadId, isValid: false }); + break; + } + case opReturn.appPrefixesHex.airdrop: { + const app = '🪂Airdrop'; + if ( + typeof stackArray[1] !== 'undefined' && + stackArray[1].length === 64 + ) { + // We have an on-spec airdrop tx if OP_RETURN prefix and tokenID at first push after prefix + const airdroppedTokenId = stackArray[1]; + let airdropMsg = ''; + if (typeof stackArray[2] !== 'undefined') { + // Legacy airdrop msg would be at [3] after cashtab msg prefix push + // on-spec airdrop msg would be at [2] + airdropMsg = + stackArray[2] === opReturn.appPrefixesHex.cashtab && + typeof stackArray[3] !== 'undefined' + ? Buffer.from(stackArray[3], 'hex').toString( + 'utf8', + ) + : Buffer.from(stackArray[2], 'hex').toString( + 'utf8', + ); + const airdropAction: AirdropAction = { + tokenId: airdroppedTokenId, + msg: airdropMsg, + }; + appActions.push({ + app, + lokadId, + isValid: true, + action: airdropAction, + }); + break; + } + const airdropAction: AirdropAction = { + tokenId: airdroppedTokenId, + }; + appActions.push({ + app, + lokadId, + isValid: true, + action: airdropAction, + }); + break; + } + appActions.push({ + app, + lokadId, + isValid: false, + }); + break; + } + case opReturn.appPrefixesHex.cashtabEncrypted: { + // Parsing is not supported but we do know the lokad + const app = 'Cashtab Encrypted (deprecated)'; + appActions.push({ app, lokadId }); + break; + } + case opReturn.appPrefixesHex.swap: { + // Parsing is not supported but we do know the lokad + const app = 'SWaP'; + appActions.push({ app, lokadId }); + break; + } + case opReturn.appPrefixesHex.paybutton: { + // PayButton tx + // https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/paybutton.md + const app = 'PayButton'; + if ( + stackArray[1] === '00' && + typeof stackArray[2] !== 'undefined' && + typeof stackArray[3] !== 'undefined' + ) { + // Valid PayButtonTx + appActions.push({ + lokadId, + app, + isValid: true, + action: { + data: + stackArray[2] !== '00' + ? Buffer.from( + stackArray[2], + 'hex', + ).toString('utf8') + : '', + nonce: stackArray[3] !== '00' ? stackArray[3] : '', + }, + }); + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + } + break; + } + case opReturn.appPrefixesHex.eCashChat: { + const app = 'eCashChat'; + if (typeof stackArray[1] !== 'undefined') { + appActions.push({ + app, + lokadId, + isValid: true, + action: { + msg: Buffer.from(stackArray[1], 'hex').toString( + 'utf8', + ), + }, + }); + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + } + break; + } + case opReturn.appPrefixesHex.paywallPayment: { + const app = 'Paywall'; + if (typeof stackArray[1] !== 'undefined') { + appActions.push({ + app, + lokadId, + isValid: true, + action: { sharedArticleTxid: stackArray[1] }, + }); + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + } + break; + } + // eCashChat authentication txs consists of authPrefixHex + a random string + // Other apps can use this same prefix followed by an authentication identifier of their choosing + case opReturn.appPrefixesHex.authPrefixHex: { + const app = 'Auth'; + appActions.push({ app, lokadId, isValid: true }); + break; + } + case opReturn.appPrefixesHex.eCashChatArticle: { + let app = 'eCashChat Article'; + if (typeof stackArray[1] !== 'undefined') { + // If this is a reply to a blog post then index 2 is txid of article and index 3 is the reply + if ( + stackArray[1] === + opReturn.appPrefixesHex.eCashChatArticleReply + ) { + app += ' Reply'; + if (stackArray.length === 4) { + appActions.push({ + app, + lokadId, + isValid: true, + action: { + replyArticleTxid: stackArray[2], + msg: Buffer.from( + stackArray[3], + 'hex', + ).toString('utf8'), + }, + }); + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + } + } else { + appActions.push({ + app, + lokadId, + isValid: true, + // Still no action for this type, we just know article created + }); + } + } else { + appActions.push({ + app, + lokadId, + isValid: false, + }); + } + break; + } + case opReturn.appPrefixesHex.cashtab: { + const app = 'Cashtab Msg'; + if (typeof stackArray[1] !== 'undefined') { + appActions.push({ + app, + lokadId, + isValid: true, + action: { + msg: Buffer.from(stackArray[1], 'hex').toString( + 'utf8', + ), + }, + }); + } else { + appActions.push({ app, lokadId, isValid: false }); + } + break; + } + default: { + // Test for some sort of lokad id + const LOKAD_BYTES_STR_LENGTH = 8; + const hasLokad = + stackArray[0].length === LOKAD_BYTES_STR_LENGTH; + const lokadId = hasLokad ? stackArray[0] : ''; + // Unsupported lokad prefixes or misc OP_RETURN msgs + // e.g. a msg sent by ElectrumABC + // Attempt to utf8 decode each push + const decodedTest = []; + for (const el of stackArray) { + decodedTest.push(Buffer.from(el, 'hex').toString('utf8')); + } + appActions.push({ + lokadId, + app: hasLokad ? 'unknown' : 'none', + action: { + stack: stackArray.join(' '), + decoded: decodedTest.join(' '), + }, + }); + break; + } + } + } + const satoshisSent = selfSendTx ? outputSatoshis : isCoinbase @@ -338,15 +767,62 @@ ? receivedSatoshis : outputSatoshis - change; - let xecTxType = incoming ? XecTxType.Received : XecTxType.Sent; + // Parse for an SLP 1 agora ad setup tx + // These are SLP1 SEND txs where + // 1. token utxo is > dust + // 2. recipient is p2sh address + const recipients = Array.from(destinationAddresses); + if (satoshisSent > appConfig.dustSats) { + if (recipients.length === 1) { + // Ad setup tx has 1 recipient + + // Ad setup tx has p2sh recipient + const listingScript = recipients[0]; + try { + const { type } = cashaddr.decode(listingScript, true); + isAgoraAdSetup = type === 'p2sh' && isTokenTx; + } catch (err) { + console.error( + `Error in cashaddr.decode(${listingScript}, true)`, + err, + ); + // No action, will be parsed as not AgoraAdSetup + } + } + } - // Parse for tx label + // Parse for ALP agora listing tx + if (!isAgoraAdSetup && !isAgoraCancel && !isAgoraPurchase) { + // If this is not already classified as agora + if ( + stackArray.length === 3 && + stackArray[0] === '50' && + stackArray[1].startsWith('41') && + stackArray[2].startsWith('534c5032') + ) { + // and this is an empp ALP and agora tx + if (recipients.length >= 1) { + try { + const { type } = cashaddr.decode(recipients[0], true); + if (type === 'p2sh') { + isAgoraOffer = true; + } + } catch (err) { + console.error( + `Error in cashaddr.decode(${recipients[0]}, true) while parsing for ALP listing tx`, + err, + ); + // No action, will be parsed as not AgoraOffer + } + } + } + } + + let xecTxType: XecTxType = incoming ? XecTxType.Received : XecTxType.Sent; + + // Parse for specific transaction types based on the original logic if (isCoinbase) { - // Note, staking rewards activated at blockheight 818670 - // For now, we assume Cashtab is parsing txs after this height - const STAKING_REWARDS_FACTOR = 0.1; // i.e. 10% - // In practice, the staking reward will almost always be the one that is exactly 10% of totalCoinbaseSats - // Use a STAKING_REWARDS_PADDING range to exclude miner and ifp outputs + const STAKING_REWARDS_FACTOR = 0.1; const STAKING_REWARDS_PADDING = 0.01; if ( satoshisSent >= @@ -362,17 +838,168 @@ ) { xecTxType = XecTxType.Staking; } else { - // We do not specifically parse for IFP reward vs miner reward xecTxType = XecTxType.Coinbase; } } - return { - xecTxType, + const parsedTokenEntries: ParsedTokenEntry[] = []; + for (const entry of tokenEntries) { + const { + tokenId, + tokenType, + txType, + burnSummary, + actualBurnAmount, + intentionalBurn, + } = entry; + + const renderedTokenType = getRenderedTokenType(tokenType); + let renderedTxType: TokenTxType | ParsedTokenTxType = txType; + + if (isAgoraAdSetup || isAgoraOffer) { + renderedTxType = ParsedTokenTxType.AgoraOffer; + } + if (isAgoraCancel) { + renderedTxType = ParsedTokenTxType.AgoraCancel; + } + + if (isAgoraPurchase) { + // If this wallet sent XEC in an agora purchase (incoming === false), it bought tokens + // If this wallet received XEC in an agora purchase, it sold tokens + renderedTxType = incoming + ? ParsedTokenTxType.AgoraSale + : ParsedTokenTxType.AgoraBuy; + } + + let isFanOutTx = false; + if (renderedTokenType === RenderedTokenType.COLLECTION) { + if (txType === 'SEND') { + // We assume collection txs that SEND are fan out txs, as this is the only + // type of SEND action Cashtab supports for this token + + isFanOutTx = true; + renderedTxType = ParsedTokenTxType.FanOut; + } + } + + const isUnintentionalBurn = + burnSummary !== '' && actualBurnAmount !== '0'; + const isIntentionalBurn = intentionalBurn !== '0'; + + let agoraSaleTokenSatoshis = 0n; + let tokenSatoshisTotal = 0n; + let tokenSatoshisReceived = 0n; // Received or change + let nftFanInputsCreated = 0; + for (const output of outputs) { + // Token output parsing + if (typeof output.token !== 'undefined') { + // Get the amount associated with this token entry + // Per ChronikClient, we will always have amount as a string in + // the token key of an output, see type Token + tokenSatoshisTotal += BigInt(output.token.amount); + + // For sales of agora partial txs, we assume the amount sold + // goes to a p2pkh address + if (renderedTxType === ParsedTokenTxType.AgoraSale) { + const { type } = cashaddr.getTypeAndHashFromOutputScript( + output.outputScript, + ); + if (type !== 'p2sh') { + agoraSaleTokenSatoshis += BigInt(output.token.amount); + } + } + for (const hash of hashes) { + if (output.outputScript.includes(hash)) { + tokenSatoshisReceived += BigInt(output.token.amount); + + if (output.token.amount === '1') { + // Note that we increment this for all qty 1 outputs we see + // But only tx of type fan input will use this var + nftFanInputsCreated += 1; + } + } + } + } + } + let tokenSatoshis = 0n; + // Determine the tokenSatoshis associated with this tokenEntry based on its type + switch (renderedTxType) { + case ParsedTokenTxType.AgoraSale: { + tokenSatoshis = agoraSaleTokenSatoshis; + break; + } + case ParsedTokenTxType.AgoraBuy: { + tokenSatoshis = tokenSatoshisReceived; + break; + } + case ParsedTokenTxType.AgoraCancel: { + tokenSatoshis = tokenSatoshisTotal; + break; + } + default: { + switch (txType) { + case 'MINT': + case 'GENESIS': { + tokenSatoshis = tokenSatoshisTotal; + break; + } + case 'SEND': { + tokenSatoshis = incoming + ? tokenSatoshisReceived + : tokenSatoshisTotal - tokenSatoshisReceived; + break; + } + case 'BURN': { + tokenSatoshis = BigInt(actualBurnAmount); + } + } + } + } + if (isUnintentionalBurn || isIntentionalBurn) { + // Overwrite txType of 'SEND' if tokens are burned + renderedTxType = 'BURN'; + // Maybe this is a SEND tx, but if it burns unintentionally, + // that is the more important info + tokenSatoshis = BigInt(actualBurnAmount); + } + const parsedTokenEntry: ParsedTokenEntry = { + tokenId, + renderedTxType, + renderedTokenType, + tokenSatoshis: tokenSatoshis.toString(), + }; + if (isFanOutTx) { + parsedTokenEntry.nftFanInputsCreated = nftFanInputsCreated; + } + parsedTokenEntries.push(parsedTokenEntry); + } + + let replyAddress: string | undefined; + if (xecTxType === XecTxType.Received) { + try { + replyAddress = cashaddr.encodeOutputScript( + inputs[0].outputScript as string, + ); + } catch (err) { + // Handle error + } + } + + const parsedTx: ParsedTx = { + recipients: Array.from(destinationAddresses), satoshisSent, stackArray, - recipients: Array.from(destinationAddresses), + xecTxType, + appActions, + parsedTokenEntries, }; + + // Add possibly undefined key if present + if (typeof replyAddress !== 'undefined') { + parsedTx.replyAddress = replyAddress; + } + + return parsedTx; }; /** diff --git a/cashtab/src/components/App/fixtures/mocks.ts b/cashtab/src/components/App/fixtures/mocks.ts --- a/cashtab/src/components/App/fixtures/mocks.ts +++ b/cashtab/src/components/App/fixtures/mocks.ts @@ -14,6 +14,7 @@ import { XecTxType } from 'chronik'; import { fromHex } from 'ecash-lib'; import * as wif from 'wif'; +import { RenderedTokenType } from 'token-protocols'; interface LegacyPathInfo_Pre_2_1_0 { publicKey: string; @@ -275,7 +276,9 @@ tokenFailedParsings: [], tokenStatus: 'TOKEN_STATUS_NORMAL', parsed: { - xecTxType: XecTxType.Received, + recipients: [ + 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', + ], satoshisSent: 546, stackArray: [ '534c5000', @@ -285,9 +288,19 @@ '0000000000000001', '0000000000000377', ], - recipients: [ - 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '3fee3384150b030490b7bee095a63900f66a45f2d8e3002ae2cf17ce3ef4d109', + renderedTxType: 'SEND', + renderedTokenType: 'SLP' as RenderedTokenType, + tokenSatoshis: '1', + }, ], + replyAddress: + 'ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6', }, }, { @@ -346,7 +359,9 @@ timestamp: 1698187386, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 553, stackArray: [ '2e786563', @@ -354,9 +369,20 @@ '6e6577746f6e', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'newton', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -415,7 +441,9 @@ timestamp: 1697463218, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 551, stackArray: [ '2e786563', @@ -423,9 +451,20 @@ '646f657374686973636c656172', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'doesthisclear', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -484,7 +523,9 @@ timestamp: 1697216026, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 551, stackArray: [ '2e786563', @@ -492,9 +533,20 @@ '776f726b736e6f77', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'worksnow', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -553,7 +605,9 @@ timestamp: 1697211295, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 554, stackArray: [ '2e786563', @@ -561,9 +615,20 @@ '7465737434', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'test4', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -622,7 +687,9 @@ timestamp: 1697211196, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 555, stackArray: [ '2e786563', @@ -630,9 +697,20 @@ '74657374', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'test', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -691,7 +769,9 @@ timestamp: 1697211196, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 555, stackArray: [ '2e786563', @@ -699,9 +779,20 @@ '74657374', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'test', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -760,7 +851,9 @@ timestamp: 1697025138, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 554, stackArray: [ '2e786563', @@ -768,9 +861,20 @@ '616c696173', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'alias', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -829,7 +933,9 @@ timestamp: 1697025138, }, parsed: { - xecTxType: XecTxType.Sent, + recipients: [ + 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + ], satoshisSent: 554, stackArray: [ '2e786563', @@ -837,9 +943,20 @@ '616c696173', '003a5fb236934ec078b4507c303d3afd82067f8fc1', ], - recipients: [ - 'ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07', + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'alias', + lokadId: '2e786563', + isValid: true, + action: { + alias: 'alias', + address: + 'ecash:qqp6t7erdy6wcputg5ruxq7n4lvzqelclsuupr75tv', + }, + }, ], + parsedTokenEntries: [], }, }, { @@ -897,12 +1014,23 @@ timestamp: 1696282475, }, parsed: { - xecTxType: XecTxType.Sent, - satoshisSent: 2200, - stackArray: ['00746162', '7374696c6c20776f726b73'], recipients: [ 'ecash:qphlhe78677sz227k83hrh542qeehh8el5lcjwk72y', ], + satoshisSent: 2200, + stackArray: ['00746162', '7374696c6c20776f726b73'], + xecTxType: 'Sent' as XecTxType, + appActions: [ + { + app: 'Cashtab Msg', + lokadId: '00746162', + isValid: true, + action: { + msg: 'still works', + }, + }, + ], + parsedTokenEntries: [], }, }, ], @@ -1467,13 +1595,28 @@ timestamp: 1707162498, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 1000000, + recipients: [ + 'ecash:qrfjv9kglpyazkdsyf0nd9nvewzagf0xsvv84u226e', + 'ecash:qphlhe78677sz227k83hrh542qeehh8el5lcjwk72y', + ], + satoshisSent: 0, stackArray: [ '00746162', '6865726520697320612043617368746162204d736720666f722075736520696e204361736874616220696e746567726174696f6e207465737473', ], - recipients: ['ecash:qphlhe78677sz227k83hrh542qeehh8el5lcjwk72y'], + xecTxType: 'Received' as XecTxType, + appActions: [ + { + app: 'Cashtab Msg', + lokadId: '00746162', + isValid: true, + action: { + msg: 'here is a Cashtab Msg for use in Cashtab integration tests', + }, + }, + ], + parsedTokenEntries: [], + replyAddress: 'ecash:qphlhe78677sz227k83hrh542qeehh8el5lcjwk72y', }, }, ]; diff --git a/cashtab/src/components/Common/CustomIcons.js b/cashtab/src/components/Common/CustomIcons.js --- a/cashtab/src/components/Common/CustomIcons.js +++ b/cashtab/src/components/Common/CustomIcons.js @@ -46,12 +46,12 @@ import { ReactComponent as MintNft } from 'assets/mintnft.svg'; import { ReactComponent as Nft } from 'assets/nft.svg'; import { ReactComponent as AgoraOffer } from 'assets/agora-offer.svg'; -import { ReactComponent as AgoraTx } from 'assets/agora-tx.svg'; import { ReactComponent as AgoraBuy } from 'assets/agora-buy.svg'; import { ReactComponent as AgoraSale } from 'assets/agora-sale.svg'; import { ReactComponent as AgoraCancel } from 'assets/agora-cancel.svg'; import { ReactComponent as Doge } from 'assets/doge.svg'; import { ReactComponent as CollapseDown } from 'assets/collapse-down.svg'; +import { ReactComponent as TokenSend } from 'assets/tokensend.svg'; import appConfig from 'config/app'; @@ -155,6 +155,7 @@ <CashtabEncrypted title="tx-encrypted-msg" /> ); export const TokenBurnIcon = () => <TokenBurn title="tx-token-burn" />; +export const TokenSendIcon = () => <TokenSend title="Token Send" />; export const PayButtonIcon = () => ( <PayButtonImg src={PayButton} alt="tx-paybutton" /> ); @@ -216,7 +217,6 @@ export const MintNftIcon = () => <MintNft title="Mint NFT" />; export const NftIcon = () => <Nft title="NFT" />; export const AgoraOfferIcon = () => <AgoraOffer title="Agora Offer" />; -export const AgoraTxIcon = () => <AgoraTx title="Agora Tx" />; export const AgoraBuyIcon = () => <AgoraBuy title="Agora Purchase" />; export const AgoraSaleIcon = () => <AgoraSale title="Agora Sale" />; export const AgoraCancelIcon = () => <AgoraCancel title="Agora Cancel" />; diff --git a/cashtab/src/components/Home/Home.tsx b/cashtab/src/components/Home/Home.tsx --- a/cashtab/src/components/Home/Home.tsx +++ b/cashtab/src/components/Home/Home.tsx @@ -11,7 +11,7 @@ import Receive from 'components/Receive/Receive'; import { Alert, Info } from 'components/Common/Atoms'; import { getUserLocale } from 'helpers'; -import { CashtabPathInfo, getHashes } from 'wallet'; +import { CashtabPathInfo, getHashes, CashtabTx } from 'wallet'; import PrimaryButton, { SecondaryButton, PrimaryLink, @@ -178,12 +178,36 @@ } }; + /** + * Type guard for latest CashtabTx[] type + * Prevents rendering tx history until wallet has loaded (or migrated) + * latest tx history + */ + const isValidParsedTxHistory = ( + parsedTxHistory: CashtabTx[], + ): parsedTxHistory is CashtabTx[] => { + if (Array.isArray(parsedTxHistory)) { + if (parsedTxHistory.length > 0) { + const testEntry = parsedTxHistory[0]; + // Migrated parsedTxHistory has appActions array in every tx + return Array.isArray(testEntry.parsed.appActions); + } + // Empty array is always valid + return true; + } + return false; + }; + return ( <> {apiError && <ApiError />} <TxHistoryCtn data-testid="tx-history"> <TxHistory - txs={Array.isArray(parsedTxHistory) ? parsedTxHistory : []} + txs={ + isValidParsedTxHistory(parsedTxHistory) + ? parsedTxHistory + : [] + } hashes={hashes} fiatPrice={fiatPrice} fiatCurrency={ diff --git a/cashtab/src/components/Home/Tx/__tests__/index.test.js b/cashtab/src/components/Home/Tx/__tests__/index.test.js --- a/cashtab/src/components/Home/Tx/__tests__/index.test.js +++ b/cashtab/src/components/Home/Tx/__tests__/index.test.js @@ -13,6 +13,7 @@ outgoingXec, stakingRwd, aliasRegistration, + invalidAliasRegistration, mockParseTxWallet, mockAliasWallet, incomingEtoken, @@ -21,6 +22,7 @@ incomingEtokenNineDecimals, legacyAirdropTx, onSpecAirdropTxNoMsg, + offSpecAirdropTx, outgoingEncryptedMsg, incomingEncryptedMsg, tokenBurn, @@ -33,11 +35,13 @@ PayButtonOffSpec, PayButtonBadVersion, MsgFromEcashChat, + offSpecEcashChat, SlpV1Mint, MsgFromElectrum, unknownAppTx, AlpTx, CashtabMsg, + offSpecCashtabMsg, mockParseTxWalletAirdrop, mockParseTxWalletEncryptedMsg, mockParseTxTokenCache, @@ -48,17 +52,23 @@ SlpParentGenesisTxMock, oneOutputReceivedTx, paywallPaymentTx, + offSpecPaywallPaymentTx, eCashChatArticleTx, + offSpecEcashChatArticleTx, eCashChatArticleReplyTx, + offSpecEcashChatArticleReplyTx, eCashChatAuthenticationTx, agoraAdSetupTxSlpNft, + agoraOneshotBuyTx, agoraOneshotSaleTx, AgoraOneshotCancelTx, agoraPartialCancelTwo, agoraPartialCancelTx, agoraPartialBuxBuyTx, + agoraPartialBuxSellTx, SlpNftParentMintTx, partialBuyBull, + partialSellBull, alpBurnTx, alpAgoraListingTx, } from 'chronik/fixtures/mocks'; @@ -66,6 +76,7 @@ import { MemoryRouter } from 'react-router-dom'; import { getHashes } from 'wallet'; import userEvent from '@testing-library/user-event'; +import { XecTxType } from 'chronik'; const AVALANCHE_FINALIZED_CHAINTIP = 800000; @@ -75,14 +86,12 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingXec.tx} - hashes={getHashes(mockParseTxWallet)} + tx={{ ...incomingXec.tx, parsed: incomingXec.parsed }} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={new CashtabState()} chaintipBlockheight={AVALANCHE_FINALIZED_CHAINTIP} /> - , </ThemeProvider> </MemoryRouter>, ); @@ -120,7 +129,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingXec.tx} + tx={{ ...incomingXec.tx, parsed: incomingXec.parsed }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -163,7 +172,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={oneOutputReceivedTx.tx} + tx={{ + ...oneOutputReceivedTx.tx, + parsed: oneOutputReceivedTx.parsed, + }} hashes={['601efc2aa406fe9eaedd41d2b5d95d1f4db9041d']} fiatPrice={0.00003} fiatCurrency="usd" @@ -206,7 +218,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={outgoingXec.tx} + tx={{ ...outgoingXec.tx, parsed: outgoingXec.parsed }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -238,7 +250,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={stakingRwd.tx} + tx={{ ...stakingRwd.tx, parsed: stakingRwd.parsed }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -271,7 +283,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={aliasRegistration.tx} + tx={{ + ...aliasRegistration.tx, + parsed: aliasRegistration.parsed, + }} hashes={getHashes(mockAliasWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -310,15 +325,8 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...aliasRegistration.tx, - outputs: [ - { - ...aliasRegistration.tx.outputs[0], - outputScript: - '6a042e786563010104627567321500dc1147663948f0dcfb00cc407eda41b121713ad3', - }, - ...aliasRegistration.tx.outputs.slice(1), - ], + ...invalidAliasRegistration.tx, + parsed: invalidAliasRegistration.parsed, }} hashes={getHashes(mockAliasWallet)} fiatPrice={0.00003} @@ -355,63 +363,15 @@ screen.getByText('Invalid alias registration'), ).toBeInTheDocument(); }); - it('Another invalid alias registration (v0)', async () => { + it('Received slpv1 fungible token', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx tx={{ - ...aliasRegistration.tx, - outputs: [ - { - ...aliasRegistration.tx.outputs[0], - outputScript: - '6a042e7865630d616e64616e6f746865726f6e65', - }, - ...aliasRegistration.tx.outputs.slice(1), - ], + ...incomingEtoken.tx, + parsed: incomingEtoken.parsed, }} - hashes={getHashes(mockAliasWallet)} - fiatPrice={0.00003} - fiatCurrency="usd" - cashtabState={new CashtabState()} - chaintipBlockheight={AVALANCHE_FINALIZED_CHAINTIP} - /> - , - </ThemeProvider> - </MemoryRouter>, - ); - - // We see the tx sent icon - expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); - - // We see the tx sent label - expect(screen.getByText(/Sent to/)).toBeInTheDocument(); - - // Coinbase txs have timeFirstSeen of 0 - // For a tx with timeFirstSeen of 0, we render the block timestamp - expect(screen.getByText('Oct 3, 2023, 12:14:36')).toBeInTheDocument(); - - // We see the formatted XEC amount - expect(screen.getByText('-5.55 XEC')).toBeInTheDocument(); - - // We see the formatted fiat amount - expect(screen.getByText('-$0.00')).toBeInTheDocument(); - - // Alias registration app action - // We see the alias registration icon - expect(screen.getByTitle('tx-alias-registration')).toBeInTheDocument(); - // We see the alias registration description - expect( - screen.getByText('Invalid alias registration'), - ).toBeInTheDocument(); - }); - it('Received slpv1 fungible token', async () => { - render( - <MemoryRouter> - <ThemeProvider theme={theme}> - <Tx - tx={incomingEtoken.tx} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -467,7 +427,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingEtoken.tx} + tx={{ + ...incomingEtoken.tx, + parsed: incomingEtoken.parsed, + }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -522,7 +485,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={outgoingEtoken.tx} + tx={{ + ...outgoingEtoken.tx, + parsed: outgoingEtoken.parsed, + }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -578,7 +544,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={outgoingEtoken.tx} + tx={{ + ...outgoingEtoken.tx, + parsed: outgoingEtoken.parsed, + }} hashes={getHashes(mockParseTxWallet)} fiatPrice={0.00003} fiatCurrency="usd" @@ -633,7 +602,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={genesisTx.tx} + tx={{ ...genesisTx.tx, parsed: genesisTx.parsed }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -690,7 +659,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={genesisTx.tx} + tx={{ ...genesisTx.tx, parsed: genesisTx.parsed }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -746,7 +715,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingEtokenNineDecimals.tx} + tx={{ + ...incomingEtokenNineDecimals.tx, + parsed: incomingEtokenNineDecimals.parsed, + }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -800,7 +772,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingEtokenNineDecimals.tx} + tx={{ + ...incomingEtokenNineDecimals.tx, + parsed: incomingEtokenNineDecimals.parsed, + }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -853,7 +828,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={legacyAirdropTx.tx} + tx={{ + ...legacyAirdropTx.tx, + parsed: legacyAirdropTx.parsed, + }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -910,7 +888,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={onSpecAirdropTxNoMsg.tx} + tx={{ + ...onSpecAirdropTxNoMsg.tx, + parsed: onSpecAirdropTxNoMsg.parsed, + }} hashes={['2a96944d06700882bbd984761d9c9e4215f2d78e']} fiatPrice={0.00003} fiatCurrency="usd" @@ -971,17 +952,10 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...onSpecAirdropTxNoMsg.tx, - outputs: [ - { - ...onSpecAirdropTxNoMsg.tx.outputs[0], - outputScript: - '6a0464726f701ffb4233e8a568993976ed38a81c2671587c5ad09552dedefa78760deed6ff87', - }, - ...onSpecAirdropTxNoMsg.tx.outputs.slice(1), - ], + ...offSpecAirdropTx.tx, + parsed: offSpecAirdropTx.parsed, }} - hashes={['2a96944d06700882bbd984761d9c9e4215f2d78e']} + hashes={[offSpecAirdropTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -1024,7 +998,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={outgoingEncryptedMsg.tx} + tx={{ + ...outgoingEncryptedMsg.tx, + parsed: outgoingEncryptedMsg.parsed, + }} hashes={getHashes(mockParseTxWalletEncryptedMsg)} fiatPrice={0.00003} fiatCurrency="usd" @@ -1058,14 +1035,19 @@ expect(screen.getByTitle('tx-encrypted-msg')).toBeInTheDocument(); // We see expected text msg - expect(screen.getByText('Encrypted Cashtab Msg')).toBeInTheDocument(); + expect( + screen.getByText('Cashtab Encrypted (deprecated)'), + ).toBeInTheDocument(); }); it('Received encrypted msg', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={incomingEncryptedMsg.tx} + tx={{ + ...incomingEncryptedMsg.tx, + parsed: incomingEncryptedMsg.parsed, + }} hashes={getHashes(mockParseTxWalletEncryptedMsg)} fiatPrice={0.00003} fiatCurrency="usd" @@ -1099,14 +1081,16 @@ expect(screen.getByTitle('tx-encrypted-msg')).toBeInTheDocument(); // We see expected text msg - expect(screen.getByText('Encrypted Cashtab Msg')).toBeInTheDocument(); + expect( + screen.getByText('Cashtab Encrypted (deprecated)'), + ).toBeInTheDocument(); }); it('Burn slpv1 fungible token', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={tokenBurn.tx} + tx={{ ...tokenBurn.tx, parsed: tokenBurn.parsed }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -1163,7 +1147,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={tokenBurn.tx} + tx={{ ...tokenBurn.tx, parsed: tokenBurn.parsed }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -1221,7 +1205,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={tokenBurnDecimals.tx} + tx={{ + ...tokenBurnDecimals.tx, + parsed: tokenBurnDecimals.parsed, + }} hashes={getHashes(mockParseTxWalletAirdrop)} fiatPrice={0.00003} fiatCurrency="usd" @@ -1282,7 +1269,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={swapTx.tx} + tx={{ ...swapTx.tx, parsed: swapTx.parsed }} hashes={['93472d56ba91581ed473225a765dd14a2db5d9d8']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1323,7 +1310,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonNoDataYesNonce.tx} + tx={{ + ...PayButtonNoDataYesNonce.tx, + parsed: PayButtonNoDataYesNonce.parsed, + }} hashes={['f66d2760b20dc7a47d9cf1a2b2f49749bf7093f6']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1364,7 +1354,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonYesDataYesNonce.tx} + tx={{ + ...PayButtonYesDataYesNonce.tx, + parsed: PayButtonYesDataYesNonce.parsed, + }} hashes={['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1408,7 +1401,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonEmpty.tx} + tx={{ + ...PayButtonEmpty.tx, + parsed: PayButtonEmpty.parsed, + }} hashes={['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1452,7 +1448,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonYesDataNoNonce.tx} + tx={{ + ...PayButtonYesDataNoNonce.tx, + parsed: PayButtonYesDataNoNonce.parsed, + }} hashes={['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1496,7 +1495,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonOffSpec.tx} + tx={{ + ...PayButtonOffSpec.tx, + parsed: PayButtonOffSpec.parsed, + }} hashes={['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1530,14 +1532,17 @@ expect(screen.getByAltText('tx-paybutton')).toBeInTheDocument(); // We see expected protocol label - expect(screen.getByText('(Invalid)')).toBeInTheDocument(); + expect(screen.getByText('Invalid PayButton')).toBeInTheDocument(); }); it('Unsupported version PayButton tx', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={PayButtonBadVersion.tx} + tx={{ + ...PayButtonBadVersion.tx, + parsed: PayButtonBadVersion.parsed, + }} hashes={['e628f12f1e911c9f20ec2eeb1847e3a2ffad5fcc']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1571,14 +1576,17 @@ expect(screen.getByAltText('tx-paybutton')).toBeInTheDocument(); // We see expected protocol label - expect(screen.getByText('(Invalid)')).toBeInTheDocument(); + expect(screen.getByText('Invalid PayButton')).toBeInTheDocument(); }); it('eCash chat tx', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={MsgFromEcashChat.tx} + tx={{ + ...MsgFromEcashChat.tx, + parsed: MsgFromEcashChat.parsed, + }} hashes={['0b7d35fda03544a08e65464d54cfae4257eb6db7']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1612,7 +1620,7 @@ expect(screen.getByTitle('tx-chat')).toBeInTheDocument(); // We see expected protocol label - expect(screen.getByText('eCash Chat')).toBeInTheDocument(); + expect(screen.getByText('eCashChat')).toBeInTheDocument(); // We see expected chat msg expect( @@ -1628,14 +1636,8 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...MsgFromEcashChat.tx, - outputs: [ - { - ...MsgFromEcashChat.tx.outputs[0], - outputScript: '6a0463686174', - }, - ...MsgFromEcashChat.tx.outputs.slice(1), - ], + ...offSpecEcashChat.tx, + parsed: offSpecEcashChat.parsed, }} hashes={['0b7d35fda03544a08e65464d54cfae4257eb6db7']} fiatPrice={0.00003} @@ -1670,14 +1672,14 @@ expect(screen.getByTitle('tx-chat')).toBeInTheDocument(); // We see expected protocol label - expect(screen.getByText('Invalid eCash Chat')).toBeInTheDocument(); + expect(screen.getByText('Invalid eCashChat')).toBeInTheDocument(); }); it('slpv1 fungible token MINT', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={SlpV1Mint.tx} + tx={{ ...SlpV1Mint.tx, parsed: SlpV1Mint.parsed }} hashes={['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1736,7 +1738,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={SlpV1Mint.tx} + tx={{ ...SlpV1Mint.tx, parsed: SlpV1Mint.parsed }} hashes={['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1792,7 +1794,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={MsgFromElectrum.tx} + tx={{ + ...MsgFromElectrum.tx, + parsed: MsgFromElectrum.parsed, + }} hashes={['4e532257c01b310b3b5c1fd947c79a72addf8523']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1841,7 +1846,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={unknownAppTx.tx} + tx={{ ...unknownAppTx.tx, parsed: unknownAppTx.parsed }} hashes={['d18b7b500f17c5db64303fec630f9dbb85aa9596']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1896,7 +1901,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={AlpTx.tx} + tx={{ ...AlpTx.tx, parsed: AlpTx.parsed }} hashes={['dee50f576362377dd2f031453c0bb09009acaf81']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1950,7 +1955,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={AlpTx.tx} + tx={{ ...AlpTx.tx, parsed: AlpTx.parsed }} hashes={['dee50f576362377dd2f031453c0bb09009acaf81']} fiatPrice={0.00003} fiatCurrency="usd" @@ -1979,6 +1984,9 @@ // We see the formatted fiat amount expect(screen.getByText('$0.00')).toBeInTheDocument(); + // We see expected Token Send action icon + expect(screen.getByTitle('Token Send')).toBeInTheDocument(); + // We see the token icon expect( screen.getByAltText( @@ -1997,7 +2005,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={CashtabMsg.tx} + tx={{ ...CashtabMsg.tx, parsed: CashtabMsg.parsed }} hashes={[CashtabMsg.tx.outputs[1].outputScript]} fiatPrice={0.00003} fiatCurrency="usd" @@ -2049,16 +2057,10 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...CashtabMsg.tx, - outputs: [ - { - ...CashtabMsg.tx.outputs[0], - outputScript: '6a0400746162', - }, - ...CashtabMsg.tx.outputs.slice(1), - ], + ...offSpecCashtabMsg.tx, + parsed: offSpecCashtabMsg.parsed, }} - hashes={[CashtabMsg.tx.outputs[1].outputScript]} + hashes={[offSpecCashtabMsg.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -2098,7 +2100,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={SlpNftParentFanTx.tx} + tx={{ + ...SlpNftParentFanTx.tx, + parsed: SlpNftParentFanTx.parsed, + }} hashes={[SlpNftParentFanTx.tx.outputs[1].outputScript]} fiatPrice={0.00003} fiatCurrency="usd" @@ -2137,8 +2142,8 @@ ), ).toBeInTheDocument(); - // Rendered token type for SLP1 NFT Parent is NFT Collection - expect(screen.getByText('NFT Collection')).toBeInTheDocument(); + // Rendered token type for SLP1 NFT Parent is Collection + expect(screen.getByText('Collection')).toBeInTheDocument(); // We see the token name expect( @@ -2163,7 +2168,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={SlpNftMint.tx} + tx={{ ...SlpNftMint.tx, parsed: SlpNftMint.parsed }} hashes={[SlpNftMint.tx.outputs[1].outputScript]} fiatPrice={0.00003} fiatCurrency="usd" @@ -2219,14 +2224,17 @@ // We see a second token action for burning the NFT Mint Input expect(screen.getByTitle('tx-token-burn')).toBeInTheDocument(); - expect(screen.getByText('Burned 1 NFT Mint Input')).toBeInTheDocument(); + expect(screen.getByText('Burned 1')).toBeInTheDocument(); }); it('Genesis tx of an SLP1 Parent Token (i.e. "Creating an NFT Collection")', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={SlpParentGenesisTxMock.tx} + tx={{ + ...SlpParentGenesisTxMock.tx, + parsed: SlpParentGenesisTxMock.parsed, + }} hashes={[ SlpParentGenesisTxMock.tx.outputs[1].outputScript, ]} @@ -2274,7 +2282,7 @@ expect(screen.getByText('GENESIS')).toBeInTheDocument(); // We see the token type - expect(screen.getAllByText('NFT Collection')[0]).toBeInTheDocument(); + expect(screen.getAllByText('Collection')[0]).toBeInTheDocument(); // We see the token name expect(screen.getByText('The Heisman')).toBeInTheDocument(); @@ -2290,7 +2298,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={paywallPaymentTx.tx} + tx={{ + ...paywallPaymentTx.tx, + parsed: paywallPaymentTx.parsed, + }} hashes={[paywallPaymentTx.tx.outputs[1].outputScript]} fiatPrice={0.00003} fiatCurrency="usd" @@ -2331,16 +2342,10 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...paywallPaymentTx.tx, - outputs: [ - { - ...paywallPaymentTx.tx.outputs[0], - outputScript: '6a0470617977', // no data after the paywall lokad ID - }, - ...paywallPaymentTx.tx.outputs.slice(1), - ], + ...offSpecPaywallPaymentTx.tx, + parsed: offSpecPaywallPaymentTx.parsed, }} - hashes={[paywallPaymentTx.tx.outputs[1].outputScript]} + hashes={[offSpecPaywallPaymentTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -2366,14 +2371,17 @@ expect(screen.getByText('-')).toBeInTheDocument(); // We see the invalid paywall tx description - expect(screen.getByText('Invalid Paywall Payment')).toBeInTheDocument(); + expect(screen.getByText('Invalid Paywall')).toBeInTheDocument(); }); it('Sent eCashChat article reply tx', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={eCashChatArticleReplyTx.tx} + tx={{ + ...eCashChatArticleReplyTx.tx, + parsed: eCashChatArticleReplyTx.parsed, + }} hashes={[ eCashChatArticleReplyTx.tx.outputs[2].outputScript, ]} @@ -2413,14 +2421,8 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...eCashChatArticleReplyTx.tx, - outputs: [ - { - ...eCashChatArticleReplyTx.tx.outputs[0], - outputScript: '6a04626c6f6704726c6f67', // no data after the article reply lokad ID i.e. stackArray !== 4 - }, - ...eCashChatArticleReplyTx.tx.outputs.slice(1), - ], + ...offSpecEcashChatArticleReplyTx.tx, + parsed: offSpecEcashChatArticleReplyTx.parsed, }} hashes={[ eCashChatArticleReplyTx.tx.outputs[2].outputScript, @@ -2448,7 +2450,7 @@ // We see the invalid article tx description expect( - screen.getByText('Invalid eCashChat Article Reply'), + screen.getByText('Invalid eCashChat Article'), ).toBeInTheDocument(); }); it('Sent eCashChat article tx', async () => { @@ -2456,7 +2458,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={eCashChatArticleTx.tx} + tx={{ + ...eCashChatArticleTx.tx, + parsed: eCashChatArticleTx.parsed, + }} hashes={[eCashChatArticleTx.tx.outputs[2].outputScript]} fiatPrice={0.00003} fiatCurrency="usd" @@ -2490,14 +2495,8 @@ <ThemeProvider theme={theme}> <Tx tx={{ - ...eCashChatArticleTx.tx, - outputs: [ - { - ...eCashChatArticleTx.tx.outputs[0], - outputScript: '6a04626c6f67', // no data after the article lokad ID - }, - ...eCashChatArticleTx.tx.outputs.slice(1), - ], + ...offSpecEcashChatArticleTx.tx, + parsed: offSpecEcashChatArticleTx.parsed, }} hashes={[eCashChatArticleTx.tx.outputs[2].outputScript]} fiatPrice={0.00003} @@ -2531,11 +2530,11 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={eCashChatAuthenticationTx.tx} - hashes={[ - eCashChatAuthenticationTx.tx.outputs[2] - .outputScript, - ]} + tx={{ + ...eCashChatAuthenticationTx.tx, + parsed: eCashChatAuthenticationTx.parsed, + }} + hashes={[eCashChatAuthenticationTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -2564,16 +2563,17 @@ expect(screen.getByText('-$0.00')).toBeInTheDocument(); // We see the article tx description - expect( - screen.getByText('eCash Chat Authentication'), - ).toBeInTheDocument(); + expect(screen.getByText('Auth')).toBeInTheDocument(); }); it('Ad setup tx for an SLP1 NFT Agora offer (cached)', async () => { render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraAdSetupTxSlpNft.tx} + tx={{ + ...agoraAdSetupTxSlpNft.tx, + parsed: agoraAdSetupTxSlpNft.parsed, + }} hashes={[ agoraAdSetupTxSlpNft.tx.inputs[0].outputScript, ]} @@ -2592,8 +2592,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -2634,7 +2634,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraAdSetupTxSlpNft.tx} + tx={{ + ...agoraAdSetupTxSlpNft.tx, + parsed: agoraAdSetupTxSlpNft.parsed, + }} hashes={[ agoraAdSetupTxSlpNft.tx.inputs[0].outputScript, ]} @@ -2650,8 +2653,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -2679,7 +2682,7 @@ expect(screen.getAllByText('NFT')[0]).toBeInTheDocument(); // We see SEND but not the token name (uncached) - expect(screen.getByText('SEND')).toBeInTheDocument(); + expect(screen.getByText('Agora Offer')).toBeInTheDocument(); // We do not see the token ticker in parenthesis in the summary column expect(screen.queryByText('(NK)')).not.toBeInTheDocument(); @@ -2692,11 +2695,11 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraOneshotSaleTx.tx} - // See mock - // Buy from this wallet - // You can't reference the usual 0 input outputScript bc it's an agora p2sh - hashes={['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6']} + tx={{ + ...agoraOneshotBuyTx.tx, + parsed: agoraOneshotBuyTx.parsed, + }} + hashes={[agoraOneshotBuyTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -2712,8 +2715,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -2754,11 +2757,11 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraOneshotSaleTx.tx} - // See mock - // Buy from this wallet - // You can't reference the usual 0 input outputScript bc it's an agora p2sh - hashes={['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6']} + tx={{ + ...agoraOneshotBuyTx.tx, + parsed: agoraOneshotBuyTx.parsed, + }} + hashes={[agoraOneshotBuyTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={new CashtabState()} @@ -2769,8 +2772,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -2802,11 +2805,14 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraOneshotSaleTx.tx} + tx={{ + ...agoraOneshotSaleTx.tx, + parsed: agoraOneshotSaleTx.parsed, + }} // See mock // Buy from this wallet // You can't reference the usual 0 input outputScript bc it's an agora p2sh - hashes={['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d']} + hashes={[agoraOneshotSaleTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -2822,8 +2828,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-received')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Received from/)).toBeInTheDocument(); @@ -2864,11 +2870,14 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraOneshotSaleTx.tx} + tx={{ + ...agoraOneshotSaleTx.tx, + parsed: agoraOneshotSaleTx.parsed, + }} // See mock // Buy from this wallet // You can't reference the usual 0 input outputScript bc it's an agora p2sh - hashes={['95e79f51d4260bc0dc3ba7fb77c7be92d0fbdd1d']} + hashes={[agoraOneshotSaleTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={new CashtabState()} @@ -2879,8 +2888,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-received')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Received from/)).toBeInTheDocument(); @@ -2912,7 +2921,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={AgoraOneshotCancelTx.tx} + tx={{ + ...AgoraOneshotCancelTx.tx, + parsed: AgoraOneshotCancelTx.parsed, + }} // See mock // Buy from this wallet // You can't reference the usual 0 input outputScript bc it's an agora p2sh @@ -2932,8 +2944,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); @@ -2971,7 +2983,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={AgoraOneshotCancelTx.tx} + tx={{ + ...AgoraOneshotCancelTx.tx, + parsed: AgoraOneshotCancelTx.parsed, + }} // See mock // Buy from this wallet // You can't reference the usual 0 input outputScript bc it's an agora p2sh @@ -2986,8 +3001,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); @@ -3017,7 +3032,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={['7847fe7070bec8567b3e810f543f2f80cc3e03be']} fiatPrice={0.00003} fiatCurrency="usd" @@ -3034,8 +3049,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); @@ -3082,7 +3097,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={['7847fe7070bec8567b3e810f543f2f80cc3e03be']} fiatPrice={0.00003} fiatCurrency="usd" @@ -3094,8 +3109,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); @@ -3110,7 +3125,7 @@ screen.getByAltText(`icon for ${thisMock.cache[0][0]}`), ).toBeInTheDocument(); - // We see the Agora Sale icon + // We see the Agora Cancel icon expect(screen.getByTitle('Agora Cancel')).toBeInTheDocument(); // We see the token type @@ -3121,7 +3136,10 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraPartialBuxBuyTx.tx} + tx={{ + ...agoraPartialBuxBuyTx.tx, + parsed: agoraPartialBuxBuyTx.parsed, + }} hashes={['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6']} fiatPrice={0.00003} fiatCurrency="usd" @@ -3138,8 +3156,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -3192,8 +3210,11 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraPartialBuxBuyTx.tx} - hashes={['76458db0ed96fe9863fc1ccec9fa2cfab884b0f6']} + tx={{ + ...agoraPartialBuxBuyTx.tx, + parsed: agoraPartialBuxBuyTx.parsed, + }} + hashes={[agoraPartialBuxBuyTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={new CashtabState()} @@ -3204,8 +3225,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -3232,20 +3253,24 @@ screen.getByAltText(`icon for ${agoraPartialBuxBuyTx.cache[0][0]}`), ).toBeInTheDocument(); - // We see the Agora Sale icon + // We see the Agora Purchase icon expect(screen.getByTitle('Agora Purchase')).toBeInTheDocument(); // We see the token type expect(screen.getAllByText('SLP')[0]).toBeInTheDocument(); }); it('Agora partial bux sell tx renders correct bought amount (token info available in cache)', async () => { + // TODO if this is supposed to be a sell tx, we need to make the SELL version of it with the right SELL hash in mocks render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={agoraPartialBuxBuyTx.tx} + tx={{ + ...agoraPartialBuxSellTx.tx, + parsed: agoraPartialBuxSellTx.parsed, + }} // the seller is paid at outputs[1] - hashes={['dee50f576362377dd2f031453c0bb09009acaf81']} + hashes={[agoraPartialBuxSellTx.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -3261,8 +3286,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-received')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Received from/)).toBeInTheDocument(); @@ -3308,17 +3333,16 @@ ).toBeInTheDocument(); }); it('Another agora partial sell tx renders correct sell amount (token info available in cache)', async () => { - const thisMock = partialBuyBull; + const thisMock = partialSellBull; render( <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} - hashes={[ - thisMock.sendingHash, - 'a9f494266e4b3c823712f27dedcb83e30b2fe59f', - '1fb76a7db96fc774cbad00e8a72890602b4be304', - ]} + tx={{ + ...thisMock.tx, + parsed: thisMock.parsed, + }} + hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" cashtabState={{ @@ -3334,8 +3358,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Received icon for the XEC action + expect(screen.getByTitle('tx-received')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Received from/)).toBeInTheDocument(); @@ -3384,7 +3408,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3401,8 +3425,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Self Send icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); @@ -3461,7 +3485,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3473,10 +3497,12 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Self Send icon for the XEC action + expect(screen.getByTitle('Self Send')).toBeInTheDocument(); // We see expected label + // Agora cancel txs are arguably XEC send + // But we are getting satoshis back from the p2sh we created earlier with a send expect(screen.getByText(/Sent to self/)).toBeInTheDocument(); // We render the timestamp @@ -3512,7 +3538,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3557,8 +3583,8 @@ screen.getByAltText(`icon for ${thisMock.cache[0][0]}`), ).toBeInTheDocument(); - // Rendered token type for SLP1 NFT Parent is NFT Collection - expect(screen.getByText('NFT Collection')).toBeInTheDocument(); + // Rendered token type for SLP1 NFT Parent is Collection + expect(screen.getByText('Collection')).toBeInTheDocument(); // We DO NOT see the Fan Out icon expect(screen.queryByTitle('Fan Out')).not.toBeInTheDocument(); @@ -3588,7 +3614,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3628,8 +3654,8 @@ screen.getByAltText(`icon for ${thisMock.cache[0][0]}`), ).toBeInTheDocument(); - // Rendered token type for SLP1 NFT Parent is NFT Collection - expect(screen.getByText('NFT Collection')).toBeInTheDocument(); + // Rendered token type for SLP1 NFT Parent is Collection + expect(screen.getByText('Collection')).toBeInTheDocument(); // We DO NOT see the Fan Out icon expect(screen.queryByTitle('Fan Out')).not.toBeInTheDocument(); @@ -3643,7 +3669,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3710,7 +3736,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3727,8 +3753,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see the Sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -3778,7 +3804,7 @@ <MemoryRouter> <ThemeProvider theme={theme}> <Tx - tx={thisMock.tx} + tx={{ ...thisMock.tx, parsed: thisMock.parsed }} hashes={[thisMock.sendingHash]} fiatPrice={0.00003} fiatCurrency="usd" @@ -3795,8 +3821,8 @@ </MemoryRouter>, ); - // We see the Agora Tx icon - expect(screen.getByTitle('Agora Tx')).toBeInTheDocument(); + // We see a conventional tx-sent icon for the XEC action + expect(screen.getByTitle('tx-sent')).toBeInTheDocument(); // We see expected label expect(screen.getByText(/Sent to/)).toBeInTheDocument(); @@ -3815,14 +3841,14 @@ screen.getByAltText(`icon for ${thisMock.cache[0][0]}`), ).toBeInTheDocument(); - // We see the Agora Offer icon + // We see the Agora Offer icon for the token action expect(screen.getByTitle('Agora Offer')).toBeInTheDocument(); // We see the token type expect(screen.getAllByText('ALP')[0]).toBeInTheDocument(); - // We see SEND but not the token name (uncached) - expect(screen.getByText('SEND')).toBeInTheDocument(); + // We see 'Agora Offer' as the rendered tx type but not the token name (uncached) + expect(screen.getByText('Agora Offer')).toBeInTheDocument(); // We do not see the token ticker in parenthesis in the summary column expect( diff --git a/cashtab/src/components/Home/Tx/index.tsx b/cashtab/src/components/Home/Tx/index.tsx --- a/cashtab/src/components/Home/Tx/index.tsx +++ b/cashtab/src/components/Home/Tx/index.tsx @@ -61,18 +61,18 @@ FanOutIcon, MintNftIcon, PaywallPaymentIcon, - AgoraTxIcon, AgoraOfferIcon, AgoraBuyIcon, AgoraSaleIcon, AgoraCancelIcon, + TokenSendIcon, } from 'components/Common/CustomIcons'; import CashtabSettings, { supportedFiatCurrencies, } from 'config/CashtabSettings'; import CopyToClipboard from 'components/Common/CopyToClipboard'; import { explorer } from 'config/explorer'; -import { parseTx, XecTxType } from 'chronik'; +import { ParsedTokenTxType } from 'chronik'; import { toFormattedXec, decimalizedTokenQtyToLocaleFormat, @@ -86,7 +86,6 @@ LegacyCashtabWallet, } from 'wallet'; import { opReturn } from 'config/opreturn'; -import cashaddr from 'ecashaddrjs'; import TokenIcon from 'components/Etokens/TokenIcon'; import Modal from 'components/Common/Modal'; import { ModalInput } from 'components/Common/Inputs'; @@ -94,31 +93,11 @@ import { getContactNameError } from 'validation'; import AvalancheFinalized from 'components/Common/AvalancheFinalized'; import { InlineLoader } from 'components/Common/Spinner'; -import { - SLP_1_PROTOCOL_NUMBER, - SLP_1_NFT_COLLECTION_PROTOCOL_NUMBER, - SLP_1_NFT_PROTOCOL_NUMBER, -} from 'token-protocols/slpv1'; import { CopyIconButton } from 'components/Common/Buttons'; -import appConfig from 'config/app'; -import { scriptOps } from 'ecash-agora'; -import { Script, fromHex, OP_0 } from 'ecash-lib'; import CashtabState, { CashtabContact } from 'config/CashtabState'; import CashtabCache from 'config/CashtabCache'; import { CashtabCacheJson, StoredCashtabWallet } from 'helpers'; -export type RenderedTxType = - | 'Created' - | 'Minted' - | 'Burned' - | 'Agora Cancel' - | 'Agora Offer' - | XecTxType - | 'Agora Buy' - | 'Agora Sale' - | 'GENESIS' - | 'SEND' - | 'Fan-out'; interface TxProps { tx: CashtabTx; hashes: string[]; @@ -141,7 +120,6 @@ } const Tx: React.FC<TxProps> = ({ tx, - hashes, fiatPrice, fiatCurrency, cashtabState, @@ -149,40 +127,25 @@ chaintipBlockheight, userLocale = 'en-US', }) => { - const { txid, timeFirstSeen, block, tokenEntries, inputs, outputs } = tx; - const { satoshisSent, xecTxType, stackArray, recipients } = parseTx( - tx, - hashes, - ); + const { txid, timeFirstSeen, block, parsed } = tx; + const { + satoshisSent, + xecTxType, + recipients, + appActions, + replyAddress, + parsedTokenEntries, + } = parsed; const { cashtabCache, contactList } = cashtabState; - let replyAddress: string | undefined, - replyAddressPreview: string | undefined, - knownSender: CashtabContact | undefined; - let isAgoraAdSetup = false; - let isAgoraCancel = false; - let isAgoraPurchase = false; + const replyAddressPreview = + typeof replyAddress !== 'undefined' + ? `${replyAddress.slice(6, 9)}...${replyAddress.slice(-3)}` + : undefined; - if (xecTxType === 'Received') { - // If Sent from Cashtab, then the sender will be the outputScript at the 0-index input - // If Received, we assume that it is "from" the outputScript of the 0-index input - // We only render these previews in history if this outputScript - // can be encoded as a p2sh or p2pkh address - try { - replyAddress = cashaddr.encodeOutputScript( - inputs[0].outputScript as string, - ); - replyAddressPreview = `${replyAddress.slice( - 6, - 9, - )}...${replyAddress.slice(-3)}`; - knownSender = contactList.find( - contact => contact.address === replyAddress, - ); - } catch (err) { - // Leave replyAddress as false so we do not try to render it - } - } + const knownSender = contactList.find( + contact => contact.address === replyAddress, + ); let knownRecipient, renderedRecipient, renderedOtherRecipients; if (xecTxType === 'Sent' && typeof recipients[0] !== 'undefined') { @@ -207,197 +170,136 @@ : ''; } - // Parse for app actions - // For now, these are broadly of two types - // token actions, which are summarized in the tokenEntries key of tx - // app actions, which are OP_RETURN txs that may or may not follow spec - // https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/op_return-prefix-guideline.md - // With EMPP, a single TX may have several app actions - // For now, we parse only token actions and non-EMPP OP_RETURN - // TODO parse EMPP - - const appActions = []; - if (stackArray.length !== 0) { - // If we have an OP_RETURN output - switch (stackArray[0]) { - case opReturn.appPrefixesHex.eToken: { - // slpv1 - // Do nothing, handle this in token actions - break; - } - case opReturn.opReserved: { - // EMPP - // For now, do nothing - // ALP will be parsed by tokenEntries below - // TODO parse EMPP app actions - break; - } + const renderedAppActions: React.ReactNode[] = []; + for (const appAction of appActions) { + const { lokadId, app, isValid, action } = appAction; + switch (lokadId) { case opReturn.appPrefixesHex.aliasRegistration: { - // Magic numbers per spec - // https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/ecash-alias.md - if ( - stackArray[1] === '00' && - typeof stackArray[2] !== 'undefined' && - typeof stackArray[3] !== 'undefined' && - stackArray[3].length === 42 - ) { - const addressTypeByte = stackArray[3].slice(0, 2); - let addressType: 'p2pkh' | 'p2sh'; - if (addressTypeByte === '00') { - addressType = 'p2pkh'; - } else if (addressTypeByte === '08') { - addressType = 'p2sh'; - } else { - appActions.push( - <IconAndLabel> - <AliasIconTx /> - <AppDescLabel> - Invalid alias registration - </AppDescLabel> - </IconAndLabel>, + if (!isValid) { + renderedAppActions.push( + <IconAndLabel> + <AliasIconTx /> + <AppDescLabel> + Invalid alias registration + </AppDescLabel> + </IconAndLabel>, + ); + } else { + if (typeof action !== 'undefined' && 'alias' in action) { + // Type guard, we know that all valid aliases will have this action + // from the parseTx function + const { alias, address } = action; + const aliasAddrPreview = `${address.slice( + 6, + 9, + )}...${address.slice(-3)}`; + renderedAppActions.push( + <> + <IconAndLabel> + <AliasIconTx /> + <AppDescLabel> + Alias Registration + </AppDescLabel> + </IconAndLabel> + <AppDescMsg> + {`${alias} to ${aliasAddrPreview}`} + </AppDescMsg> + </>, ); - break; } - const aliasAddress = cashaddr.encode( - 'ecash', - addressType, - stackArray[3].slice(1), - ); - const aliasAddrPreview = `${aliasAddress.slice( - 6, - 9, - )}...${aliasAddress.slice(-3)}`; - appActions.push( - <> - <IconAndLabel> - <AliasIconTx /> - <AppDescLabel>Alias Registration</AppDescLabel> - </IconAndLabel> - <AppDescMsg> - {`${Buffer.from(stackArray[2], 'hex').toString( - 'utf8', - )} to ${aliasAddrPreview}`} - </AppDescMsg> - </>, - ); - break; } - appActions.push( - <IconAndLabel> - <AliasIconTx /> - <AppDescLabel>Invalid alias registration</AppDescLabel> - </IconAndLabel>, - ); break; } case opReturn.appPrefixesHex.airdrop: { - if ( - typeof stackArray[1] !== 'undefined' && - stackArray[1].length === 64 - ) { - // We have an on-spec airdrop tx if OP_RETURN prefix and tokenID at first push after prefix - const airdroppedTokenId = stackArray[1]; - let airdropMsg = ''; - if (typeof stackArray[2] !== 'undefined') { - // Legacy airdrop msg would be at [3] after cashtab msg prefix push - // on-spec airdrop msg would be at [2] - airdropMsg = - stackArray[2] === opReturn.appPrefixesHex.cashtab && - typeof stackArray[3] !== 'undefined' - ? Buffer.from(stackArray[3], 'hex').toString( - 'utf8', - ) - : Buffer.from(stackArray[2], 'hex').toString( - 'utf8', - ); - } - // Add token info if we have it in cache - const airdroppedTokenInfo = - cashtabCache.tokens.get(airdroppedTokenId); - if (typeof airdroppedTokenInfo !== 'undefined') { - const { genesisInfo, tokenType } = airdroppedTokenInfo; - const { tokenName, tokenTicker } = genesisInfo; - const { protocol, number } = tokenType; - const parsedTokenType = `${protocol}${ - protocol !== 'ALP' ? ` ${number}` : '' - }`; - appActions.push( + if (!isValid) { + renderedAppActions.push( + <IconAndLabel> + <AirdropIcon /> + <AppDescLabel> + Off-spec airdrop: tokenId unavailable + </AppDescLabel> + </IconAndLabel>, + ); + } else { + if (typeof action !== 'undefined' && 'tokenId' in action) { + const { tokenId, msg } = action; + // Add token info if we have it in cache + const airdroppedTokenInfo = + cashtabCache.tokens.get(tokenId); + if (typeof airdroppedTokenInfo !== 'undefined') { + const { genesisInfo, tokenType } = + airdroppedTokenInfo; + const { tokenName, tokenTicker } = genesisInfo; + const { protocol, number } = tokenType; + const parsedTokenType = `${protocol}${ + protocol !== 'ALP' ? ` ${number}` : '' + }`; + renderedAppActions.push( + <> + <IconAndLabel> + <AirdropIcon /> + <AppDescLabel> + Airdrop (XEC) + </AppDescLabel> + </IconAndLabel> + <TokenIcon size={32} tokenId={tokenId} /> + <TokenInfoCol> + <TokenType>{parsedTokenType}</TokenType> + <TokenName> + <ActionLink + href={`${explorer.blockExplorerUrl}/tx/${tokenId}`} + target="_blank" + rel="noreferrer" + > + {tokenName} + </ActionLink> + </TokenName> + <TokenTicker> + ({tokenTicker}) + </TokenTicker> + </TokenInfoCol> + {typeof msg !== 'undefined' && ( + <AppDescMsg>{msg}</AppDescMsg> + )} + </>, + ); + break; + } + // If we do not have token info + renderedAppActions.push( <> <IconAndLabel> <AirdropIcon /> - <AppDescLabel>Airdrop (XEC)</AppDescLabel> - </IconAndLabel> - <TokenIcon - size={32} - tokenId={airdroppedTokenId} - /> - <TokenInfoCol> - <TokenType>{parsedTokenType}</TokenType> - <TokenName> + <AppDescLabel> + Airdrop to holders of{' '} <ActionLink - href={`${explorer.blockExplorerUrl}/tx/${airdroppedTokenId}`} + href={`${explorer.blockExplorerUrl}/tx/${tokenId}`} target="_blank" rel="noreferrer" > - {tokenName} + {`${tokenId.slice( + 0, + 3, + )}...${tokenId.slice(-3)}`} </ActionLink> - </TokenName> - <TokenTicker>({tokenTicker})</TokenTicker> - </TokenInfoCol> - {airdropMsg !== '' && ( - <AppDescMsg>{airdropMsg}</AppDescMsg> + </AppDescLabel> + </IconAndLabel> + <TokenIcon size={32} tokenId={tokenId} /> + {typeof msg !== 'undefined' && ( + <AppDescMsg>{msg}</AppDescMsg> )} </>, ); - break; } - appActions.push( - <> - <IconAndLabel> - <AirdropIcon /> - <AppDescLabel> - Airdrop to holders of{' '} - <ActionLink - href={`${explorer.blockExplorerUrl}/tx/${airdroppedTokenId}`} - target="_blank" - rel="noreferrer" - > - {`${airdroppedTokenId.slice( - 0, - 3, - )}...${airdroppedTokenId.slice(-3)}`} - </ActionLink> - </AppDescLabel> - </IconAndLabel> - <TokenIcon size={32} tokenId={airdroppedTokenId} /> - {airdropMsg !== '' && ( - <AppDescMsg>{airdropMsg}</AppDescMsg> - )} - </>, - ); - break; } - // off-spec airdrop - appActions.push( - <> - <IconAndLabel> - <AirdropIcon /> - <AppDescLabel> - Off-spec airdrop: tokenId unavailable - </AppDescLabel> - </IconAndLabel> - </>, - ); break; } case opReturn.appPrefixesHex.cashtabEncrypted: { - // Deprecated, we do not parse - // Just render the lokad - // <lokad> <encrypted utf8> - appActions.push( + // Deprecated, just print the app + renderedAppActions.push( <IconAndLabel> <EncryptedMsgIcon /> - <AppDescLabel>Encrypted Cashtab Msg</AppDescLabel> + <AppDescLabel>{app}</AppDescLabel> </IconAndLabel>, ); break; @@ -405,601 +307,438 @@ case opReturn.appPrefixesHex.swap: { // Limited parse support for SWaP txs, which are not expected in Cashtab // Just print the type - appActions.push( + renderedAppActions.push( <IconAndLabel> <SwapIcon /> - <AppDescLabel>SWaP</AppDescLabel> + <AppDescLabel>{app}</AppDescLabel> </IconAndLabel>, ); break; } case opReturn.appPrefixesHex.paybutton: { - // PayButton tx - // https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/paybutton.md - if ( - stackArray[1] === '00' && - typeof stackArray[2] !== 'undefined' && - typeof stackArray[3] !== 'undefined' - ) { - // Valid PayButtonTx - appActions.push( - <> - <IconAndLabel> - <PayButtonIcon /> - </IconAndLabel> - {stackArray[2] !== '00' && ( - <AppDescMsg> - {Buffer.from(stackArray[2], 'hex').toString( - 'utf8', - )} - </AppDescMsg> - )} - {stackArray[3] !== '00' && ( - <AppDescMsg>{stackArray[3]}</AppDescMsg> - )} - </>, - ); - } else { - appActions.push( + if (!isValid) { + renderedAppActions.push( <IconAndLabel> <PayButtonIcon /> - <AppDescLabel>(Invalid)</AppDescLabel> + <AppDescLabel>Invalid {app}</AppDescLabel> </IconAndLabel>, ); + } else { + if (typeof action !== 'undefined' && 'data' in action) { + const { data, nonce } = action; + // Valid PayButtonTx + renderedAppActions.push( + <> + <IconAndLabel> + <PayButtonIcon /> + </IconAndLabel> + {data !== '' && <AppDescMsg>{data}</AppDescMsg>} + {nonce !== '' && ( + <AppDescMsg>{nonce}</AppDescMsg> + )} + </>, + ); + } } break; } case opReturn.appPrefixesHex.eCashChat: { - if (typeof stackArray[1] !== 'undefined') { - appActions.push( - <> - <IconAndLabel> - <ChatIcon /> - <AppDescLabel>eCash Chat</AppDescLabel> - </IconAndLabel> - <AppDescMsg> - {Buffer.from(stackArray[1], 'hex').toString( - 'utf8', - )} - </AppDescMsg> - </>, - ); - } else { - appActions.push( + if (!isValid) { + renderedAppActions.push( <IconAndLabel> <ChatIcon /> - <AppDescLabel>Invalid eCash Chat</AppDescLabel> + <AppDescLabel>Invalid {app}</AppDescLabel> </IconAndLabel>, ); + } else { + if (typeof action !== 'undefined' && 'msg' in action) { + const { msg } = action; + renderedAppActions.push( + <> + <IconAndLabel> + <ChatIcon /> + <AppDescLabel>{app}</AppDescLabel> + </IconAndLabel> + <AppDescMsg>{msg}</AppDescMsg> + </>, + ); + } } break; } case opReturn.appPrefixesHex.paywallPayment: { - if (typeof stackArray[1] !== 'undefined') { - appActions.push( - <> - <IconAndLabel> - <PaywallPaymentIcon /> - <AppDescLabel>Paywall Payment</AppDescLabel> - </IconAndLabel> - <AppDescMsg> - <a - href={`https://www.ecashchat.com/?sharedArticleTxid=${stackArray[1]}`} - target="_blank" - rel="noreferrer" - > - Paywall Article - </a> - </AppDescMsg> - </>, - ); - } else { - appActions.push( + if (!isValid) { + renderedAppActions.push( <IconAndLabel> <PaywallPaymentIcon /> - <AppDescLabel>Invalid Paywall Payment</AppDescLabel> + <AppDescLabel>Invalid {app}</AppDescLabel> </IconAndLabel>, ); + } else { + if ( + typeof action !== 'undefined' && + 'sharedArticleTxid' in action + ) { + const { sharedArticleTxid } = action; + renderedAppActions.push( + <> + <IconAndLabel> + <PaywallPaymentIcon /> + <AppDescLabel>{app}</AppDescLabel> + </IconAndLabel> + <AppDescMsg> + <a + href={`https://www.ecashchat.com/?sharedArticleTxid=${sharedArticleTxid}`} + target="_blank" + rel="noreferrer" + > + Paywall Article + </a> + </AppDescMsg> + </>, + ); + } } break; } - // eCashChat authentication txs consists of authPrefixHex + a random string - // Other apps can use this same prefix followed by an authentication identifier of their choosing case opReturn.appPrefixesHex.authPrefixHex: { - appActions.push( - <> - <IconAndLabel> - <ChatIcon /> - <AppDescLabel> - eCash Chat Authentication - </AppDescLabel> - </IconAndLabel> - </>, + // If it has the lokad, it's valid + renderedAppActions.push( + <IconAndLabel> + <ChatIcon /> + <AppDescLabel>{app}</AppDescLabel> + </IconAndLabel>, ); break; } case opReturn.appPrefixesHex.eCashChatArticle: { - if (typeof stackArray[1] !== 'undefined') { - // If this is a reply to a blog post then index 2 is txid of article and index 3 is the reply + if (!isValid) { + renderedAppActions.push( + <IconAndLabel> + <ChatIcon /> + <AppDescLabel> + Invalid eCashChat Article + </AppDescLabel> + </IconAndLabel>, + ); + } else { if ( - stackArray[1] === - opReturn.appPrefixesHex.eCashChatArticleReply + typeof action !== 'undefined' && + 'replyArticleTxid' in action ) { - if (stackArray.length === 4) { - appActions.push( - <> - <IconAndLabel> - <ChatIcon /> - <AppDescLabel> - eCash Chat - Reply to - <a - href={`https://www.ecashchat.com/?sharedArticleTxid=${stackArray[2]}`} - target="_blank" - rel="noreferrer" - > - article - </a> - </AppDescLabel> - </IconAndLabel> - <AppDescMsg> - {Buffer.from( - stackArray[3], - 'hex', - ).toString('utf8')} - </AppDescMsg> - </>, - ); - } else { - appActions.push( - <IconAndLabel> - <ChatIcon /> - <AppDescLabel> - Invalid eCashChat Article Reply - </AppDescLabel> - </IconAndLabel>, - ); - } - } else { - appActions.push( + const { replyArticleTxid, msg } = action; + renderedAppActions.push( <> <IconAndLabel> <ChatIcon /> <AppDescLabel> - eCash Chat article created + eCash Chat - Reply to + <a + href={`https://www.ecashchat.com/?sharedArticleTxid=${replyArticleTxid}`} + target="_blank" + rel="noreferrer" + > + article + </a> </AppDescLabel> </IconAndLabel> + <AppDescMsg>{msg}</AppDescMsg> </>, ); + } else { + renderedAppActions.push( + <IconAndLabel> + <ChatIcon /> + <AppDescLabel> + eCash Chat article created + </AppDescLabel> + </IconAndLabel>, + ); } - } else { - appActions.push( + } + break; + } + case opReturn.appPrefixesHex.cashtab: { + if (!isValid) { + renderedAppActions.push( <IconAndLabel> - <ChatIcon /> - <AppDescLabel> - Invalid eCashChat Article - </AppDescLabel> + <CashtabMsgIcon /> + <AppDescLabel>Invalid Cashtab Msg</AppDescLabel> </IconAndLabel>, ); + } else { + if (typeof action !== 'undefined' && 'msg' in action) { + const { msg } = action; + renderedAppActions.push( + <> + <IconAndLabel> + <CashtabMsgIcon /> + <AppDescLabel>Cashtab Msg</AppDescLabel> + </IconAndLabel> + <AppDescMsg>{msg}</AppDescMsg> + {xecTxType === 'Received' && + typeof replyAddress !== 'undefined' && ( + <ReplyLink + to="/send" + state={{ + replyAddress: replyAddress, + }} + > + <ReplyIcon /> + </ReplyLink> + )} + </>, + ); + } } break; } - case opReturn.appPrefixesHex.cashtab: { - if (typeof stackArray[1] !== 'undefined') { - appActions.push( + case 'unknown': { + if (typeof action !== 'undefined' && 'decoded' in action) { + const { stack, decoded } = action; + renderedAppActions.push( <> <IconAndLabel> - <CashtabMsgIcon /> - <AppDescLabel>Cashtab Msg</AppDescLabel> + <UnknownIcon /> + <AppDescLabel> + Unknown LokadId {lokadId} + </AppDescLabel> </IconAndLabel> - <AppDescMsg> - {Buffer.from(stackArray[1], 'hex').toString( - 'utf8', - )} - </AppDescMsg> - {xecTxType === 'Received' && - typeof replyAddress !== 'undefined' && ( - <ReplyLink - to="/send" - state={{ - replyAddress: replyAddress, - }} - > - <ReplyIcon /> - </ReplyLink> - )} + <UnknownMsgColumn> + <AppDescMsg>{stack}</AppDescMsg> + <AppDescMsg>{decoded}</AppDescMsg> + </UnknownMsgColumn> </>, ); - } else { - appActions.push( + } + break; + } + default: { + if (typeof action !== 'undefined' && 'decoded' in action) { + const { stack, decoded } = action; + renderedAppActions.push( <> <IconAndLabel> - <CashtabMsgIcon /> - <AppDescLabel>Invalid Cashtab Msg</AppDescLabel> + <UnknownIcon /> + <AppDescLabel>Unknown App</AppDescLabel> </IconAndLabel> + <UnknownMsgColumn> + <AppDescMsg>{stack}</AppDescMsg> + <AppDescMsg>{decoded}</AppDescMsg> + </UnknownMsgColumn> </>, ); - } - break; - } - default: { - // Unsupported lokad prefixes or misc OP_RETURN msgs - // e.g. a msg sent by ElectrumABC - // Attempt to utf8 decode each push - const decodedTest = []; - for (const el of stackArray) { - decodedTest.push(Buffer.from(el, 'hex').toString('utf8')); - } - appActions.push( - <> + } else { + renderedAppActions.push( <IconAndLabel> <UnknownIcon /> <AppDescLabel>Unknown App</AppDescLabel> - </IconAndLabel> - <UnknownMsgColumn> - <AppDescMsg>{stackArray.join(' ')}</AppDescMsg> - <AppDescMsg>{decodedTest.join(' ')}</AppDescMsg> - </UnknownMsgColumn> - </>, - ); + </IconAndLabel>, + ); + } break; } } } + const tokenActions: React.ReactNode[] = []; - for (let i = 0; i < tokenEntries.length; i += 1) { - // Each entry will get a parsed token action row - const entry = tokenEntries[i]; + + for (const parsedTokenEntry of parsedTokenEntries) { + // Note that parsedTokenEntries[i] correspondes to tokenEntries[i] + // Not used for now but could be used for other rendering cases const { tokenId, - tokenType, - txType, - burnSummary, - actualBurnAmount, - intentionalBurn, - } = entry; - const { protocol, number } = tokenType; - const isUnintentionalBurn = - burnSummary !== '' && actualBurnAmount !== '0'; - const isIntentionalBurn = intentionalBurn !== '0'; + renderedTokenType, + renderedTxType, + tokenSatoshis, + nftFanInputsCreated, + } = parsedTokenEntry; // Every token entry has a token icon const tokenIcon = <TokenIcon size={32} tokenId={tokenId} />; - - // Every token entry has a token type - // We parse it to be more human friendly (...less dev friendly 🤔) in tx history - let parsedTokenType = ''; - switch (protocol) { - case 'ALP': { - parsedTokenType = 'ALP'; + let actionIcon: React.ReactNode; + switch (renderedTxType) { + // "NONE" | "UNKNOWN" | "SEND" | + // ParsedTokenTxType + case 'GENESIS': { + if (renderedTokenType === 'NFT') { + actionIcon = <MintNftIcon />; + } else { + actionIcon = <GenesisIcon />; + } + break; + } + case 'MINT': { + actionIcon = <MintIcon />; break; } - case 'SLP': { - if (number === SLP_1_PROTOCOL_NUMBER) { - parsedTokenType = 'SLP'; - } else if (number === SLP_1_NFT_COLLECTION_PROTOCOL_NUMBER) { - parsedTokenType = 'NFT Collection'; - } else if (number === SLP_1_NFT_PROTOCOL_NUMBER) { - parsedTokenType = 'NFT'; + case 'UNKNOWN': + case 'NONE': { + // We get the NONE type for NFT mints on the parsedTokenEntry that burns + // a qty-1 COLLECTION token + if (renderedTokenType === 'Collection') { + actionIcon = <TokenBurnIcon />; + } else { + actionIcon = <UnknownIcon />; } break; } - default: { - parsedTokenType = `${protocol} ${number}`; + case 'SEND': { + actionIcon = <TokenSendIcon />; break; } - } - - // Ref TokenTxType in ChronikClient - if (txType === 'NONE' || txType === 'UNKNOWN') { - // Handle special case of burning qty 1 NFT Parent token utxo for an NFT mint - // Assume when you see txType === 'NONE' for an SLP 1 NFT Parent, that this is burning an NFT mint - // In Cashtab, this is the only case - if (parsedTokenType === 'NFT Collection') { - tokenActions.push( - <TokenAction> - <IconAndLabel> - <TokenBurnIcon /> - {tokenIcon} - </IconAndLabel> - <TokenType>{parsedTokenType}</TokenType> - <TokenDesc>Burned 1 NFT Mint Input</TokenDesc> - </TokenAction>, - ); - // No more parsing for this token action - continue; + case 'BURN': { + actionIcon = <TokenBurnIcon />; + break; } - - // Render a token entry row for this - // Exercise for the user to figure out what is going on with this tx - tokenActions.push( - <TokenAction> - {tokenIcon} - <TokenType>{parsedTokenType}</TokenType> - <TokenDesc>Unknown token action</TokenDesc> - </TokenAction>, - ); - continue; - } - - // Other txTypes have an associated quantity - // We will render this if we can get the token's decimals from cache - - // Parse for an agora buy/sell/cancel - // Will have the token input coming from a p2sh script - // The input will be at inputs[0] - // Iterate over inputs to find p2sh - for (const input of inputs) { - if (typeof input.token !== 'undefined') { - try { - const { type } = cashaddr.getTypeAndHashFromOutputScript( - // we try..catch for this not existing - // not good practice but we are just implementing ts here now, refactor later - input.outputScript as string, - ); - if (type === 'p2sh') { - // Check if this is a cancellation - // See agora.ts from ecash-agora lib - // For now, I don't think it makes sense to have an 'isCanceled' method from ecash-agora - // This is a pretty specific application - const ops = scriptOps( - new Script(fromHex(input.inputScript)), - ); - // isCanceled is always the last pushop (before redeemScript) - const opIsCanceled = ops[ops.length - 2]; - - const isCanceled = opIsCanceled === OP_0; - - if (isCanceled) { - isAgoraCancel = true; - } else { - // We have a cashtab-created agora-offered input going to a Cashtab wallet - // Buy or sell depends on whether the XEC is sent or received - isAgoraPurchase = true; - } - } - } catch (err) { - console.error( - `Error in cashaddr.getTypeAndHashFromOutputScript(${inputs[0].outputScript}) from txid ${txid}`, - ); - // Do not parse it as an agora tx - } - // We don't need to find any other inputs for this case - continue; + case ParsedTokenTxType.AgoraBuy: { + actionIcon = <AgoraBuyIcon />; + break; } - } - - // Parse for an SLP 1 agora ad setup tx - // These are SLP1 SEND txs where - // 1. token utxo is > dust - // 2. recipient is p2sh address - if (satoshisSent > appConfig.dustSats) { - if (recipients.length === 1) { - // Ad setup tx has 1 recipient - - // Ad setup tx has p2sh recipient - const listingScript = recipients[0]; - try { - const { type } = cashaddr.decode(listingScript, true); - isAgoraAdSetup = type === 'p2sh'; - } catch (err) { - console.error( - `Error in cashaddr.decode(${listingScript}, true)`, - err, - ); - // Continue parsing as token tx - } + case ParsedTokenTxType.AgoraSale: { + actionIcon = <AgoraSaleIcon />; + break; } - } - - // Parse for ALP agora listing tx - if (!isAgoraAdSetup && !isAgoraCancel && !isAgoraPurchase) { - // If this is not already classified as agora - if ( - stackArray.length === 3 && - stackArray[0] === '50' && - stackArray[1].startsWith('41') && - stackArray[2].startsWith('534c5032') - ) { - // and this is an empp ALP and agora tx - if (recipients.length >= 1) { - try { - const { type } = cashaddr.decode(recipients[0], true); - if (type === 'p2sh') { - isAgoraAdSetup = true; - } - } catch (err) { - console.error( - `Error in cashaddr.decode(${recipients[0]}, true) while parsing for ALP listing tx`, - err, - ); - // Continue parsing as token tx - } - } + case ParsedTokenTxType.AgoraCancel: { + actionIcon = <AgoraCancelIcon />; + break; + } + case ParsedTokenTxType.AgoraOffer: { + actionIcon = <AgoraOfferIcon />; + break; + } + case ParsedTokenTxType.FanOut: { + actionIcon = <FanOutIcon />; + break; + } + default: { + // We could handle UNKNOWN and NONE types here + // But keep them split out to show they are possible types + // We may want them to have distinct rendering in the future + actionIcon = <UnknownIcon />; + break; } } + // Get action icon based on renderedTxType + + // Token name and ticker depends on availability of cache info const cachedTokenInfo = cashtabCache.tokens.get(tokenId); - const renderedTxType = isAgoraCancel - ? 'Agora Cancel' - : isAgoraAdSetup - ? 'Agora Offer' - : isAgoraPurchase && xecTxType === 'Sent' - ? 'Agora Buy' - : isAgoraPurchase && xecTxType === 'Received' - ? 'Agora Sale' - : txType === 'SEND' && - !isUnintentionalBurn && - !isIntentionalBurn && - parsedTokenType !== 'NFT Collection' && - !isAgoraAdSetup && - !isAgoraPurchase - ? xecTxType - : txType === 'GENESIS' && parsedTokenType !== 'NFT' - ? 'Created' - : isUnintentionalBurn || txType === 'BURN' || isIntentionalBurn - ? 'Burned' - : txType === 'MINT' || - (txType === 'GENESIS' && parsedTokenType === 'NFT') - ? 'Minted' - : txType !== 'GENESIS' && parsedTokenType === 'NFT Collection' - ? 'Fan-out' - : txType; + let tokenTicker: string; + let tokenName: string; + let decimals: undefined | number; if (typeof cachedTokenInfo === 'undefined') { - tokenActions.push( - <TokenAction tokenTxType={renderedTxType}> - <IconAndLabel> - {renderedTxType === 'Fan-out' && <FanOutIcon />} - {renderedTxType === 'Agora Offer' && <AgoraOfferIcon />} - {renderedTxType === 'Agora Cancel' && ( - <AgoraCancelIcon /> - )} - {renderedTxType === 'Agora Buy' && <AgoraBuyIcon />} - {renderedTxType === 'Agora Sale' && <AgoraSaleIcon />} - {txType === 'GENESIS' && parsedTokenType !== 'NFT' && ( - <GenesisIcon /> - )} - {txType === 'GENESIS' && parsedTokenType === 'NFT' && ( - <MintNftIcon /> - )} - {txType === 'MINT' && <MintIcon />} - {renderedTxType === 'Burned' && <TokenBurnIcon />} - {tokenIcon} - <TokenInfoCol> - <TokenType>{parsedTokenType}</TokenType> - <TokenType>{txType}</TokenType> - </TokenInfoCol> - </IconAndLabel> - <TokenDesc> - {renderedTxType === 'Agora Offer' - ? `Listed` - : renderedTxType} - </TokenDesc> - </TokenAction>, - ); - continue; + tokenName = `${tokenId.slice(0, 3)}...${tokenId.slice(-3)}`; + tokenTicker = ''; + // Leave decimals as undefined, we will not use it if we do not have it } else { - const { decimals, tokenName, tokenTicker } = - cachedTokenInfo.genesisInfo; - let amountTotal = BigInt(0); - let amountThisWallet = BigInt(0); - let amountSold = 0n; - // Special case for NFT1 Parent Fan-out tx - // This can only be a number between 0 and 19, so we do not need BigInt - let qtyOneInputsCreated = 0; - // For burns, we do not need to iterate over outputs - // Enough info is available in the burnSummary key - if (isUnintentionalBurn || isIntentionalBurn) { - amountTotal = BigInt(actualBurnAmount); - } else { - for (const output of outputs) { - if (typeof output.token !== 'undefined') { - // Get the amount associated with this token entry - // Per ChronikClient, we will always have amount as a string in - // the token key of an output, see type Token - amountTotal += BigInt(output.token.amount); - - // For sales of agora partial txs, we assume the amount sold - // goes to a p2pkh address - if (renderedTxType === 'Agora Sale') { - const { type } = - cashaddr.getTypeAndHashFromOutputScript( - output.outputScript, - ); - if (type !== 'p2sh') { - amountSold += BigInt(output.token.amount); - } - } - for (const hash of hashes) { - if (output.outputScript.includes(hash)) { - amountThisWallet += BigInt(output.token.amount); - - if (output.token.amount === '1') { - qtyOneInputsCreated += 1; - } - } - } - } - } - } - - // Calculate amount to render in tx history based on tx type - // For a received tx, we are only interested in amountThisWallet - // For a genesis tx -- cashtab will only create outputs at this wallet. So, just render this. - // For a sent tx, we want amountTotal - amountThisWallet (amountThisWallet is change) - const renderedTokenAmount = - renderedTxType === 'Agora Sale' - ? amountSold - : renderedTxType === 'Received' || - renderedTxType === 'Agora Buy' - ? amountThisWallet - : renderedTxType === 'Created' || - renderedTxType === 'Minted' || - renderedTxType === 'Agora Cancel' - ? amountTotal - : amountTotal - amountThisWallet; - - const decimalizedAmount = decimalizeTokenAmount( - renderedTokenAmount.toString(), - decimals as SlpDecimals, - ); - const formattedAmount = decimalizedTokenQtyToLocaleFormat( - decimalizedAmount, - userLocale, - ); - tokenActions.push( - <TokenAction tokenTxType={renderedTxType}> - <IconAndLabel> - {renderedTxType === 'Agora Offer' && <AgoraOfferIcon />} - {renderedTxType === 'Agora Cancel' && ( - <AgoraCancelIcon /> - )} - {renderedTxType === 'Agora Buy' && <AgoraBuyIcon />} - {renderedTxType === 'Agora Sale' && <AgoraSaleIcon />} - {txType === 'GENESIS' && parsedTokenType !== 'NFT' && ( - <GenesisIcon /> - )} - {txType === 'GENESIS' && parsedTokenType === 'NFT' && ( - <MintNftIcon /> - )} - {renderedTxType === 'Fan-out' && <FanOutIcon />} - {txType === 'MINT' && <MintIcon />} - {renderedTxType === 'Burned' && <TokenBurnIcon />} - {tokenIcon} - <TokenInfoCol> - <TokenType>{parsedTokenType}</TokenType> - <TokenType> - {renderedTxType !== 'Fan-out' - ? txType - : renderedTxType} - </TokenType> - </TokenInfoCol> - </IconAndLabel> + ({ tokenName, tokenTicker, decimals } = + cachedTokenInfo.genesisInfo); + } + const decimalizedAmount = + typeof decimals === 'number' + ? decimalizeTokenAmount(tokenSatoshis, decimals as SlpDecimals) + : '0'; + const formattedAmount = + typeof decimals === 'number' + ? decimalizedTokenQtyToLocaleFormat( + decimalizedAmount, + userLocale, + ) + : '0'; + tokenActions.push( + <TokenAction tokenTxType={renderedTxType}> + <IconAndLabel> + {actionIcon} + {tokenIcon} <TokenInfoCol> - <TokenName>{tokenName}</TokenName> - {tokenTicker !== '' && ( - <TokenTicker>({tokenTicker})</TokenTicker> - )} + <TokenType>{renderedTokenType}</TokenType> + <TokenType> + {renderedTokenType === 'Collection' && + renderedTxType === 'NONE' + ? 'BURN' + : renderedTxType} + </TokenType> </TokenInfoCol> - <TokenDesc> - {renderedTxType === 'Fan-out' - ? `Created ${qtyOneInputsCreated} NFT Mint Input${ - qtyOneInputsCreated > 1 ? 's' : '' - }` - : renderedTxType === 'Agora Offer' - ? `Listed ${formattedAmount} ${tokenTicker}` - : renderedTxType === 'Agora Buy' - ? `Bought ${formattedAmount} ${tokenTicker}` - : renderedTxType === 'Agora Sale' - ? `Sold ${formattedAmount} ${tokenTicker}` - : renderedTxType === 'Agora Cancel' - ? `Canceled offer of ${formattedAmount} ${tokenTicker}` - : `${renderedTxType} ${formattedAmount} ${tokenTicker}`} - </TokenDesc> - </TokenAction>, - ); - } + </IconAndLabel> + <TokenInfoCol> + <TokenName>{tokenName}</TokenName> + {tokenTicker !== '' && ( + <TokenTicker>({tokenTicker})</TokenTicker> + )} + </TokenInfoCol> + <TokenDesc> + {renderedTxType === ParsedTokenTxType.FanOut + ? `Created ${nftFanInputsCreated} NFT Mint Input${ + (nftFanInputsCreated as number) > 1 ? 's' : '' + }` + : renderedTxType === ParsedTokenTxType.AgoraOffer + ? `Listed ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === ParsedTokenTxType.AgoraBuy + ? `Bought ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === ParsedTokenTxType.AgoraSale + ? `Sold ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === ParsedTokenTxType.AgoraCancel + ? `Canceled offer ${ + typeof decimals === 'number' + ? `of ${formattedAmount}` + : '' + } ${tokenTicker}` + : renderedTxType === 'BURN' + ? `Burned ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === 'SEND' + ? `${xecTxType} ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === 'MINT' || + (renderedTxType === 'GENESIS' && + renderedTokenType === 'NFT') + ? `Minted ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === 'NONE' && + renderedTokenType === 'Collection' + ? `Burned 1 ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : renderedTxType === 'GENESIS' + ? `Created ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}` + : `${renderedTxType} ${ + typeof decimals === 'number' + ? formattedAmount + : '' + } ${tokenTicker}`} + </TokenDesc> + </TokenAction>, + ); } const [showPanel, setShowPanel] = useState(false); @@ -1092,7 +831,6 @@ ), ) : new Date(); - const renderedTimestamp = timestamp.toLocaleTimeString(userLocale, { year: 'numeric', month: 'short', @@ -1106,9 +844,10 @@ typeof knownRecipient === 'undefined' && typeof recipients[0] !== 'undefined'); + // AgoraCancels can get the satoshisSent === 0 condition const isSelfSendTx = - typeof recipients[0] === 'undefined' && xecTxType !== 'Received'; - + (typeof recipients[0] === 'undefined' && xecTxType !== 'Received') || + satoshisSent === 0; return ( <> {showAddNewContactModal && ( @@ -1134,30 +873,27 @@ </Modal> )} <TxWrapper> - {/* We always display the MainRow, which is the XEC tx summary*/} <Collapse onClick={() => setShowPanel(!showPanel)}> <MainRow type={xecTxType}> <MainRowLeft> - {isAgoraAdSetup || - isAgoraPurchase || - isAgoraCancel ? ( - <AgoraTxIcon /> - ) : xecTxType === 'Received' && !isSelfSendTx ? ( + {isSelfSendTx ? ( + <SelfSendIcon /> + ) : xecTxType === 'Received' ? ( <ReceiveIcon /> - ) : xecTxType === 'Sent' && !isSelfSendTx ? ( + ) : xecTxType === 'Sent' ? ( <SendIcon /> - ) : isSelfSendTx ? ( - <SelfSendIcon /> ) : ( <MinedIcon /> )} <TxDescCol> <TxDesc> <TxDescSendRcvMsg> - {xecTxType} - {typeof replyAddress === 'string' ? ( + {!isSelfSendTx ? xecTxType : 'Sent'} + {typeof replyAddress === 'string' && + !isSelfSendTx ? ( <> {' from'} + <AddressLink href={`${explorer.blockExplorerUrl}/address/${replyAddress}`} target="_blank" @@ -1271,7 +1007,7 @@ </AmountBottom> </AmountCol> </MainRow> - {appActions.map((action, index) => { + {renderedAppActions.map((action, index) => { return <AppAction key={index}>{action}</AppAction>; })} {tokenActions.map((action, index) => { diff --git a/cashtab/src/components/Home/Tx/styled.ts b/cashtab/src/components/Home/Tx/styled.ts --- a/cashtab/src/components/Home/Tx/styled.ts +++ b/cashtab/src/components/Home/Tx/styled.ts @@ -4,7 +4,7 @@ import styled, { css } from 'styled-components'; import { Link } from 'react-router-dom'; -import { RenderedTxType } from './index'; +import { XecTxType } from 'chronik'; export const TxWrapper = styled.div` border-bottom: 1px solid ${props => props.theme.border}; @@ -62,7 +62,7 @@ } `; export const MainRow = styled.div<{ - type?: RenderedTxType; + type?: XecTxType; }>` display: flex; justify-content: space-between; @@ -209,7 +209,7 @@ text-align: left; `; export const TokenAction = styled(AppAction)<{ - tokenTxType?: RenderedTxType; + tokenTxType?: string; }>` ${props => props.tokenTxType === 'Received' && Incoming} ${props => diff --git a/cashtab/src/components/Nfts/fixtures/mocks.ts b/cashtab/src/components/Nfts/fixtures/mocks.ts --- a/cashtab/src/components/Nfts/fixtures/mocks.ts +++ b/cashtab/src/components/Nfts/fixtures/mocks.ts @@ -8,6 +8,7 @@ import { CashtabWallet, CashtabWalletPaths } from 'wallet'; import { XecTxType } from 'chronik'; import { Token } from 'chronik-client'; +import { RenderedTokenType } from 'token-protocols'; export const nftMarketWallet: CashtabWallet = { state: { @@ -400,8 +401,11 @@ timestamp: 1720807766, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 1754, + recipients: [ + 'ecash:pz3dhqpgk02fq3sv3hurf5j5kvw49ql0ks2eyjpcy0', + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', + ], + satoshisSent: 0, stackArray: [ '534c5000', '41', @@ -409,9 +413,19 @@ '9f0f14f88fc78f64394eee852bac2617a38fac577fdb8097b2f596b1dc25b794', '0000000000000001', ], - recipients: [ - 'ecash:pz3dhqpgk02fq3sv3hurf5j5kvw49ql0ks2eyjpcy0', + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '9f0f14f88fc78f64394eee852bac2617a38fac577fdb8097b2f596b1dc25b794', + renderedTxType: 'Agora Sale', + renderedTokenType: 'NFT' as RenderedTokenType, + tokenSatoshis: '0', + }, ], + replyAddress: + 'ecash:pq5ghfhus093wpfj95887hnjh4cfj3ue9uz40ydh0e', }, }, { @@ -521,8 +535,11 @@ timestamp: 1720807766, }, parsed: { - xecTxType: XecTxType.Sent, - satoshisSent: 3000, + recipients: [ + 'ecash:pq5ghfhus093wpfj95887hnjh4cfj3ue9uz40ydh0e', + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', + ], + satoshisSent: 0, stackArray: [ '534c5000', '41', @@ -530,9 +547,19 @@ '9f0f14f88fc78f64394eee852bac2617a38fac577fdb8097b2f596b1dc25b794', '0000000000000001', ], - recipients: [ - 'ecash:pq5ghfhus093wpfj95887hnjh4cfj3ue9uz40ydh0e', + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '9f0f14f88fc78f64394eee852bac2617a38fac577fdb8097b2f596b1dc25b794', + renderedTxType: 'SEND', + renderedTokenType: 'NFT' as RenderedTokenType, + tokenSatoshis: '0', + }, ], + replyAddress: + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', }, }, { @@ -662,8 +689,10 @@ timestamp: 1720807766, }, parsed: { - xecTxType: XecTxType.Sent, - satoshisSent: 989960, + recipients: [ + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', + ], + satoshisSent: 0, stackArray: [ '534c5000', '41', @@ -676,7 +705,27 @@ '', '0000000000000001', ], - recipients: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '9f0f14f88fc78f64394eee852bac2617a38fac577fdb8097b2f596b1dc25b794', + renderedTxType: 'GENESIS', + renderedTokenType: 'NFT' as RenderedTokenType, + tokenSatoshis: '1', + }, + { + tokenId: + '631fd95d1c3016526f098f46fe8613b216cd1bdb4f8b8859b3ff8e9d7cadd2cc', + renderedTxType: 'NONE', + renderedTokenType: + 'Collection' as RenderedTokenType, + tokenSatoshis: '0', + }, + ], + replyAddress: + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', }, }, { @@ -975,8 +1024,10 @@ }, isFinal: true, parsed: { - xecTxType: XecTxType.Sent, - satoshisSent: 996949, + recipients: [ + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', + ], + satoshisSent: 0, stackArray: [ '534c5000', '81', @@ -995,7 +1046,21 @@ '0000000000000001', '0000000000000001', ], - recipients: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '631fd95d1c3016526f098f46fe8613b216cd1bdb4f8b8859b3ff8e9d7cadd2cc', + renderedTxType: 'Fan Out', + renderedTokenType: + 'Collection' as RenderedTokenType, + tokenSatoshis: '0', + nftFanInputsCreated: 0, + }, + ], + replyAddress: + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', }, }, { @@ -1100,8 +1165,10 @@ }, isFinal: true, parsed: { - xecTxType: XecTxType.Sent, - satoshisSent: 999298, + recipients: [ + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', + ], + satoshisSent: 0, stackArray: [ '534c5000', '81', @@ -1114,7 +1181,20 @@ '02', '000000000000000c', ], - recipients: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [ + { + tokenId: + '631fd95d1c3016526f098f46fe8613b216cd1bdb4f8b8859b3ff8e9d7cadd2cc', + renderedTxType: 'GENESIS', + renderedTokenType: + 'Collection' as RenderedTokenType, + tokenSatoshis: '12', + }, + ], + replyAddress: + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', }, }, { @@ -1176,12 +1256,17 @@ }, isFinal: true, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 1000000, - stackArray: [], recipients: [ + 'ecash:qplvc8a5eyfehtwjyu539xwsck9dw0clpqah3r8al9', 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', ], + satoshisSent: 0, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qz2708636snqhsxu8wnlka78h6fdp77ar59jrf5035', }, }, ], diff --git a/cashtab/src/config/opreturn.js b/cashtab/src/config/opreturn.ts rename from cashtab/src/config/opreturn.js rename to cashtab/src/config/opreturn.ts --- a/cashtab/src/config/opreturn.js +++ b/cashtab/src/config/opreturn.ts @@ -2,8 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -'use strict'; - export const opReturn = { opReserved: '50', opReturnPrefixHex: '6a', diff --git a/cashtab/src/token-protocols/__tests__/index.test.ts b/cashtab/src/token-protocols/__tests__/index.test.ts --- a/cashtab/src/token-protocols/__tests__/index.test.ts +++ b/cashtab/src/token-protocols/__tests__/index.test.ts @@ -6,6 +6,7 @@ getAllSendUtxos, getSendTokenInputs, getMaxDecimalizedQty, + getRenderedTokenType, } from 'token-protocols'; import vectors from '../fixtures/vectors'; import { initWasm } from 'ecash-lib'; @@ -80,4 +81,13 @@ }); }); }); + describe('We can get a human readable token type from TokenType', () => { + const { expectedReturns } = vectors.getRenderedTokenType; + expectedReturns.forEach(expectedReturn => { + const { description, tokenType, returned } = expectedReturn; + it(`getRenderedTokenType: ${description}`, () => { + expect(getRenderedTokenType(tokenType)).toBe(returned); + }); + }); + }); }); diff --git a/cashtab/src/token-protocols/fixtures/vectors.ts b/cashtab/src/token-protocols/fixtures/vectors.ts --- a/cashtab/src/token-protocols/fixtures/vectors.ts +++ b/cashtab/src/token-protocols/fixtures/vectors.ts @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. import { CashtabUtxo, TokenUtxo, SlpDecimals } from 'wallet'; -import { TokenTargetOutput } from 'token-protocols'; +import { TokenTargetOutput, RenderedTokenType } from 'token-protocols'; import { OutPoint, Token, TokenType } from 'chronik-client'; import appConfig from 'config/app'; import { Script, fromHex } from 'ecash-lib'; @@ -38,6 +38,12 @@ decimals: SlpDecimals; returned: string; } + +interface GetRenderedTokenTypeReturn { + description: string; + tokenType: TokenType; + returned: RenderedTokenType; +} interface TokenProtocolsVectors { getAllSendUtxos: { expectedReturns: GetAllSendUtxosReturn[] }; getSendTokenInputs: { @@ -47,6 +53,9 @@ getMaxDecimalizedQty: { expectedReturns: GetMaxDecimalizedQtyReturn[]; }; + getRenderedTokenType: { + expectedReturns: GetRenderedTokenTypeReturn[]; + }; } const MOCK_TOKEN_ID = @@ -761,6 +770,83 @@ }, ], }, + getRenderedTokenType: { + // note I use number:1 everywhere here as it is not (currently) used by the function + expectedReturns: [ + { + description: 'Renders ALP_TOKEN_TYPE_STANDARD', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_STANDARD', + number: 1, + }, + returned: RenderedTokenType.ALP, + }, + { + description: 'Renders ALP_TOKEN_TYPE_UNKNOWN', + tokenType: { + protocol: 'ALP', + type: 'ALP_TOKEN_TYPE_UNKNOWN', + number: 1, + }, + returned: RenderedTokenType.ALP_UNKNOWN, + }, + { + description: 'Renders SLP_TOKEN_TYPE_FUNGIBLE', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_FUNGIBLE', + number: 1, + }, + returned: RenderedTokenType.SLP, + }, + { + description: 'Renders SLP_TOKEN_TYPE_MINT_VAULT', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_MINT_VAULT', + number: 1, + }, + returned: RenderedTokenType.MINTVAULT, + }, + { + description: 'Renders SLP_TOKEN_TYPE_NFT1_GROUP', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_GROUP', + number: 1, + }, + returned: RenderedTokenType.COLLECTION, + }, + { + description: 'Renders SLP_TOKEN_TYPE_NFT1_CHILD', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_NFT1_CHILD', + number: 1, + }, + returned: RenderedTokenType.NFT, + }, + { + description: 'Renders SLP_TOKEN_TYPE_UNKNOWN', + tokenType: { + protocol: 'SLP', + type: 'SLP_TOKEN_TYPE_UNKNOWN', + number: 1, + }, + returned: RenderedTokenType.SLP_UNKNOWN, + }, + { + description: 'Renders a totally unknown token', + tokenType: { + protocol: 'SLPALP' as 'SLP', // some totally new type + type: 'SLP_TOKEN_TYPE_ERC20' as 'SLP_TOKEN_TYPE_UNKNOWN', + number: 1, + }, + returned: RenderedTokenType.UNKNOWN_UNKNOWN, + }, + ], + }, }; export default vectors; diff --git a/cashtab/src/token-protocols/index.ts b/cashtab/src/token-protocols/index.ts --- a/cashtab/src/token-protocols/index.ts +++ b/cashtab/src/token-protocols/index.ts @@ -8,6 +8,7 @@ import { decimalizeTokenAmount, undecimalizeTokenAmount } from 'wallet'; import { Script } from 'ecash-lib'; import appConfig from 'config/app'; +import { TokenType } from 'chronik-client'; // Cashtab spec // This is how Cashtab defines a token utxo to be received @@ -130,3 +131,60 @@ ? getMaxDecimalizedSlpQty(decimals) : getMaxDecimalizedAlpQty(decimals); }; + +export enum RenderedTokenType { + NFT = 'NFT', + SLP = 'SLP', + COLLECTION = 'Collection', + MINTVAULT = 'Mint Vault', + ALP = 'ALP', + ALP_UNKNOWN = 'Unknown ALP', + SLP_UNKNOWN = 'Unknown SLP', + UNKNOWN_UNKNOWN = 'Unknown Token Type', + FAN_OUT = 'Fan Output Tx', +} +/** + * Get a human-readable name for a token by its type + * e.g. "NFT" for "SLP1_CHILD" + */ +export const getRenderedTokenType = ( + tokenType: TokenType, +): RenderedTokenType => { + const { protocol, type } = tokenType; + if (protocol === 'ALP') { + switch (type) { + case 'ALP_TOKEN_TYPE_STANDARD': { + return RenderedTokenType.ALP; + } + case 'ALP_TOKEN_TYPE_UNKNOWN': { + return RenderedTokenType.ALP_UNKNOWN; + } + default: { + return RenderedTokenType.ALP_UNKNOWN; + } + } + } else if (protocol === 'SLP') { + switch (type) { + case 'SLP_TOKEN_TYPE_FUNGIBLE': { + return RenderedTokenType.SLP; + } + case 'SLP_TOKEN_TYPE_MINT_VAULT': { + return RenderedTokenType.MINTVAULT; + } + case 'SLP_TOKEN_TYPE_NFT1_GROUP': { + return RenderedTokenType.COLLECTION; + } + case 'SLP_TOKEN_TYPE_NFT1_CHILD': { + return RenderedTokenType.NFT; + } + case 'SLP_TOKEN_TYPE_UNKNOWN': { + return RenderedTokenType.SLP_UNKNOWN; + } + default: { + return RenderedTokenType.SLP_UNKNOWN; + } + } + } else { + return RenderedTokenType.UNKNOWN_UNKNOWN; + } +}; diff --git a/cashtab/src/transactions/fixtures/mocks.ts b/cashtab/src/transactions/fixtures/mocks.ts --- a/cashtab/src/transactions/fixtures/mocks.ts +++ b/cashtab/src/transactions/fixtures/mocks.ts @@ -182,12 +182,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 25000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 25000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, { @@ -289,12 +293,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 10000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 10000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, { @@ -348,12 +356,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 100000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 100000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, ], @@ -535,12 +547,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 25000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 25000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, { @@ -642,12 +658,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 10000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 10000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, { @@ -701,12 +721,16 @@ timestamp: 1695161321, }, parsed: { - xecTxType: XecTxType.Received, - satoshisSent: 100000, - stackArray: [], recipients: [ 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', ], + satoshisSent: 100000, + stackArray: [], + xecTxType: 'Received' as XecTxType, + appActions: [], + parsedTokenEntries: [], + replyAddress: + 'ecash:qplkmuz3rx480u6vc4xgc0qxnza42p0e7vll6p90wr', }, }, ],