diff --git a/Cargo.lock b/Cargo.lock index f49a9c927c..142e4dccd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -797,6 +797,7 @@ dependencies = [ "chain", "common", "crypto", + "db_common", "derive_more", "dirs", "ethabi", @@ -868,6 +869,7 @@ dependencies = [ "common", "crypto", "derive_more", + "futures 0.3.15", "hex 0.4.3", "rpc", "rpc_task", @@ -896,6 +898,7 @@ dependencies = [ "chrono", "crossbeam", "crossterm", + "db_common", "derive_more", "findshlibs", "fnv", @@ -935,7 +938,6 @@ dependencies = [ "prost", "rand 0.7.3", "regex", - "rusqlite", "rustc-hex 2.1.0", "ser_error", "ser_error_derive", @@ -1271,6 +1273,16 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72aa14c04dfae8dd7d8a2b1cb7ca2152618cd01336dbfe704b8dcbf8d41dbd69" +[[package]] +name = "db_common" +version = "0.1.0" +dependencies = [ + "log 0.4.11", + "rusqlite", + "sql-builder", + "uuid", +] + [[package]] name = "debug_stub_derive" version = "0.3.0" @@ -3245,6 +3257,7 @@ dependencies = [ "crc32fast", "crossbeam", "crypto", + "db_common", "derive_more", "dirs", "either", @@ -3294,7 +3307,6 @@ dependencies = [ "serialization_derive", "sp-runtime-interface", "sp-trie", - "sql-builder", "testcontainers", "tokio", "trie-db", diff --git a/Cargo.toml b/Cargo.toml index 4986492465..1060b422e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ crc = "1.8" crc32fast = { version = "1.2", features = ["std", "nightly"] } crossbeam = "0.7" crypto = { path = "mm2src/crypto" } +db_common = { path = "mm2src/db_common" } derive_more = "0.99" either = "1.6" ethereum-types = { version = "0.4", default-features = false, features = ["std", "serialize"] } @@ -109,7 +110,6 @@ serialization = { path = "mm2src/mm2_bitcoin/serialization" } serialization_derive = { path = "mm2src/mm2_bitcoin/serialization_derive" } sp-runtime-interface = { version = "3.0.0", default-features = false, features = ["disable_target_static_assertions"] } sp-trie = { version = "3.0", default-features = false } -sql-builder = "3.1.1" trie-db = { version = "0.22.6", default-features = false } trie-root = "0.16.0" @@ -147,6 +147,7 @@ members = [ "mm2src/coins/utxo_signer", "mm2src/coins_activation", "mm2src/crypto", + "mm2src/db_common", "mm2src/derives/ser_error", "mm2src/derives/ser_error_derive", "mm2src/floodsub", diff --git a/azure-pipelines-build-stage-job.yml b/azure-pipelines-build-stage-job.yml index 85d7d0e6bb..4667fa4e35 100644 --- a/azure-pipelines-build-stage-job.yml +++ b/azure-pipelines-build-stage-job.yml @@ -40,7 +40,6 @@ jobs: displayName: 'Build MM2 Release' # Build WASM. - bash: | - cargo clean -p mm2-libp2p -p mm2 --target=wasm32-unknown-unknown wasm-pack build --release --target web --out-dir target/target-wasm-release displayName: 'Build MM2 WASM Release' condition: eq( variables['Agent.OS'], 'Linux' ) @@ -56,7 +55,6 @@ jobs: # Explicit --test-threads=16 makes testing process slightly faster on agents that have <16 CPU cores. # Always run tests on mm2.1 branch and PRs - bash: | - cargo clean -p mm2-libp2p -p mm2 cargo test --all -- --test-threads=16 displayName: 'Test MM2' timeoutInMinutes: 22 diff --git a/etomic_build/client/enable_tBCH_USDF b/etomic_build/client/enable_tBCH_USDF new file mode 100755 index 0000000000..3b378adf62 --- /dev/null +++ b/etomic_build/client/enable_tBCH_USDF @@ -0,0 +1,20 @@ +#!/bin/bash +source userpass +curl --url "http://127.0.0.1:7783" --data '{ + "userpass": "'$userpass'", + "method": "enable_bch_with_tokens", + "mmrpc": "2.0", + "params": { + "ticker": "tBCH", + "allow_slp_unsafe_conf": true, + "bchd_urls": [], + "mode": { + "rpc": "Electrum", + "rpc_data":{ + "servers": [{"url":"electroncash.de:50003"},{"url":"tbch.loping.net:60001"},{"url":"blackie.c3-soft.com:60001"},{"url":"bch0.kister.net:51001"},{"url":"testnet.imaginary.cash:50001"}] + } + }, + "tx_history": true, + "slp_tokens_requests": [{"ticker":"USDF"}] + } + }' diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index c3246b5b02..54c6a02099 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -26,6 +26,7 @@ cfg-if = "1.0" chain = { path = "../mm2_bitcoin/chain" } common = { path = "../common" } crypto = { path = "../crypto" } +db_common = { path = "../db_common" } derive_more = "0.99" ethabi = { git = "https://github.com/artemii235/ethabi" } ethcore-transaction = { git = "https://github.com/artemii235/parity-ethereum.git" } diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 22406bee89..550ddcaf4d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -18,6 +18,7 @@ // // Copyright © 2017-2019 SuperNET. All rights reserved. // +use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcrypto::sha256; use common::custom_futures::TimedAsyncMutex; @@ -659,6 +660,7 @@ impl Deref for EthCoin { fn deref(&self) -> &EthCoinImpl { &*self.0 } } +#[async_trait] impl SwapOps for EthCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let address = try_fus!(addr_from_raw_pubkey(fee_addr)); @@ -986,7 +988,7 @@ impl SwapOps for EthCoin { Box::new(fut.boxed().compat()) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, _time_lock: u32, _other_pub: &[u8], @@ -999,7 +1001,7 @@ impl SwapOps for EthCoin { self.search_for_swap_tx_spend(tx, swap_contract_address, search_from_block) } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, _time_lock: u32, _other_pub: &[u8], diff --git a/mm2src/coins/eth/web3_transport.rs b/mm2src/coins/eth/web3_transport.rs index 01efff708e..b057960e3b 100644 --- a/mm2src/coins/eth/web3_transport.rs +++ b/mm2src/coins/eth/web3_transport.rs @@ -114,7 +114,7 @@ impl Future for SendFuture { fn poll(&mut self) -> Poll { self.0.poll() } } -unsafe impl Send for SendFuture {} +unsafe impl Send for SendFuture where T: Send {} unsafe impl Sync for SendFuture {} impl Transport for Web3Transport { diff --git a/mm2src/coins/for_tests/tBCH_tx_history_fixtures.json b/mm2src/coins/for_tests/tBCH_tx_history_fixtures.json new file mode 100644 index 0000000000..6949461b3e --- /dev/null +++ b/mm2src/coins/for_tests/tBCH_tx_history_fixtures.json @@ -0,0 +1,246 @@ +[ +{"tx_hex":"0100000001ce59a734f33811afcc00c19dcb12202ed00067a50efed80424fabd2b723678c0020000006b483045022100ec1fecff9c60fb7e821b9a412bd8c4ce4a757c68287f9cf9e0f461165492d6530220222f020dd05d65ba35cddd0116c99255612ec90d63019bb1cea45e2cf09a62a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914953b3909ff6aa269f85da34c132a92424440e18e879decad00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd1215c61","tx_hash":"6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pz2nkwgfla42y60ctk35cye2jfpygs8p3csm2zkhzd","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.11400301","spent_by_me":"0.11400301","received_by_me":"0.11398301","my_balance_change":"-0.00002000","block_height":0,"timestamp":0,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000001ce59a734f33811afcc00c19dcb12202ed00067a50efed80424fabd2b723678c0020000006b483045022100ec1fecff9c60fb7e821b9a412bd8c4ce4a757c68287f9cf9e0f461165492d6530220222f020dd05d65ba35cddd0116c99255612ec90d63019bb1cea45e2cf09a62a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914953b3909ff6aa269f85da34c132a92424440e18e879decad00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd1215c61","tx_hash":"6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69","from":[],"to":["slptest:pz2nkwgfla42y60ctk35cye2jfpygs8p3ct0devqss"],"total_amount":"0","spent_by_me":"0","received_by_me":"0","my_balance_change":"0","block_height":0,"timestamp":0,"fee_details":null,"coin":"tBCH","internal_id":"421b9d5aed93ab2a20fb41d6a30d85ee6e315a506a6ac521eafaec4cb09739df","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000001c0b02bc3ded9a8684fcd729e19e6c53a5cf1467106554273b1b2684229771809000000006a4730440220607616e5ed18ac83461c8b3c1c258e5245efe936d3b37d2e60b667ec6accd47602204e2c55ba355f58206be3e30bb5aebabc72ce7878306c41a319156a67094eea494121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a914953b3909ff6aa269f85da34c132a92424440e18e88ac6df4ad00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accc1d5c61","tx_hash":"c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qz2nkwgfla42y60ctk35cye2jfpygs8p3c87hd35es","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.11402301","spent_by_me":"0.11402301","received_by_me":"0.11400301","my_balance_change":"-0.00002000","block_height":1468165,"timestamp":1633426943,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000001c0b02bc3ded9a8684fcd729e19e6c53a5cf1467106554273b1b2684229771809000000006a4730440220607616e5ed18ac83461c8b3c1c258e5245efe936d3b37d2e60b667ec6accd47602204e2c55ba355f58206be3e30bb5aebabc72ce7878306c41a319156a67094eea494121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a914953b3909ff6aa269f85da34c132a92424440e18e88ac6df4ad00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accc1d5c61","tx_hash":"c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce","from":[],"to":["slptest:qz2nkwgfla42y60ctk35cye2jfpygs8p3cu2sktrtd"],"total_amount":"0","spent_by_me":"0","received_by_me":"0","my_balance_change":"0","block_height":1468165,"timestamp":1633426943,"fee_details":null,"coin":"tBCH","internal_id":"8c18978529a68bb9eb0cd4b3488775ef2dcfa473baab23158174c4a8b68a03e8","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000001a789174935fb6af2d669b52d03e4dc37dbf0d6afced2d598c54bb692c02367d7010000006b483045022100c3fee0b751f098debd3cfd6befdcd7210f192840143655dee95157c20c9731920220548dab4ddaabd4da92c838d036853a97d6ab98af6d4d8894f82f261c9ed14aa34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff013dfcad00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acda865161","tx_hash":"091877294268b2b1734255067146f15c3ac5e6199e72cd4f68a8d9dec32bb0c0","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.11403301","spent_by_me":"0.11403301","received_by_me":"0.11402301","my_balance_change":"-0.00001000","block_height":1467009,"timestamp":1632733367,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"091877294268b2b1734255067146f15c3ac5e6199e72cd4f68a8d9dec32bb0c0","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000190e35c09c83b5818b441c18a2d5ec54734851e5581fb21bde7936e77c6c3dca8030000006b483045022100e6b1415cbd81f2d04360597fba65965bc77ab5a972f5b8f8d5c0f1b1912923c402206a63f305f03e9c49ffba6c71c7a76ef60631f67dce7631f673a0e8485b86898d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff020000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e82500ae00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac62715161","tx_hash":"d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.11404301","spent_by_me":"0.11404301","received_by_me":"0.11403301","my_balance_change":"-0.00001000","block_height":1467000,"timestamp":1632728165,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000190e35c09c83b5818b441c18a2d5ec54734851e5581fb21bde7936e77c6c3dca8030000006b483045022100e6b1415cbd81f2d04360597fba65965bc77ab5a972f5b8f8d5c0f1b1912923c402206a63f305f03e9c49ffba6c71c7a76ef60631f67dce7631f673a0e8485b86898d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff020000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e82500ae00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac62715161","tx_hash":"d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7","from":[],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1467000,"timestamp":1632728165,"fee_details":null,"coin":"tBCH","internal_id":"045fa17faacd5e2b420266cca1265b37549aa45e140a30f0b92da7fb54ac3cdf","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000027f6af57604a18438921d5a1ce0c62af7e6f372fdf8c31a654796903f613145e6020000006a47304402200657110d9cad55a3cddb6515006a0263e93d4017f9eded90196d7ef51783cd3d022046b40ceccd9e5edd14a9651db8ea1a2a8a7bd5a8d49a2e5c37cc725763b95ae04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5a181e6feadb8db84c6aebea0cd2006a09f1981a0d88df2fa6a3fc1350ecc9e5010000006b483045022100d3600f5b4db791d4385a205bc1b27723bf950fdca15471e23577ab4244e1b51802203584b8d66324a29117699a72cb0ae40989fd22fdd3aecb1a1228445ccce359914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000271008000000000000ceeee8030000000000001976a914eed5d3ad264ffc68fc0a6454e1696a30d8f405be88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0d04ae00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f3e1261","tx_hash":"a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qrhdt5adye8lc68upfj9fctfdgcd3aq9hctf8ft6md","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.11407782","spent_by_me":"0.11407782","received_by_me":"0.11405301","my_balance_change":"-0.00002481","block_height":1460099,"timestamp":1628586152,"fee_details":{"type":"Utxo","amount":"0.00001481"},"coin":"tBCH","internal_id":"a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000027f6af57604a18438921d5a1ce0c62af7e6f372fdf8c31a654796903f613145e6020000006a47304402200657110d9cad55a3cddb6515006a0263e93d4017f9eded90196d7ef51783cd3d022046b40ceccd9e5edd14a9651db8ea1a2a8a7bd5a8d49a2e5c37cc725763b95ae04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5a181e6feadb8db84c6aebea0cd2006a09f1981a0d88df2fa6a3fc1350ecc9e5010000006b483045022100d3600f5b4db791d4385a205bc1b27723bf950fdca15471e23577ab4244e1b51802203584b8d66324a29117699a72cb0ae40989fd22fdd3aecb1a1228445ccce359914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000271008000000000000ceeee8030000000000001976a914eed5d3ad264ffc68fc0a6454e1696a30d8f405be88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0d04ae00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f3e1261","tx_hash":"a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qrhdt5adye8lc68upfj9fctfdgcd3aq9hcsaqj3dfs","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.2974","spent_by_me":"6.2974","received_by_me":"5.2974","my_balance_change":"-1.0000","block_height":1460099,"timestamp":1628586152,"fee_details":null,"coin":"tBCH","internal_id":"20976b31d1e0a5257bf983bdcbbb4230cc465197cc6dd886a9cf2e17b1b9acb0","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000017f6af57604a18438921d5a1ce0c62af7e6f372fdf8c31a654796903f613145e6030000006b483045022100c335dd0f22e047b806a9d84e02b70aab609093e960888f6f1878e605a173e3da02201c274ce4983d8e519a47c4bd17aeca897b084954ce7a9d77033100e06aa999304121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0280969800000000001976a914eed5d3ad264ffc68fc0a6454e1696a30d8f405be88acbe0dae00000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7a361261","tx_hash":"e5c9ec5013fca3a62fdf880d1a98f1096a00d20ceaeb6a4cb88ddbea6f1e185a","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qrhdt5adye8lc68upfj9fctfdgcd3aq9hctf8ft6md","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21407847","spent_by_me":"0.21407847","received_by_me":"0.11406782","my_balance_change":"-0.10001065","block_height":1460096,"timestamp":1628584118,"fee_details":{"type":"Utxo","amount":"0.00001065"},"coin":"tBCH","internal_id":"e5c9ec5013fca3a62fdf880d1a98f1096a00d20ceaeb6a4cb88ddbea6f1e185a","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002ebc10f58f220ec1bad5d634684ae649aa7bdd2f9c9081d36e5384e579caa95c2020000006a4730440220639ac218f572520c7d8addae74be6bfdefa9c86bc91474b6dedd7e117d232085022015a92f45f9ae5cee08c188e01fc614b77c461a41733649a55abfcc3e7ca207444121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffebc10f58f220ec1bad5d634684ae649aa7bdd2f9c9081d36e5384e579caa95c2030000006a47304402204c27a2c04df44f34bd71ec69cc0a24291a96f265217473affb3c3fce2dbd937202202c2ad2e6cfaac3901c807d9b048ccb2b5e7b0dbd922f2066e637f6bbf459313a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000f5fee80300000000000017a9146569d9a853a1934c642223a9432f18c3b3f2a64b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac67a84601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac87caee60","tx_hash":"e64531613f909647651ac3f8fd72f3e6f72ac6e01c5a1d923884a10476f56a7f","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppjknkdg2wsexnryyg36jse0rrpm8u4xfv9hwa0rgl","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21411847","spent_by_me":"0.21411847","received_by_me":"0.21408847","my_balance_change":"-0.00003000","block_height":1456230,"timestamp":1626262632,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"e64531613f909647651ac3f8fd72f3e6f72ac6e01c5a1d923884a10476f56a7f","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002ebc10f58f220ec1bad5d634684ae649aa7bdd2f9c9081d36e5384e579caa95c2020000006a4730440220639ac218f572520c7d8addae74be6bfdefa9c86bc91474b6dedd7e117d232085022015a92f45f9ae5cee08c188e01fc614b77c461a41733649a55abfcc3e7ca207444121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffebc10f58f220ec1bad5d634684ae649aa7bdd2f9c9081d36e5384e579caa95c2030000006a47304402204c27a2c04df44f34bd71ec69cc0a24291a96f265217473affb3c3fce2dbd937202202c2ad2e6cfaac3901c807d9b048ccb2b5e7b0dbd922f2066e637f6bbf459313a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000f5fee80300000000000017a9146569d9a853a1934c642223a9432f18c3b3f2a64b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac67a84601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac87caee60","tx_hash":"e64531613f909647651ac3f8fd72f3e6f72ac6e01c5a1d923884a10476f56a7f","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppjknkdg2wsexnryyg36jse0rrpm8u4xfv7rfx456z","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.3974","spent_by_me":"6.3974","received_by_me":"6.2974","my_balance_change":"-0.1000","block_height":1456230,"timestamp":1626262632,"fee_details":null,"coin":"tBCH","internal_id":"babe9bd0dc1495dff0920da14a76311b744daadc9d01314f8bd4e2438c6b183b","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002f418c909e5baba0708643146d6f1b0b77af9d3fa7f199c56a0e61b230d3dbcee020000006a47304402201367fc23d4acf145c1aa9b7b4111db42a01bf9e8d1555f09b99bfc0e3a26cac7022053dd8f2d617e0acf132f3930b5e91515fd997e07e04e945a2066f09c63739ce24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffff418c909e5baba0708643146d6f1b0b77af9d3fa7f199c56a0e61b230d3dbcee030000006a4730440220010f1d0f1d6246575cbb3d666b453bdd1515f3d9f6cabfb4a7907df50b8aee4f022066c56d4bb7126882c2044d2c777f5c78a23a7a36a9709b735e69d2bd3946c92f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000f9e6e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1fb44601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85caee60","tx_hash":"c295aa9c574e38e5361d08c9f9d2bda79a64ae8446635dad1bec20f2580fc1eb","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21414847","spent_by_me":"0.21414847","received_by_me":"0.21411847","my_balance_change":"-0.00003000","block_height":1456230,"timestamp":1626262632,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"c295aa9c574e38e5361d08c9f9d2bda79a64ae8446635dad1bec20f2580fc1eb","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002f418c909e5baba0708643146d6f1b0b77af9d3fa7f199c56a0e61b230d3dbcee020000006a47304402201367fc23d4acf145c1aa9b7b4111db42a01bf9e8d1555f09b99bfc0e3a26cac7022053dd8f2d617e0acf132f3930b5e91515fd997e07e04e945a2066f09c63739ce24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffff418c909e5baba0708643146d6f1b0b77af9d3fa7f199c56a0e61b230d3dbcee030000006a4730440220010f1d0f1d6246575cbb3d666b453bdd1515f3d9f6cabfb4a7907df50b8aee4f022066c56d4bb7126882c2044d2c777f5c78a23a7a36a9709b735e69d2bd3946c92f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000f9e6e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1fb44601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85caee60","tx_hash":"c295aa9c574e38e5361d08c9f9d2bda79a64ae8446635dad1bec20f2580fc1eb","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.3975","spent_by_me":"6.3975","received_by_me":"6.3974","my_balance_change":"-0.0001","block_height":1456230,"timestamp":1626262632,"fee_details":null,"coin":"tBCH","internal_id":"433b641bc89e1b59c22717918583c60ec98421805c8e85b064691705d9aeb970","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000270fba4f0921a57c550bfe911fa436757cc65f56825f2ff0581aed9775a72fb9c020000006b483045022100c0b9faeb97307ed33db1ac5c5b1b189d7b18267676a3e01d65a48d310651779302205e5be1e1d5ebfeed6994f52c1cc1af2908ff2d9d9b7eb846c7e715e9673e228a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff70fba4f0921a57c550bfe911fa436757cc65f56825f2ff0581aed9775a72fb9c030000006b483045022100965eed3d4152262adbacc52f928b59385480cd4ef44e899d2064a6f38503794902205cebbf1abaab0c116f4b63417cdf6a13dd681cf75e520e26caa7257f9064c6454121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000f9e7e80300000000000017a914fe9318c279369c68cb240c88ef2c2df18cea63e087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd7bf4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc3c7ee60","tx_hash":"eebc3d0d231be6a0569c197ffad3f97ab7b0f1d64631640807babae509c918f4","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prlfxxxz0ymfc6xtysxg3mev9hcce6nruq9p6sq73k","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21417847","spent_by_me":"0.21417847","received_by_me":"0.21414847","my_balance_change":"-0.00003000","block_height":1456229,"timestamp":1626261653,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"eebc3d0d231be6a0569c197ffad3f97ab7b0f1d64631640807babae509c918f4","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000270fba4f0921a57c550bfe911fa436757cc65f56825f2ff0581aed9775a72fb9c020000006b483045022100c0b9faeb97307ed33db1ac5c5b1b189d7b18267676a3e01d65a48d310651779302205e5be1e1d5ebfeed6994f52c1cc1af2908ff2d9d9b7eb846c7e715e9673e228a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff70fba4f0921a57c550bfe911fa436757cc65f56825f2ff0581aed9775a72fb9c030000006b483045022100965eed3d4152262adbacc52f928b59385480cd4ef44e899d2064a6f38503794902205cebbf1abaab0c116f4b63417cdf6a13dd681cf75e520e26caa7257f9064c6454121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000f9e7e80300000000000017a914fe9318c279369c68cb240c88ef2c2df18cea63e087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd7bf4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc3c7ee60","tx_hash":"eebc3d0d231be6a0569c197ffad3f97ab7b0f1d64631640807babae509c918f4","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prlfxxxz0ymfc6xtysxg3mev9hcce6nruq74at6frt","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.4975","spent_by_me":"6.4975","received_by_me":"6.3975","my_balance_change":"-0.1000","block_height":1456229,"timestamp":1626261653,"fee_details":null,"coin":"tBCH","internal_id":"cd6ec10b0cd9747ddc66ac5c97c2d7b493e8cea191bc2d847b3498719d4bd989","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000026fd35b26526cebfc7df0b229bde298b04aa853c0499c4c54c12df0118ed84052020000006a47304402203bd00a6a61434abb4fe4359aad6991e28eeb224fc1f4524309bebca89fbe5807022062a38c4e1da944942c6722141df6bae9c44c07ed52fd736e1f8c75e15aaf99f44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6fd35b26526cebfc7df0b229bde298b04aa853c0499c4c54c12df0118ed84052030000006b483045022100909a8d0be19172c68c2889f240b1531d4a921bf9df8d081fce172d95c7a971cd02206ab0de0ed044b002341e72678106c558cd5e8565352fd78dcdf88a574c409a754121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000fdcfe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8fcb4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc0c7ee60","tx_hash":"9cfb725a77d9ae8105fff22568f565cc576743fa11e9bf50c5571a92f0a4fb70","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21420847","spent_by_me":"0.21420847","received_by_me":"0.21417847","my_balance_change":"-0.00003000","block_height":1456229,"timestamp":1626261653,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"9cfb725a77d9ae8105fff22568f565cc576743fa11e9bf50c5571a92f0a4fb70","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000026fd35b26526cebfc7df0b229bde298b04aa853c0499c4c54c12df0118ed84052020000006a47304402203bd00a6a61434abb4fe4359aad6991e28eeb224fc1f4524309bebca89fbe5807022062a38c4e1da944942c6722141df6bae9c44c07ed52fd736e1f8c75e15aaf99f44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6fd35b26526cebfc7df0b229bde298b04aa853c0499c4c54c12df0118ed84052030000006b483045022100909a8d0be19172c68c2889f240b1531d4a921bf9df8d081fce172d95c7a971cd02206ab0de0ed044b002341e72678106c558cd5e8565352fd78dcdf88a574c409a754121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000fdcfe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8fcb4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc0c7ee60","tx_hash":"9cfb725a77d9ae8105fff22568f565cc576743fa11e9bf50c5571a92f0a4fb70","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.4976","spent_by_me":"6.4976","received_by_me":"6.4975","my_balance_change":"-0.0001","block_height":1456229,"timestamp":1626261653,"fee_details":null,"coin":"tBCH","internal_id":"1c1e68357cf5a6dacb53881f13aa5d2048fe0d0fab24b76c9ec48f53884bed97","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000024aaac282f81cc302e86957d19acd73bdf2757a2ad84b9377ef8dcab593a34545020000006a4730440220772cb5f66b9eb22a48d9aa65711f121a7d074cc645c7bd32e6068f28a7f67e16022070b627a64c0b81c8f3a25d398da12707488cdc8b1782629d2b1cb4c6e17f2b0a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff4aaac282f81cc302e86957d19acd73bdf2757a2ad84b9377ef8dcab593a34545030000006a473044022074bac9d2396dc7b9e44fd83a722620b2f553404d94356267debb421027bed67e02200513bc889699dab01a7abc0248a8ecdcabbceaac119b453fe6b553848d5178534121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000fdd0e80300000000000017a914fbda7aee561fd22fd76c6c29b712aee35b8dc44187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47d74601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7a5aed60","tx_hash":"5240d88e11f02dc1544c9c49c053a84ab098e2bd29b2f07dfceb6c52265bd36f","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:praa57hw2c0ayt7hd3kzndcj4m34hrwygy4jffn8sy","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21423847","spent_by_me":"0.21423847","received_by_me":"0.21420847","my_balance_change":"-0.00003000","block_height":1456064,"timestamp":1626168435,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"5240d88e11f02dc1544c9c49c053a84ab098e2bd29b2f07dfceb6c52265bd36f","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000024aaac282f81cc302e86957d19acd73bdf2757a2ad84b9377ef8dcab593a34545020000006a4730440220772cb5f66b9eb22a48d9aa65711f121a7d074cc645c7bd32e6068f28a7f67e16022070b627a64c0b81c8f3a25d398da12707488cdc8b1782629d2b1cb4c6e17f2b0a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff4aaac282f81cc302e86957d19acd73bdf2757a2ad84b9377ef8dcab593a34545030000006a473044022074bac9d2396dc7b9e44fd83a722620b2f553404d94356267debb421027bed67e02200513bc889699dab01a7abc0248a8ecdcabbceaac119b453fe6b553848d5178534121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000fdd0e80300000000000017a914fbda7aee561fd22fd76c6c29b712aee35b8dc44187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47d74601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7a5aed60","tx_hash":"5240d88e11f02dc1544c9c49c053a84ab098e2bd29b2f07dfceb6c52265bd36f","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:praa57hw2c0ayt7hd3kzndcj4m34hrwygywxwjfsze","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.5976","spent_by_me":"6.5976","received_by_me":"6.4976","my_balance_change":"-0.1000","block_height":1456064,"timestamp":1626168435,"fee_details":null,"coin":"tBCH","internal_id":"c4304b5ef4f1b88ed4939534a8ca9eca79f592939233174ae08002e8454e3f06","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002de1e81fdbb6766cfbd5feed3f71845fb9980df3d3029d07012a48b6eef48552a020000006a473044022064459a789f9dc6efbf1464922bb4e778b434afdc9a4034f587776169d2e2a966022031f38a543b67354263d865371a931f6fd9c9a70fa336e563d1aa71579376f6004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffde1e81fdbb6766cfbd5feed3f71845fb9980df3d3029d07012a48b6eef48552a030000006b483045022100f1f35326636053589c9dcbe5d60e9ab95d04076ba5563862cd00b39e6af9326f02201f31c95858d534298aa5a5044d744cb9f6ee5a057d0177735e3b8b3ebd36c26d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000101b8e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acffe24601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac765aed60","tx_hash":"4545a393b5ca8def77934bd82a7a75f2bd73cd9ad15769e802c31cf882c2aa4a","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21426847","spent_by_me":"0.21426847","received_by_me":"0.21423847","my_balance_change":"-0.00003000","block_height":1456064,"timestamp":1626168435,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"4545a393b5ca8def77934bd82a7a75f2bd73cd9ad15769e802c31cf882c2aa4a","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002de1e81fdbb6766cfbd5feed3f71845fb9980df3d3029d07012a48b6eef48552a020000006a473044022064459a789f9dc6efbf1464922bb4e778b434afdc9a4034f587776169d2e2a966022031f38a543b67354263d865371a931f6fd9c9a70fa336e563d1aa71579376f6004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffde1e81fdbb6766cfbd5feed3f71845fb9980df3d3029d07012a48b6eef48552a030000006b483045022100f1f35326636053589c9dcbe5d60e9ab95d04076ba5563862cd00b39e6af9326f02201f31c95858d534298aa5a5044d744cb9f6ee5a057d0177735e3b8b3ebd36c26d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000101b8e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acffe24601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac765aed60","tx_hash":"4545a393b5ca8def77934bd82a7a75f2bd73cd9ad15769e802c31cf882c2aa4a","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.5977","spent_by_me":"6.5977","received_by_me":"6.5976","my_balance_change":"-0.0001","block_height":1456064,"timestamp":1626168435,"fee_details":null,"coin":"tBCH","internal_id":"b0035434a1e7be5af2ed991ee2a21a90b271c5852a684a0b7d315c5a770d1b1c","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000029ee15b0b97c5fd25baafbf7375caab4110a74653566c902f15c62383a445f013020000006b483045022100b738bb36ad5dd6d35f2c21d1817a77df2830e27c40d5bd950460542ed1382d580220740f189c29ff9a8acb488db22be5c04ce06c33f44911f742236389cd62acf06c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff9ee15b0b97c5fd25baafbf7375caab4110a74653566c902f15c62383a445f013030000006b4830450221008278cab9ea89412af4366b7cf13223a66c75f1b99b8d2426ab45874bb76fda020220153585a9c531f53eff0a1de2285159aa60d882d9b0f8c4b81abafa06608d15c54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000101b9e80300000000000017a914fd3dee29c96afa812f7fad76a04a2499d1555fac87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7ee4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca745ed60","tx_hash":"2a5548ef6e8ba41270d029303ddf8099fb4518f7d3ee5fbdcf6667bbfd811ede","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pr7nmm3fe9404qf007khdgz2yjvaz42l4sqdkmt79k","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21429847","spent_by_me":"0.21429847","received_by_me":"0.21426847","my_balance_change":"-0.00003000","block_height":1456060,"timestamp":1626163734,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"2a5548ef6e8ba41270d029303ddf8099fb4518f7d3ee5fbdcf6667bbfd811ede","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000029ee15b0b97c5fd25baafbf7375caab4110a74653566c902f15c62383a445f013020000006b483045022100b738bb36ad5dd6d35f2c21d1817a77df2830e27c40d5bd950460542ed1382d580220740f189c29ff9a8acb488db22be5c04ce06c33f44911f742236389cd62acf06c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff9ee15b0b97c5fd25baafbf7375caab4110a74653566c902f15c62383a445f013030000006b4830450221008278cab9ea89412af4366b7cf13223a66c75f1b99b8d2426ab45874bb76fda020220153585a9c531f53eff0a1de2285159aa60d882d9b0f8c4b81abafa06608d15c54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000101b9e80300000000000017a914fd3dee29c96afa812f7fad76a04a2499d1555fac87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7ee4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca745ed60","tx_hash":"2a5548ef6e8ba41270d029303ddf8099fb4518f7d3ee5fbdcf6667bbfd811ede","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pr7nmm3fe9404qf007khdgz2yjvaz42l4sme3q3fht","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.6977","spent_by_me":"6.6977","received_by_me":"6.5977","my_balance_change":"-0.1000","block_height":1456060,"timestamp":1626163734,"fee_details":null,"coin":"tBCH","internal_id":"bd9e35d35e4296a53693074c51e92458a5982bf60e966c919be6d05958f4c406","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000203d79bcfeb47659aeabf17f71043fb9ce7f985edf4a20d3244673f737943fce6020000006a4730440220340bed348f70c0fb7362d7b37451ae6a604116140172e866edead7200eb92693022027880c0aa2bbc2eaa3834238d4e04f4675200d4424e9bec21e1d0c6bb3832c594121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff03d79bcfeb47659aeabf17f71043fb9ce7f985edf4a20d3244673f737943fce6030000006a473044022042452a36d3d44bc85f77881a1bb6a55120a269c95544ca0a0951492e439bc0f1022020a375bf7f34f95148b8b9c55129a995805cc35e84c5c3c89603a0d5f181be694121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000105a1e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6ffa4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca645ed60","tx_hash":"13f045a48323c6152f906c565346a71041abca7573bfafba25fdc5970b5be19e","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21432847","spent_by_me":"0.21432847","received_by_me":"0.21429847","my_balance_change":"-0.00003000","block_height":1456060,"timestamp":1626163734,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"13f045a48323c6152f906c565346a71041abca7573bfafba25fdc5970b5be19e","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000203d79bcfeb47659aeabf17f71043fb9ce7f985edf4a20d3244673f737943fce6020000006a4730440220340bed348f70c0fb7362d7b37451ae6a604116140172e866edead7200eb92693022027880c0aa2bbc2eaa3834238d4e04f4675200d4424e9bec21e1d0c6bb3832c594121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff03d79bcfeb47659aeabf17f71043fb9ce7f985edf4a20d3244673f737943fce6030000006a473044022042452a36d3d44bc85f77881a1bb6a55120a269c95544ca0a0951492e439bc0f1022020a375bf7f34f95148b8b9c55129a995805cc35e84c5c3c89603a0d5f181be694121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000105a1e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6ffa4601000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca645ed60","tx_hash":"13f045a48323c6152f906c565346a71041abca7573bfafba25fdc5970b5be19e","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.6978","spent_by_me":"6.6978","received_by_me":"6.6977","my_balance_change":"-0.0001","block_height":1456060,"timestamp":1626163734,"fee_details":null,"coin":"tBCH","internal_id":"3c76ca7ab4290a09683d13794e8636e2071344beb7364ab043ce8c2dd14514a8","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002dc7d15bb62351eabe269d01499d2a1c00bee0705eaa1cef29cf8d04a8bcd184d020000006b483045022100d113d6de671c750ef79bc60f14da46a9e255e33e3f0b85fb37533706a63826390220777565b655e7e28d6f6e12a89a4d5c6e6a56f47d6b4c5f2aef418b4d7a8710a74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffdc7d15bb62351eabe269d01499d2a1c00bee0705eaa1cef29cf8d04a8bcd184d030000006a47304402204f63572b779323619eb16c40db07360346bd5f60ee90075c97e4db40ea59aed602206c7753de0f58417caf6fc92a6bec8fefcad4ae410bb73d9206719244ff53834f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000105a2e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac27064701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc336ec60","tx_hash":"e6fc4379733f6744320da2f4ed85f9e79cfb4310f717bfea9a6547ebcf9bd703","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21435847","spent_by_me":"0.21435847","received_by_me":"0.21432847","my_balance_change":"-0.00003000","block_height":1455944,"timestamp":1626094075,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"e6fc4379733f6744320da2f4ed85f9e79cfb4310f717bfea9a6547ebcf9bd703","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002dc7d15bb62351eabe269d01499d2a1c00bee0705eaa1cef29cf8d04a8bcd184d020000006b483045022100d113d6de671c750ef79bc60f14da46a9e255e33e3f0b85fb37533706a63826390220777565b655e7e28d6f6e12a89a4d5c6e6a56f47d6b4c5f2aef418b4d7a8710a74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffdc7d15bb62351eabe269d01499d2a1c00bee0705eaa1cef29cf8d04a8bcd184d030000006a47304402204f63572b779323619eb16c40db07360346bd5f60ee90075c97e4db40ea59aed602206c7753de0f58417caf6fc92a6bec8fefcad4ae410bb73d9206719244ff53834f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000105a2e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac27064701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc336ec60","tx_hash":"e6fc4379733f6744320da2f4ed85f9e79cfb4310f717bfea9a6547ebcf9bd703","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.6979","spent_by_me":"6.6979","received_by_me":"6.6978","my_balance_change":"-0.0001","block_height":1455944,"timestamp":1626094075,"fee_details":null,"coin":"tBCH","internal_id":"d7b73b1e45e78f5738760355cf643bb0ce7f84a87e51dfed3ddcd999f5a1892a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000026d51c211fbbb091312efc8f4051666807e13402102f90aaccac7be62fb5958de020000006b483045022100e660ebcb57c4a2d7aa67d02be84e7347a50e277544f734ca7edd58a76b8ded1c022069153d86b2df7663c79c79d6411c1edb287595b0e96557af353fce8ca9b4291d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6d51c211fbbb091312efc8f4051666807e13402102f90aaccac7be62fb5958de030000006a47304402204b0ce7a6baf38d93b70ffd069a96e714d07668ee8c79a0df5ff37ecf5e3f6490022039b32d03755772032b513311bdcc5fcd5aadc1ec863fe31bfecddad204eb1a324121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001098be8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac971d4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc52fec60","tx_hash":"bc2fc4aa6996da2267fd0f8cc18d3752d290dad15d2291c887351b18ffd10cb0","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21441847","spent_by_me":"0.21441847","received_by_me":"0.21438847","my_balance_change":"-0.00003000","block_height":1455942,"timestamp":1626092520,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"bc2fc4aa6996da2267fd0f8cc18d3752d290dad15d2291c887351b18ffd10cb0","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000026d51c211fbbb091312efc8f4051666807e13402102f90aaccac7be62fb5958de020000006b483045022100e660ebcb57c4a2d7aa67d02be84e7347a50e277544f734ca7edd58a76b8ded1c022069153d86b2df7663c79c79d6411c1edb287595b0e96557af353fce8ca9b4291d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6d51c211fbbb091312efc8f4051666807e13402102f90aaccac7be62fb5958de030000006a47304402204b0ce7a6baf38d93b70ffd069a96e714d07668ee8c79a0df5ff37ecf5e3f6490022039b32d03755772032b513311bdcc5fcd5aadc1ec863fe31bfecddad204eb1a324121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001098be8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac971d4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc52fec60","tx_hash":"bc2fc4aa6996da2267fd0f8cc18d3752d290dad15d2291c887351b18ffd10cb0","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.798","spent_by_me":"6.798","received_by_me":"6.7979","my_balance_change":"-0.0001","block_height":1455942,"timestamp":1626092520,"fee_details":null,"coin":"tBCH","internal_id":"2a5f6789a28e62ebfcac80e1e371c87ac1c8a363ee844b65e52fe603633a12fe","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b00cd1ff181b3587c891225dd1da90d252378dc18c0ffd6722da9669aac42fbc020000006a47304402206a76876825e83613dea316a03db8df83cdf198d11da60e601fb2e436cbb813ea02206f5450aff9dfa35c9f3bffef649474d4b974746f822ba2f674907601872a7dc94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb00cd1ff181b3587c891225dd1da90d252378dc18c0ffd6722da9669aac42fbc030000006b483045022100ce05de693f51b977545a59aff4eb9f8293c4590ae5a69ac823a2a92d5d7dc33502206271a537f50713f6d79800977a9695023ddcae6a9758642c2397b57991de19224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000105a3e80300000000000017a914bf0e3e4395363c21f2ae5f8514d6e0636d64753b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf114701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc82fec60","tx_hash":"4d18cd8b4ad0f89cf2cea1ea0507ee0bc0a1d29914d069e2ab1e3562bb157ddc","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzlsu0jrj5mrcg0j4e0c29xkup3k6er48vw7yxjdtl","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21438847","spent_by_me":"0.21438847","received_by_me":"0.21435847","my_balance_change":"-0.00003000","block_height":1455942,"timestamp":1626092520,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"4d18cd8b4ad0f89cf2cea1ea0507ee0bc0a1d29914d069e2ab1e3562bb157ddc","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b00cd1ff181b3587c891225dd1da90d252378dc18c0ffd6722da9669aac42fbc020000006a47304402206a76876825e83613dea316a03db8df83cdf198d11da60e601fb2e436cbb813ea02206f5450aff9dfa35c9f3bffef649474d4b974746f822ba2f674907601872a7dc94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb00cd1ff181b3587c891225dd1da90d252378dc18c0ffd6722da9669aac42fbc030000006b483045022100ce05de693f51b977545a59aff4eb9f8293c4590ae5a69ac823a2a92d5d7dc33502206271a537f50713f6d79800977a9695023ddcae6a9758642c2397b57991de19224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000105a3e80300000000000017a914bf0e3e4395363c21f2ae5f8514d6e0636d64753b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf114701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc82fec60","tx_hash":"4d18cd8b4ad0f89cf2cea1ea0507ee0bc0a1d29914d069e2ab1e3562bb157ddc","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzlsu0jrj5mrcg0j4e0c29xkup3k6er48v42rag6ez","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.7979","spent_by_me":"6.7979","received_by_me":"6.6979","my_balance_change":"-0.1000","block_height":1455942,"timestamp":1626092520,"fee_details":null,"coin":"tBCH","internal_id":"eb51cc74f9ed8b567ed7e2d5e93f94e34846407fccc8b4c82e02ff92bfc69bd6","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002174c10d97ce1db602e2ec12a79566029a58290b7f679d349bd535a0b66f23903020000006b483045022100fec07d643397cf597d7850158605d57123c9436167ac7ec4ba9a87f618bf26a2022057f5999ef200e63995cf76f238cf1efdfdbc579009685e394d43821a0498e1d74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff174c10d97ce1db602e2ec12a79566029a58290b7f679d349bd535a0b66f23903030000006a47304402202d292987b9de77aaa624c51518dfc4715b3f86329bb10c61f20bffe07d8c76a9022005c93c381c8d9af5569e300a8b3fea1a00d6d5256b5c2fb11835f4d81747f88d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000001098ce80300000000000017a9144a016e56ef1c3846f3636da1938cdcff489d267f87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f294701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfa1bec60","tx_hash":"de5859fb62bec7caac0af9022140137e80661605f4c8ef121309bbfb11c2516d","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp9qzmjkauwrs3hnvdk6ryuvmnl538fx0ujw2qtywk","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21444847","spent_by_me":"0.21444847","received_by_me":"0.21441847","my_balance_change":"-0.00003000","block_height":1455932,"timestamp":1626086540,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"de5859fb62bec7caac0af9022140137e80661605f4c8ef121309bbfb11c2516d","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002174c10d97ce1db602e2ec12a79566029a58290b7f679d349bd535a0b66f23903020000006b483045022100fec07d643397cf597d7850158605d57123c9436167ac7ec4ba9a87f618bf26a2022057f5999ef200e63995cf76f238cf1efdfdbc579009685e394d43821a0498e1d74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff174c10d97ce1db602e2ec12a79566029a58290b7f679d349bd535a0b66f23903030000006a47304402202d292987b9de77aaa624c51518dfc4715b3f86329bb10c61f20bffe07d8c76a9022005c93c381c8d9af5569e300a8b3fea1a00d6d5256b5c2fb11835f4d81747f88d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000001098ce80300000000000017a9144a016e56ef1c3846f3636da1938cdcff489d267f87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f294701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfa1bec60","tx_hash":"de5859fb62bec7caac0af9022140137e80661605f4c8ef121309bbfb11c2516d","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp9qzmjkauwrs3hnvdk6ryuvmnl538fx0uf6dm3nut","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.898","spent_by_me":"6.898","received_by_me":"6.798","my_balance_change":"-0.100","block_height":1455932,"timestamp":1626086540,"fee_details":null,"coin":"tBCH","internal_id":"0f14bb119589b11dae2554544265ba60d3558ae5e73d4ca73bfae3abafaf1188","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000025e3205d6a4a8c7b823572c2cb7c5f3172d7986f1bfed2b04321d3dcf44b22f7f020000006a47304402207b4ebcbbb8dc10a288397b9c0a25d54f59e85df648bd32f56e5f367579819142022051bfdacb030374cc04fb7436c877114b3d824e7e55b7a34ddfab05fe68092e8c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5e3205d6a4a8c7b823572c2cb7c5f3172d7986f1bfed2b04321d3dcf44b22f7f030000006a473044022052a24a37a1bc67772c12c8426c91f4fd6a69d7066f83908b14b2ea10dac2e65102206f7858e0681f736303d23b6fe3f178e6b9785f30957028f5ffe5b29d702ae0734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000010d74e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac07354701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aced1bec60","tx_hash":"0339f2660b5a53bd49d379f6b79082a5296056792ac12e2e60dbe17cd9104c17","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21447847","spent_by_me":"0.21447847","received_by_me":"0.21444847","my_balance_change":"-0.00003000","block_height":1455932,"timestamp":1626086540,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"0339f2660b5a53bd49d379f6b79082a5296056792ac12e2e60dbe17cd9104c17","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000025e3205d6a4a8c7b823572c2cb7c5f3172d7986f1bfed2b04321d3dcf44b22f7f020000006a47304402207b4ebcbbb8dc10a288397b9c0a25d54f59e85df648bd32f56e5f367579819142022051bfdacb030374cc04fb7436c877114b3d824e7e55b7a34ddfab05fe68092e8c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5e3205d6a4a8c7b823572c2cb7c5f3172d7986f1bfed2b04321d3dcf44b22f7f030000006a473044022052a24a37a1bc67772c12c8426c91f4fd6a69d7066f83908b14b2ea10dac2e65102206f7858e0681f736303d23b6fe3f178e6b9785f30957028f5ffe5b29d702ae0734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000010d74e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac07354701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aced1bec60","tx_hash":"0339f2660b5a53bd49d379f6b79082a5296056792ac12e2e60dbe17cd9104c17","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.8981","spent_by_me":"6.8981","received_by_me":"6.898","my_balance_change":"-0.0001","block_height":1455932,"timestamp":1626086540,"fee_details":null,"coin":"tBCH","internal_id":"2b2c364bcbda16dc1c91f5939fc57fda12a350954cbf6cedbc7c233713f4740a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002bf7ec5e2f89089897ba9a327e5b1d45c8446193cbc9eedb90d2f4c5e83329f45020000006a473044022073e4c2b8c72d5597feaa4aac2d3122e30f6dd2e68d627fb7dc7e220acd70ea6c02206de3aec2dc49aff8b06c9575938379f5077db441a5c843a4d8bb7e326ec509f84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbf7ec5e2f89089897ba9a327e5b1d45c8446193cbc9eedb90d2f4c5e83329f45030000006b483045022100b1df08b3be7aad4a5b1e3abf3643f8bfb54b1c7c625a1710e9860439a1d7df1f022034d24cdbe29b1148eeaa0555823385e29f8acb305ec671907bd4ac9ef950d3304121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000010d75e80300000000000017a914eb39dbf19aedc8fb22467ce18fafcd97cb8cc2b187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf404701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0c03ec60","tx_hash":"7f2fb244cf3d1d32042bedbff186792d17f3c5b72c2c5723b8c7a8a4d605325e","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pr4nnkl3ntku37ezge7wrra0ektuhrxzkyk9gpw5ce","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21450847","spent_by_me":"0.21450847","received_by_me":"0.21447847","my_balance_change":"-0.00003000","block_height":1455920,"timestamp":1626080445,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"7f2fb244cf3d1d32042bedbff186792d17f3c5b72c2c5723b8c7a8a4d605325e","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002bf7ec5e2f89089897ba9a327e5b1d45c8446193cbc9eedb90d2f4c5e83329f45020000006a473044022073e4c2b8c72d5597feaa4aac2d3122e30f6dd2e68d627fb7dc7e220acd70ea6c02206de3aec2dc49aff8b06c9575938379f5077db441a5c843a4d8bb7e326ec509f84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbf7ec5e2f89089897ba9a327e5b1d45c8446193cbc9eedb90d2f4c5e83329f45030000006b483045022100b1df08b3be7aad4a5b1e3abf3643f8bfb54b1c7c625a1710e9860439a1d7df1f022034d24cdbe29b1148eeaa0555823385e29f8acb305ec671907bd4ac9ef950d3304121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000010d75e80300000000000017a914eb39dbf19aedc8fb22467ce18fafcd97cb8cc2b187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf404701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0c03ec60","tx_hash":"7f2fb244cf3d1d32042bedbff186792d17f3c5b72c2c5723b8c7a8a4d605325e","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pr4nnkl3ntku37ezge7wrra0ektuhrxzkyd3065r2y","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.9981","spent_by_me":"6.9981","received_by_me":"6.8981","my_balance_change":"-0.1000","block_height":1455920,"timestamp":1626080445,"fee_details":null,"coin":"tBCH","internal_id":"c97ea51d4c9fef38bcef7f5f8889187233c99907f087ae4fd27e9a3305e493f4","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002528acbbae8d79a7dcef6ddf53eddbab835880c88522d79fdf4f1512ab6685382020000006b483045022100c6a0be60fcb959f94980bc6ca0913793cbf17e9c84f79ef692daf4e603a4124402204c4ff28b0476a0e9363d0251468314499ffccebce9ddd8f2286d4220a5e3b0a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff528acbbae8d79a7dcef6ddf53eddbab835880c88522d79fdf4f1512ab6685382030000006b483045022100f1189b76a0f58d5ea2e75420dd6277d2030ef2aa7e1bdc301715870c7860e2a60220239d1d7b6678427c50d6e6e7f2a69d87c54c75be1578a4b3c8b9b246ef164eb04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001115de8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac774c4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff02ec60","tx_hash":"459f32835e4c2f0db9ed9ebc3c1946845cd4b1e527a3a97b898990f8e2c57ebf","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21453847","spent_by_me":"0.21453847","received_by_me":"0.21450847","my_balance_change":"-0.00003000","block_height":1455920,"timestamp":1626080445,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"459f32835e4c2f0db9ed9ebc3c1946845cd4b1e527a3a97b898990f8e2c57ebf","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002528acbbae8d79a7dcef6ddf53eddbab835880c88522d79fdf4f1512ab6685382020000006b483045022100c6a0be60fcb959f94980bc6ca0913793cbf17e9c84f79ef692daf4e603a4124402204c4ff28b0476a0e9363d0251468314499ffccebce9ddd8f2286d4220a5e3b0a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff528acbbae8d79a7dcef6ddf53eddbab835880c88522d79fdf4f1512ab6685382030000006b483045022100f1189b76a0f58d5ea2e75420dd6277d2030ef2aa7e1bdc301715870c7860e2a60220239d1d7b6678427c50d6e6e7f2a69d87c54c75be1578a4b3c8b9b246ef164eb04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001115de8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac774c4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff02ec60","tx_hash":"459f32835e4c2f0db9ed9ebc3c1946845cd4b1e527a3a97b898990f8e2c57ebf","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"6.9982","spent_by_me":"6.9982","received_by_me":"6.9981","my_balance_change":"-0.0001","block_height":1455920,"timestamp":1626080445,"fee_details":null,"coin":"tBCH","internal_id":"622eded551f4ab8052e462d9b13a5826b46d0850117b5309f7cf35d4b2dd7d20","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b8c5dc25ebdbf124674e408d85367c8454a68ea3dbae0a8bf4e3039c4ebef0e6020000006b483045022100b6ca21e41daa73b6b6a0a053b5b6a72156c5af5258122e56a1c7fe0cd49695cb02202d2e09e50c874bc711f4fabf0d469846a5fdb599731720dffc9e9ec4521023904121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb8c5dc25ebdbf124674e408d85367c8454a68ea3dbae0a8bf4e3039c4ebef0e6030000006a47304402205f486aad621801ada4206fdef983224ed4a10e1d85785929870bfbf0ab7c939202201a37f499351f69a7ffe119b5f73d8e03cc746bfafbfb90d950bb1d4ffcfde4364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011546e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace7634701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3cf7e760","tx_hash":"c156cb702b0dbe463f64a354386169dd1a0b3808c904c27db8ed0256ced2c37e","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21459847","spent_by_me":"0.21459847","received_by_me":"0.21456847","my_balance_change":"-0.00003000","block_height":1455481,"timestamp":1625814954,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"c156cb702b0dbe463f64a354386169dd1a0b3808c904c27db8ed0256ced2c37e","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b8c5dc25ebdbf124674e408d85367c8454a68ea3dbae0a8bf4e3039c4ebef0e6020000006b483045022100b6ca21e41daa73b6b6a0a053b5b6a72156c5af5258122e56a1c7fe0cd49695cb02202d2e09e50c874bc711f4fabf0d469846a5fdb599731720dffc9e9ec4521023904121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb8c5dc25ebdbf124674e408d85367c8454a68ea3dbae0a8bf4e3039c4ebef0e6030000006a47304402205f486aad621801ada4206fdef983224ed4a10e1d85785929870bfbf0ab7c939202201a37f499351f69a7ffe119b5f73d8e03cc746bfafbfb90d950bb1d4ffcfde4364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011546e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace7634701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3cf7e760","tx_hash":"c156cb702b0dbe463f64a354386169dd1a0b3808c904c27db8ed0256ced2c37e","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.0983","spent_by_me":"7.0983","received_by_me":"7.0982","my_balance_change":"-0.0001","block_height":1455481,"timestamp":1625814954,"fee_details":null,"coin":"tBCH","internal_id":"01108977dad384b3495ed3ee6d07401785431326784102c7f8b4e33c7fceedda","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000027ec3d2ce5602edb87dc204c908380b1add69613854a3643f46be0d2b70cb56c1020000006b4830450221008e47c2c07a9c4856fdec40a13abbbb87dab56706917e5314278549686febc43b022042e07e4b477ac5f29fa6c7ee2a97c73901d8861ad1c299a718c4c92ed5a2d1804121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff7ec3d2ce5602edb87dc204c908380b1add69613854a3643f46be0d2b70cb56c1030000006a473044022017821ab2ae4d31e6eebcf3e4575e06e8180ad03c17207f339d7b5441d85e50aa02200f78eb7687e600348742129ade40099e33902b30f638ac5574570be09b8c81c14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000001115ee80300000000000017a914b7e0007cf03669a5b4ae5268617432b030dc9d5187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f584701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ef7e760","tx_hash":"825368b62a51f1f4fd792d52880c8835b8badd3ef5ddf6ce7d9ad7e8bacb8a52","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzm7qqru7qmxnfd54efxsct5x2crphya2yx0cn77dm","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21456847","spent_by_me":"0.21456847","received_by_me":"0.21453847","my_balance_change":"-0.00003000","block_height":1455481,"timestamp":1625814954,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"825368b62a51f1f4fd792d52880c8835b8badd3ef5ddf6ce7d9ad7e8bacb8a52","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000027ec3d2ce5602edb87dc204c908380b1add69613854a3643f46be0d2b70cb56c1020000006b4830450221008e47c2c07a9c4856fdec40a13abbbb87dab56706917e5314278549686febc43b022042e07e4b477ac5f29fa6c7ee2a97c73901d8861ad1c299a718c4c92ed5a2d1804121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff7ec3d2ce5602edb87dc204c908380b1add69613854a3643f46be0d2b70cb56c1030000006a473044022017821ab2ae4d31e6eebcf3e4575e06e8180ad03c17207f339d7b5441d85e50aa02200f78eb7687e600348742129ade40099e33902b30f638ac5574570be09b8c81c14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000001115ee80300000000000017a914b7e0007cf03669a5b4ae5268617432b030dc9d5187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f584701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ef7e760","tx_hash":"825368b62a51f1f4fd792d52880c8835b8badd3ef5ddf6ce7d9ad7e8bacb8a52","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzm7qqru7qmxnfd54efxsct5x2crphya2yamlgyflx","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.0982","spent_by_me":"7.0982","received_by_me":"6.9982","my_balance_change":"-0.1000","block_height":1455481,"timestamp":1625814954,"fee_details":null,"coin":"tBCH","internal_id":"70dd3998d70330772870f23db91beeee9d52f7dc9de80c4e4a5369fa1c244a7b","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020a54c63de908f7db54cbda8595ba47b616205d919e27b0534f784ac564ba313a020000006b483045022100daa11f5ece3150332a4283ee221450948ed35d261441dcedcf41823edc9357d80220474574926bd3002cadbc98ee2d08d9f4fb031376cf47d920fa70fee717c87eff4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0a54c63de908f7db54cbda8595ba47b616205d919e27b0534f784ac564ba313a030000006b483045022100afd96dfe543efe8d84b5e1c05216db0bf4269d4f3986c8c04f3ec344079d2b330220498b5d147b9901b60aee2d7afb25f9acf5fe8b81616b70bb07dc4f6a6125a96b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011547e80300000000000017a91472a1f30385c63ee266b6955d6edfdb10596de93087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f6f4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb80de760","tx_hash":"e6f0be4e9c03e3f48b0aaedba38ea654847c36858d404e6724f1dbeb25dcc5b8","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppe2rucrshrracnxk6246mklmvg9jm0fxqvlx3y9ty","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21462847","spent_by_me":"0.21462847","received_by_me":"0.21459847","my_balance_change":"-0.00003000","block_height":1455413,"timestamp":1625755850,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"e6f0be4e9c03e3f48b0aaedba38ea654847c36858d404e6724f1dbeb25dcc5b8","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020a54c63de908f7db54cbda8595ba47b616205d919e27b0534f784ac564ba313a020000006b483045022100daa11f5ece3150332a4283ee221450948ed35d261441dcedcf41823edc9357d80220474574926bd3002cadbc98ee2d08d9f4fb031376cf47d920fa70fee717c87eff4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0a54c63de908f7db54cbda8595ba47b616205d919e27b0534f784ac564ba313a030000006b483045022100afd96dfe543efe8d84b5e1c05216db0bf4269d4f3986c8c04f3ec344079d2b330220498b5d147b9901b60aee2d7afb25f9acf5fe8b81616b70bb07dc4f6a6125a96b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011547e80300000000000017a91472a1f30385c63ee266b6955d6edfdb10596de93087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f6f4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb80de760","tx_hash":"e6f0be4e9c03e3f48b0aaedba38ea654847c36858d404e6724f1dbeb25dcc5b8","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppe2rucrshrracnxk6246mklmvg9jm0fxqhtp27jee","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.1983","spent_by_me":"7.1983","received_by_me":"7.0983","my_balance_change":"-0.1000","block_height":1455413,"timestamp":1625755850,"fee_details":null,"coin":"tBCH","internal_id":"ce6c7660410cc159b0d57509238189383d47ca5e1a154eea457b5615b3655833","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000263a5fab0683011ee4d18541e2aed8fb190f26fe08d216e88e247f602acc6eba7020000006b483045022100e78ce23da10343611783990aecdc833e68d6a41389af52c44be92c4a78ddc9db022058833c1c05deff16327cf48be706a5da3ed4227bf946463516409deb3cb8d86b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff63a5fab0683011ee4d18541e2aed8fb190f26fe08d216e88e247f602acc6eba7030000006b483045022100a232e5521febc0fb36bb01f50657662cc7297e27ea278067ade677fe98796cfd022015962e70f0c5a079655ecf485f42f3a28330eaf5fcad045bdd853da45394cda54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001192fe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac577b4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb50de760","tx_hash":"3a31ba64c54a784f53b0279e915d2016b647ba9585dacb54dbf708e93dc6540a","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21465847","spent_by_me":"0.21465847","received_by_me":"0.21462847","my_balance_change":"-0.00003000","block_height":1455413,"timestamp":1625755850,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"3a31ba64c54a784f53b0279e915d2016b647ba9585dacb54dbf708e93dc6540a","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000263a5fab0683011ee4d18541e2aed8fb190f26fe08d216e88e247f602acc6eba7020000006b483045022100e78ce23da10343611783990aecdc833e68d6a41389af52c44be92c4a78ddc9db022058833c1c05deff16327cf48be706a5da3ed4227bf946463516409deb3cb8d86b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff63a5fab0683011ee4d18541e2aed8fb190f26fe08d216e88e247f602acc6eba7030000006b483045022100a232e5521febc0fb36bb01f50657662cc7297e27ea278067ade677fe98796cfd022015962e70f0c5a079655ecf485f42f3a28330eaf5fcad045bdd853da45394cda54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000001192fe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac577b4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb50de760","tx_hash":"3a31ba64c54a784f53b0279e915d2016b647ba9585dacb54dbf708e93dc6540a","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.1984","spent_by_me":"7.1984","received_by_me":"7.1983","my_balance_change":"-0.0001","block_height":1455413,"timestamp":1625755850,"fee_details":null,"coin":"tBCH","internal_id":"2c2a602e6fbbb97045ba95afb534479a59d1cf179a36959070c67d4ef9e92d56","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002bb93d534bfa95c5a746c22671ef5e9f7dae48b414c46d7885862e50887fcdc2b020000006a4730440220474ee418db2760c703016d01f8cd1440d36a45ae3eb5bea1d8ec257f22e34a0802201516a8b32af513c3914839d1bb6871ffe4b77928070444bd0e7ca1033ef53b1d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbb93d534bfa95c5a746c22671ef5e9f7dae48b414c46d7885862e50887fcdc2b030000006a47304402203627759d399bb8ca178926fc93412bce1f78e2c6c43803e33db4eb79a4f6c7fa022016a1c2a54df3503a9749ac97f482b819a236cadc1273fc8dd70a9e2ef69193ce4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011930e80300000000000017a914cdad3b10b52f6e13c606cdca160bc8f510c48e5187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0f874701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5eb0e660","tx_hash":"a7ebc6ac02f647e2886e218de06ff290b18fed2a1e54184dee113068b0faa563","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prx66wcsk5hkuy7xqmxu59ster63p3yw2ywmgzqrqz","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21468847","spent_by_me":"0.21468847","received_by_me":"0.21465847","my_balance_change":"-0.00003000","block_height":1455393,"timestamp":1625732178,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"a7ebc6ac02f647e2886e218de06ff290b18fed2a1e54184dee113068b0faa563","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002bb93d534bfa95c5a746c22671ef5e9f7dae48b414c46d7885862e50887fcdc2b020000006a4730440220474ee418db2760c703016d01f8cd1440d36a45ae3eb5bea1d8ec257f22e34a0802201516a8b32af513c3914839d1bb6871ffe4b77928070444bd0e7ca1033ef53b1d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbb93d534bfa95c5a746c22671ef5e9f7dae48b414c46d7885862e50887fcdc2b030000006a47304402203627759d399bb8ca178926fc93412bce1f78e2c6c43803e33db4eb79a4f6c7fa022016a1c2a54df3503a9749ac97f482b819a236cadc1273fc8dd70a9e2ef69193ce4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011930e80300000000000017a914cdad3b10b52f6e13c606cdca160bc8f510c48e5187e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0f874701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5eb0e660","tx_hash":"a7ebc6ac02f647e2886e218de06ff290b18fed2a1e54184dee113068b0faa563","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prx66wcsk5hkuy7xqmxu59ster63p3yw2y400e65jl","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.2984","spent_by_me":"7.2984","received_by_me":"7.1984","my_balance_change":"-0.1000","block_height":1455393,"timestamp":1625732178,"fee_details":null,"coin":"tBCH","internal_id":"f4e1812cc0095cece6d05ec831d13c8ed9e58f546ad05bf41e28c37f2e4cf085","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002d01df8b7a9a203a5d1b1b797d339f69ff0f3c929e638758948f1497599f3ef7d020000006a47304402200e2dfab7c1cea057f825c65b5158c33e4bcefcce0d492cddc220fb63dc4d9bda022016048782f9b321406f8991c6b38562bf240626cbc35825a2a34f7e1bd49848024121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffd01df8b7a9a203a5d1b1b797d339f69ff0f3c929e638758948f1497599f3ef7d030000006b483045022100de0917450e56164d8cca69bc0e29f070eafd0b0b4239407ffbed73b673a2843d022062406ce0bb6c13b916a24cbb781aa44d6ac4f3db28a6d8b22ed06028f060f69d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011d18e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc7924701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5bb0e660","tx_hash":"2bdcfc8708e5625888d7464c418be4daf7e9f51e67226c745a5ca9bf34d593bb","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21471847","spent_by_me":"0.21471847","received_by_me":"0.21468847","my_balance_change":"-0.00003000","block_height":1455393,"timestamp":1625732178,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"2bdcfc8708e5625888d7464c418be4daf7e9f51e67226c745a5ca9bf34d593bb","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002d01df8b7a9a203a5d1b1b797d339f69ff0f3c929e638758948f1497599f3ef7d020000006a47304402200e2dfab7c1cea057f825c65b5158c33e4bcefcce0d492cddc220fb63dc4d9bda022016048782f9b321406f8991c6b38562bf240626cbc35825a2a34f7e1bd49848024121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffd01df8b7a9a203a5d1b1b797d339f69ff0f3c929e638758948f1497599f3ef7d030000006b483045022100de0917450e56164d8cca69bc0e29f070eafd0b0b4239407ffbed73b673a2843d022062406ce0bb6c13b916a24cbb781aa44d6ac4f3db28a6d8b22ed06028f060f69d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011d18e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc7924701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5bb0e660","tx_hash":"2bdcfc8708e5625888d7464c418be4daf7e9f51e67226c745a5ca9bf34d593bb","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.2985","spent_by_me":"7.2985","received_by_me":"7.2984","my_balance_change":"-0.0001","block_height":1455393,"timestamp":1625732178,"fee_details":null,"coin":"tBCH","internal_id":"536ba3818af4beb7eff054adc313c01a21cbca40dc480a2040e9f165af5d3ffd","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002846a1b801449b070e701db8d41c905fcad7db3fd7645987903c2a8b348ffe47f020000006b483045022100ecdcb4e81e0976693c7974029f74ebe0e2697f8547f4ef06130fa6d89519720f02203e794f2d66b6549a088f49d3d18ffbf8d46166d01af35fa2d03b3fedb6721ed64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff846a1b801449b070e701db8d41c905fcad7db3fd7645987903c2a8b348ffe47f030000006b483045022100f7db307d111357b6926564728a52a83b714c5a850e1a8fcb081cb6499929e2f702200fd5a171f9a06ec03ad844ee5513b72e1f6f6def1ddd0360f20f6161cae46be44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011d19e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f9e4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace828df60","tx_hash":"7deff3997549f148897538e629c9f3f09ff639d397b7b1d1a503a2a9b7f81dd0","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21474847","spent_by_me":"0.21474847","received_by_me":"0.21471847","my_balance_change":"-0.00003000","block_height":1454520,"timestamp":1625238393,"fee_details":{"type":"Utxo","amount":"0.00002"},"coin":"tBCH","internal_id":"7deff3997549f148897538e629c9f3f09ff639d397b7b1d1a503a2a9b7f81dd0","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002846a1b801449b070e701db8d41c905fcad7db3fd7645987903c2a8b348ffe47f020000006b483045022100ecdcb4e81e0976693c7974029f74ebe0e2697f8547f4ef06130fa6d89519720f02203e794f2d66b6549a088f49d3d18ffbf8d46166d01af35fa2d03b3fedb6721ed64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff846a1b801449b070e701db8d41c905fcad7db3fd7645987903c2a8b348ffe47f030000006b483045022100f7db307d111357b6926564728a52a83b714c5a850e1a8fcb081cb6499929e2f702200fd5a171f9a06ec03ad844ee5513b72e1f6f6def1ddd0360f20f6161cae46be44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000011d19e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f9e4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace828df60","tx_hash":"7deff3997549f148897538e629c9f3f09ff639d397b7b1d1a503a2a9b7f81dd0","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.2986","spent_by_me":"7.2986","received_by_me":"7.2985","my_balance_change":"-0.0001","block_height":1454520,"timestamp":1625238393,"fee_details":null,"coin":"tBCH","internal_id":"d0d0d27da94208523d7aa15e69c01e26aaf2e57d3babb59cb33c2a12312139c9","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002bc2f060f95f49adebada3a716b8b41f8ae910116a0a785025424083bd9f4a227020000006a47304402200801537c34845451ee32d55d92d067692d5a7e90b42e40b494b110aa600a7512022045812131c23b0372cc1f08e86fe09511aa84ded6c5bc7785f7af1dff1d01bf5a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbc2f060f95f49adebada3a716b8b41f8ae910116a0a785025424083bd9f4a227030000006a473044022057c3ca0a94ffd218809c362244777aceff638dd673d492dc305e6bf4d0c8eeab02205f3863339664b1cbe6aa15d70b959b30646e581f9d7b009afc7b0cd2df839ea54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000124ebe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca7c14701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac63ccde60","tx_hash":"ec8eed8490565c17685f8ad2a0399b67af0433c2b16d1ce53c5e1c3a0f416f60","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21482847","spent_by_me":"0.21482847","received_by_me":"0.21480847","my_balance_change":"-0.00002000","block_height":1454479,"timestamp":1625215221,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"ec8eed8490565c17685f8ad2a0399b67af0433c2b16d1ce53c5e1c3a0f416f60","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002bc2f060f95f49adebada3a716b8b41f8ae910116a0a785025424083bd9f4a227020000006a47304402200801537c34845451ee32d55d92d067692d5a7e90b42e40b494b110aa600a7512022045812131c23b0372cc1f08e86fe09511aa84ded6c5bc7785f7af1dff1d01bf5a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbc2f060f95f49adebada3a716b8b41f8ae910116a0a785025424083bd9f4a227030000006a473044022057c3ca0a94ffd218809c362244777aceff638dd673d492dc305e6bf4d0c8eeab02205f3863339664b1cbe6aa15d70b959b30646e581f9d7b009afc7b0cd2df839ea54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000124ebe8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca7c14701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac63ccde60","tx_hash":"ec8eed8490565c17685f8ad2a0399b67af0433c2b16d1ce53c5e1c3a0f416f60","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.4988","spent_by_me":"7.4988","received_by_me":"7.4987","my_balance_change":"-0.0001","block_height":1454479,"timestamp":1625215221,"fee_details":null,"coin":"tBCH","internal_id":"74a914ba7cdd9164cbb36cc26d3af17bf4c54619e1d3118b542cef44352a61a2","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002624c73d2d461f17c8c65240185ebc5f8c5e7864cbebc7e9cb837c58712d51558020000006b483045022100c95e3beb4f2b4ba1880de7631cbd0570e5b5cc4b53cc6d72f505db4db119ca8f02205389a8eb3fef0a3986accdb86a9fabf83968ddc91f5aed76e18abb58a05ae92f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff624c73d2d461f17c8c65240185ebc5f8c5e7864cbebc7e9cb837c58712d51558030000006b483045022100e30e6e76b0e201d607ec23c12d52d0e68cb7c524b4ce30dbdebb3e25256feb4802207fa3ca01ed8a8e304ba4bdf9229ca3159210949dca22bf45d8b17c27e1f5014c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011d1ae80300000000000017a914a532cabaee0701e1e1db193683e3cda43161612b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac37aa4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac32cede60","tx_hash":"7fe4ff48b3a8c20379984576fdb37dadfc05c9418ddb01e770b04914801b6a84","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzjn9j46acrsrc0pmvvndqlrekjrzctp9vpmhqt026","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21476847","spent_by_me":"0.21476847","received_by_me":"0.21474847","my_balance_change":"-0.00002000","block_height":1454479,"timestamp":1625215221,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"7fe4ff48b3a8c20379984576fdb37dadfc05c9418ddb01e770b04914801b6a84","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002624c73d2d461f17c8c65240185ebc5f8c5e7864cbebc7e9cb837c58712d51558020000006b483045022100c95e3beb4f2b4ba1880de7631cbd0570e5b5cc4b53cc6d72f505db4db119ca8f02205389a8eb3fef0a3986accdb86a9fabf83968ddc91f5aed76e18abb58a05ae92f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff624c73d2d461f17c8c65240185ebc5f8c5e7864cbebc7e9cb837c58712d51558030000006b483045022100e30e6e76b0e201d607ec23c12d52d0e68cb7c524b4ce30dbdebb3e25256feb4802207fa3ca01ed8a8e304ba4bdf9229ca3159210949dca22bf45d8b17c27e1f5014c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000011d1ae80300000000000017a914a532cabaee0701e1e1db193683e3cda43161612b87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac37aa4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac32cede60","tx_hash":"7fe4ff48b3a8c20379984576fdb37dadfc05c9418ddb01e770b04914801b6a84","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzjn9j46acrsrc0pmvvndqlrekjrzctp9v60sm3cc8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.3986","spent_by_me":"7.3986","received_by_me":"7.2986","my_balance_change":"-0.1000","block_height":1454479,"timestamp":1625215221,"fee_details":null,"coin":"tBCH","internal_id":"0a0a509bc58762751e9c55d683d829c25a02d8a2e2882bc9477ebb52444300f6","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000276aea71963b604d2232ca7b6e2fc0ba9a584e21c199cfef3b1cf802fa8a55552020000006b483045022100c1689ac6f5bf90ed8d70612fff5fa275eecbbf1cbaa7768e3f56e610d1af2bca022069e5ffc3c74878b5c9addf0f8730514d14047c0cbdb74aebabcb6e6f2768854b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff76aea71963b604d2232ca7b6e2fc0ba9a584e21c199cfef3b1cf802fa8a55552030000006a47304402205f460fa1e3b82b364551446ad60aa218e77ab04af3c9db72eeb0dbbea2f5fe9a02206a5dcba75809dda38e370c4f8b1d0de3f7b44e34f3d115c59981e329dce9d9274121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000012102e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac07b24701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac30cede60","tx_hash":"5815d51287c537b89c7ebcbe4c86e7c5f8c5eb850124658c7cf161d4d2734c62","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21478847","spent_by_me":"0.21478847","received_by_me":"0.21476847","my_balance_change":"-0.00002000","block_height":1454479,"timestamp":1625215221,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"5815d51287c537b89c7ebcbe4c86e7c5f8c5eb850124658c7cf161d4d2734c62","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000276aea71963b604d2232ca7b6e2fc0ba9a584e21c199cfef3b1cf802fa8a55552020000006b483045022100c1689ac6f5bf90ed8d70612fff5fa275eecbbf1cbaa7768e3f56e610d1af2bca022069e5ffc3c74878b5c9addf0f8730514d14047c0cbdb74aebabcb6e6f2768854b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff76aea71963b604d2232ca7b6e2fc0ba9a584e21c199cfef3b1cf802fa8a55552030000006a47304402205f460fa1e3b82b364551446ad60aa218e77ab04af3c9db72eeb0dbbea2f5fe9a02206a5dcba75809dda38e370c4f8b1d0de3f7b44e34f3d115c59981e329dce9d9274121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000012102e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac07b24701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac30cede60","tx_hash":"5815d51287c537b89c7ebcbe4c86e7c5f8c5eb850124658c7cf161d4d2734c62","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.3987","spent_by_me":"7.3987","received_by_me":"7.3986","my_balance_change":"-0.0001","block_height":1454479,"timestamp":1625215221,"fee_details":null,"coin":"tBCH","internal_id":"cd72e89cb7d7ef8311f019acf44a0d6fc4e2c3f3682e103ded1be9b9e95e95b7","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002606f410f3a1c5e3ce51c6db1c23304af679b39a0d28a5f68175c569084ed8eec020000006b483045022100b52e86356200712da855e10b02ef62148bb05f26eb6ff8a851a6765b12d4f7f502206df1ba9aa53ee0e9d49e3c5f63f250045bc73d16d66b0387dcd36666e03162f74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff606f410f3a1c5e3ce51c6db1c23304af679b39a0d28a5f68175c569084ed8eec030000006a47304402207ce91e1cf6ace3165e66018123b17d7fcd11bfcf75c2e529916746123c899359022072b40bcebfd4f535de42f837c762b4723ecb3d98213258af4d35dcc6412fcb404121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000012103e80300000000000017a9149a1411ace5b6c6a4b683a88cfedb343d2e7f1c7487e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd7b94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac65ccde60","tx_hash":"5255a5a82f80cfb1f3fe9c191ce284a5a90bfce2b6a72c23d204b66319a7ae76","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzdpgydvukmvdf9ksw5gelkmxs7julcuwse7d2n3n2","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21480847","spent_by_me":"0.21480847","received_by_me":"0.21478847","my_balance_change":"-0.00002000","block_height":1454479,"timestamp":1625215221,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"5255a5a82f80cfb1f3fe9c191ce284a5a90bfce2b6a72c23d204b66319a7ae76","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002606f410f3a1c5e3ce51c6db1c23304af679b39a0d28a5f68175c569084ed8eec020000006b483045022100b52e86356200712da855e10b02ef62148bb05f26eb6ff8a851a6765b12d4f7f502206df1ba9aa53ee0e9d49e3c5f63f250045bc73d16d66b0387dcd36666e03162f74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff606f410f3a1c5e3ce51c6db1c23304af679b39a0d28a5f68175c569084ed8eec030000006a47304402207ce91e1cf6ace3165e66018123b17d7fcd11bfcf75c2e529916746123c899359022072b40bcebfd4f535de42f837c762b4723ecb3d98213258af4d35dcc6412fcb404121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000012103e80300000000000017a9149a1411ace5b6c6a4b683a88cfedb343d2e7f1c7487e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd7b94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac65ccde60","tx_hash":"5255a5a82f80cfb1f3fe9c191ce284a5a90bfce2b6a72c23d204b66319a7ae76","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzdpgydvukmvdf9ksw5gelkmxs7julcuwsz223fxph","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.4987","spent_by_me":"7.4987","received_by_me":"7.3987","my_balance_change":"-0.1000","block_height":1454479,"timestamp":1625215221,"fee_details":null,"coin":"tBCH","internal_id":"ad9ec7b0c12fed34a7f859abfc18cdcad5bb046e4a20c6d52fb7e43efaecf195","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002381f4c7570e528446c92c2b9d28cce1d457ddeb8d6ae5590995852592b2ba8ab020000006b483045022100fba4e3d9bfc56c6ece835cec5ee14178918065241389661fd89d7db1eea357a302207e892529c9e3324f5d11b0492484f871dab3457631aa55cc1d72ceb4078717064121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff381f4c7570e528446c92c2b9d28cce1d457ddeb8d6ae5590995852592b2ba8ab030000006a47304402203907a215422e6816403301d2829b11b5d984ee89c55a7a612d4321b418c61d7702202a59c70515751d320d27e0d4d4b058b12f54a6d992e739829cfbd4b29faa2e0d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000128d4e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47d14701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb4c9de60","tx_hash":"875d961219c90391427eaf86ca6ad1d1f67d787cb004c39fe9fe284c6191c258","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21486847","spent_by_me":"0.21486847","received_by_me":"0.21484847","my_balance_change":"-0.00002000","block_height":1454477,"timestamp":1625213445,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"875d961219c90391427eaf86ca6ad1d1f67d787cb004c39fe9fe284c6191c258","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002381f4c7570e528446c92c2b9d28cce1d457ddeb8d6ae5590995852592b2ba8ab020000006b483045022100fba4e3d9bfc56c6ece835cec5ee14178918065241389661fd89d7db1eea357a302207e892529c9e3324f5d11b0492484f871dab3457631aa55cc1d72ceb4078717064121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff381f4c7570e528446c92c2b9d28cce1d457ddeb8d6ae5590995852592b2ba8ab030000006a47304402203907a215422e6816403301d2829b11b5d984ee89c55a7a612d4321b418c61d7702202a59c70515751d320d27e0d4d4b058b12f54a6d992e739829cfbd4b29faa2e0d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000128d4e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47d14701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb4c9de60","tx_hash":"875d961219c90391427eaf86ca6ad1d1f67d787cb004c39fe9fe284c6191c258","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.5989","spent_by_me":"7.5989","received_by_me":"7.5988","my_balance_change":"-0.0001","block_height":1454477,"timestamp":1625213445,"fee_details":null,"coin":"tBCH","internal_id":"7913669d09ec17078156a5765f4a356d3186a34eedff2f8a51fabfc4c28e955c","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000258c291614c28fee99fc304b07c787df6d1d16aca86af7e429103c91912965d87020000006a47304402204d2bbeb9a5defa77ef04a6ec115c925e76dee55203df6c4714c5b2122ed81a46022052f696df673dff637ee2db36b1f760c5d58a9dbf74a8ec5e8d976b430ca49d334121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff58c291614c28fee99fc304b07c787df6d1d16aca86af7e429103c91912965d87030000006b483045022100a6d6b9ec4023662628401bf524ac2713d8579026a275cf346c10843eadd7f141022074721fff37a3665a80c0f7324f0499f686cf73ad827c6ff9acea3bf99080448a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000124ece80300000000000017a914a85daa483c80249a83beaa8defdff18c4e8b5b1287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77c94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc6c9de60","tx_hash":"27a2f4d93b0824540285a7a0160191aef8418b6b713adabade9af4950f062fbc","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pz59m2jg8jqzfx5rh64gmm7l7xxyaz6mzgqzr8dnzs","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21484847","spent_by_me":"0.21484847","received_by_me":"0.21482847","my_balance_change":"-0.00002000","block_height":1454477,"timestamp":1625213445,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"27a2f4d93b0824540285a7a0160191aef8418b6b713adabade9af4950f062fbc","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000258c291614c28fee99fc304b07c787df6d1d16aca86af7e429103c91912965d87020000006a47304402204d2bbeb9a5defa77ef04a6ec115c925e76dee55203df6c4714c5b2122ed81a46022052f696df673dff637ee2db36b1f760c5d58a9dbf74a8ec5e8d976b430ca49d334121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff58c291614c28fee99fc304b07c787df6d1d16aca86af7e429103c91912965d87030000006b483045022100a6d6b9ec4023662628401bf524ac2713d8579026a275cf346c10843eadd7f141022074721fff37a3665a80c0f7324f0499f686cf73ad827c6ff9acea3bf99080448a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000124ece80300000000000017a914a85daa483c80249a83beaa8defdff18c4e8b5b1287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77c94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc6c9de60","tx_hash":"27a2f4d93b0824540285a7a0160191aef8418b6b713adabade9af4950f062fbc","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pz59m2jg8jqzfx5rh64gmm7l7xxyaz6mzgmkyuhysd","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.5988","spent_by_me":"7.5988","received_by_me":"7.4988","my_balance_change":"-0.1000","block_height":1454477,"timestamp":1625213445,"fee_details":null,"coin":"tBCH","internal_id":"df5314098d5124ac85f35adec6243b1c6222b08d1b4592dcb6a3be5dd5eb92df","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b14ff412501d21f232f57f6f712feb4499a58cf614b88834e6a730d36661dd17020000006a473044022078af5d9b47d6f1c17fce8dacb078e8a83fcc1451ad5fcfb0bd6a2208541bcc610220471178547c4c0136bcd0d43bc922b82fe97b9bcaf00f9e790a7396eb7a857b6b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb14ff412501d21f232f57f6f712feb4499a58cf614b88834e6a730d36661dd17030000006b483045022100d4152ffdb6a5cd0cc821a0210ada7f505d05439a2bc7210a6e6dbeb520b5bb5602202a1f0d1587b92bd518e9272c4d89002245f2c431c3b624fc14acd7358c686ae14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000128d5e80300000000000017a914b0deb23cc680b5916cff0e43a6c3cb40d470a95287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac17d94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdebfde60","tx_hash":"aba82b2b595258999055aed6b8de7d451dce8cd2b9c2926c4428e570754c1f38","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzcdav3uc6qttytvlu8y8fkredqdgu9f2gq6epdgy3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21488847","spent_by_me":"0.21488847","received_by_me":"0.21486847","my_balance_change":"-0.00002000","block_height":1454471,"timestamp":1625210966,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"aba82b2b595258999055aed6b8de7d451dce8cd2b9c2926c4428e570754c1f38","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b14ff412501d21f232f57f6f712feb4499a58cf614b88834e6a730d36661dd17020000006a473044022078af5d9b47d6f1c17fce8dacb078e8a83fcc1451ad5fcfb0bd6a2208541bcc610220471178547c4c0136bcd0d43bc922b82fe97b9bcaf00f9e790a7396eb7a857b6b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb14ff412501d21f232f57f6f712feb4499a58cf614b88834e6a730d36661dd17030000006b483045022100d4152ffdb6a5cd0cc821a0210ada7f505d05439a2bc7210a6e6dbeb520b5bb5602202a1f0d1587b92bd518e9272c4d89002245f2c431c3b624fc14acd7358c686ae14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000128d5e80300000000000017a914b0deb23cc680b5916cff0e43a6c3cb40d470a95287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac17d94701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdebfde60","tx_hash":"aba82b2b595258999055aed6b8de7d451dce8cd2b9c2926c4428e570754c1f38","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzcdav3uc6qttytvlu8y8fkredqdgu9f2gmw76hlkv","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.6989","spent_by_me":"7.6989","received_by_me":"7.5989","my_balance_change":"-0.1000","block_height":1454471,"timestamp":1625210966,"fee_details":null,"coin":"tBCH","internal_id":"3941fda591fbabaa4b2b9bb5bd5d774e3e8d417e7b19a092ab2dfd2124d70277","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b264484d1a7bbd70b3b241631097807996523c717fc780e9db2cc9567c84504c020000006a47304402205125b6b70030809178251997c95efdfcfbafe28eac68b6f571348c24d705fcfd02206ca33eeca12657574bbddde106e9b3073cb7fd44ad9818bc14dc451fd2b65d704121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb264484d1a7bbd70b3b241631097807996523c717fc780e9db2cc9567c84504c030000006b483045022100f8eddf3d5e9b5cff19735e5f61e7198228bd35a56ace386a2b62c559263967e602205e89690bbe2c93bc92baafe31a60d2435e434a34c5aed89e04be7af2f80b687e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000012cbde8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace7e04701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdabfde60","tx_hash":"17dd6166d330a7e63488b814f68ca59944eb2f716f7ff532f2211d5012f44fb1","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21490847","spent_by_me":"0.21490847","received_by_me":"0.21488847","my_balance_change":"-0.00002000","block_height":1454471,"timestamp":1625210966,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"17dd6166d330a7e63488b814f68ca59944eb2f716f7ff532f2211d5012f44fb1","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b264484d1a7bbd70b3b241631097807996523c717fc780e9db2cc9567c84504c020000006a47304402205125b6b70030809178251997c95efdfcfbafe28eac68b6f571348c24d705fcfd02206ca33eeca12657574bbddde106e9b3073cb7fd44ad9818bc14dc451fd2b65d704121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb264484d1a7bbd70b3b241631097807996523c717fc780e9db2cc9567c84504c030000006b483045022100f8eddf3d5e9b5cff19735e5f61e7198228bd35a56ace386a2b62c559263967e602205e89690bbe2c93bc92baafe31a60d2435e434a34c5aed89e04be7af2f80b687e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000012cbde8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace7e04701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdabfde60","tx_hash":"17dd6166d330a7e63488b814f68ca59944eb2f716f7ff532f2211d5012f44fb1","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.699","spent_by_me":"7.699","received_by_me":"7.6989","my_balance_change":"-0.0001","block_height":1454471,"timestamp":1625210966,"fee_details":null,"coin":"tBCH","internal_id":"e3e26682d20fbfb643e1a74e9d0f87d70b06f1900b9df3033dab6b76bbce34d3","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002745e24ccb72de11bb5b1a1232f0847e777bd1d9cd075356122864e029c6a7e4c020000006a47304402204303e231d3b6b8bce817c6db01e5800aec588d0e50d9d3786a66c69daf1190f502205805d5ace2e7a143b94899529dbe02b004152026891c1c616bb64d982e8ae4984121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff745e24ccb72de11bb5b1a1232f0847e777bd1d9cd075356122864e029c6a7e4c030000006b483045022100f386e5b02696878c7a1f34b3b5f6ecf83aabb4ebf0c9831bcb5c2ef52fbae918022018c0c90f3fb35aaa666c355d40f295d5542442398d31f3bc540b334349ceeb284121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000003dee8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9fec4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac93a9dd60","tx_hash":"b3427413c0f84d9eca4bfba66133ff781e7569f69f451f20786be7d2df5e39b6","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21493847","spent_by_me":"0.21493847","received_by_me":"0.21491847","my_balance_change":"-0.00002000","block_height":1454353,"timestamp":1625139879,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"b3427413c0f84d9eca4bfba66133ff781e7569f69f451f20786be7d2df5e39b6","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002745e24ccb72de11bb5b1a1232f0847e777bd1d9cd075356122864e029c6a7e4c020000006a47304402204303e231d3b6b8bce817c6db01e5800aec588d0e50d9d3786a66c69daf1190f502205805d5ace2e7a143b94899529dbe02b004152026891c1c616bb64d982e8ae4984121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff745e24ccb72de11bb5b1a1232f0847e777bd1d9cd075356122864e029c6a7e4c030000006b483045022100f386e5b02696878c7a1f34b3b5f6ecf83aabb4ebf0c9831bcb5c2ef52fbae918022018c0c90f3fb35aaa666c355d40f295d5542442398d31f3bc540b334349ceeb284121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000003dee8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9fec4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac93a9dd60","tx_hash":"b3427413c0f84d9eca4bfba66133ff781e7569f69f451f20786be7d2df5e39b6","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.0991","spent_by_me":"0.0991","received_by_me":"0.099","my_balance_change":"-0.0001","block_height":1454353,"timestamp":1625139879,"fee_details":null,"coin":"tBCH","internal_id":"4f213288582062897888cfe263628e2aa1ab9d90562da1a8f6951dd6f57e942a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000003b6395edfd2e76b78201f459ff669751e78ff3361a6fb4bca9e4df8c0137442b3020000006a473044022004c90086c6990d9764b5ed20c7e0edf9ba10328ff4536bd088bc24b851f9929402202f7c9d525e79c85bd2734d3de06432c1464f392c7fc5482c50b8ae2e9ff9f4734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffafece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a535020000006a47304402203a14293b5b7cae47f2bfcb47c4323d029669fd57505cd7085877deb1f839829702203957e8624a0d1abc8dfd44d6443e61146469031f474eff7de342bb42626767814121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb6395edfd2e76b78201f459ff669751e78ff3361a6fb4bca9e4df8c0137442b3030000006b4830450221008f0a6397407f57ea7a78d413e80c5249739a3694bbccb85b61cf8b29f1a0fc940220362b2fcbded953c8dc38dcb320b2f69ade2b0a17be7f89a6da1290465b6fa7364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000012cbee80300000000000017a9149e8513db6a052a73d09f3db084d76d666b7d3b0c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7e84701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97a9dd60","tx_hash":"4c50847c56c92cdbe980c77f713c5296798097106341b2b370bd7b1a4d4864b2","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pz0g2y7mdgzj5u7snu7mppxhd4nxklfmpseptch3ch","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21492847","spent_by_me":"0.21492847","received_by_me":"0.21490847","my_balance_change":"-0.00002000","block_height":1454353,"timestamp":1625139879,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4c50847c56c92cdbe980c77f713c5296798097106341b2b370bd7b1a4d4864b2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000003b6395edfd2e76b78201f459ff669751e78ff3361a6fb4bca9e4df8c0137442b3020000006a473044022004c90086c6990d9764b5ed20c7e0edf9ba10328ff4536bd088bc24b851f9929402202f7c9d525e79c85bd2734d3de06432c1464f392c7fc5482c50b8ae2e9ff9f4734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffafece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a535020000006a47304402203a14293b5b7cae47f2bfcb47c4323d029669fd57505cd7085877deb1f839829702203957e8624a0d1abc8dfd44d6443e61146469031f474eff7de342bb42626767814121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb6395edfd2e76b78201f459ff669751e78ff3361a6fb4bca9e4df8c0137442b3030000006b4830450221008f0a6397407f57ea7a78d413e80c5249739a3694bbccb85b61cf8b29f1a0fc940220362b2fcbded953c8dc38dcb320b2f69ade2b0a17be7f89a6da1290465b6fa7364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000012cbee80300000000000017a9149e8513db6a052a73d09f3db084d76d666b7d3b0c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7e84701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97a9dd60","tx_hash":"4c50847c56c92cdbe980c77f713c5296798097106341b2b370bd7b1a4d4864b2","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pz0g2y7mdgzj5u7snu7mppxhd4nxklfmpsz4vrdx22","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"7.799","spent_by_me":"7.799","received_by_me":"7.699","my_balance_change":"-0.100","block_height":1454353,"timestamp":1625139879,"fee_details":null,"coin":"tBCH","internal_id":"f753153240944a31b59dc5918baaa8135ca06f82209e98b1ef258b8b084500d5","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b6fa38deca7b73a3f32973b02228316240889b837e4ac086d4038f714b983248020000006a4730440220370c51125798e3ec8fb69575dc28d348f328f8ecf472360219bb72738ba511ec0220590df2673525d0bf62b25a2060626cd1802189895e3d649b7f192b8c81155b054121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb6fa38deca7b73a3f32973b02228316240889b837e4ac086d4038f714b983248030000006b483045022100c22856aeffa0c2adee96e7e5a17b743bd70f6830985d846f046e3d0da0e44f7802201a59294c8e5dc51e5049744d773e08c8626e9446ba48095f03b36b5353b576ae4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000003dfe80300000000000017a91412009a5b3c6cea48a56aa118c7ce956de1c0144c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6ff44701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdfa5dd60","tx_hash":"4c7e6a9c024e8622613575d09c1dbd77e747082f23a1b1b51be12db7cc245e74","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pqfqpxjm83kw5j99d2s3337wj4k7rsq5fsngexvak8","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21495847","spent_by_me":"0.21495847","received_by_me":"0.21493847","my_balance_change":"-0.00002000","block_height":1454352,"timestamp":1625138664,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4c7e6a9c024e8622613575d09c1dbd77e747082f23a1b1b51be12db7cc245e74","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b6fa38deca7b73a3f32973b02228316240889b837e4ac086d4038f714b983248020000006a4730440220370c51125798e3ec8fb69575dc28d348f328f8ecf472360219bb72738ba511ec0220590df2673525d0bf62b25a2060626cd1802189895e3d649b7f192b8c81155b054121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb6fa38deca7b73a3f32973b02228316240889b837e4ac086d4038f714b983248030000006b483045022100c22856aeffa0c2adee96e7e5a17b743bd70f6830985d846f046e3d0da0e44f7802201a59294c8e5dc51e5049744d773e08c8626e9446ba48095f03b36b5353b576ae4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000003dfe80300000000000017a91412009a5b3c6cea48a56aa118c7ce956de1c0144c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6ff44701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdfa5dd60","tx_hash":"4c7e6a9c024e8622613575d09c1dbd77e747082f23a1b1b51be12db7cc245e74","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pqfqpxjm83kw5j99d2s3337wj4k7rsq5fsgu7ak2y6","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1991","spent_by_me":"0.1991","received_by_me":"0.0991","my_balance_change":"-0.1000","block_height":1454352,"timestamp":1625138664,"fee_details":null,"coin":"tBCH","internal_id":"54e9e51fab97edde4696049c04ee322711920e792047fda1dbe9590884ab312c","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002606e9b9101d8cf579a7c10992ab425111295388d81b3bce466d6a028ead11b21020000006a473044022100f6bc368f8a049aaa177f43c5cc2b3426f59e0ae05778f225ba312862e4efc0a6021f4435be0843850fbfaabe415ed11db44551019d72e25528d2a75d6a80962fd64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff606e9b9101d8cf579a7c10992ab425111295388d81b3bce466d6a028ead11b21030000006b483045022100f450a3eed8521ad8e06c9b7403739653f6ff6d4ea259ffd0b936bb8d0329a527022033006270d50b46f542e0d1a77b9050fc37d0ddbe89180a0aa64fd51645f397244121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000007c7e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ffc4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdba5dd60","tx_hash":"4832984b718f03d486c04a7e839b884062312822b07329f3a3737bcade38fab6","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21497847","spent_by_me":"0.21497847","received_by_me":"0.21495847","my_balance_change":"-0.00002000","block_height":1454352,"timestamp":1625138664,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4832984b718f03d486c04a7e839b884062312822b07329f3a3737bcade38fab6","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002606e9b9101d8cf579a7c10992ab425111295388d81b3bce466d6a028ead11b21020000006a473044022100f6bc368f8a049aaa177f43c5cc2b3426f59e0ae05778f225ba312862e4efc0a6021f4435be0843850fbfaabe415ed11db44551019d72e25528d2a75d6a80962fd64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff606e9b9101d8cf579a7c10992ab425111295388d81b3bce466d6a028ead11b21030000006b483045022100f450a3eed8521ad8e06c9b7403739653f6ff6d4ea259ffd0b936bb8d0329a527022033006270d50b46f542e0d1a77b9050fc37d0ddbe89180a0aa64fd51645f397244121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000007c7e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ffc4701000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdba5dd60","tx_hash":"4832984b718f03d486c04a7e839b884062312822b07329f3a3737bcade38fab6","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1992","spent_by_me":"0.1992","received_by_me":"0.1991","my_balance_change":"-0.0001","block_height":1454352,"timestamp":1625138664,"fee_details":null,"coin":"tBCH","internal_id":"7fe7d452f05a91f3fa0cce061cea66d9dde340ef6827ea138b46c23c30b1817f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002484f0fe857e30fa9650ea31f9a985e7f5fd446d782ab133e999b2e755f8d78aa020000006a473044022028197c9ccc954c6a8dc9943d8c0567d1cb03012fb424e1bf926184fa2348818802206737f2eaccbaeec3db04593d151e08e98e4072a38c17225e5e8e57f8df207eb44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff484f0fe857e30fa9650ea31f9a985e7f5fd446d782ab133e999b2e755f8d78aa030000006b483045022100fdd6886519021be6ecd9223adcd281ecfa30c0d63e4db3d04868f4321f47a32f02202069e3916205c6b286b7baf307fc697118936d51d6b58b4353279474d4c7849f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000000bb0e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf0b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f53dc60","tx_hash":"6b386c5d39cf82738fdf29ef330b0583e3ce9503a98ca2474fde2c539a346e28","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21501847","spent_by_me":"0.21501847","received_by_me":"0.21499847","my_balance_change":"-0.00002000","block_height":1454208,"timestamp":1625052599,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"6b386c5d39cf82738fdf29ef330b0583e3ce9503a98ca2474fde2c539a346e28","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002484f0fe857e30fa9650ea31f9a985e7f5fd446d782ab133e999b2e755f8d78aa020000006a473044022028197c9ccc954c6a8dc9943d8c0567d1cb03012fb424e1bf926184fa2348818802206737f2eaccbaeec3db04593d151e08e98e4072a38c17225e5e8e57f8df207eb44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff484f0fe857e30fa9650ea31f9a985e7f5fd446d782ab133e999b2e755f8d78aa030000006b483045022100fdd6886519021be6ecd9223adcd281ecfa30c0d63e4db3d04868f4321f47a32f02202069e3916205c6b286b7baf307fc697118936d51d6b58b4353279474d4c7849f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000000bb0e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf0b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f53dc60","tx_hash":"6b386c5d39cf82738fdf29ef330b0583e3ce9503a98ca2474fde2c539a346e28","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.2993","spent_by_me":"0.2993","received_by_me":"0.2992","my_balance_change":"-0.0001","block_height":1454208,"timestamp":1625052599,"fee_details":null,"coin":"tBCH","internal_id":"542af7b65cb4a844fa59e8acf48bbae2df00dfb298d25a6a53addc7121f336c1","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002286e349a532cde4f47a28ca90395cee383050b33ef29df8f7382cf395d6c386b020000006a47304402204471099da0be58324ccfd44f6d2174a7ae2e52d83d4361ec36224ebba1e90f6b022045e601f05e215c09bf9f5bef4cbec8405a1f811b7be65938bca49307d4a012d04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff286e349a532cde4f47a28ca90395cee383050b33ef29df8f7382cf395d6c386b030000006a4730440220711074ad3cd3e52be20dc880a2f0209f5f026af3d7e8634d831815f75177180a02201cc04718debe4d3ec4d57d5ef653e985bacd0394a6788f3ce0a11f90bd3c1a164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000007c8e80300000000000017a9148898ff6101d77e1cb7a6f83bf7842b79a766c77287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0f044801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5353dc60","tx_hash":"211bd1ea28a0d666e4bcb3818d3895121125b42a99107c9a57cfd801919b6e60","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzyf3lmpq8thu89h5murhauy9du6wek8wgjmxqakvv","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21499847","spent_by_me":"0.21499847","received_by_me":"0.21497847","my_balance_change":"-0.00002000","block_height":1454208,"timestamp":1625052599,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"211bd1ea28a0d666e4bcb3818d3895121125b42a99107c9a57cfd801919b6e60","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002286e349a532cde4f47a28ca90395cee383050b33ef29df8f7382cf395d6c386b020000006a47304402204471099da0be58324ccfd44f6d2174a7ae2e52d83d4361ec36224ebba1e90f6b022045e601f05e215c09bf9f5bef4cbec8405a1f811b7be65938bca49307d4a012d04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff286e349a532cde4f47a28ca90395cee383050b33ef29df8f7382cf395d6c386b030000006a4730440220711074ad3cd3e52be20dc880a2f0209f5f026af3d7e8634d831815f75177180a02201cc04718debe4d3ec4d57d5ef653e985bacd0394a6788f3ce0a11f90bd3c1a164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000007c8e80300000000000017a9148898ff6101d77e1cb7a6f83bf7842b79a766c77287e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0f044801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5353dc60","tx_hash":"211bd1ea28a0d666e4bcb3818d3895121125b42a99107c9a57cfd801919b6e60","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzyf3lmpq8thu89h5murhauy9du6wek8wgf0pm8p73","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.2992","spent_by_me":"0.2992","received_by_me":"0.1992","my_balance_change":"-0.1000","block_height":1454208,"timestamp":1625052599,"fee_details":null,"coin":"tBCH","internal_id":"a9522765d09e3d1fb53377f8bb6bb032bef17d8ce3e0183a075502134bcea9de","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002fd24acecb2c35ae5420799d8da8b45cfa892479bd9fd2ec1153f1696390a7908020000006b483045022100b1b53abea221bf3dffb9ffc29a83a9808fbd52d42148b52b5c2d60b63879d5e60220557a4b60f5d13144ad53c5be8c025080167725800bf41ccbe63075526714ee8f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffffd24acecb2c35ae5420799d8da8b45cfa892479bd9fd2ec1153f1696390a7908030000006a47304402206c3ae471148a8963a9d260ed6cc341658e774e65d6e55bd3bd6837d9854cbce60220241b4222bf42096ba190f0243982058ec03e3beab52e9d4801cf4e5bd153107a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000000bb1e80300000000000017a914ba3828c392666b5f7a0d1740c09903bbcf03794387e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acaf134801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf09db60","tx_hash":"aa788d5f752e9b993e13ab82d746d45f7f5e989a1fa30e65a90fe357e80f4f48","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzars2xrjfnxkhm6p5t5psyeqwau7qmegvmp67a2g2","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21503847","spent_by_me":"0.21503847","received_by_me":"0.21501847","my_balance_change":"-0.00002000","block_height":1454069,"timestamp":1624968647,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"aa788d5f752e9b993e13ab82d746d45f7f5e989a1fa30e65a90fe357e80f4f48","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002fd24acecb2c35ae5420799d8da8b45cfa892479bd9fd2ec1153f1696390a7908020000006b483045022100b1b53abea221bf3dffb9ffc29a83a9808fbd52d42148b52b5c2d60b63879d5e60220557a4b60f5d13144ad53c5be8c025080167725800bf41ccbe63075526714ee8f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffffd24acecb2c35ae5420799d8da8b45cfa892479bd9fd2ec1153f1696390a7908030000006a47304402206c3ae471148a8963a9d260ed6cc341658e774e65d6e55bd3bd6837d9854cbce60220241b4222bf42096ba190f0243982058ec03e3beab52e9d4801cf4e5bd153107a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000000bb1e80300000000000017a914ba3828c392666b5f7a0d1740c09903bbcf03794387e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acaf134801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf09db60","tx_hash":"aa788d5f752e9b993e13ab82d746d45f7f5e989a1fa30e65a90fe357e80f4f48","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzars2xrjfnxkhm6p5t5psyeqwau7qmegvq4a98a6h","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.3993","spent_by_me":"0.3993","received_by_me":"0.2993","my_balance_change":"-0.1000","block_height":1454069,"timestamp":1624968647,"fee_details":null,"coin":"tBCH","internal_id":"d0c497e3523a4616fdb3fe23e07381edd1de5d0a368daf42f222b11553d65e87","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002719f36a33aec61ba5833511b9348436d4823996e03a00842595f7840df2b3648020000006a473044022071d1f37e21109d5c75cc3fa07a84a53259528d3acabbe885e6b9210637f14c3802205b87daecbcb9a45c690e8ea84b9fa7a30879d7d3b86747732e90e4d734f287fd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff719f36a33aec61ba5833511b9348436d4823996e03a00842595f7840df2b3648030000006b4830450221008581c9b36c3f7041051fbf22eafa2032a9dca65d6e9500d3636df1b4777a415502201a22260b15675f9e0983d4b246c37579dc482878237a49e2c897f4802c24f02f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000000f99e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f1b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdc09db60","tx_hash":"08790a3996163f15c12efdd99b4792a8cf458bdad8990742e55ac3b2ecac24fd","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21505847","spent_by_me":"0.21505847","received_by_me":"0.21503847","my_balance_change":"-0.00002000","block_height":1454069,"timestamp":1624968647,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"08790a3996163f15c12efdd99b4792a8cf458bdad8990742e55ac3b2ecac24fd","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002719f36a33aec61ba5833511b9348436d4823996e03a00842595f7840df2b3648020000006a473044022071d1f37e21109d5c75cc3fa07a84a53259528d3acabbe885e6b9210637f14c3802205b87daecbcb9a45c690e8ea84b9fa7a30879d7d3b86747732e90e4d734f287fd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff719f36a33aec61ba5833511b9348436d4823996e03a00842595f7840df2b3648030000006b4830450221008581c9b36c3f7041051fbf22eafa2032a9dca65d6e9500d3636df1b4777a415502201a22260b15675f9e0983d4b246c37579dc482878237a49e2c897f4802c24f02f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000000f99e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f1b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdc09db60","tx_hash":"08790a3996163f15c12efdd99b4792a8cf458bdad8990742e55ac3b2ecac24fd","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.3994","spent_by_me":"0.3994","received_by_me":"0.3993","my_balance_change":"-0.0001","block_height":1454069,"timestamp":1624968647,"fee_details":null,"coin":"tBCH","internal_id":"a940cbe5c7e40fcd2a933029ae6b6106e5ebb379e3c5092cfbf09051d023a191","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002ca93a81b3cc4d41793169a7698479a41c0598f53b27159db11eba1ec4c6b7564020000006b483045022100ef7f948d86a99993fdb352718244c0f3286225063ac4287a8263b8138800b7cd02200d8667ec71cab66ef0e2bc39ab39bc6f5beea33020b2ed496f8997acc31a472e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffca93a81b3cc4d41793169a7698479a41c0598f53b27159db11eba1ec4c6b7564030000006b483045022100fd1a44ff9c079add9233e806215ce64108faafbd057a7317f9d6604625d5eb85022006b5c1650fe8c245a2303d516a90bb843de811c4f30819c8efbbc54527acabaa4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001382e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1f2b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2007db60","tx_hash":"d5b0c5505d128e1763070a1eccf0f6f8112c5a19d3d099d930c3fbcfde947310","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21509847","spent_by_me":"0.21509847","received_by_me":"0.21507847","my_balance_change":"-0.00002000","block_height":1454067,"timestamp":1624967412,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"d5b0c5505d128e1763070a1eccf0f6f8112c5a19d3d099d930c3fbcfde947310","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002ca93a81b3cc4d41793169a7698479a41c0598f53b27159db11eba1ec4c6b7564020000006b483045022100ef7f948d86a99993fdb352718244c0f3286225063ac4287a8263b8138800b7cd02200d8667ec71cab66ef0e2bc39ab39bc6f5beea33020b2ed496f8997acc31a472e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffca93a81b3cc4d41793169a7698479a41c0598f53b27159db11eba1ec4c6b7564030000006b483045022100fd1a44ff9c079add9233e806215ce64108faafbd057a7317f9d6604625d5eb85022006b5c1650fe8c245a2303d516a90bb843de811c4f30819c8efbbc54527acabaa4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001382e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1f2b4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2007db60","tx_hash":"d5b0c5505d128e1763070a1eccf0f6f8112c5a19d3d099d930c3fbcfde947310","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.4995","spent_by_me":"0.4995","received_by_me":"0.4994","my_balance_change":"-0.0001","block_height":1454067,"timestamp":1624967412,"fee_details":null,"coin":"tBCH","internal_id":"b7da4342782f017c6d2b2137685669002d8110be6c0871dc50b0faeec1aa060f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002107394decffbc330d999d0d3195a2c11f8f6f0cc1e0a0763178e125d50c5b0d5020000006a473044022064d75b688e8b0abed68fefb7b4bca0b48fe5e1d6509a7845f0916d3588f5ea980220663f2d457a96fabbfd7ba96d04eb5174227c2431db8e45e3eac7c3c832ed61164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff107394decffbc330d999d0d3195a2c11f8f6f0cc1e0a0763178e125d50c5b0d5030000006a47304402204dc0aff8fea6834b79d9e0672faa00eed90c5dc6f8668fa24ae514e64630010902203aab6b0b68082201c6a783e5e01f13a0ccb1e6ff5a2be26418dbf2a55bbea90d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000000f9ae80300000000000017a91465d345bf85c86b496f4a0adb5158087bfdd41afd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f234801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2207db60","tx_hash":"48362bdf40785f594208a0036e9923486d4348931b513358ba61ec3aa3369f71","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppjax3dlshyxkjt0fg9dk52cppalm4q6l5v6k2s8qh","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21507847","spent_by_me":"0.21507847","received_by_me":"0.21505847","my_balance_change":"-0.00002000","block_height":1454067,"timestamp":1624967412,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"48362bdf40785f594208a0036e9923486d4348931b513358ba61ec3aa3369f71","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002107394decffbc330d999d0d3195a2c11f8f6f0cc1e0a0763178e125d50c5b0d5020000006a473044022064d75b688e8b0abed68fefb7b4bca0b48fe5e1d6509a7845f0916d3588f5ea980220663f2d457a96fabbfd7ba96d04eb5174227c2431db8e45e3eac7c3c832ed61164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff107394decffbc330d999d0d3195a2c11f8f6f0cc1e0a0763178e125d50c5b0d5030000006a47304402204dc0aff8fea6834b79d9e0672faa00eed90c5dc6f8668fa24ae514e64630010902203aab6b0b68082201c6a783e5e01f13a0ccb1e6ff5a2be26418dbf2a55bbea90d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000000f9ae80300000000000017a91465d345bf85c86b496f4a0adb5158087bfdd41afd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f234801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2207db60","tx_hash":"48362bdf40785f594208a0036e9923486d4348931b513358ba61ec3aa3369f71","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppjax3dlshyxkjt0fg9dk52cppalm4q6l5hw332sj2","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.4994","spent_by_me":"0.4994","received_by_me":"0.3994","my_balance_change":"-0.1000","block_height":1454067,"timestamp":1624967412,"fee_details":null,"coin":"tBCH","internal_id":"7252512b3bc9266a2b975ef7824ebec128b38094596ae0e9b8c88cb233546d22","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002c768520d2e03203f3a5a4f55e92d62fcfb70f84943333c0d8f8ccbfadcba4943020000006b483045022100d9cfb5b8ab11bbe54f9565b0c60ddebbe0e89b7f80a96b27eb2614790d551ab8022064badd7ae055c1584fd2b9df63ed1b647eb51c52d68317a4e338b614f9175cf94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc768520d2e03203f3a5a4f55e92d62fcfb70f84943333c0d8f8ccbfadcba4943030000006a473044022028e8ed10835b13d1982eab1af2da309fef19ee7837960ac3b73b8e4e7af51b9b02204b0d4c7c959dedccaf52b958cf665dda02c378a45912892ca5b0a96d3c47c6634121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000176be8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf3a4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf5c9d960","tx_hash":"80f4eec1d8b306695210ee47bb533e0bf7c8f7d4bfa9d16dae5045beea0806af","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21513847","spent_by_me":"0.21513847","received_by_me":"0.21511847","my_balance_change":"-0.00002000","block_height":1453937,"timestamp":1624886141,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"80f4eec1d8b306695210ee47bb533e0bf7c8f7d4bfa9d16dae5045beea0806af","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002c768520d2e03203f3a5a4f55e92d62fcfb70f84943333c0d8f8ccbfadcba4943020000006b483045022100d9cfb5b8ab11bbe54f9565b0c60ddebbe0e89b7f80a96b27eb2614790d551ab8022064badd7ae055c1584fd2b9df63ed1b647eb51c52d68317a4e338b614f9175cf94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc768520d2e03203f3a5a4f55e92d62fcfb70f84943333c0d8f8ccbfadcba4943030000006a473044022028e8ed10835b13d1982eab1af2da309fef19ee7837960ac3b73b8e4e7af51b9b02204b0d4c7c959dedccaf52b958cf665dda02c378a45912892ca5b0a96d3c47c6634121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb708000000000000000108000000000000176be8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf3a4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf5c9d960","tx_hash":"80f4eec1d8b306695210ee47bb533e0bf7c8f7d4bfa9d16dae5045beea0806af","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.5996","spent_by_me":"0.5996","received_by_me":"0.5995","my_balance_change":"-0.0001","block_height":1453937,"timestamp":1624886141,"fee_details":null,"coin":"tBCH","internal_id":"fc2805af1ab0a96830e54451dcc701bc4f9fc42988fe3508710f814b1719dfb6","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002af0608eabe4550ae6dd1a9bfd4f7c8f70b3e53bb47ee10526906b3d8c1eef480020000006a47304402205926028c225d9cfe0b848338ab9d7aa9b307dc894a14a32017927c6df78333a202205b93595f0d8f60425f81015ee93a131bf8b7cb7838f77dc174aedb4de593c0a44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffaf0608eabe4550ae6dd1a9bfd4f7c8f70b3e53bb47ee10526906b3d8c1eef480030000006a47304402207556d56d124a9f3d14eded152e944e33335a36c2f517899fdee50d40ec2e0a92022048a1d9b3ef72dd89595a900dbe7a2416151593711e22af2a7dc6d2bffa10053d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001383e80300000000000017a914e14c86f86b702a81293c9b4f044fefaec74b717887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acef324801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf8c9d960","tx_hash":"64756b4ceca1eb11db5971b2538f59c0419a4798769a169317d4c43c1ba893ca","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prs5ephcddcz4qff8jd57pz0a7hvwjm30qfrrgsyld","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21511847","spent_by_me":"0.21511847","received_by_me":"0.21509847","my_balance_change":"-0.00002000","block_height":1453937,"timestamp":1624886141,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"64756b4ceca1eb11db5971b2538f59c0419a4798769a169317d4c43c1ba893ca","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002af0608eabe4550ae6dd1a9bfd4f7c8f70b3e53bb47ee10526906b3d8c1eef480020000006a47304402205926028c225d9cfe0b848338ab9d7aa9b307dc894a14a32017927c6df78333a202205b93595f0d8f60425f81015ee93a131bf8b7cb7838f77dc174aedb4de593c0a44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffaf0608eabe4550ae6dd1a9bfd4f7c8f70b3e53bb47ee10526906b3d8c1eef480030000006a47304402207556d56d124a9f3d14eded152e944e33335a36c2f517899fdee50d40ec2e0a92022048a1d9b3ef72dd89595a900dbe7a2416151593711e22af2a7dc6d2bffa10053d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001383e80300000000000017a914e14c86f86b702a81293c9b4f044fefaec74b717887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acef324801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf8c9d960","tx_hash":"64756b4ceca1eb11db5971b2538f59c0419a4798769a169317d4c43c1ba893ca","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prs5ephcddcz4qff8jd57pz0a7hvwjm30qjhyn2nds","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.5995","spent_by_me":"0.5995","received_by_me":"0.4995","my_balance_change":"-0.1000","block_height":1453937,"timestamp":1624886141,"fee_details":null,"coin":"tBCH","internal_id":"37c0458520cd8c90b00b39efaf39d26bd9da8ad8f24220627d74b01fc2c928d1","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000244dfc25d083a84dd6f6b7e20e1df5125ee14e3dabfa14633e4d1b6e388f8172f020000006a47304402207712ee78491d287bc451bcd8065a56c514db29dbbd194dea21dd52646a51f2ae02206c37d7d5d80511d8d302bd3e9be9880faac730c906d9ed26cbe6e557f9fdb2174121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff44dfc25d083a84dd6f6b7e20e1df5125ee14e3dabfa14633e4d1b6e388f8172f030000006a47304402201a244bf563679202b2aa5237d00227423463102b8d1d402b7b15694e065b6d5102201f26706918081fd99a34966bc9b51c3d244fbd56ac78df3fd64e3b601904ce8f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001b54e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5f4a4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c2d960","tx_hash":"ddcd0c6edba3462b3b7cc52108d8a3efc5f81e0eaea99c62efdb2577c26acf75","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21517847","spent_by_me":"0.21517847","received_by_me":"0.21515847","my_balance_change":"-0.00002000","block_height":1453933,"timestamp":1624884016,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"ddcd0c6edba3462b3b7cc52108d8a3efc5f81e0eaea99c62efdb2577c26acf75","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000244dfc25d083a84dd6f6b7e20e1df5125ee14e3dabfa14633e4d1b6e388f8172f020000006a47304402207712ee78491d287bc451bcd8065a56c514db29dbbd194dea21dd52646a51f2ae02206c37d7d5d80511d8d302bd3e9be9880faac730c906d9ed26cbe6e557f9fdb2174121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff44dfc25d083a84dd6f6b7e20e1df5125ee14e3dabfa14633e4d1b6e388f8172f030000006a47304402201a244bf563679202b2aa5237d00227423463102b8d1d402b7b15694e065b6d5102201f26706918081fd99a34966bc9b51c3d244fbd56ac78df3fd64e3b601904ce8f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001b54e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5f4a4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c2d960","tx_hash":"ddcd0c6edba3462b3b7cc52108d8a3efc5f81e0eaea99c62efdb2577c26acf75","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.6997","spent_by_me":"0.6997","received_by_me":"0.6996","my_balance_change":"-0.0001","block_height":1453933,"timestamp":1624884016,"fee_details":null,"coin":"tBCH","internal_id":"56c200ecd4f819f46e0954f87fb829cac1a2be27f10922eff982f68145c74cdc","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000275cf6ac27725dbef629ca9ae0e1ef8c5efa3d80821c57c3b2b46a3db6e0ccddd020000006a47304402204161d535f2494050dc10c1cd24ff0bcfe8c5df9e6389ad01eb4dffdf6478cdc402205ef8737bc6b18f1171237cbc46517ff362d6760738a228ee147a6ea7c22c5a784121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff75cf6ac27725dbef629ca9ae0e1ef8c5efa3d80821c57c3b2b46a3db6e0ccddd030000006a47304402203d2783dd35d55ebc0522d0551b1f50f3c2d694b5b77abfc8e8ca18efea3d3eeb022019a6fa027b4f6be432ae318b522f3169c6d0c3434f59af69c24adf34e0b906a04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000176ce80300000000000017a9145bbccc15f66b9c23a09fedd529e62fdcb40737bd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8f424801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace8c2d960","tx_hash":"4349badcfacb8c8f0d3c334349f870fbfc622de9554f5a3a3f20032e0d5268c7","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppdmenq47e4ecgaqnlka220x9lwtgpehh5f9g8tku6","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21515847","spent_by_me":"0.21515847","received_by_me":"0.21513847","my_balance_change":"-0.00002000","block_height":1453933,"timestamp":1624884016,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4349badcfacb8c8f0d3c334349f870fbfc622de9554f5a3a3f20032e0d5268c7","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000275cf6ac27725dbef629ca9ae0e1ef8c5efa3d80821c57c3b2b46a3db6e0ccddd020000006a47304402204161d535f2494050dc10c1cd24ff0bcfe8c5df9e6389ad01eb4dffdf6478cdc402205ef8737bc6b18f1171237cbc46517ff362d6760738a228ee147a6ea7c22c5a784121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff75cf6ac27725dbef629ca9ae0e1ef8c5efa3d80821c57c3b2b46a3db6e0ccddd030000006a47304402203d2783dd35d55ebc0522d0551b1f50f3c2d694b5b77abfc8e8ca18efea3d3eeb022019a6fa027b4f6be432ae318b522f3169c6d0c3434f59af69c24adf34e0b906a04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e808000000000000176ce80300000000000017a9145bbccc15f66b9c23a09fedd529e62fdcb40737bd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8f424801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace8c2d960","tx_hash":"4349badcfacb8c8f0d3c334349f870fbfc622de9554f5a3a3f20032e0d5268c7","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppdmenq47e4ecgaqnlka220x9lwtgpehh5j30u3pw8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.6996","spent_by_me":"0.6996","received_by_me":"0.5996","my_balance_change":"-0.1000","block_height":1453933,"timestamp":1624884016,"fee_details":null,"coin":"tBCH","internal_id":"89a6f9c88e1eab39e65d2cb5ee152f7d99d5cff386b71615e838c6ca2b7f9d9a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002c808ec40b3b5efbfd4f44da81812af98b42f50d246f18ac21862575087f3820d020000006a4730440220508fac4b539cde4afc40a1acb8d36977254f14f38d224a3d4b16e6d6a9e6bedc022021cb03286f6eede49727ba6e7ca3fd152ac16414e2caf648d0542914acf163e44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc808ec40b3b5efbfd4f44da81812af98b42f50d246f18ac21862575087f3820d030000006a47304402200e08f25dae26dbd0c4e001478c3e5c046d52358da8eb15524e8b183de42ced1d022028961d5639337864351f40bd7f50f7b88fe649bb9e34b69ba3d7cde7a8c0f58e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001b55e80300000000000017a9146c7e381da62699d3e1986a101d91046d4affa0a887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f524801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6c99d960","tx_hash":"2f17f888e3b6d1e43346a1bfdae314ee2551dfe1207e6b6fdd843a085dc2df44","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppk8uwqa5cnfn5lpnp4pq8v3q3k54laq4qpxj823qc","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21519847","spent_by_me":"0.21519847","received_by_me":"0.21517847","my_balance_change":"-0.00002000","block_height":1453914,"timestamp":1624873371,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"2f17f888e3b6d1e43346a1bfdae314ee2551dfe1207e6b6fdd843a085dc2df44","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002c808ec40b3b5efbfd4f44da81812af98b42f50d246f18ac21862575087f3820d020000006a4730440220508fac4b539cde4afc40a1acb8d36977254f14f38d224a3d4b16e6d6a9e6bedc022021cb03286f6eede49727ba6e7ca3fd152ac16414e2caf648d0542914acf163e44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc808ec40b3b5efbfd4f44da81812af98b42f50d246f18ac21862575087f3820d030000006a47304402200e08f25dae26dbd0c4e001478c3e5c046d52358da8eb15524e8b183de42ced1d022028961d5639337864351f40bd7f50f7b88fe649bb9e34b69ba3d7cde7a8c0f58e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001b55e80300000000000017a9146c7e381da62699d3e1986a101d91046d4affa0a887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f524801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6c99d960","tx_hash":"2f17f888e3b6d1e43346a1bfdae314ee2551dfe1207e6b6fdd843a085dc2df44","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppk8uwqa5cnfn5lpnp4pq8v3q3k54laq4q6j4usxj9","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.7997","spent_by_me":"0.7997","received_by_me":"0.6997","my_balance_change":"-0.1000","block_height":1453914,"timestamp":1624873371,"fee_details":null,"coin":"tBCH","internal_id":"d127f5c07cf70753f059e039900e0b7c918bf211dce31f193c058b6ae44ef964","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b249bb0a56d954fb1f1f737365df288f61dae8fbf8c60f7a00455bfb0b1635e9020000006a4730440220367a94a77ea8d8ba3fb401cd27204e163490d8186be8447ec57dea6f28cb983f022018b9de29b3c58686d7b76d3c73b1ccd5fe0821dbf85ce0c22dd02422115aac224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb249bb0a56d954fb1f1f737365df288f61dae8fbf8c60f7a00455bfb0b1635e9030000006b483045022100c5acda6db723a488b5762c69e2030a5513173c49fa2b14db301c50cd8fab03490220257e50ada7fc92ff2071b57d05185aaa458d7d270b9a5c44324f0ac6b95976f94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001f3de8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff594801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6999d960","tx_hash":"0d82f38750576218c28af146d2502fb498af1218a84df4d4bfefb5b340ec08c8","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21521847","spent_by_me":"0.21521847","received_by_me":"0.21519847","my_balance_change":"-0.00002000","block_height":1453914,"timestamp":1624873371,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0d82f38750576218c28af146d2502fb498af1218a84df4d4bfefb5b340ec08c8","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b249bb0a56d954fb1f1f737365df288f61dae8fbf8c60f7a00455bfb0b1635e9020000006a4730440220367a94a77ea8d8ba3fb401cd27204e163490d8186be8447ec57dea6f28cb983f022018b9de29b3c58686d7b76d3c73b1ccd5fe0821dbf85ce0c22dd02422115aac224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb249bb0a56d954fb1f1f737365df288f61dae8fbf8c60f7a00455bfb0b1635e9030000006b483045022100c5acda6db723a488b5762c69e2030a5513173c49fa2b14db301c50cd8fab03490220257e50ada7fc92ff2071b57d05185aaa458d7d270b9a5c44324f0ac6b95976f94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000001f3de8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff594801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6999d960","tx_hash":"0d82f38750576218c28af146d2502fb498af1218a84df4d4bfefb5b340ec08c8","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.7998","spent_by_me":"0.7998","received_by_me":"0.7997","my_balance_change":"-0.0001","block_height":1453914,"timestamp":1624873371,"fee_details":null,"coin":"tBCH","internal_id":"c747951c681709645102156e2e289823482513014433a5db0d4938c66e49236e","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002736cf584f877ec7b6b95974bc461a9cfb9f126655b5d335471683154cc6cf4c5020000006a47304402206be99fe56a98e7a8c2ffe6f2d05c5c1f46a6577064b84d27d45fe0e959f6e77402201c512629313b48cd4df873222aa49046ae9a3a6e34e359d10d4308cb40438fba4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff736cf584f877ec7b6b95974bc461a9cfb9f126655b5d335471683154cc6cf4c5030000006a473044022020d774d045bbe3dce5b04af836f6a5629c6c4ce75b0b5ba8a1da0ae9a4ecc0530220522f86d20c9e4142e40f9a9c8d25db16fde91d4a0ad6f6ff2107e201386131b64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001f3ee80300000000000017a914b0ca1fea17cf522c7e858416093fc6d95e55824087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accf614801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8c83d460","tx_hash":"e935160bfb5b45007a0fc6f8fbe8da618f28df6573731f1ffb54d9560abb49b2","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzcv58l2zl84ytr7skzpvzflcmv4u4vzgqc2sdq3kz","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21523847","spent_by_me":"0.21523847","received_by_me":"0.21521847","my_balance_change":"-0.00002000","block_height":1453354,"timestamp":1624540312,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"e935160bfb5b45007a0fc6f8fbe8da618f28df6573731f1ffb54d9560abb49b2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002736cf584f877ec7b6b95974bc461a9cfb9f126655b5d335471683154cc6cf4c5020000006a47304402206be99fe56a98e7a8c2ffe6f2d05c5c1f46a6577064b84d27d45fe0e959f6e77402201c512629313b48cd4df873222aa49046ae9a3a6e34e359d10d4308cb40438fba4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff736cf584f877ec7b6b95974bc461a9cfb9f126655b5d335471683154cc6cf4c5030000006a473044022020d774d045bbe3dce5b04af836f6a5629c6c4ce75b0b5ba8a1da0ae9a4ecc0530220522f86d20c9e4142e40f9a9c8d25db16fde91d4a0ad6f6ff2107e201386131b64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001f3ee80300000000000017a914b0ca1fea17cf522c7e858416093fc6d95e55824087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accf614801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8c83d460","tx_hash":"e935160bfb5b45007a0fc6f8fbe8da618f28df6573731f1ffb54d9560abb49b2","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzcv58l2zl84ytr7skzpvzflcmv4u4vzgqr7hk6xyl","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.8998","spent_by_me":"0.8998","received_by_me":"0.7998","my_balance_change":"-0.1000","block_height":1453354,"timestamp":1624540312,"fee_details":null,"coin":"tBCH","internal_id":"9145538486e5c0fec6ec12f8a93b6769a4ec31bdd197777ca9e2b9c96a5a5d8e","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000232809631da50999813c96996d587ceda2829db5e16247477a0eafcbb1ab9a10b020000006a473044022057c88d815fa563eda8ef7d0dd5c522f4501ffa6110df455b151b31609f149c22022048fecfc9b16e983fbfd05b0d2b7c011c3dbec542577fa00cd9bd192b81961f8e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff32809631da50999813c96996d587ceda2829db5e16247477a0eafcbb1ab9a10b030000006a4730440220539e1204d2805c0474111a1f233ff82c0ab06e6e2bfc0cbe4975eacae64a0b1f02200ec83d32c2180f5567d0f760e85f1efc99d9341cfebd86c9a334310f6d4381494121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000002326e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f694801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8983d460","tx_hash":"c5f46ccc5431687154335d5b6526f1b9cfa961c44b97956b7bec77f884f56c73","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21525847","spent_by_me":"0.21525847","received_by_me":"0.21523847","my_balance_change":"-0.00002000","block_height":1453354,"timestamp":1624540312,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"c5f46ccc5431687154335d5b6526f1b9cfa961c44b97956b7bec77f884f56c73","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000232809631da50999813c96996d587ceda2829db5e16247477a0eafcbb1ab9a10b020000006a473044022057c88d815fa563eda8ef7d0dd5c522f4501ffa6110df455b151b31609f149c22022048fecfc9b16e983fbfd05b0d2b7c011c3dbec542577fa00cd9bd192b81961f8e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff32809631da50999813c96996d587ceda2829db5e16247477a0eafcbb1ab9a10b030000006a4730440220539e1204d2805c0474111a1f233ff82c0ab06e6e2bfc0cbe4975eacae64a0b1f02200ec83d32c2180f5567d0f760e85f1efc99d9341cfebd86c9a334310f6d4381494121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000000001080000000000002326e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f694801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8983d460","tx_hash":"c5f46ccc5431687154335d5b6526f1b9cfa961c44b97956b7bec77f884f56c73","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.8999","spent_by_me":"0.8999","received_by_me":"0.8998","my_balance_change":"-0.0001","block_height":1453354,"timestamp":1624540312,"fee_details":null,"coin":"tBCH","internal_id":"070c126f57e38edc060ae9636aab5ed1fbf0fcd29f288863aeba8aaacf629232","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002f6859c372f562f72b9935499310c50707a6630d6550e8220227beb6666718b91010000006a4730440220566c9f2184a1c7911449f81ec78255a103c46dff96d4912491fae7d96c606a6b02202213eb87ed44145ff2afb83d177a9b5d8a8555b23bc8fb425dbfd037fe9b290e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffff6859c372f562f72b9935499310c50707a6630d6550e8220227beb6666718b91020000006b483045022100a2e4426090de97c9a0e3d78d6146bc8d56deb3124e0c37e27ae63cc8ffad531402204d3ed43b7a98e6b003bb2487ead570c9aeb5c0398e1ffdc712ac37ee1ad86cf84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000003e7e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac57754801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0482d460","tx_hash":"26516535a6f61f750522ae7e459133b0aad0ba41aa04dbb384d037290a242e19","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58uu0a8dg36","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21528847","spent_by_me":"0.21528847","received_by_me":"0.21526847","my_balance_change":"-0.00002000","block_height":1453354,"timestamp":1624540312,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"26516535a6f61f750522ae7e459133b0aad0ba41aa04dbb384d037290a242e19","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002f6859c372f562f72b9935499310c50707a6630d6550e8220227beb6666718b91010000006a4730440220566c9f2184a1c7911449f81ec78255a103c46dff96d4912491fae7d96c606a6b02202213eb87ed44145ff2afb83d177a9b5d8a8555b23bc8fb425dbfd037fe9b290e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cfffffffff6859c372f562f72b9935499310c50707a6630d6550e8220227beb6666718b91020000006b483045022100a2e4426090de97c9a0e3d78d6146bc8d56deb3124e0c37e27ae63cc8ffad531402204d3ed43b7a98e6b003bb2487ead570c9aeb5c0398e1ffdc712ac37ee1ad86cf84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000000010800000000000003e7e8030000000000001976a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ace8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac57754801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0482d460","tx_hash":"26516535a6f61f750522ae7e459133b0aad0ba41aa04dbb384d037290a242e19","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:qr9pupr5t6x2p3sd33vgz5ca2xlvgur58u8m6uhlr8","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0.0999","my_balance_change":"-0.0001","block_height":1453354,"timestamp":1624540312,"fee_details":null,"coin":"tBCH","internal_id":"3494cf5ac3a03a85f03d73bacce5a331cfaafd735e4522eed3cc405f77f351bd","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000003192e240a2937d084b3db04aa41bad0aab03391457eae2205751ff6a635655126020000006a47304402205df1f20c02835ab8b7f687d2bcdb028dffc6b1772b3813e4cc75475fba4def6f0220131559457a20df685137fa249e72428e8e7d2d27968df351a7044dab8e7778a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff2682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd020000006a473044022034b496e18d8f4255ee840c9f97102b59a43a6fc50f2c18248eed1f932c30d247022005053a85b80af9539eed1232a8bc389c6d1b088587366b4afe8fd9729fc3ef034121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff192e240a2937d084b3db04aa41bad0aab03391457eae2205751ff6a635655126030000006b48304502210098fc91a689f922c16614dd548639711c47a5ca6efe8aa0603a4ba192e2e394850220586b571f9eee789746e64d8a270c18e6e246cb95d5d5ce88cbac69581baa20dd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002327e80300000000000017a914600760da42613ec484d739a52c672aa4dc3b29dd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6f714801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0882d460","tx_hash":"0ba1b91abbfceaa0777424165edb2928dace87d59669c913989950da31968032","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppsqwcx6gfsna3yy6uu62tr892jdcwefm5qy04gp3q","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21527847","spent_by_me":"0.21527847","received_by_me":"0.21525847","my_balance_change":"-0.00002000","block_height":1453354,"timestamp":1624540312,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0ba1b91abbfceaa0777424165edb2928dace87d59669c913989950da31968032","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000003192e240a2937d084b3db04aa41bad0aab03391457eae2205751ff6a635655126020000006a47304402205df1f20c02835ab8b7f687d2bcdb028dffc6b1772b3813e4cc75475fba4def6f0220131559457a20df685137fa249e72428e8e7d2d27968df351a7044dab8e7778a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff2682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd020000006a473044022034b496e18d8f4255ee840c9f97102b59a43a6fc50f2c18248eed1f932c30d247022005053a85b80af9539eed1232a8bc389c6d1b088587366b4afe8fd9729fc3ef034121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff192e240a2937d084b3db04aa41bad0aab03391457eae2205751ff6a635655126030000006b48304502210098fc91a689f922c16614dd548639711c47a5ca6efe8aa0603a4ba192e2e394850220586b571f9eee789746e64d8a270c18e6e246cb95d5d5ce88cbac69581baa20dd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002327e80300000000000017a914600760da42613ec484d739a52c672aa4dc3b29dd87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6f714801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0882d460","tx_hash":"0ba1b91abbfceaa0777424165edb2928dace87d59669c913989950da31968032","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppsqwcx6gfsna3yy6uu62tr892jdcwefm5msgwjkra","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.9999","spent_by_me":"0.9999","received_by_me":"0.8999","my_balance_change":"-0.1000","block_height":1453354,"timestamp":1624540312,"fee_details":null,"coin":"tBCH","internal_id":"8ac5a09bd55cd5875e57bf6b2ad46ded395e038edc13e69670720884602e9d52","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000023b73ed4180f25328865e326356890047e448911b14ea013cc086e3ad73b57b0301000000d8483045022100ba5cfb6dfe65296dad41023252593c99776c5ae34526f93029058db8463604ca0220500d93700e67702b60c10d88188b818b001dea81a8a13dd7ce678643fb89237a41200000000000000000000000000000000000000000000000000000000000000000004c6b6304c09dc860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff3b73ed4180f25328865e326356890047e448911b14ea013cc086e3ad73b57b03020000006a47304402204329285e2fcbb6f5ff1bd6d23eaee132e0e0494cdc3ec05092a9782e866e4aee02202395943dd6e11fe2e13c79873c5e47c1ef986f78e97dc882adb37ee2424de9f14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac277d4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc09dc860","tx_hash":"918b716666eb7b2220820e55d630667a70500c31995493b9722f562f379c85f6","from":["bchtest:prlh6yhf8tlwnnvyk3klaath66dq3gd27yvc5anfy4","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21529847","spent_by_me":"0.21528847","received_by_me":"0.21528847","my_balance_change":"0.00000000","block_height":1452134,"timestamp":1623760650,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"918b716666eb7b2220820e55d630667a70500c31995493b9722f562f379c85f6","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000023b73ed4180f25328865e326356890047e448911b14ea013cc086e3ad73b57b0301000000d8483045022100ba5cfb6dfe65296dad41023252593c99776c5ae34526f93029058db8463604ca0220500d93700e67702b60c10d88188b818b001dea81a8a13dd7ce678643fb89237a41200000000000000000000000000000000000000000000000000000000000000000004c6b6304c09dc860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff3b73ed4180f25328865e326356890047e448911b14ea013cc086e3ad73b57b03020000006a47304402204329285e2fcbb6f5ff1bd6d23eaee132e0e0494cdc3ec05092a9782e866e4aee02202395943dd6e11fe2e13c79873c5e47c1ef986f78e97dc882adb37ee2424de9f14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac277d4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc09dc860","tx_hash":"918b716666eb7b2220820e55d630667a70500c31995493b9722f562f379c85f6","from":["slptest:prlh6yhf8tlwnnvyk3klaath66dq3gd27yhvnxf7kg"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1452134,"timestamp":1623760650,"fee_details":null,"coin":"tBCH","internal_id":"7e23adb9b707f842ce5c633cca58f5a4c3ec15fca31278d7576380429543b3b1","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002a2685746afd55241c7860e4fb9ad7fbc2d1be032738dc1209f2188d2a07e70a1010000006a47304402207ba49344eee4c5d03b349cd20498e6b326fda219d2bc235fd0077405f89c3ab4022010a40351ce3337386bb28acfce5ae5abb63965b5daddbfcf0b6abe7110dc2c164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffa2685746afd55241c7860e4fb9ad7fbc2d1be032738dc1209f2188d2a07e70a1020000006a4730440220259fcb86b2cdd3d41d52a1f04eea77491d1c87ffd3f4c1be99b9a3858ee90e46022063728ab5b0c9e7e0ac4d6e99c6549dc57b6804fae6bd78257d60f3f0483461e14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914ff7d12e93afee9cd84b46dfef577d69a08a1aaf1870f814801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc09dc860","tx_hash":"037bb573ade386c03c01ea141b9148e44700895663325e862853f28041ed733b","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prlh6yhf8tlwnnvyk3klaath66dq3gd27yvc5anfy4","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21530847","spent_by_me":"0.21530847","received_by_me":"0.21528847","my_balance_change":"-0.00002000","block_height":1452134,"timestamp":1623760650,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"037bb573ade386c03c01ea141b9148e44700895663325e862853f28041ed733b","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002a2685746afd55241c7860e4fb9ad7fbc2d1be032738dc1209f2188d2a07e70a1010000006a47304402207ba49344eee4c5d03b349cd20498e6b326fda219d2bc235fd0077405f89c3ab4022010a40351ce3337386bb28acfce5ae5abb63965b5daddbfcf0b6abe7110dc2c164121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffa2685746afd55241c7860e4fb9ad7fbc2d1be032738dc1209f2188d2a07e70a1020000006a4730440220259fcb86b2cdd3d41d52a1f04eea77491d1c87ffd3f4c1be99b9a3858ee90e46022063728ab5b0c9e7e0ac4d6e99c6549dc57b6804fae6bd78257d60f3f0483461e14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914ff7d12e93afee9cd84b46dfef577d69a08a1aaf1870f814801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc09dc860","tx_hash":"037bb573ade386c03c01ea141b9148e44700895663325e862853f28041ed733b","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prlh6yhf8tlwnnvyk3klaath66dq3gd27yhvnxf7kg"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1452134,"timestamp":1623760650,"fee_details":null,"coin":"tBCH","internal_id":"0e7bf55e1c0fd31ece3febcffba8366d1fde3f87c5457e55c32edcc899a2055c","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002410a8a85384fbbe8648b3a85cc20065aa9ae5b46bfbd67eb9a8e404c58f71177010000006a473044022029550c628335be94cf7366b40bc60da2b9157a3e71a10d50af259e0d98b52ea702205ff9ed3eab4255cb6c4d5cd910edb9e0c7460d3e6747e6e3994533753d7a89504121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff410a8a85384fbbe8648b3a85cc20065aa9ae5b46bfbd67eb9a8e404c58f71177020000006a47304402206dccbd9ef82d300f3f4af4fe625c67aaf8254851e5515413c6e166f0b536e47a02206c1d7b7142c2204adc31ff6f037f2ed497baf7905df832915dc58ccb897917344121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914c3699d1d972d8ec7db7baf37b6493126fc364c2187af904801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac738dc860","tx_hash":"e80d66fd0b4b8cba533789719f06341ee0715e32068a41e4198b0cc697280740","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prpkn8gajukca37m0whn0djfxyn0cdjvyytta8w7m6","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21534847","spent_by_me":"0.21534847","received_by_me":"0.21532847","my_balance_change":"-0.00002000","block_height":1452131,"timestamp":1623756980,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"e80d66fd0b4b8cba533789719f06341ee0715e32068a41e4198b0cc697280740","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002410a8a85384fbbe8648b3a85cc20065aa9ae5b46bfbd67eb9a8e404c58f71177010000006a473044022029550c628335be94cf7366b40bc60da2b9157a3e71a10d50af259e0d98b52ea702205ff9ed3eab4255cb6c4d5cd910edb9e0c7460d3e6747e6e3994533753d7a89504121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff410a8a85384fbbe8648b3a85cc20065aa9ae5b46bfbd67eb9a8e404c58f71177020000006a47304402206dccbd9ef82d300f3f4af4fe625c67aaf8254851e5515413c6e166f0b536e47a02206c1d7b7142c2204adc31ff6f037f2ed497baf7905df832915dc58ccb897917344121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914c3699d1d972d8ec7db7baf37b6493126fc364c2187af904801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac738dc860","tx_hash":"e80d66fd0b4b8cba533789719f06341ee0715e32068a41e4198b0cc697280740","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prpkn8gajukca37m0whn0djfxyn0cdjvyysl6u5ff8"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1452131,"timestamp":1623756980,"fee_details":null,"coin":"tBCH","internal_id":"ea1da4ab1b0970b3f05bda183a7bb7e2d13abfb4b0d732e93072cd65d96aa4a0","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002aab749c051de90b293772ca8b89aa793dd53896d764499ab61f7a945bebc9a0101000000d747304402205cbf6b72120cb686b8723c07b144ecd64f6dd264ab633c4e3e4f15c35bcf7dc902206e1a87cfec14807ccd8e721153de284c928d9f8c4c5b3a329d9b3a9a642bec9641200000000000000000000000000000000000000000000000000000000000000000004c6b63046390c860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffaab749c051de90b293772ca8b89aa793dd53896d764499ab61f7a945bebc9a01020000006b483045022100a1fea0fb751ca2509525ddfa65b3bac1bd27a93986dd4466dab0dd07810364dc02207428be9d24d414048111488e9ea0bea7f453a866181df8fd70fba13ae3fe7cb14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf7844801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6390c860","tx_hash":"a1707ea0d288219f20c18d7332e01b2dbc7fadb94f0e86c74152d5af465768a2","from":["bchtest:pr805s2lsjgc5prldg8tjtu720rdld6lqssjl22saf","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21531847","spent_by_me":"0.21530847","received_by_me":"0.21530847","my_balance_change":"0.00000000","block_height":1452131,"timestamp":1623756980,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"a1707ea0d288219f20c18d7332e01b2dbc7fadb94f0e86c74152d5af465768a2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002aab749c051de90b293772ca8b89aa793dd53896d764499ab61f7a945bebc9a0101000000d747304402205cbf6b72120cb686b8723c07b144ecd64f6dd264ab633c4e3e4f15c35bcf7dc902206e1a87cfec14807ccd8e721153de284c928d9f8c4c5b3a329d9b3a9a642bec9641200000000000000000000000000000000000000000000000000000000000000000004c6b63046390c860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffaab749c051de90b293772ca8b89aa793dd53896d764499ab61f7a945bebc9a01020000006b483045022100a1fea0fb751ca2509525ddfa65b3bac1bd27a93986dd4466dab0dd07810364dc02207428be9d24d414048111488e9ea0bea7f453a866181df8fd70fba13ae3fe7cb14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf7844801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6390c860","tx_hash":"a1707ea0d288219f20c18d7332e01b2dbc7fadb94f0e86c74152d5af465768a2","from":["slptest:pr805s2lsjgc5prldg8tjtu720rdld6lqstxc3s805"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1452131,"timestamp":1623756980,"fee_details":null,"coin":"tBCH","internal_id":"beed6e74f8d6818b97e93fa6af50922621041be59129a8646e981c62e112b657","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000240072897c60c8b19e4418a06325e71e01e34069f71893753ba8c4b0bfd660de801000000d7473044022067bf6d382b26ea5010a02822e1e4ad3983450fef71dc90713fdd71cda537f45202202845eba1b72e172ca8f4e8e1cef297517ae13ee1e23b6bd587e5e3c7709dfe4e41200000000000000000000000000000000000000000000000000000000000000000004c6b6304728dc860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff40072897c60c8b19e4418a06325e71e01e34069f71893753ba8c4b0bfd660de8020000006a47304402206e7e7e013e58c05b9811072050957661afa2e769451dfd45bab866fe80bd330102203e6c9aeeeb3c4e693404140e33fc9e9c0360188d7e569c968768f30e0c5035f04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc78c4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac728dc860","tx_hash":"0d14600f4054dd60cfc51625010c31f1cc1300f8f22e6e9865120f5ec0294616","from":["bchtest:prpkn8gajukca37m0whn0djfxyn0cdjvyytta8w7m6","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21533847","spent_by_me":"0.21532847","received_by_me":"0.21532847","my_balance_change":"0.00000000","block_height":1452131,"timestamp":1623756980,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0d14600f4054dd60cfc51625010c31f1cc1300f8f22e6e9865120f5ec0294616","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000240072897c60c8b19e4418a06325e71e01e34069f71893753ba8c4b0bfd660de801000000d7473044022067bf6d382b26ea5010a02822e1e4ad3983450fef71dc90713fdd71cda537f45202202845eba1b72e172ca8f4e8e1cef297517ae13ee1e23b6bd587e5e3c7709dfe4e41200000000000000000000000000000000000000000000000000000000000000000004c6b6304728dc860b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff40072897c60c8b19e4418a06325e71e01e34069f71893753ba8c4b0bfd660de8020000006a47304402206e7e7e013e58c05b9811072050957661afa2e769451dfd45bab866fe80bd330102203e6c9aeeeb3c4e693404140e33fc9e9c0360188d7e569c968768f30e0c5035f04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc78c4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac728dc860","tx_hash":"0d14600f4054dd60cfc51625010c31f1cc1300f8f22e6e9865120f5ec0294616","from":["slptest:prpkn8gajukca37m0whn0djfxyn0cdjvyysl6u5ff8"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1452131,"timestamp":1623756980,"fee_details":null,"coin":"tBCH","internal_id":"06756d80c727a8b9622d2c71ce711e951770ac4ce941be05956d46b1ae66dc35","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002164629c05e0f1265986e2ef2f80013ccf1310c012516c5cf60dd54400f60140d010000006b483045022100c8c22ac7e4788adaa1907771092a54280120969aa38ed3076a4fcb197134ced9022015f50a4866f85ce1b8d069e344a885836c33c2afdb53632ff407114987c9462f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff164629c05e0f1265986e2ef2f80013ccf1310c012516c5cf60dd54400f60140d020000006b483045022100f7fef47051925d395ab5dd237322ed3ef1070e91375e4f49d85e6ecd2a8bc01702200727b678032300035b21c96a69298daedaecf434b82df0edd09cfe21ab7cd0234121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914cefa415f84918a047f6a0eb92f9e53c6dfb75f0487df884801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6490c860","tx_hash":"019abcbe45a9f761ab9944766d8953dd93a79ab8a82c7793b290de51c049b7aa","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pr805s2lsjgc5prldg8tjtu720rdld6lqssjl22saf","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21532847","spent_by_me":"0.21532847","received_by_me":"0.21530847","my_balance_change":"-0.00002000","block_height":1452131,"timestamp":1623756980,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"019abcbe45a9f761ab9944766d8953dd93a79ab8a82c7793b290de51c049b7aa","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002164629c05e0f1265986e2ef2f80013ccf1310c012516c5cf60dd54400f60140d010000006b483045022100c8c22ac7e4788adaa1907771092a54280120969aa38ed3076a4fcb197134ced9022015f50a4866f85ce1b8d069e344a885836c33c2afdb53632ff407114987c9462f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff164629c05e0f1265986e2ef2f80013ccf1310c012516c5cf60dd54400f60140d020000006b483045022100f7fef47051925d395ab5dd237322ed3ef1070e91375e4f49d85e6ecd2a8bc01702200727b678032300035b21c96a69298daedaecf434b82df0edd09cfe21ab7cd0234121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914cefa415f84918a047f6a0eb92f9e53c6dfb75f0487df884801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6490c860","tx_hash":"019abcbe45a9f761ab9944766d8953dd93a79ab8a82c7793b290de51c049b7aa","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pr805s2lsjgc5prldg8tjtu720rdld6lqstxc3s805"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1452131,"timestamp":1623756980,"fee_details":null,"coin":"tBCH","internal_id":"c28747759edb023a57cf8cb86259548d3f1aa48b26683924d2e64f13811738d6","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e34e90e127bbe6740a13a079a6cf19dab7f8f8e6bf84796487e55504056e0c3801000000d7473044022059220530aca5131991b9c7cee76bd1d57530c53e9418132e56f131f1f33efc4a022022d87c69f635a1d8103ddc5d76a5d0a85255c9b2672ad5daee0b458826a4682d41200000000000000000000000000000000000000000000000000000000000000000004c6b6304a001c260b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe34e90e127bbe6740a13a079a6cf19dab7f8f8e6bf84796487e55504056e0c38020000006a47304402201d6a1ad6094ebb7cd7e7921ccc49fce2e628ab6c510149f69505711c60351365022021c7f3bcad9ae1fd75f2e65e13dba4bd6bf7af5850566f74d9dbd48b8fe466914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97944801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca001c260","tx_hash":"7711f7584c408e9aeb67bdbf465baea95a0620cc853a8b64e8bb4f38858a0a41","from":["bchtest:pzdlyeepfu7a85yjqs8kjhmqmtt84a2w056yc2ccax","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21535847","spent_by_me":"0.21534847","received_by_me":"0.21534847","my_balance_change":"0.00000000","block_height":1449202,"timestamp":1623327926,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"7711f7584c408e9aeb67bdbf465baea95a0620cc853a8b64e8bb4f38858a0a41","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e34e90e127bbe6740a13a079a6cf19dab7f8f8e6bf84796487e55504056e0c3801000000d7473044022059220530aca5131991b9c7cee76bd1d57530c53e9418132e56f131f1f33efc4a022022d87c69f635a1d8103ddc5d76a5d0a85255c9b2672ad5daee0b458826a4682d41200000000000000000000000000000000000000000000000000000000000000000004c6b6304a001c260b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe34e90e127bbe6740a13a079a6cf19dab7f8f8e6bf84796487e55504056e0c38020000006a47304402201d6a1ad6094ebb7cd7e7921ccc49fce2e628ab6c510149f69505711c60351365022021c7f3bcad9ae1fd75f2e65e13dba4bd6bf7af5850566f74d9dbd48b8fe466914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97944801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca001c260","tx_hash":"7711f7584c408e9aeb67bdbf465baea95a0620cc853a8b64e8bb4f38858a0a41","from":["slptest:pzdlyeepfu7a85yjqs8kjhmqmtt84a2w05psl3z00m"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1449202,"timestamp":1623327926,"fee_details":null,"coin":"tBCH","internal_id":"8ed0dd4cdb558f5d425d577676b8795c109cef7b27e5d9744ea6cc0086009bb1","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002cf434aca56ad8f23162765f944782ba76cd2694307e39a0ce00a401f7f83baef010000006a473044022058f4e2b7306b063cf97af4dd9fcdcbd45feed4160a418708f3e62539499404f7022050fc3bc7a13e634c4dc41657474d0629e576d7b4e0c5b8ef8623b77afcff996f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffcf434aca56ad8f23162765f944782ba76cd2694307e39a0ce00a401f7f83baef020000006b483045022100c638bc57150d9f53048f25ab5c9799af31d9f6ede98d9d04982bfa2f1730a14f02200af28c72f35ae09111f9d7047776a6571d57de532ebe1315b62b9086793301224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a9149bf267214f3dd3d092040f695f60dad67af54e7d877f984801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca001c260","tx_hash":"380c6e050455e587647984bfe6f8f8b7da19cfa679a0130a74e6bb27e1904ee3","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzdlyeepfu7a85yjqs8kjhmqmtt84a2w056yc2ccax","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21536847","spent_by_me":"0.21536847","received_by_me":"0.21534847","my_balance_change":"-0.00002000","block_height":1449202,"timestamp":1623327926,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"380c6e050455e587647984bfe6f8f8b7da19cfa679a0130a74e6bb27e1904ee3","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002cf434aca56ad8f23162765f944782ba76cd2694307e39a0ce00a401f7f83baef010000006a473044022058f4e2b7306b063cf97af4dd9fcdcbd45feed4160a418708f3e62539499404f7022050fc3bc7a13e634c4dc41657474d0629e576d7b4e0c5b8ef8623b77afcff996f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffcf434aca56ad8f23162765f944782ba76cd2694307e39a0ce00a401f7f83baef020000006b483045022100c638bc57150d9f53048f25ab5c9799af31d9f6ede98d9d04982bfa2f1730a14f02200af28c72f35ae09111f9d7047776a6571d57de532ebe1315b62b9086793301224121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a9149bf267214f3dd3d092040f695f60dad67af54e7d877f984801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca001c260","tx_hash":"380c6e050455e587647984bfe6f8f8b7da19cfa679a0130a74e6bb27e1904ee3","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzdlyeepfu7a85yjqs8kjhmqmtt84a2w05psl3z00m"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1449202,"timestamp":1623327926,"fee_details":null,"coin":"tBCH","internal_id":"3564c09cca002561f56b05abd63500018bd7b2633fac3605f28a40cba003dacf","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000256333aaa3bd3f67ad5c0dd1f8b999d58766bab0416e149f7111ac0c4b448344301000000d747304402203bcd71f0b8a61dba3e1ad5cc4833873343235f429acd2f5108bccd2a78fd4c1c02201f10102ee2f7c968dd19700c23b193f55d587c3e7add9c775d127786ef9eb26b41200000000000000000000000000000000000000000000000000000000000000000004c6b6304c358bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff56333aaa3bd3f67ad5c0dd1f8b999d58766bab0416e149f7111ac0c4b4483443020000006b483045022100b017d816fe381c0fb200cc154117d1f65ddd668800a75d5fa6099bd16f23be1e02200e0635852d63580259a2479b88065c5e75d61eb6af45eb6dff42ef3654fafba44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac679c4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc358bf60","tx_hash":"efba837f1f400ae00c9ae3074369d26ca72b7844f9652716238fad56ca4a43cf","from":["bchtest:pzgwyss0ajdyvfxgjelqu85fy9yx2yfk9u4m7ad4zy","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21537847","spent_by_me":"0.21536847","received_by_me":"0.21536847","my_balance_change":"0.00000000","block_height":1449059,"timestamp":1623153240,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"efba837f1f400ae00c9ae3074369d26ca72b7844f9652716238fad56ca4a43cf","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000256333aaa3bd3f67ad5c0dd1f8b999d58766bab0416e149f7111ac0c4b448344301000000d747304402203bcd71f0b8a61dba3e1ad5cc4833873343235f429acd2f5108bccd2a78fd4c1c02201f10102ee2f7c968dd19700c23b193f55d587c3e7add9c775d127786ef9eb26b41200000000000000000000000000000000000000000000000000000000000000000004c6b6304c358bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff56333aaa3bd3f67ad5c0dd1f8b999d58766bab0416e149f7111ac0c4b4483443020000006b483045022100b017d816fe381c0fb200cc154117d1f65ddd668800a75d5fa6099bd16f23be1e02200e0635852d63580259a2479b88065c5e75d61eb6af45eb6dff42ef3654fafba44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac679c4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc358bf60","tx_hash":"efba837f1f400ae00c9ae3074369d26ca72b7844f9652716238fad56ca4a43cf","from":["slptest:pzgwyss0ajdyvfxgjelqu85fy9yx2yfk9uw0exhzse"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1449059,"timestamp":1623153240,"fee_details":null,"coin":"tBCH","internal_id":"7a87dc602fb74b66ffdadc35efb67cdd4688c4c57e5bdbd4f4335d25eceee309","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000025bda96aeabdc64916e14920236d4df010ad6aa009ed77375370a0450131fd211010000006b483045022100ad6f91abd961da2f87bd60911dc937bcbb0cab9c054d89c5f93fc3ed755a158402203eac6c254cfb808b42e449f3a395b0f7cf4566e45ccc2b5a752c9fb52d95cc934121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5bda96aeabdc64916e14920236d4df010ad6aa009ed77375370a0450131fd211020000006a47304402203db71882057cb8f590954d15f740f70f30ee3db57af1c6822d76dfa0d4c14742022008767a3df6a2bfef875b5922a4131e884ad99208a4a31b6dadc9c11517ee7a044121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a91490e2420fec9a4624c8967e0e1e8921486511362f874fa04801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc358bf60","tx_hash":"433448b4c4c01a11f749e11604ab6b76589d998b1fddc0d57af6d33baa3a3356","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzgwyss0ajdyvfxgjelqu85fy9yx2yfk9u4m7ad4zy","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21538847","spent_by_me":"0.21538847","received_by_me":"0.21536847","my_balance_change":"-0.00002000","block_height":1449059,"timestamp":1623153240,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"433448b4c4c01a11f749e11604ab6b76589d998b1fddc0d57af6d33baa3a3356","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000025bda96aeabdc64916e14920236d4df010ad6aa009ed77375370a0450131fd211010000006b483045022100ad6f91abd961da2f87bd60911dc937bcbb0cab9c054d89c5f93fc3ed755a158402203eac6c254cfb808b42e449f3a395b0f7cf4566e45ccc2b5a752c9fb52d95cc934121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5bda96aeabdc64916e14920236d4df010ad6aa009ed77375370a0450131fd211020000006a47304402203db71882057cb8f590954d15f740f70f30ee3db57af1c6822d76dfa0d4c14742022008767a3df6a2bfef875b5922a4131e884ad99208a4a31b6dadc9c11517ee7a044121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a91490e2420fec9a4624c8967e0e1e8921486511362f874fa04801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc358bf60","tx_hash":"433448b4c4c01a11f749e11604ab6b76589d998b1fddc0d57af6d33baa3a3356","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzgwyss0ajdyvfxgjelqu85fy9yx2yfk9uw0exhzse"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1449059,"timestamp":1623153240,"fee_details":null,"coin":"tBCH","internal_id":"b590067f740be1f064fe3914a94d20daa3c6030e96a121a92a48733f6838926a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000261c03a8fa3713a1c69f5d72e49535bda965fee2b108b817a2963a209107eb176010000006a4730440220562c4ceee979119d1c2195369bbe62aba1e3fc44c1f5db2c8ae26b767feae8df0220331550ba31fedc8904e25ff2d7387f33d19d9c9fd91749ce00e4992ea75a1d484121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff61c03a8fa3713a1c69f5d72e49535bda965fee2b108b817a2963a209107eb176020000006a4730440220550ae9fa5bb1c12e7272eef9a32f3664fca340199826de16323100e11138a8c6022058b2a7c1bebeed29e436f5b7d5a0a7794830ae5c210e986a87083dbfca59e0da4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002328e80300000000000017a914fb01b4ac662ae5b17ef686d78d353c28f26c228c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1fa84801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9e50bf60","tx_hash":"bda0a249ab74f448c8b4612f3edc9dadcde646494afafb458cd406076d818226","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prasrd9vvc4wtvt776rd0rf48s50ympz3s24vepcad","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21541847","spent_by_me":"0.21541847","received_by_me":"0.21539847","my_balance_change":"-0.00002000","block_height":1449057,"timestamp":1623150810,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"bda0a249ab74f448c8b4612f3edc9dadcde646494afafb458cd406076d818226","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000261c03a8fa3713a1c69f5d72e49535bda965fee2b108b817a2963a209107eb176010000006a4730440220562c4ceee979119d1c2195369bbe62aba1e3fc44c1f5db2c8ae26b767feae8df0220331550ba31fedc8904e25ff2d7387f33d19d9c9fd91749ce00e4992ea75a1d484121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff61c03a8fa3713a1c69f5d72e49535bda965fee2b108b817a2963a209107eb176020000006a4730440220550ae9fa5bb1c12e7272eef9a32f3664fca340199826de16323100e11138a8c6022058b2a7c1bebeed29e436f5b7d5a0a7794830ae5c210e986a87083dbfca59e0da4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002328e80300000000000017a914fb01b4ac662ae5b17ef686d78d353c28f26c228c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1fa84801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9e50bf60","tx_hash":"bda0a249ab74f448c8b4612f3edc9dadcde646494afafb458cd406076d818226","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prasrd9vvc4wtvt776rd0rf48s50ympz3s3ptzm00s","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"1","received_by_me":"0.9","my_balance_change":"-0.1","block_height":1449057,"timestamp":1623150810,"fee_details":null,"coin":"tBCH","internal_id":"b87b0c4a4487dd7f0727fb1484b7bef702d865e438afb4c74a784b5d369a8d30","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd01000000d747304402201b17877e953cf30a4c6f454f6b5bb848b8e22d63314faf10d6dd84eb58890c1c022027a710c07477a35f8a676dca775b60cf60d8ff50fb9435d8dffd7f5cb329db7441200000000000000000000000000000000000000000000000000000000000000000004c6b63049e50bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff2682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd030000006b483045022100b3cc1ff2e40d708111e822dc44a0531f635268815a33907946abd6e9e463bc0902203699ed5e35bd96151959d99081ffc00a4284b2fb6796d99f2b1e755add919ddd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac37a44801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9e50bf60","tx_hash":"11d21f1350040a377573d79e00aad60a01dfd4360292146e9164dcabae96da5b","from":["bchtest:prasrd9vvc4wtvt776rd0rf48s50ympz3s24vepcad","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21539847","spent_by_me":"0.21538847","received_by_me":"0.21538847","my_balance_change":"0.00000000","block_height":1449057,"timestamp":1623150810,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"11d21f1350040a377573d79e00aad60a01dfd4360292146e9164dcabae96da5b","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd01000000d747304402201b17877e953cf30a4c6f454f6b5bb848b8e22d63314faf10d6dd84eb58890c1c022027a710c07477a35f8a676dca775b60cf60d8ff50fb9435d8dffd7f5cb329db7441200000000000000000000000000000000000000000000000000000000000000000004c6b63049e50bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff2682816d0706d48c45fbfa4a4946e6cdad9ddc3e2f61b4c848f474ab49a2a0bd030000006b483045022100b3cc1ff2e40d708111e822dc44a0531f635268815a33907946abd6e9e463bc0902203699ed5e35bd96151959d99081ffc00a4284b2fb6796d99f2b1e755add919ddd4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac37a44801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9e50bf60","tx_hash":"11d21f1350040a377573d79e00aad60a01dfd4360292146e9164dcabae96da5b","from":["slptest:prasrd9vvc4wtvt776rd0rf48s50ympz3s3ptzm00s"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1449057,"timestamp":1623150810,"fee_details":null,"coin":"tBCH","internal_id":"ad73b00f1f0bf7635e480573b31574f38a257cac39b0a9a8134ac53a16f5e980","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000247721382b1cbadd5a935b7ea5054ee9c47ef93f8a1c804ea8228057ca5f5625b01000000b6473044022007e1a1e08c86c4d67bc48b468ee1bff60204135e35b14b72dc46c27a34600097022026205ef3706f44094d464d47a54bc0f2a21762abaff4f9aa34527a2f8232baf941514c6b63041b24bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff47721382b1cbadd5a935b7ea5054ee9c47ef93f8a1c804ea8228057ca5f5625b020000006b483045022100906ae8f5b2e75571ec7442264f2b775731ca98d1e56bda6671ef869d1ae0156902200d1367b5adaec03158633a6380f60aa3a6a6a668320b333eb2f0efb3635684d84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acefaf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace625bf60","tx_hash":"76b17e1009a263297a818b102bee5f96da5b53492ed7f5691c3a71a38f3ac061","from":["bchtest:pp2zukdgpr7u6x45v8kg30hc8c9mndvavs30ttm4v3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21542847","spent_by_me":"0.21541847","received_by_me":"0.21541847","my_balance_change":"0.00000000","block_height":1449054,"timestamp":1623147145,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"76b17e1009a263297a818b102bee5f96da5b53492ed7f5691c3a71a38f3ac061","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000247721382b1cbadd5a935b7ea5054ee9c47ef93f8a1c804ea8228057ca5f5625b01000000b6473044022007e1a1e08c86c4d67bc48b468ee1bff60204135e35b14b72dc46c27a34600097022026205ef3706f44094d464d47a54bc0f2a21762abaff4f9aa34527a2f8232baf941514c6b63041b24bf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff47721382b1cbadd5a935b7ea5054ee9c47ef93f8a1c804ea8228057ca5f5625b020000006b483045022100906ae8f5b2e75571ec7442264f2b775731ca98d1e56bda6671ef869d1ae0156902200d1367b5adaec03158633a6380f60aa3a6a6a668320b333eb2f0efb3635684d84121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acefaf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace625bf60","tx_hash":"76b17e1009a263297a818b102bee5f96da5b53492ed7f5691c3a71a38f3ac061","from":["slptest:pp2zukdgpr7u6x45v8kg30hc8c9mndvavs2mvspz7v"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1449054,"timestamp":1623147145,"fee_details":null,"coin":"tBCH","internal_id":"c2ebf21255a77ea055e56b796c8aea5346f09de21c04acce3256775b3b78aeb0","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002addbd6e7f33432871f2c5a0a568b85f4ef6aca3ebc1cfe2810ba33def3f9d355010000006a473044022013ddc4993f9466d220b53ef2716bd53cdb8fdfecb54e69192013cf6c10c8af4802203fff4654ea16c31f313d2013b958974c3e2f57c888351b0b76266ba82d798ff74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffaddbd6e7f33432871f2c5a0a568b85f4ef6aca3ebc1cfe2810ba33def3f9d355020000006a4730440220332a1361aa1a5980796f9c65d901087ce799589e94c5c581664f056dde63e17b022028c5c82bb173c8e51995f4325a0f56ffe1b07be8901ae395facdcc5c19b2371e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914542e59a808fdcd1ab461ec88bef83e0bb9b59d6487d7b34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3c40bf60","tx_hash":"5b62f5a57c052882ea04c8a1f893ef479cee5450eab735a9d5adcbb182137247","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp2zukdgpr7u6x45v8kg30hc8c9mndvavs30ttm4v3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21543847","spent_by_me":"0.21543847","received_by_me":"0.21541847","my_balance_change":"-0.00002000","block_height":1449054,"timestamp":1623147145,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"5b62f5a57c052882ea04c8a1f893ef479cee5450eab735a9d5adcbb182137247","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002addbd6e7f33432871f2c5a0a568b85f4ef6aca3ebc1cfe2810ba33def3f9d355010000006a473044022013ddc4993f9466d220b53ef2716bd53cdb8fdfecb54e69192013cf6c10c8af4802203fff4654ea16c31f313d2013b958974c3e2f57c888351b0b76266ba82d798ff74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffaddbd6e7f33432871f2c5a0a568b85f4ef6aca3ebc1cfe2810ba33def3f9d355020000006a4730440220332a1361aa1a5980796f9c65d901087ce799589e94c5c581664f056dde63e17b022028c5c82bb173c8e51995f4325a0f56ffe1b07be8901ae395facdcc5c19b2371e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914542e59a808fdcd1ab461ec88bef83e0bb9b59d6487d7b34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3c40bf60","tx_hash":"5b62f5a57c052882ea04c8a1f893ef479cee5450eab735a9d5adcbb182137247","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp2zukdgpr7u6x45v8kg30hc8c9mndvavs2mvspz7v"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1449054,"timestamp":1623147145,"fee_details":null,"coin":"tBCH","internal_id":"2ed101b6d14b4837dcc630be904fb8985ee7a3fdd8fd26909784fdbfb10cf64a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002afece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a53501000000b7483045022100f00a64f90282a063d887a4a8cbc06adcad7c437f85dcee8c8cd95371bf7664eb02203a5a0a8ccf15c43c0f3f80bb0fa762a975d810937cab93070f9062fdab01954741514c6b6304c71ebf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffffafece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a535030000006a47304402207b48da2aaae3600782d847b9bdc1a463ac84db39c72c5ed2ccb4ef62547adf21022079736eb9c4554c4e6b323ae78414d54b5122062ac3798b44664210d88fe20af24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbfb74801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1821bf60","tx_hash":"55d3f9f3de33ba1028fe1cbc3eca6aeff4858b560a5a2c1f873234f3e7d6dbad","from":["bchtest:pp422sn4fflcuvfvkfaqnrkwl7tjkm75lqwvyk3s9g","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21544847","spent_by_me":"0.21543847","received_by_me":"0.21543847","my_balance_change":"0.00000000","block_height":1449053,"timestamp":1623145925,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"55d3f9f3de33ba1028fe1cbc3eca6aeff4858b560a5a2c1f873234f3e7d6dbad","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002afece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a53501000000b7483045022100f00a64f90282a063d887a4a8cbc06adcad7c437f85dcee8c8cd95371bf7664eb02203a5a0a8ccf15c43c0f3f80bb0fa762a975d810937cab93070f9062fdab01954741514c6b6304c71ebf60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffffafece59188497a02c4aca4a05c8da14b545fd9ceed94d4f44e74a3c10759a535030000006a47304402207b48da2aaae3600782d847b9bdc1a463ac84db39c72c5ed2ccb4ef62547adf21022079736eb9c4554c4e6b323ae78414d54b5122062ac3798b44664210d88fe20af24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbfb74801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1821bf60","tx_hash":"55d3f9f3de33ba1028fe1cbc3eca6aeff4858b560a5a2c1f873234f3e7d6dbad","from":["slptest:pp422sn4fflcuvfvkfaqnrkwl7tjkm75lq4crdt8h4"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1449053,"timestamp":1623145925,"fee_details":null,"coin":"tBCH","internal_id":"d68d695eb3338366bb4382effdf295f311651e9f135b36777359f0083a13d661","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000225e1230d5c75a6eee27b9927c6b3157b0863f3877ee2e9a912c2a907664da37f010000006a47304402200960739cd5f8af37a9fd4001c6730d491c1deab1de01f3029c58296457783d240220261b14e3b5dde5d3ea58534425fba176697008ae137ba2540ffc4182616c9fdf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff25e1230d5c75a6eee27b9927c6b3157b0863f3877ee2e9a912c2a907664da37f020000006b483045022100d9e2be197b9abfc5dd426f6ce38a2549d214897a7b93f4c59cf7ad07a64a0b8802202bb44e708df28d3d6f9eff46ce951b206f1551d605f6dff8dd5d069f3f92e4f04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914dce608c2df96812f8ff8246d9abfec0249204bca878fbf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace73abf60","tx_hash":"4238cf14335697e3512af0ec047fdcb58de45dbed0d77b031877f0eb47d90ab5","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prwwvzxzm7tgztu0lqjxmx4laspyjgztegks0enazx","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21546847","spent_by_me":"0.21546847","received_by_me":"0.21544847","my_balance_change":"-0.00002000","block_height":1449053,"timestamp":1623145925,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4238cf14335697e3512af0ec047fdcb58de45dbed0d77b031877f0eb47d90ab5","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000225e1230d5c75a6eee27b9927c6b3157b0863f3877ee2e9a912c2a907664da37f010000006a47304402200960739cd5f8af37a9fd4001c6730d491c1deab1de01f3029c58296457783d240220261b14e3b5dde5d3ea58534425fba176697008ae137ba2540ffc4182616c9fdf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff25e1230d5c75a6eee27b9927c6b3157b0863f3877ee2e9a912c2a907664da37f020000006b483045022100d9e2be197b9abfc5dd426f6ce38a2549d214897a7b93f4c59cf7ad07a64a0b8802202bb44e708df28d3d6f9eff46ce951b206f1551d605f6dff8dd5d069f3f92e4f04121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914dce608c2df96812f8ff8246d9abfec0249204bca878fbf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace73abf60","tx_hash":"4238cf14335697e3512af0ec047fdcb58de45dbed0d77b031877f0eb47d90ab5","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prwwvzxzm7tgztu0lqjxmx4laspyjgztegdygzf2sm"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1449053,"timestamp":1623145925,"fee_details":null,"coin":"tBCH","internal_id":"926ec71808b36d4e794d0cc40305fa427eefe8b0dde82d72c4db96f51129656f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000303897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f3020000006a473044022048cc5e2103d3d02092dea7cf75bd1a87b09a0aedef205a35e6a7c83259823b4102203ccaabcd115b0f033c67f21ccbcca87ed5c5323c58278439af3b141e4fcd39d54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a020000006b483045022100f4a3148fff695d5cb6839c67a2dcc392e5efc793cf1b7cb952e711a6b6649a4702203c6f675eb30782964e55dead027cdb87cf916f3b717a5aa0599b8ff001011b004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb50ad947ebf07718037bd7d0be5de48db5dc7f04ecf02a51e397563314cf3842020000006a47304402204681615e42b599e0febd9b8107080903f03be146eefcc07efa243f929360bc2f02202a2afcfe72f45d06e8c48fca98fda5ee8005a6a0a35fa521f1444bf0ebb928574121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000012cc8e80300000000000017a9146aa542754a7f8e312cb27a098eceff972b6fd4f887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca7bb4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace73abf60","tx_hash":"35a55907c1a3744ef4d494edced95f544ba18d5ca0a4acc4027a498891e5ecaf","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp422sn4fflcuvfvkfaqnrkwl7tjkm75lqwvyk3s9g","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21546847","spent_by_me":"0.21546847","received_by_me":"0.21544847","my_balance_change":"-0.00002000","block_height":1449053,"timestamp":1623145925,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"35a55907c1a3744ef4d494edced95f544ba18d5ca0a4acc4027a498891e5ecaf","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000303897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f3020000006a473044022048cc5e2103d3d02092dea7cf75bd1a87b09a0aedef205a35e6a7c83259823b4102203ccaabcd115b0f033c67f21ccbcca87ed5c5323c58278439af3b141e4fcd39d54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a020000006b483045022100f4a3148fff695d5cb6839c67a2dcc392e5efc793cf1b7cb952e711a6b6649a4702203c6f675eb30782964e55dead027cdb87cf916f3b717a5aa0599b8ff001011b004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb50ad947ebf07718037bd7d0be5de48db5dc7f04ecf02a51e397563314cf3842020000006a47304402204681615e42b599e0febd9b8107080903f03be146eefcc07efa243f929360bc2f02202a2afcfe72f45d06e8c48fca98fda5ee8005a6a0a35fa521f1444bf0ebb928574121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000012cc8e80300000000000017a9146aa542754a7f8e312cb27a098eceff972b6fd4f887e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88aca7bb4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace73abf60","tx_hash":"35a55907c1a3744ef4d494edced95f544ba18d5ca0a4acc4027a498891e5ecaf","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp422sn4fflcuvfvkfaqnrkwl7tjkm75lq4crdt8h4","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"8.7","spent_by_me":"8.7","received_by_me":"7.7","my_balance_change":"-1.0","block_height":1449053,"timestamp":1623145925,"fee_details":null,"coin":"tBCH","internal_id":"6c2441a91cac06cb087ae55d216d52cbc6f8c4e47a955dc32829814325c64653","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002c26e8b5503cf67379fdf81adf2747ffafff43d50b746d19ca7e39612fc05ac92010000006a4730440220033a209e7072eaa46bed21a7d27c4d45f38f068ca855883bbc568dc89cc2fd15022053165e8b959535c5aa269794c18bf617e43499166ae2bf0d36d5ec2c1f2390204121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc26e8b5503cf67379fdf81adf2747ffafff43d50b746d19ca7e39612fc05ac92020000006a47304402207bac287b5a8f6d2bd3ecfac57b7a992c56f8303fe89130efb4b42cb2472d92ff02206f196c89b7b1cbd9bd52a7c3f584d27871cd290c74c30c63f1fffb4052d542614121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a91469a0891adb04109c8d31e9fc6f27edc41e87206c875fc74801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac221dbe60","tx_hash":"b0dde35f1a1b9c98dd775c03e46afdf8072dcc68ad36cac7148ad9d2048d016c","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp56pzg6mvzpp8ydx85lcme8ahzpapeqds2lhdxyta","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21548847","spent_by_me":"0.21548847","received_by_me":"0.21546847","my_balance_change":"-0.00002000","block_height":1448993,"timestamp":1623072673,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"b0dde35f1a1b9c98dd775c03e46afdf8072dcc68ad36cac7148ad9d2048d016c","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002c26e8b5503cf67379fdf81adf2747ffafff43d50b746d19ca7e39612fc05ac92010000006a4730440220033a209e7072eaa46bed21a7d27c4d45f38f068ca855883bbc568dc89cc2fd15022053165e8b959535c5aa269794c18bf617e43499166ae2bf0d36d5ec2c1f2390204121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc26e8b5503cf67379fdf81adf2747ffafff43d50b746d19ca7e39612fc05ac92020000006a47304402207bac287b5a8f6d2bd3ecfac57b7a992c56f8303fe89130efb4b42cb2472d92ff02206f196c89b7b1cbd9bd52a7c3f584d27871cd290c74c30c63f1fffb4052d542614121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a91469a0891adb04109c8d31e9fc6f27edc41e87206c875fc74801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac221dbe60","tx_hash":"b0dde35f1a1b9c98dd775c03e46afdf8072dcc68ad36cac7148ad9d2048d016c","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp56pzg6mvzpp8ydx85lcme8ahzpapeqds3tskuneq"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1448993,"timestamp":1623072673,"fee_details":null,"coin":"tBCH","internal_id":"db5de208cc0504197c0314d2c65e3ac3d3f18e40b9e5ca96d5323652a768326f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e98601b61821a5369f9e5d74bed4ae624166ce77df427a8e420ddc46e2666a8801000000d74730440220413afe0ff2672516caae61ee09156ba2f09098c71c7a0c019bca7e15fcee59a8022027846c0fd3a1df05dc95cf28d81cc46b1e8b5783bcac758e1fc4b0e2bc786dfd41200000000000000000000000000000000000000000000000000000000000000000004c6b63049f1cbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe98601b61821a5369f9e5d74bed4ae624166ce77df427a8e420ddc46e2666a88020000006b483045022100eb6044621a663634bf559dbea3d0ecf9495cdcc833c7da3faba5cef2612d16c1022056215d69ed28c10b50f531e3bfeb79f751ede2ac5086d398d1ee91768e7bf6274121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47cb4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f1cbe60","tx_hash":"92ac05fc1296e3a79cd146b7503df4fffa7f74f2ad81df9f3767cf03558b6ec2","from":["bchtest:pzj6q9rrdzr9wlrvlqznt8cuzlf7gfhlhc04n8kkkw","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21549847","spent_by_me":"0.21548847","received_by_me":"0.21548847","my_balance_change":"0.00000000","block_height":1448993,"timestamp":1623072673,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"92ac05fc1296e3a79cd146b7503df4fffa7f74f2ad81df9f3767cf03558b6ec2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e98601b61821a5369f9e5d74bed4ae624166ce77df427a8e420ddc46e2666a8801000000d74730440220413afe0ff2672516caae61ee09156ba2f09098c71c7a0c019bca7e15fcee59a8022027846c0fd3a1df05dc95cf28d81cc46b1e8b5783bcac758e1fc4b0e2bc786dfd41200000000000000000000000000000000000000000000000000000000000000000004c6b63049f1cbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe98601b61821a5369f9e5d74bed4ae624166ce77df427a8e420ddc46e2666a88020000006b483045022100eb6044621a663634bf559dbea3d0ecf9495cdcc833c7da3faba5cef2612d16c1022056215d69ed28c10b50f531e3bfeb79f751ede2ac5086d398d1ee91768e7bf6274121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac47cb4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f1cbe60","tx_hash":"92ac05fc1296e3a79cd146b7503df4fffa7f74f2ad81df9f3767cf03558b6ec2","from":["slptest:pzj6q9rrdzr9wlrvlqznt8cuzlf7gfhlhc5p5uvpyn"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1448993,"timestamp":1623072673,"fee_details":null,"coin":"tBCH","internal_id":"2f16d6629b3da90140cb3bce4fc1149add1a5d43f2bda8ecb18032e909d64061","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000238edeb1b3f37607ef191934d0b4f56f98faa05df894aead091313c3d08289b0b010000006b483045022100c42500ba0e9275de19c2b48f38680a86fc7f0e7ec3e4597797fe2829a954b50c02204c456f45c54ab89714ded72cbd4b88679d09220f928b9eb85c16c75da89b287c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff38edeb1b3f37607ef191934d0b4f56f98faa05df894aead091313c3d08289b0b020000006b483045022100e83e62bb7500a163bb49a938aedf6bb8ba2d181732f4dd6b3503996299a6223b022025c6962467ea069fb28b3dc0473b448fe60c743ef60fdb365f4c72d87fa1512e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914a5a014636886577c6cf805359f1c17d3e426ffbe872fcf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f1cbe60","tx_hash":"886a66e246dc0d428e7a42df77ce664162aed4be745d9e9f36a52118b60186e9","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzj6q9rrdzr9wlrvlqznt8cuzlf7gfhlhc04n8kkkw","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21550847","spent_by_me":"0.21550847","received_by_me":"0.21548847","my_balance_change":"-0.00002000","block_height":1448993,"timestamp":1623072673,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"886a66e246dc0d428e7a42df77ce664162aed4be745d9e9f36a52118b60186e9","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000238edeb1b3f37607ef191934d0b4f56f98faa05df894aead091313c3d08289b0b010000006b483045022100c42500ba0e9275de19c2b48f38680a86fc7f0e7ec3e4597797fe2829a954b50c02204c456f45c54ab89714ded72cbd4b88679d09220f928b9eb85c16c75da89b287c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff38edeb1b3f37607ef191934d0b4f56f98faa05df894aead091313c3d08289b0b020000006b483045022100e83e62bb7500a163bb49a938aedf6bb8ba2d181732f4dd6b3503996299a6223b022025c6962467ea069fb28b3dc0473b448fe60c743ef60fdb365f4c72d87fa1512e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e80300000000000017a914a5a014636886577c6cf805359f1c17d3e426ffbe872fcf4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f1cbe60","tx_hash":"886a66e246dc0d428e7a42df77ce664162aed4be745d9e9f36a52118b60186e9","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzj6q9rrdzr9wlrvlqznt8cuzlf7gfhlhc5p5uvpyn"],"total_amount":"0.1","spent_by_me":"0.1","received_by_me":"0","my_balance_change":"-0.1","block_height":1448993,"timestamp":1623072673,"fee_details":null,"coin":"tBCH","internal_id":"0f28bec12eadfbf239b019f2314ef9bf3d664d6ba0299ecf2c4b25fe853e0f84","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000026c018d04d2d98a14c7ca36ad68cc2d07f8fd6ae4035c77dd989c1b1a5fe3ddb001000000d8483045022100ac5ecbb037892a26e296c1e4c97f8e4b51cb46877a921248ca3f2af06d49d3a102202d70e0afc20c0e81ca18a54b125a676a3e67c892c6e817ae9f279ed0681e15d941200000000000000000000000000000000000000000000000000000000000000000004c6b6304211dbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff6c018d04d2d98a14c7ca36ad68cc2d07f8fd6ae4035c77dd989c1b1a5fe3ddb0020000006a47304402201eaa2b3c2a074cafd734a9deec5f649dcdef044f0cba1a1a3d30939cf024bd37022024927f9e61ec3f260fe496e4afbd3e6e262861dfe255305c9c86fd89409b464a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77c34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac211dbe60","tx_hash":"7fa34d6607a9c212a9e9e27e87f363087b15b3c627997be2eea6755c0d23e125","from":["bchtest:pp56pzg6mvzpp8ydx85lcme8ahzpapeqds2lhdxyta","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21547847","spent_by_me":"0.21546847","received_by_me":"0.21546847","my_balance_change":"0.00000000","block_height":1448993,"timestamp":1623072673,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"7fa34d6607a9c212a9e9e27e87f363087b15b3c627997be2eea6755c0d23e125","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000026c018d04d2d98a14c7ca36ad68cc2d07f8fd6ae4035c77dd989c1b1a5fe3ddb001000000d8483045022100ac5ecbb037892a26e296c1e4c97f8e4b51cb46877a921248ca3f2af06d49d3a102202d70e0afc20c0e81ca18a54b125a676a3e67c892c6e817ae9f279ed0681e15d941200000000000000000000000000000000000000000000000000000000000000000004c6b6304211dbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff6c018d04d2d98a14c7ca36ad68cc2d07f8fd6ae4035c77dd989c1b1a5fe3ddb0020000006a47304402201eaa2b3c2a074cafd734a9deec5f649dcdef044f0cba1a1a3d30939cf024bd37022024927f9e61ec3f260fe496e4afbd3e6e262861dfe255305c9c86fd89409b464a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77c34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac211dbe60","tx_hash":"7fa34d6607a9c212a9e9e27e87f363087b15b3c627997be2eea6755c0d23e125","from":["slptest:pp56pzg6mvzpp8ydx85lcme8ahzpapeqds3tskuneq"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1448993,"timestamp":1623072673,"fee_details":null,"coin":"tBCH","internal_id":"280b66943031c696ec5917538f12140e4cc739442d5caf51c4ee665f02648150","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002030e0d7566fc734f1cb9e7eed0fe75fd5804e53c05a2252cd97cb67337479952020000006b483045022100acdc3c9c95ac4201ffac479ba605aca31473b28035e2111f4ddcd2a48459eb89022004d5a2846a2474a2ad7883253ba3eef61b78f8e4e9060ced5baa5b7a55a40a3f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030e0d7566fc734f1cb9e7eed0fe75fd5804e53c05a2252cd97cb67337479952030000006a473044022027e720db123438e86d6c22b039aea73a5ed861d1dd8511c745bdb73a07267f5402201f39d23b1f68cc56286b3fffe38d1f7bb60e560c8635a4aae08f3ce1e4e37e914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001f40e80300000000000017a9143dc0ff80ccbabd473d3837493304b02ee07a179f87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acffd64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e17be60","tx_hash":"f3286af3d9afc41b33eb43f6e7a4ec3a3b9c2a1ff8fdad28d34a38b3157e8903","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pq7upluqejat63ea8qm5jvcykqhwq7shnu2zklyu30","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21553847","spent_by_me":"0.21553847","received_by_me":"0.21551847","my_balance_change":"-0.00002000","block_height":1448992,"timestamp":1623071467,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"f3286af3d9afc41b33eb43f6e7a4ec3a3b9c2a1ff8fdad28d34a38b3157e8903","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002030e0d7566fc734f1cb9e7eed0fe75fd5804e53c05a2252cd97cb67337479952020000006b483045022100acdc3c9c95ac4201ffac479ba605aca31473b28035e2111f4ddcd2a48459eb89022004d5a2846a2474a2ad7883253ba3eef61b78f8e4e9060ced5baa5b7a55a40a3f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030e0d7566fc734f1cb9e7eed0fe75fd5804e53c05a2252cd97cb67337479952030000006a473044022027e720db123438e86d6c22b039aea73a5ed861d1dd8511c745bdb73a07267f5402201f39d23b1f68cc56286b3fffe38d1f7bb60e560c8635a4aae08f3ce1e4e37e914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000001f40e80300000000000017a9143dc0ff80ccbabd473d3837493304b02ee07a179f87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acffd64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e17be60","tx_hash":"f3286af3d9afc41b33eb43f6e7a4ec3a3b9c2a1ff8fdad28d34a38b3157e8903","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pq7upluqejat63ea8qm5jvcykqhwq7shnu3k3y7trj","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.9","spent_by_me":"0.9","received_by_me":"0.8","my_balance_change":"-0.1","block_height":1448992,"timestamp":1623071467,"fee_details":null,"coin":"tBCH","internal_id":"a37998be419f60124b0f181de9f007a6de8af97acbe1f9a2205bdec4af09c4f2","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002473519679e2222927e2e4b500a9d6b4a16ce7ac6aa8d888c0888a5a47ff2c572010000006b483045022100b84086ebca7e9feedf83f1808e6126d43ff806cf027988150562bcf4f5857db40220231932caf6c852847879d77d01f94bb18e5e54005865c449ccb2b88fe77ec2b44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff473519679e2222927e2e4b500a9d6b4a16ce7ac6aa8d888c0888a5a47ff2c572020000006a473044022043ca455e96018b72aecd8279af8aba38f0a703fd6aae1c35ac10d20b953125b302203a1e5ce6c476f67c026ce9763d8847feceb7712bb5e6775bd64e74aaf6cce5a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002328e80300000000000017a9148d3b2f3ede519beeb220fbd67ca9207f8b8652f487e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accfde4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf316be60","tx_hash":"5299473773b67cd92c25a2053ce50458fd75fed0eee7b91c4f73fc66750d0e03","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzxnkte7megehm4jyraavl9fyplchpjj7s8d9hpss3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21555847","spent_by_me":"0.21555847","received_by_me":"0.21553847","my_balance_change":"-0.00002000","block_height":1448992,"timestamp":1623071467,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"5299473773b67cd92c25a2053ce50458fd75fed0eee7b91c4f73fc66750d0e03","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002473519679e2222927e2e4b500a9d6b4a16ce7ac6aa8d888c0888a5a47ff2c572010000006b483045022100b84086ebca7e9feedf83f1808e6126d43ff806cf027988150562bcf4f5857db40220231932caf6c852847879d77d01f94bb18e5e54005865c449ccb2b88fe77ec2b44121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff473519679e2222927e2e4b500a9d6b4a16ce7ac6aa8d888c0888a5a47ff2c572020000006a473044022043ca455e96018b72aecd8279af8aba38f0a703fd6aae1c35ac10d20b953125b302203a1e5ce6c476f67c026ce9763d8847feceb7712bb5e6775bd64e74aaf6cce5a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8080000000000002328e80300000000000017a9148d3b2f3ede519beeb220fbd67ca9207f8b8652f487e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accfde4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acf316be60","tx_hash":"5299473773b67cd92c25a2053ce50458fd75fed0eee7b91c4f73fc66750d0e03","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzxnkte7megehm4jyraavl9fyplchpjj7suezvm8zv","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"1","received_by_me":"0.9","my_balance_change":"-0.1","block_height":1448992,"timestamp":1623071467,"fee_details":null,"coin":"tBCH","internal_id":"74177c389de71ea31757e5cf1f99741ebc103b340c135ba6944d5b28d872d21e","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000203897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f301000000d8483045022100e079f6b6d627fe58ab7454e5501623cc2a205ec6b77ccb6e18ac468c13f7e090022038f39424c06a5b8ae80a58dfa197839050cb1e10985fb2ca31a202387ddb530b41200000000000000000000000000000000000000000000000000000000000000000004c6b63044e17be60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff03897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f3030000006b483045022100b38320d57ce4bd33b4ec2aa3a3471aa063677d3e4f768ec532271e66df81334e02202a54df0d82c7a1efd57b853c29390a5a12a02dce935d3ad0d11a0b0b7739bee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac17d34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e17be60","tx_hash":"0b9b28083d3c3191d0ea4a89df05aa8ff9564f0b4d9391f17e60373f1bebed38","from":["bchtest:pq7upluqejat63ea8qm5jvcykqhwq7shnu2zklyu30","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21551847","spent_by_me":"0.21550847","received_by_me":"0.21550847","my_balance_change":"0.00000000","block_height":1448992,"timestamp":1623071467,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0b9b28083d3c3191d0ea4a89df05aa8ff9564f0b4d9391f17e60373f1bebed38","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000203897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f301000000d8483045022100e079f6b6d627fe58ab7454e5501623cc2a205ec6b77ccb6e18ac468c13f7e090022038f39424c06a5b8ae80a58dfa197839050cb1e10985fb2ca31a202387ddb530b41200000000000000000000000000000000000000000000000000000000000000000004c6b63044e17be60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff03897e15b3384ad328adfdf81f2a9c3b3aeca4e7f643eb331bc4afd9f36a28f3030000006b483045022100b38320d57ce4bd33b4ec2aa3a3471aa063677d3e4f768ec532271e66df81334e02202a54df0d82c7a1efd57b853c29390a5a12a02dce935d3ad0d11a0b0b7739bee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e8e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac17d34801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e17be60","tx_hash":"0b9b28083d3c3191d0ea4a89df05aa8ff9564f0b4d9391f17e60373f1bebed38","from":["slptest:pq7upluqejat63ea8qm5jvcykqhwq7shnu3k3y7trj"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"0.1","spent_by_me":"0","received_by_me":"0.1","my_balance_change":"0.1","block_height":1448992,"timestamp":1623071467,"fee_details":null,"coin":"tBCH","internal_id":"76c92ad50b78118449cb01575ee8535b32703b56d72badfe90db45d855831bb8","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000024c40732416a3bf28aca49fdeaa3c74e4c37d44db9a1a8cab830fbd751284560a01000000d7473044022016083f68dae0cbe440d4c674ca3db9010e7cb0485f86a569ac5cf717d65f746c02202669fe140ba642a71a7fd15f3dc5c59d2f757ca12e49bb928ca695750d80bbc541200000000000000000000000000000000000000000000000000000000000000000004c6b6304240ebe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff4c40732416a3bf28aca49fdeaa3c74e4c37d44db9a1a8cab830fbd751284560a020000006b483045022100afc972c131187f3dc00df05c07164499e5b587a1adc880fb3394d02b1c2df831022018dc3e7da4113e98ac847a9d1d372ebdf0895de8835c803547e41011e05ce0914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9fe64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac240ebe60","tx_hash":"72c5f27fa4a588088c888daac67ace164a6b9d0a504b2e7e9222229e67193547","from":["bchtest:pzaaxmwyk9x6vfkk5y9vck2dk88vr5jd6yts8zusej","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21556847","spent_by_me":"0.21555847","received_by_me":"0.21555847","my_balance_change":"0.00000000","block_height":1448990,"timestamp":1623069027,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"72c5f27fa4a588088c888daac67ace164a6b9d0a504b2e7e9222229e67193547","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000024c40732416a3bf28aca49fdeaa3c74e4c37d44db9a1a8cab830fbd751284560a01000000d7473044022016083f68dae0cbe440d4c674ca3db9010e7cb0485f86a569ac5cf717d65f746c02202669fe140ba642a71a7fd15f3dc5c59d2f757ca12e49bb928ca695750d80bbc541200000000000000000000000000000000000000000000000000000000000000000004c6b6304240ebe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff4c40732416a3bf28aca49fdeaa3c74e4c37d44db9a1a8cab830fbd751284560a020000006b483045022100afc972c131187f3dc00df05c07164499e5b587a1adc880fb3394d02b1c2df831022018dc3e7da4113e98ac847a9d1d372ebdf0895de8835c803547e41011e05ce0914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9fe64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac240ebe60","tx_hash":"72c5f27fa4a588088c888daac67ace164a6b9d0a504b2e7e9222229e67193547","from":["slptest:pzaaxmwyk9x6vfkk5y9vck2dk88vr5jd6ysyqex8t0"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448990,"timestamp":1623069027,"fee_details":null,"coin":"tBCH","internal_id":"6fd296ec8afb8f471733829c61ad3338c58e66b568c2495bc10ba01c59d017e2","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000028d372281608c372e656dfb6c0e08605552a59fb63dc17cd15f63101904efe874010000006b483045022100be47ac47975dc15e952d822dfebae2fffd8a9a8d88b31700150fd199604c52ee02206e5405c8d173cf345485ce580800e040f0700f4ab3c73f689caf4705010497374121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff8d372281608c372e656dfb6c0e08605552a59fb63dc17cd15f63101904efe874020000006b483045022100cb771d6df08b9a1b1c29ba13bd7ef73f274df3f52de89845a2701a203b8b02e0022041444bf0f2ef0311511df4b65461880aba5c8108557050cc7e4dc68a4aa43edf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914bbd36dc4b14da626d6a10acc594db1cec1d24dd18787ea4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac250ebe60","tx_hash":"0a56841275bd0f83ab8c1a9adb447dc3e4743caade9fa4ac28bfa3162473404c","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzaaxmwyk9x6vfkk5y9vck2dk88vr5jd6yts8zusej","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21557847","spent_by_me":"0.21557847","received_by_me":"0.21555847","my_balance_change":"-0.00002000","block_height":1448990,"timestamp":1623069027,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0a56841275bd0f83ab8c1a9adb447dc3e4743caade9fa4ac28bfa3162473404c","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000028d372281608c372e656dfb6c0e08605552a59fb63dc17cd15f63101904efe874010000006b483045022100be47ac47975dc15e952d822dfebae2fffd8a9a8d88b31700150fd199604c52ee02206e5405c8d173cf345485ce580800e040f0700f4ab3c73f689caf4705010497374121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff8d372281608c372e656dfb6c0e08605552a59fb63dc17cd15f63101904efe874020000006b483045022100cb771d6df08b9a1b1c29ba13bd7ef73f274df3f52de89845a2701a203b8b02e0022041444bf0f2ef0311511df4b65461880aba5c8108557050cc7e4dc68a4aa43edf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914bbd36dc4b14da626d6a10acc594db1cec1d24dd18787ea4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac250ebe60","tx_hash":"0a56841275bd0f83ab8c1a9adb447dc3e4743caade9fa4ac28bfa3162473404c","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzaaxmwyk9x6vfkk5y9vck2dk88vr5jd6ysyqex8t0"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448990,"timestamp":1623069027,"fee_details":null,"coin":"tBCH","internal_id":"de700a925438bd828eb789ce0da9243fa79bef20405d7d34328ef1ea9fb1ad14","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020ced642178dd794991b49e680e3a1b7292b657b5f4496515b0f15008073da81701000000d747304402201133296646156e6de500f5d56b7c00ccfdbc3928b2bdd5646c8e4c16196e410f02205133ddf69d72c5db416c1d447bfd80f90d1d827bed80fe16b934212b9d41785041200000000000000000000000000000000000000000000000000000000000000000004c6b63049a0bbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff0ced642178dd794991b49e680e3a1b7292b657b5f4496515b0f15008073da817020000006b483045022100db1eb4b1cd1b606f131ac77ef0e4c5c24401e03e1d95d8b9f01c9dbace485bad02203b0281aba051f7ac2e1fece64c499b78bb928efff589d7286df6f605b14086204121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6fee4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9a0bbe60","tx_hash":"74e8ef041910635fd17cc13db69fa5525560080e6cfb6d652e378c608122378d","from":["bchtest:ppfk6n4rhvnfyxemegc7whsxmuqqcgc9g502thwzj7","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21558847","spent_by_me":"0.21557847","received_by_me":"0.21557847","my_balance_change":"0.00000000","block_height":1448989,"timestamp":1623067807,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"74e8ef041910635fd17cc13db69fa5525560080e6cfb6d652e378c608122378d","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020ced642178dd794991b49e680e3a1b7292b657b5f4496515b0f15008073da81701000000d747304402201133296646156e6de500f5d56b7c00ccfdbc3928b2bdd5646c8e4c16196e410f02205133ddf69d72c5db416c1d447bfd80f90d1d827bed80fe16b934212b9d41785041200000000000000000000000000000000000000000000000000000000000000000004c6b63049a0bbe60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff0ced642178dd794991b49e680e3a1b7292b657b5f4496515b0f15008073da817020000006b483045022100db1eb4b1cd1b606f131ac77ef0e4c5c24401e03e1d95d8b9f01c9dbace485bad02203b0281aba051f7ac2e1fece64c499b78bb928efff589d7286df6f605b14086204121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6fee4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9a0bbe60","tx_hash":"74e8ef041910635fd17cc13db69fa5525560080e6cfb6d652e378c608122378d","from":["slptest:ppfk6n4rhvnfyxemegc7whsxmuqqcgc9g557vv54qr"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448989,"timestamp":1623067807,"fee_details":null,"coin":"tBCH","internal_id":"ebc8206ac816600285c0cc362e31a8bfaac3df56d5fccd053bf37d5953011e87","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000021c213665e6720e83cbf8eb2c9c57669e40f404b848e21627ef02a7fbc061c60e010000006a47304402201238eee290c2a687b48b4f4d2568b97c37e19b7e5ca2a2fb567895b7448d00c602203c3bc584f4bc77d57b9801067ee6f3fbc766ecd79f64bbb153fde68ed33bef734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff1c213665e6720e83cbf8eb2c9c57669e40f404b848e21627ef02a7fbc061c60e020000006a473044022015fe771d1ec5cc545c41e52fbd278ab32a8a89c69013db52d2523e5e38228a4a022008d25953117ca9cfe8bf5ecf406b3e9a7dd34f6c615d6b7b3d5c71d57ac569a14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914536d4ea3bb26921b3bca31e75e06df000c2305458757f24801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9a0bbe60","tx_hash":"17a83d070850f1b0156549f4b557b692721b3a0e689eb4914979dd782164ed0c","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppfk6n4rhvnfyxemegc7whsxmuqqcgc9g502thwzj7","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21559847","spent_by_me":"0.21559847","received_by_me":"0.21557847","my_balance_change":"-0.00002000","block_height":1448989,"timestamp":1623067807,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"17a83d070850f1b0156549f4b557b692721b3a0e689eb4914979dd782164ed0c","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000021c213665e6720e83cbf8eb2c9c57669e40f404b848e21627ef02a7fbc061c60e010000006a47304402201238eee290c2a687b48b4f4d2568b97c37e19b7e5ca2a2fb567895b7448d00c602203c3bc584f4bc77d57b9801067ee6f3fbc766ecd79f64bbb153fde68ed33bef734121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff1c213665e6720e83cbf8eb2c9c57669e40f404b848e21627ef02a7fbc061c60e020000006a473044022015fe771d1ec5cc545c41e52fbd278ab32a8a89c69013db52d2523e5e38228a4a022008d25953117ca9cfe8bf5ecf406b3e9a7dd34f6c615d6b7b3d5c71d57ac569a14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914536d4ea3bb26921b3bca31e75e06df000c2305458757f24801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9a0bbe60","tx_hash":"17a83d070850f1b0156549f4b557b692721b3a0e689eb4914979dd782164ed0c","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppfk6n4rhvnfyxemegc7whsxmuqqcgc9g557vv54qr"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448989,"timestamp":1623067807,"fee_details":null,"coin":"tBCH","internal_id":"e6a9f22657479057367138f2c5668140033b7cb090338f91fa6ed858119c075f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002bec21db1d300d9ef27d50618842e958b8137723e29cea3864716a8348e2ab566010000006a47304402206a8f3705675d6ee112a64611a70830eeb60a6674cbb17b6c322e827077b6f7a50220520bb3454ecd4174939b0e41d661ce6eea5dbae36ad65e1ae4f9c4dd568d1a914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbec21db1d300d9ef27d50618842e958b8137723e29cea3864716a8348e2ab566020000006a47304402205188db5d2e9bade41b204fd7e7a244aac4cba6d276c5671ee87ad2afa65d5df00220442cf7f68492597303de5ba6d5b77666eb673374ec6ca2b887a7be1cbba268e64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914746fc9a5f758c8a422484f24b45f538cc0e26d6a8727fa4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb8ffbd60","tx_hash":"8df08337cb7755ee1d9d7e4f0015b3dce123e8db9cb04c9adf11d753fb3a6891","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp6xljd97avv3fpzfp8jfdzl2wxvpcnddgkk85xs4n","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21561847","spent_by_me":"0.21561847","received_by_me":"0.21559847","my_balance_change":"-0.00002000","block_height":1448987,"timestamp":1623065357,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"8df08337cb7755ee1d9d7e4f0015b3dce123e8db9cb04c9adf11d753fb3a6891","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002bec21db1d300d9ef27d50618842e958b8137723e29cea3864716a8348e2ab566010000006a47304402206a8f3705675d6ee112a64611a70830eeb60a6674cbb17b6c322e827077b6f7a50220520bb3454ecd4174939b0e41d661ce6eea5dbae36ad65e1ae4f9c4dd568d1a914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffbec21db1d300d9ef27d50618842e958b8137723e29cea3864716a8348e2ab566020000006a47304402205188db5d2e9bade41b204fd7e7a244aac4cba6d276c5671ee87ad2afa65d5df00220442cf7f68492597303de5ba6d5b77666eb673374ec6ca2b887a7be1cbba268e64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914746fc9a5f758c8a422484f24b45f538cc0e26d6a8727fa4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb8ffbd60","tx_hash":"8df08337cb7755ee1d9d7e4f0015b3dce123e8db9cb04c9adf11d753fb3a6891","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp6xljd97avv3fpzfp8jfdzl2wxvpcnddgdzq0u88w"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448987,"timestamp":1623065357,"fee_details":null,"coin":"tBCH","internal_id":"29e5a4ee599d058989e0aa3ea35963f039e6e505a01bd9140238fad1fb358a19","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000291683afb53d711df9a4cb09cdbe823e1dcb315004f7e9d1dee5577cb3783f08d01000000d84830450221008ab8f20ca1d670c169baec53044c51062539e4d9b144ff6a1019ad43497f9b8e02204b7081af2f26779b61368ec4f90157b2e4ed073c46c50b3080234bbab0e73c1a41200000000000000000000000000000000000000000000000000000000000000000004c6b6304b7ffbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff91683afb53d711df9a4cb09cdbe823e1dcb315004f7e9d1dee5577cb3783f08d020000006b48304502210093e395ebd62a80a756476069124b41cc33adbfcc9a3961cd7aaee9843649593d02207fc1b1a16cebf63e2fb6f85375c7ee6de07f266d1239f69a64c0adbd7fc15be74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ff64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7ffbd60","tx_hash":"0ec661c0fba702ef2716e248b804f4409e66579c2cebf8cb830e72e66536211c","from":["bchtest:pp6xljd97avv3fpzfp8jfdzl2wxvpcnddgkk85xs4n","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21560847","spent_by_me":"0.21559847","received_by_me":"0.21559847","my_balance_change":"0.00000000","block_height":1448987,"timestamp":1623065357,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0ec661c0fba702ef2716e248b804f4409e66579c2cebf8cb830e72e66536211c","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000291683afb53d711df9a4cb09cdbe823e1dcb315004f7e9d1dee5577cb3783f08d01000000d84830450221008ab8f20ca1d670c169baec53044c51062539e4d9b144ff6a1019ad43497f9b8e02204b7081af2f26779b61368ec4f90157b2e4ed073c46c50b3080234bbab0e73c1a41200000000000000000000000000000000000000000000000000000000000000000004c6b6304b7ffbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff91683afb53d711df9a4cb09cdbe823e1dcb315004f7e9d1dee5577cb3783f08d020000006b48304502210093e395ebd62a80a756476069124b41cc33adbfcc9a3961cd7aaee9843649593d02207fc1b1a16cebf63e2fb6f85375c7ee6de07f266d1239f69a64c0adbd7fc15be74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3ff64801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb7ffbd60","tx_hash":"0ec661c0fba702ef2716e248b804f4409e66579c2cebf8cb830e72e66536211c","from":["slptest:pp6xljd97avv3fpzfp8jfdzl2wxvpcnddgdzq0u88w"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448987,"timestamp":1623065357,"fee_details":null,"coin":"tBCH","internal_id":"5369720668b62322dc28e81b6dcfe0e02f766376015ce8ff903955a867ceebaf","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e8cb661f49a212f4a7daa46bb5bba024859dd520767e1e6b7b8dbcee4c843695010000006a47304402203384a1aa2e3366006ed1460541b84c9b3790f0b16b2ea1611d470bc646d2a27a022062633c7ffe5286ef56d83468a0d39e180a0a001723dd76a75d364bf19f697db64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffe8cb661f49a212f4a7daa46bb5bba024859dd520767e1e6b7b8dbcee4c843695020000006a473044022075372ba8c37fdd8a9ecfe3d821b90893d0fb3095284e928e9f75751fd492fb9a02202405dbbfffec129afe195c224b37ce0179e5ad999d65af37f8d9705745c8302b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914460dd524ea15822352e3e817380114f96ddbdd6987f7014901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acebf1bd60","tx_hash":"8dbcd953732a1f5ab474d96913bc565858c60fb96cdea1be3d88f85cd335ade7","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pprqm4fyag2cyg6ju05pwwqpznukmk7adypch6rq6t","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21563847","spent_by_me":"0.21563847","received_by_me":"0.21561847","my_balance_change":"-0.00002000","block_height":1448984,"timestamp":1623061716,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"8dbcd953732a1f5ab474d96913bc565858c60fb96cdea1be3d88f85cd335ade7","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e8cb661f49a212f4a7daa46bb5bba024859dd520767e1e6b7b8dbcee4c843695010000006a47304402203384a1aa2e3366006ed1460541b84c9b3790f0b16b2ea1611d470bc646d2a27a022062633c7ffe5286ef56d83468a0d39e180a0a001723dd76a75d364bf19f697db64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffe8cb661f49a212f4a7daa46bb5bba024859dd520767e1e6b7b8dbcee4c843695020000006a473044022075372ba8c37fdd8a9ecfe3d821b90893d0fb3095284e928e9f75751fd492fb9a02202405dbbfffec129afe195c224b37ce0179e5ad999d65af37f8d9705745c8302b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914460dd524ea15822352e3e817380114f96ddbdd6987f7014901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acebf1bd60","tx_hash":"8dbcd953732a1f5ab474d96913bc565858c60fb96cdea1be3d88f85cd335ade7","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pprqm4fyag2cyg6ju05pwwqpznukmk7ady6vspehgk"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448984,"timestamp":1623061716,"fee_details":null,"coin":"tBCH","internal_id":"d17b4dcf7a76093fb6043b2d3b689b3dcd6d96f563a986b44c25b6c808634982","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e7ad35d35cf8883dbea1de6cb90fc6585856bc1369d974b45a1f2a7353d9bc8d01000000d7473044022006fc5db60f583c351d96f5844025018d8b65a39cff8c6d13c54f2a5d338c74af0220324b0a60acc95cbf8bf5d708d6e5e649da291d8163d967dcdbb1f382c8cbac7941200000000000000000000000000000000000000000000000000000000000000000004c6b6304ebf1bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe7ad35d35cf8883dbea1de6cb90fc6585856bc1369d974b45a1f2a7353d9bc8d020000006b483045022100e7d8a8e7b3169a2e4f7c3955a8818e13206e9eb2b870e870fde814a9b96e5d0402204141202de05dcf0c491f3118b4a3dfb125cdd21b8760cf82383dabe1691787a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0ffe4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acebf1bd60","tx_hash":"66b52a8e34a8164786a3ce293e7237818b952e841806d527efd900d3b11dc2be","from":["bchtest:pprqm4fyag2cyg6ju05pwwqpznukmk7adypch6rq6t","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21562847","spent_by_me":"0.21561847","received_by_me":"0.21561847","my_balance_change":"0.00000000","block_height":1448984,"timestamp":1623061716,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"66b52a8e34a8164786a3ce293e7237818b952e841806d527efd900d3b11dc2be","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e7ad35d35cf8883dbea1de6cb90fc6585856bc1369d974b45a1f2a7353d9bc8d01000000d7473044022006fc5db60f583c351d96f5844025018d8b65a39cff8c6d13c54f2a5d338c74af0220324b0a60acc95cbf8bf5d708d6e5e649da291d8163d967dcdbb1f382c8cbac7941200000000000000000000000000000000000000000000000000000000000000000004c6b6304ebf1bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe7ad35d35cf8883dbea1de6cb90fc6585856bc1369d974b45a1f2a7353d9bc8d020000006b483045022100e7d8a8e7b3169a2e4f7c3955a8818e13206e9eb2b870e870fde814a9b96e5d0402204141202de05dcf0c491f3118b4a3dfb125cdd21b8760cf82383dabe1691787a34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac0ffe4801000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acebf1bd60","tx_hash":"66b52a8e34a8164786a3ce293e7237818b952e841806d527efd900d3b11dc2be","from":["slptest:pprqm4fyag2cyg6ju05pwwqpznukmk7ady6vspehgk"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448984,"timestamp":1623061716,"fee_details":null,"coin":"tBCH","internal_id":"fe0ae7a5662b7f83ae3e6537a2938f2cd29c0ba6844eb23a259a61a49d024ccf","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000261d6cd1c6b14fc8f790ad2c430b163f9547c3a8f1afb65892d264726227cfe3101000000d8483045022100e07f1c59fd6305f249dd7f12f0d8db8257086236783f3980c1756e6e5f9e2429022059dd0a797eb56b548cee46e786aa3bf56a2a49f2f31e87cd837437160caea25a41200000000000000000000000000000000000000000000000000000000000000000004c6b630412edbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff61d6cd1c6b14fc8f790ad2c430b163f9547c3a8f1afb65892d264726227cfe31020000006b483045022100ebdd5374355658a2792db69ecd10333f2b3e242c265e22a59f401f7222d3e61e02205e9a3e0ac55f430bfbcbde0b87d6ea77ff0b6a0733ed3512c940b6f56e8470bf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f154901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac12edbd60","tx_hash":"ba6acd2ab2d7bd2d57c8e01d5bb46ca94017633ab4ef3f492f65ab14e3c44666","from":["bchtest:pqy2nmkf0z4a496j9vusgrl9racx07fydq8qak75mv","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21568847","spent_by_me":"0.21567847","received_by_me":"0.21567847","my_balance_change":"0.00000000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"ba6acd2ab2d7bd2d57c8e01d5bb46ca94017633ab4ef3f492f65ab14e3c44666","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000261d6cd1c6b14fc8f790ad2c430b163f9547c3a8f1afb65892d264726227cfe3101000000d8483045022100e07f1c59fd6305f249dd7f12f0d8db8257086236783f3980c1756e6e5f9e2429022059dd0a797eb56b548cee46e786aa3bf56a2a49f2f31e87cd837437160caea25a41200000000000000000000000000000000000000000000000000000000000000000004c6b630412edbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff61d6cd1c6b14fc8f790ad2c430b163f9547c3a8f1afb65892d264726227cfe31020000006b483045022100ebdd5374355658a2792db69ecd10333f2b3e242c265e22a59f401f7222d3e61e02205e9a3e0ac55f430bfbcbde0b87d6ea77ff0b6a0733ed3512c940b6f56e8470bf4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7f154901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac12edbd60","tx_hash":"ba6acd2ab2d7bd2d57c8e01d5bb46ca94017633ab4ef3f492f65ab14e3c44666","from":["slptest:pqy2nmkf0z4a496j9vusgrl9racx07fydqu56dyrf3"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"2e327fb6476cbfcdfcaa629a145c363ce42139148b7afb6bb10c96603e43e22d","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002d2e5e3432e407641b5754143c8cb18333c03c5e659528ab6f89567d8d7dd012f010000006b483045022100adf485b76d97f1679fbf5a8354fa25e6fcb56ce6fdd658e326862f58a05d7d1f022001d2a5cc3cf29ea5bd72fd9218c0842f889d137a20a78e18bd4aae2c93d2dee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffd2e5e3432e407641b5754143c8cb18333c03c5e659528ab6f89567d8d7dd012f020000006a47304402207ca5780c73ab3a1f12a51b413519865bc68b10359fd99676f26bb805c6be40ba0220099cb4d444782bd3dc035adc304b264bb392d9c3285dac91d51d937869be841a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91422142d4b9ae623e9892b05b9dbc6e4c649b65b0387c7094901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac88efbd60","tx_hash":"a3cf3e996893e8b6657adca71368c03bd4839f8961a7e7e55d86f0dba5576ae9","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pq3pgt2tntnz86vf9vzmnk7xunryndjmqvczt7agdp","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21565847","spent_by_me":"0.21565847","received_by_me":"0.21563847","my_balance_change":"-0.00002000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"a3cf3e996893e8b6657adca71368c03bd4839f8961a7e7e55d86f0dba5576ae9","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002d2e5e3432e407641b5754143c8cb18333c03c5e659528ab6f89567d8d7dd012f010000006b483045022100adf485b76d97f1679fbf5a8354fa25e6fcb56ce6fdd658e326862f58a05d7d1f022001d2a5cc3cf29ea5bd72fd9218c0842f889d137a20a78e18bd4aae2c93d2dee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffd2e5e3432e407641b5754143c8cb18333c03c5e659528ab6f89567d8d7dd012f020000006a47304402207ca5780c73ab3a1f12a51b413519865bc68b10359fd99676f26bb805c6be40ba0220099cb4d444782bd3dc035adc304b264bb392d9c3285dac91d51d937869be841a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91422142d4b9ae623e9892b05b9dbc6e4c649b65b0387c7094901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac88efbd60","tx_hash":"a3cf3e996893e8b6657adca71368c03bd4839f8961a7e7e55d86f0dba5576ae9","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pq3pgt2tntnz86vf9vzmnk7xunryndjmqvrkv98llu"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"ee9abad0053f22f6910db1cd2520d5c1e416209b9ce89afe72d34cf911c17f60","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e96a57a5dbf0865de5e7a761899f83d43bc06813a7dc7a65b6e89368993ecfa301000000d8483045022100c927451bc5eeba0b6a0e186000c916c8230add92088ebd6cf13d3457ff73001b02202bef90393de9eac6db17078fdf2300cc677fe4471c57d855ebaa164a04c82c2a41200000000000000000000000000000000000000000000000000000000000000000004c6b630488efbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe96a57a5dbf0865de5e7a761899f83d43bc06813a7dc7a65b6e89368993ecfa3020000006a473044022055d30fd50898767ec6589c749862534293286014face1181d966a079fd2255f2022003afbce939dd8f42962c039a3c67dace0a2f473163707b2323bece1fa216c22e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf054901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac88efbd60","tx_hash":"9536844ceebc8d7b6b1e7e7620d59d8524a0bbb56ba4daa7f412a2491f66cbe8","from":["bchtest:pq3pgt2tntnz86vf9vzmnk7xunryndjmqvczt7agdp","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21564847","spent_by_me":"0.21563847","received_by_me":"0.21563847","my_balance_change":"0.00000000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"9536844ceebc8d7b6b1e7e7620d59d8524a0bbb56ba4daa7f412a2491f66cbe8","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e96a57a5dbf0865de5e7a761899f83d43bc06813a7dc7a65b6e89368993ecfa301000000d8483045022100c927451bc5eeba0b6a0e186000c916c8230add92088ebd6cf13d3457ff73001b02202bef90393de9eac6db17078fdf2300cc677fe4471c57d855ebaa164a04c82c2a41200000000000000000000000000000000000000000000000000000000000000000004c6b630488efbd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffffe96a57a5dbf0865de5e7a761899f83d43bc06813a7dc7a65b6e89368993ecfa3020000006a473044022055d30fd50898767ec6589c749862534293286014face1181d966a079fd2255f2022003afbce939dd8f42962c039a3c67dace0a2f473163707b2323bece1fa216c22e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf054901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac88efbd60","tx_hash":"9536844ceebc8d7b6b1e7e7620d59d8524a0bbb56ba4daa7f412a2491f66cbe8","from":["slptest:pq3pgt2tntnz86vf9vzmnk7xunryndjmqvrkv98llu"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"f2e367fe86013767afdbf17dd1fdd00bd99b1bd3b35cafc1f2491c999f73d328","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000026646c4e314ab652f493fefb43a631740a96cb45b1de0c8572dbdd7b22acd6aba010000006a4730440220751dde7ce8fa749bfd1d876cb389751b679a1273cd146a441323d72e5fc64aaf0220280340a6a1255f8b2964832f1f6ba587e820672ecf83c2725d785c5c6249c2704121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6646c4e314ab652f493fefb43a631740a96cb45b1de0c8572dbdd7b22acd6aba020000006a47304402202bd479f7d6270ac3de8022fcff1b7febe4fd1e7c19bdb14ac07738f376baa0aa0220320fc182f01fd707e14ccc52f587371b05e949e1e185e08d57409aa28694dd7b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91459be927343984e5202ebb0fcb4615e1d24d0db788797114901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85eebd60","tx_hash":"4739a8e36f94b8e53d8250fb42a0e1ec9de509cffe0990ba43e8f791ba5a87fb","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppvmaynngwvyu5szawc0edrptcwjf5xm0qp2l20gfx","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21567847","spent_by_me":"0.21567847","received_by_me":"0.21565847","my_balance_change":"-0.00002000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"4739a8e36f94b8e53d8250fb42a0e1ec9de509cffe0990ba43e8f791ba5a87fb","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000026646c4e314ab652f493fefb43a631740a96cb45b1de0c8572dbdd7b22acd6aba010000006a4730440220751dde7ce8fa749bfd1d876cb389751b679a1273cd146a441323d72e5fc64aaf0220280340a6a1255f8b2964832f1f6ba587e820672ecf83c2725d785c5c6249c2704121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6646c4e314ab652f493fefb43a631740a96cb45b1de0c8572dbdd7b22acd6aba020000006a47304402202bd479f7d6270ac3de8022fcff1b7febe4fd1e7c19bdb14ac07738f376baa0aa0220320fc182f01fd707e14ccc52f587371b05e949e1e185e08d57409aa28694dd7b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91459be927343984e5202ebb0fcb4615e1d24d0db788797114901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85eebd60","tx_hash":"4739a8e36f94b8e53d8250fb42a0e1ec9de509cffe0990ba43e8f791ba5a87fb","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppvmaynngwvyu5szawc0edrptcwjf5xm0q67c34lmm"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"b3f2a55c23fa55c78ae94db413436fc454ec0935a4292b1adfcce86d5547dd4f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002c66715333dee76a1e1deb51c0aab6b95f0b2ef5c39f65550f3c76c1d90e873ed010000006a47304402202f0b32c9ec246f34bab48302ce275a705f526054547dbd5a9b1e75676e682d76022009c446f734ed582d4cc2bad5b4ab4b17078edd7ec89b69edac62b37ffa4cfb9f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc66715333dee76a1e1deb51c0aab6b95f0b2ef5c39f65550f3c76c1d90e873ed020000006a47304402202b9306f536fecf767a0d6c0f5ef064eaba177a10f764dca1405a42a0a8e2789002203e7366a9f1a25666fc44859f70f7b858b70747622f9694059a60e80d8355c4924121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91408a9eec978abda97522b39040fe51f7067f924688767194901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac12edbd60","tx_hash":"31fe7c222647262d8965fb1a8f3a7c54f963b130c4d20a798ffc146b1ccdd661","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pqy2nmkf0z4a496j9vusgrl9racx07fydq8qak75mv","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21569847","spent_by_me":"0.21569847","received_by_me":"0.21567847","my_balance_change":"-0.00002000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"31fe7c222647262d8965fb1a8f3a7c54f963b130c4d20a798ffc146b1ccdd661","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002c66715333dee76a1e1deb51c0aab6b95f0b2ef5c39f65550f3c76c1d90e873ed010000006a47304402202f0b32c9ec246f34bab48302ce275a705f526054547dbd5a9b1e75676e682d76022009c446f734ed582d4cc2bad5b4ab4b17078edd7ec89b69edac62b37ffa4cfb9f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc66715333dee76a1e1deb51c0aab6b95f0b2ef5c39f65550f3c76c1d90e873ed020000006a47304402202b9306f536fecf767a0d6c0f5ef064eaba177a10f764dca1405a42a0a8e2789002203e7366a9f1a25666fc44859f70f7b858b70747622f9694059a60e80d8355c4924121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91408a9eec978abda97522b39040fe51f7067f924688767194901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac12edbd60","tx_hash":"31fe7c222647262d8965fb1a8f3a7c54f963b130c4d20a798ffc146b1ccdd661","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pqy2nmkf0z4a496j9vusgrl9racx07fydqu56dyrf3"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"f29d3076b7f68e91cee0b33de0e825871b7ae1f31997fefac7b6f6305f7c9108","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002fb875aba91f7e843ba9009fecf09e59dece1a042fb50823de5b8946fe3a8394701000000d747304402205304ccb5f1cfeee3181c6d5f41f2a3e3ae7da1756776ed627f15035fd67bed4602200beffdd4aec720c93d679123d9e6acfb3c5ec6251bdcb6b7b48f9c08888935b441200000000000000000000000000000000000000000000000000000000000000000004c6b630485eebd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68fffffffffb875aba91f7e843ba9009fecf09e59dece1a042fb50823de5b8946fe3a83947020000006a473044022048fe68b727125b7e9154319db07bc60090b2e99a8edb90bebd867c2e1c0891bb022010b442ca3bea131da2a14ee8f629140ff29a7a177b9c20802316a418f2c5671c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acaf0d4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85eebd60","tx_hash":"2f01ddd7d86795f8b68a5259e6c5033c3318cbc8434175b54176402e43e3e5d2","from":["bchtest:ppvmaynngwvyu5szawc0edrptcwjf5xm0qp2l20gfx","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21566847","spent_by_me":"0.21565847","received_by_me":"0.21565847","my_balance_change":"0.00000000","block_height":1448983,"timestamp":1623060512,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"2f01ddd7d86795f8b68a5259e6c5033c3318cbc8434175b54176402e43e3e5d2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002fb875aba91f7e843ba9009fecf09e59dece1a042fb50823de5b8946fe3a8394701000000d747304402205304ccb5f1cfeee3181c6d5f41f2a3e3ae7da1756776ed627f15035fd67bed4602200beffdd4aec720c93d679123d9e6acfb3c5ec6251bdcb6b7b48f9c08888935b441200000000000000000000000000000000000000000000000000000000000000000004c6b630485eebd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68fffffffffb875aba91f7e843ba9009fecf09e59dece1a042fb50823de5b8946fe3a83947020000006a473044022048fe68b727125b7e9154319db07bc60090b2e99a8edb90bebd867c2e1c0891bb022010b442ca3bea131da2a14ee8f629140ff29a7a177b9c20802316a418f2c5671c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acaf0d4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac85eebd60","tx_hash":"2f01ddd7d86795f8b68a5259e6c5033c3318cbc8434175b54176402e43e3e5d2","from":["slptest:ppvmaynngwvyu5szawc0edrptcwjf5xm0q67c34lmm"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448983,"timestamp":1623060512,"fee_details":null,"coin":"tBCH","internal_id":"52d14fbbf5bccb69704797c22c72e42b2340c73d2429fec743f3887c4bada513","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000281b24f0023a60bf0e9e5f7890cdb262898cf6c2f669f1d1e80b7d775d45be93101000000d74730440220345a848e10f1c50e7c08af6a0083c223dfc326fb96aedc6aad6f42585ca8d253022045b335c86dc7f2ab04375f87d44ea6e551a66233aef79425b24649a7712cf3f441200000000000000000000000000000000000000000000000000000000000000000004c6b630483e7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff81b24f0023a60bf0e9e5f7890cdb262898cf6c2f669f1d1e80b7d775d45be931020000006b483045022100feac49df391ab602ed381c7923d7d39b9b816886316a8ba809395510567e5238022008db6e325845bd8abe31d4ae84d8cb49f01de5df93e0d9b13778978bdc6bcec74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f1d4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac83e7bd60","tx_hash":"ed73e8901d6cc7f35055f6395cefb2f0956bab0a1cb5dee1a176ee3d331567c6","from":["bchtest:pph4aex9zhqhkeax7c87k9jv5dwe0h8zx5g8v9pwdy","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21570847","spent_by_me":"0.21569847","received_by_me":"0.21569847","my_balance_change":"0.00000000","block_height":1448982,"timestamp":1623059292,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"ed73e8901d6cc7f35055f6395cefb2f0956bab0a1cb5dee1a176ee3d331567c6","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000281b24f0023a60bf0e9e5f7890cdb262898cf6c2f669f1d1e80b7d775d45be93101000000d74730440220345a848e10f1c50e7c08af6a0083c223dfc326fb96aedc6aad6f42585ca8d253022045b335c86dc7f2ab04375f87d44ea6e551a66233aef79425b24649a7712cf3f441200000000000000000000000000000000000000000000000000000000000000000004c6b630483e7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff81b24f0023a60bf0e9e5f7890cdb262898cf6c2f669f1d1e80b7d775d45be931020000006b483045022100feac49df391ab602ed381c7923d7d39b9b816886316a8ba809395510567e5238022008db6e325845bd8abe31d4ae84d8cb49f01de5df93e0d9b13778978bdc6bcec74121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4f1d4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac83e7bd60","tx_hash":"ed73e8901d6cc7f35055f6395cefb2f0956bab0a1cb5dee1a176ee3d331567c6","from":["slptest:pph4aex9zhqhkeax7c87k9jv5dwe0h8zx5nnt7mele"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448982,"timestamp":1623059292,"fee_details":null,"coin":"tBCH","internal_id":"294bdf000824a966898c940e934fbbc6097fb97fbb87b27fdb4a46ffeaa2893a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020d2614aa2b88026aef1d7a478244aded4bc30cad7f97055b8e1c6f636e154339010000006b483045022100ff683b0c28bd5b92e12f1813ad89b0eba014ecdbf51cefaeb280531f94bdc4b302203457fa2af3f1935f47a316923d146693539514118c12aa95dea46fe8c08c09284121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0d2614aa2b88026aef1d7a478244aded4bc30cad7f97055b8e1c6f636e154339020000006b483045022100dbbb1a39cae424103d68e2544c6ec9d518f0d29713179c8cdc3ef17033ad0b1a02201ae5974383dd18d9cb78838623cc7349a3b32055c8de7e27e1996aac3e1600574121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91452401fa60edd8f41b54f16f895f59f74f100764c8707294901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfce6bd60","tx_hash":"e1d52d89ea18f1e8481768ba644fb8c4b1aefa5a440567c037cf3165ee25ac51","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppfyq8axpmwc7sd4fut03904na60zqrkfszvct9qh4","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21573847","spent_by_me":"0.21573847","received_by_me":"0.21571847","my_balance_change":"-0.00002000","block_height":1448982,"timestamp":1623059292,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"e1d52d89ea18f1e8481768ba644fb8c4b1aefa5a440567c037cf3165ee25ac51","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020d2614aa2b88026aef1d7a478244aded4bc30cad7f97055b8e1c6f636e154339010000006b483045022100ff683b0c28bd5b92e12f1813ad89b0eba014ecdbf51cefaeb280531f94bdc4b302203457fa2af3f1935f47a316923d146693539514118c12aa95dea46fe8c08c09284121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0d2614aa2b88026aef1d7a478244aded4bc30cad7f97055b8e1c6f636e154339020000006b483045022100dbbb1a39cae424103d68e2544c6ec9d518f0d29713179c8cdc3ef17033ad0b1a02201ae5974383dd18d9cb78838623cc7349a3b32055c8de7e27e1996aac3e1600574121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a91452401fa60edd8f41b54f16f895f59f74f100764c8707294901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfce6bd60","tx_hash":"e1d52d89ea18f1e8481768ba644fb8c4b1aefa5a440567c037cf3165ee25ac51","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppfyq8axpmwc7sd4fut03904na60zqrkfseclslh9g"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448982,"timestamp":1623059292,"fee_details":null,"coin":"tBCH","internal_id":"1c4c13bc66014629c3b740e4a0fdc6056c4d17a3ef6015d061dc75285f45f5e5","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000251ac25ee6531cf37c06705445afaaeb1c4b84f64ba681748e8f118ea892dd5e101000000d8483045022100bf505f3622712cc9eb28ce8b2e243eeea47dd151bce0608666b375e87c7ed80202207a00f813034214d1996ec5a4ef4ab1d37968473ac3d024b5df40ff4f98809f6e41200000000000000000000000000000000000000000000000000000000000000000004c6b6304fbe6bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff51ac25ee6531cf37c06705445afaaeb1c4b84f64ba681748e8f118ea892dd5e1020000006b4830450221009a71afff96779e6e3ac23a069d2dd617cbeb9aca9bfba05f6c3efaff24d417990220734e2f07d8659287bb6d87d83887796a9224cf7500929ddf0a506a611d3275b54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1f254901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfbe6bd60","tx_hash":"804a357229dfd1513737da9350156051b7bf455dc4f47f3b55e5172cc84d1e7b","from":["bchtest:ppfyq8axpmwc7sd4fut03904na60zqrkfszvct9qh4","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21572847","spent_by_me":"0.21571847","received_by_me":"0.21571847","my_balance_change":"0.00000000","block_height":1448982,"timestamp":1623059292,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"804a357229dfd1513737da9350156051b7bf455dc4f47f3b55e5172cc84d1e7b","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000251ac25ee6531cf37c06705445afaaeb1c4b84f64ba681748e8f118ea892dd5e101000000d8483045022100bf505f3622712cc9eb28ce8b2e243eeea47dd151bce0608666b375e87c7ed80202207a00f813034214d1996ec5a4ef4ab1d37968473ac3d024b5df40ff4f98809f6e41200000000000000000000000000000000000000000000000000000000000000000004c6b6304fbe6bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff51ac25ee6531cf37c06705445afaaeb1c4b84f64ba681748e8f118ea892dd5e1020000006b4830450221009a71afff96779e6e3ac23a069d2dd617cbeb9aca9bfba05f6c3efaff24d417990220734e2f07d8659287bb6d87d83887796a9224cf7500929ddf0a506a611d3275b54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1f254901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acfbe6bd60","tx_hash":"804a357229dfd1513737da9350156051b7bf455dc4f47f3b55e5172cc84d1e7b","from":["slptest:ppfyq8axpmwc7sd4fut03904na60zqrkfseclslh9g"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448982,"timestamp":1623059292,"fee_details":null,"coin":"tBCH","internal_id":"8d0cd035534eed79ea612e11354e63a96a4e623e0ee6de5603e56b5fe530cdb6","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000027b1e4dc82c17e5553b7ff4c45d45bfb75160155093da373751d1df2972354a80010000006b483045022100db9096d5d187a83da35d0f548a106f3c124001559bfafe0ef672f6c4c40cf632022008f89189e5d31c694b9ef940afc1d4d141d4349df29ed9e5ec6b819bbc14a3954121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff7b1e4dc82c17e5553b7ff4c45d45bfb75160155093da373751d1df2972354a80020000006b483045022100aef72036d7324c61807b7517900df36090c6e0743106f15d380f3f3fba565bd8022048885301964f0f319cd96926d3cc62b073749af9701dd98aea9555e69e5ec0614121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9146f5ee4c515c17b67a6f60feb164ca35d97dce2358737214901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac84e7bd60","tx_hash":"31e95bd475d7b7801e1d9f662f6ccf982826db0c89f7e5e9f00ba623004fb281","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pph4aex9zhqhkeax7c87k9jv5dwe0h8zx5g8v9pwdy","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21571847","spent_by_me":"0.21571847","received_by_me":"0.21569847","my_balance_change":"-0.00002000","block_height":1448982,"timestamp":1623059292,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"31e95bd475d7b7801e1d9f662f6ccf982826db0c89f7e5e9f00ba623004fb281","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000027b1e4dc82c17e5553b7ff4c45d45bfb75160155093da373751d1df2972354a80010000006b483045022100db9096d5d187a83da35d0f548a106f3c124001559bfafe0ef672f6c4c40cf632022008f89189e5d31c694b9ef940afc1d4d141d4349df29ed9e5ec6b819bbc14a3954121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff7b1e4dc82c17e5553b7ff4c45d45bfb75160155093da373751d1df2972354a80020000006b483045022100aef72036d7324c61807b7517900df36090c6e0743106f15d380f3f3fba565bd8022048885301964f0f319cd96926d3cc62b073749af9701dd98aea9555e69e5ec0614121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9146f5ee4c515c17b67a6f60feb164ca35d97dce2358737214901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac84e7bd60","tx_hash":"31e95bd475d7b7801e1d9f662f6ccf982826db0c89f7e5e9f00ba623004fb281","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pph4aex9zhqhkeax7c87k9jv5dwe0h8zx5nnt7mele"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448982,"timestamp":1623059292,"fee_details":null,"coin":"tBCH","internal_id":"30468ca5f542169af50153c167ed01f1f269abd7dee0c6001e738d6c72b2135c","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002c9e8fe17429d092f4c707c6fa2b0e568bd76a3adee663ebdca841935d0e896f4010000006a4730440220648f29f63aef5e84c30b3af157d113a294fef830502b037ccbff924ef287931502206d42b2a31e7ac32487cfc127c07607fae056c83de05d113dec4c1697f3d162e24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc9e8fe17429d092f4c707c6fa2b0e568bd76a3adee663ebdca841935d0e896f4020000006b483045022100b8a0100b1c0f26a1011aa0057177578426f169345c731176a5e9f2e281bf00c602200682ae012ed909bfba19ca1982db297748c5fd83d013c655f98abee1465d851b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914173cf5e4b0bc1db5ebbf8a4ce14dad646b2d78298777404901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5be3bd60","tx_hash":"ad947c93d048fc0092c07e5b667dee6c6707955a11cd92d720c5781edc1db48d","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pqtnea0ykz7pmd0th79yec2d44jxkttc9y5uwsgrtg","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21579847","spent_by_me":"0.21579847","received_by_me":"0.21577847","my_balance_change":"-0.00002000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"ad947c93d048fc0092c07e5b667dee6c6707955a11cd92d720c5781edc1db48d","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002c9e8fe17429d092f4c707c6fa2b0e568bd76a3adee663ebdca841935d0e896f4010000006a4730440220648f29f63aef5e84c30b3af157d113a294fef830502b037ccbff924ef287931502206d42b2a31e7ac32487cfc127c07607fae056c83de05d113dec4c1697f3d162e24121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffc9e8fe17429d092f4c707c6fa2b0e568bd76a3adee663ebdca841935d0e896f4020000006b483045022100b8a0100b1c0f26a1011aa0057177578426f169345c731176a5e9f2e281bf00c602200682ae012ed909bfba19ca1982db297748c5fd83d013c655f98abee1465d851b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914173cf5e4b0bc1db5ebbf8a4ce14dad646b2d78298777404901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5be3bd60","tx_hash":"ad947c93d048fc0092c07e5b667dee6c6707955a11cd92d720c5781edc1db48d","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pqtnea0ykz7pmd0th79yec2d44jxkttc9y0gftj5e4"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"77767aa5f40c48a27d22565d02aa669698372502695b8f89618463afc93c8480","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002e2516dc1e6ddf2f829ffe899d8bbdd72b276b0d1d818676368028457c696ba43010000006a47304402201f4afa08d87957ec2b6f5f524dbee3295c1134508a7b07654d0087f38dff466b022067553b4bbc1a7e41c4a66dad093414296c787897ebcb56a52464d70efe352ba94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffe2516dc1e6ddf2f829ffe899d8bbdd72b276b0d1d818676368028457c696ba43020000006b483045022100fab2c87fef91116a723de5c200f2dbc1b4d0f077e54195e299244840126e89e002207ffc10bb70038eda05f371e59e4d9c6938662f3fea878e4c7610ae3f75a0e8364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9141e5373a7ca04506a71701eaf73f1d219337cd79a87d7304901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7de4bd60","tx_hash":"6a7836c2c35548944a86a00dea0a6f070eac4611c1b0ee3bf6d6a398174d460a","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pq09xua8egz9q6n3wq027ul36gvnxlxhngh59889lt","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21575847","spent_by_me":"0.21575847","received_by_me":"0.21573847","my_balance_change":"-0.00002000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"6a7836c2c35548944a86a00dea0a6f070eac4611c1b0ee3bf6d6a398174d460a","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002e2516dc1e6ddf2f829ffe899d8bbdd72b276b0d1d818676368028457c696ba43010000006a47304402201f4afa08d87957ec2b6f5f524dbee3295c1134508a7b07654d0087f38dff466b022067553b4bbc1a7e41c4a66dad093414296c787897ebcb56a52464d70efe352ba94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffe2516dc1e6ddf2f829ffe899d8bbdd72b276b0d1d818676368028457c696ba43020000006b483045022100fab2c87fef91116a723de5c200f2dbc1b4d0f077e54195e299244840126e89e002207ffc10bb70038eda05f371e59e4d9c6938662f3fea878e4c7610ae3f75a0e8364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9141e5373a7ca04506a71701eaf73f1d219337cd79a87d7304901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7de4bd60","tx_hash":"6a7836c2c35548944a86a00dea0a6f070eac4611c1b0ee3bf6d6a398174d460a","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pq09xua8egz9q6n3wq027ul36gvnxlxhngvqzuajdk"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"0dfb8bef02991b571367240d81e5d278c82ae74adf1ce55a07f74c53b0b6ed26","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002025b2359779f0f8de247f1e3636243e83f14bd03aa30fa20362fbdc505d89b0401000000b7483045022100aaf3dd9263301250ad7ba746e85d8e299df99db2915fc80d0165048170d13b1b02204f95ca4ed98ae452ed41e787bd6f88398937bfaaade1e78b75d1e5f5be7241ca41514c6b6304f8c7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff025b2359779f0f8de247f1e3636243e83f14bd03aa30fa20362fbdc505d89b04020000006a4730440220327e09c8eeba7bf952b75e3c0788b6b6d3340fcb75b87ca903a7405320404e02022075d5dc9283037ece5d6609481fa5dbc7bba5c7d136321298f468b1056ab90c0d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf344901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"43ba96c657840268636718d8d1b076b272ddbbd899e8ff29f8f2dde6c16d51e2","from":["bchtest:presvtclnyz57rsqc5l3xs0cs8xpftxy7vfjya7qww","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21576847","spent_by_me":"0.21575847","received_by_me":"0.21575847","my_balance_change":"0.00000000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"43ba96c657840268636718d8d1b076b272ddbbd899e8ff29f8f2dde6c16d51e2","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002025b2359779f0f8de247f1e3636243e83f14bd03aa30fa20362fbdc505d89b0401000000b7483045022100aaf3dd9263301250ad7ba746e85d8e299df99db2915fc80d0165048170d13b1b02204f95ca4ed98ae452ed41e787bd6f88398937bfaaade1e78b75d1e5f5be7241ca41514c6b6304f8c7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff025b2359779f0f8de247f1e3636243e83f14bd03aa30fa20362fbdc505d89b04020000006a4730440220327e09c8eeba7bf952b75e3c0788b6b6d3340fcb75b87ca903a7405320404e02022075d5dc9283037ece5d6609481fa5dbc7bba5c7d136321298f468b1056ab90c0d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acbf344901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"43ba96c657840268636718d8d1b076b272ddbbd899e8ff29f8f2dde6c16d51e2","from":["slptest:presvtclnyz57rsqc5l3xs0cs8xpftxy7vjxrxyhun"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"711b7ec3e347fd49c511168f684caabd00f0edc29790dacb821fa329c654db7e","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020a464d1798a3d6f63beeb0c11146ac0e076f0aea0da0864a944855c3c236786a01000000b6473044022050d0bf1e449ccb2499c5bbdb2ee4f4bf7b4c238fbe02581641c98fd715f5298b02205b67e08155ac2d64bbee8731d791fb2044e4a9de3c478ec6c2b956c7915f908a41514c6b63045cc8bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff0a464d1798a3d6f63beeb0c11146ac0e076f0aea0da0864a944855c3c236786a020000006a47304402202b438547d1eb7118b35d89c38e0d8c8dd27469b6a055211f11527bb785c00741022019168de07cbdebf5bf51cd502460a723beae4862798b9f75cb4d5abaceda6e364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acef2c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"3943156e636f1c8e5b05977fad0cc34bedad4482477a1def6a02882baa14260d","from":["bchtest:pq09xua8egz9q6n3wq027ul36gvnxlxhngh59889lt","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21574847","spent_by_me":"0.21573847","received_by_me":"0.21573847","my_balance_change":"0.00000000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"3943156e636f1c8e5b05977fad0cc34bedad4482477a1def6a02882baa14260d","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020a464d1798a3d6f63beeb0c11146ac0e076f0aea0da0864a944855c3c236786a01000000b6473044022050d0bf1e449ccb2499c5bbdb2ee4f4bf7b4c238fbe02581641c98fd715f5298b02205b67e08155ac2d64bbee8731d791fb2044e4a9de3c478ec6c2b956c7915f908a41514c6b63045cc8bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821010101010101010101010101010101010101010101010101010101010101010101ac68feffffff0a464d1798a3d6f63beeb0c11146ac0e076f0aea0da0864a944855c3c236786a020000006a47304402202b438547d1eb7118b35d89c38e0d8c8dd27469b6a055211f11527bb785c00741022019168de07cbdebf5bf51cd502460a723beae4862798b9f75cb4d5abaceda6e364121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acef2c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"3943156e636f1c8e5b05977fad0cc34bedad4482477a1def6a02882baa14260d","from":["slptest:pq09xua8egz9q6n3wq027ul36gvnxlxhngvqzuajdk"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"052a317c46538a9909ec3ee762b1858f14226b55634e4d31bc12aa490980c59f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000028db41ddc1e78c520d792cd115a9507676cee7d665b7ec09200fc48d0937c94ad01000000b7483045022100af09669cf2c6a7d99466f4c91707608c31239e1fd617111990ba0ad64d80678502204b44003cf57ead30571643cc26eb25d9db117d810029b635c731c09be6d7582941514c6b63043bc7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff8db41ddc1e78c520d792cd115a9507676cee7d665b7ec09200fc48d0937c94ad020000006a4730440220172c864b5f0bb3c93029c4d9a86d1ce391810c5d9be92b4867d5ac50fe0bceb602204e5b01ed308a67f90c71f050319701ecea7095c357265b46d5bd707a795653004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8f3c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"1d909ab0da84973b2a8dece0b3b2c54d6d22e2fe1b2f2fb84b42203e23d45392","from":["bchtest:pqtnea0ykz7pmd0th79yec2d44jxkttc9y5uwsgrtg","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21578847","spent_by_me":"0.21577847","received_by_me":"0.21577847","my_balance_change":"0.00000000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"1d909ab0da84973b2a8dece0b3b2c54d6d22e2fe1b2f2fb84b42203e23d45392","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000028db41ddc1e78c520d792cd115a9507676cee7d665b7ec09200fc48d0937c94ad01000000b7483045022100af09669cf2c6a7d99466f4c91707608c31239e1fd617111990ba0ad64d80678502204b44003cf57ead30571643cc26eb25d9db117d810029b635c731c09be6d7582941514c6b63043bc7bd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff8db41ddc1e78c520d792cd115a9507676cee7d665b7ec09200fc48d0937c94ad020000006a4730440220172c864b5f0bb3c93029c4d9a86d1ce391810c5d9be92b4867d5ac50fe0bceb602204e5b01ed308a67f90c71f050319701ecea7095c357265b46d5bd707a795653004121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac8f3c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ace3c9bd60","tx_hash":"1d909ab0da84973b2a8dece0b3b2c54d6d22e2fe1b2f2fb84b42203e23d45392","from":["slptest:pqtnea0ykz7pmd0th79yec2d44jxkttc9y0gftj5e4"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"b8fdd342ce47c9560ea75eefd1596e8efebe0673d8251c5fe896a2ef71d96a7f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000029253d4233e20424bb82f2f1bfee2226d4dc5b2b3e0ec8d2a3b9784dab09a901d010000006b48304502210080bdcb450dce368184393981092d80154510ebccc747049aa09797be08ec5714022020cf5412eb7ecb45a099cab997e8e04e9bc568bffa687ace37e35d5881c499214121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff9253d4233e20424bb82f2f1bfee2226d4dc5b2b3e0ec8d2a3b9784dab09a901d020000006b483045022100c561e126f60eaf9c34d5aa4a1b2103f083c95570ee9d9856cdd2f71f1911d43b022039df2709cd0d6af4ba3406479245e9b308558baa42e77abe5f261938370da8104121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914f3062f1f99054f0e00c53f1341f881cc14acc4f387a7384901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac19e4bd60","tx_hash":"049bd805c5bd2f3620fa30aa03bd143fe8436263e3f147e28d0f9f7759235b02","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:presvtclnyz57rsqc5l3xs0cs8xpftxy7vfjya7qww","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21577847","spent_by_me":"0.21577847","received_by_me":"0.21575847","my_balance_change":"-0.00002000","block_height":1448981,"timestamp":1623058067,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"049bd805c5bd2f3620fa30aa03bd143fe8436263e3f147e28d0f9f7759235b02","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000029253d4233e20424bb82f2f1bfee2226d4dc5b2b3e0ec8d2a3b9784dab09a901d010000006b48304502210080bdcb450dce368184393981092d80154510ebccc747049aa09797be08ec5714022020cf5412eb7ecb45a099cab997e8e04e9bc568bffa687ace37e35d5881c499214121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff9253d4233e20424bb82f2f1bfee2226d4dc5b2b3e0ec8d2a3b9784dab09a901d020000006b483045022100c561e126f60eaf9c34d5aa4a1b2103f083c95570ee9d9856cdd2f71f1911d43b022039df2709cd0d6af4ba3406479245e9b308558baa42e77abe5f261938370da8104121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914f3062f1f99054f0e00c53f1341f881cc14acc4f387a7384901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac19e4bd60","tx_hash":"049bd805c5bd2f3620fa30aa03bd143fe8436263e3f147e28d0f9f7759235b02","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:presvtclnyz57rsqc5l3xs0cs8xpftxy7vjxrxyhun"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448981,"timestamp":1623058067,"fee_details":null,"coin":"tBCH","internal_id":"a3d37a930f179f044d119037c2ca06e4d910e3e3ed85fec217bf8d9570da3b66","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022e8f723af79d13f3d05c23aef11d9d094c246784dfe686807e25b11087bc1a8b01000000b6473044022064fdab4412e25cba07cfc3075a42af3dea7c8f84ccab8fd9819d4ef8370ebdc302203e7d03c11a057192a3fa223710d7324d77fb87e4b96cf9a1df109af430b8dc0b41514c6b630452babd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff2e8f723af79d13f3d05c23aef11d9d094c246784dfe686807e25b11087bc1a8b020000006b483045022100b8e002014f60210662c647f25ca23d0af29563ca6cbaf375d24d7549c633ea2202201491fe1fd024ed99c09c8fe0a6c73663af424a42e26019a2c02085746b82a1a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5f444901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97bbbd60","tx_hash":"f496e8d0351984cabd3e66eeada376bd68e5b0a26f7c704c2f099d4217fee8c9","from":["bchtest:pp0mu82rlztc3mzdz7knpvk9m6t5yrkn5sewsqr9y3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21580847","spent_by_me":"0.21579847","received_by_me":"0.21579847","my_balance_change":"0.00000000","block_height":1448978,"timestamp":1623054396,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"f496e8d0351984cabd3e66eeada376bd68e5b0a26f7c704c2f099d4217fee8c9","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022e8f723af79d13f3d05c23aef11d9d094c246784dfe686807e25b11087bc1a8b01000000b6473044022064fdab4412e25cba07cfc3075a42af3dea7c8f84ccab8fd9819d4ef8370ebdc302203e7d03c11a057192a3fa223710d7324d77fb87e4b96cf9a1df109af430b8dc0b41514c6b630452babd60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff2e8f723af79d13f3d05c23aef11d9d094c246784dfe686807e25b11087bc1a8b020000006b483045022100b8e002014f60210662c647f25ca23d0af29563ca6cbaf375d24d7549c633ea2202201491fe1fd024ed99c09c8fe0a6c73663af424a42e26019a2c02085746b82a1a94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac5f444901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac97bbbd60","tx_hash":"f496e8d0351984cabd3e66eeada376bd68e5b0a26f7c704c2f099d4217fee8c9","from":["slptest:pp0mu82rlztc3mzdz7knpvk9m6t5yrkn5sz6hmejkv"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448978,"timestamp":1623054396,"fee_details":null,"coin":"tBCH","internal_id":"15cae3ece8450ec511d4aae630a4ed808504e1eb79b9da4139ce444f580cb043","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000025511dba5b0ba801ae50d725217a41fb3329678a8f3bee3d4d3f4a2aeacf4cf59010000006a47304402201014b3fbd217d4007008ed9e02ca91b8af6c3b957eefc73dcdd32a1dbba5ebc10220536785bda7bf014b6624b261cced5e09f9db126b993ead405148f7dccc28fdf64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5511dba5b0ba801ae50d725217a41fb3329678a8f3bee3d4d3f4a2aeacf4cf59020000006b483045022100e75c5bd3717f71f74ef425b59628e496c8268bb279e1d324f8d25106356382da022011f37dc96d083a20b41777b4e83fe95b89e8be7f28c40918afb9140ba6e5b6654121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9145fbe1d43f89788ec4d17ad30b2c5de97420ed3a48747484901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac72d6bd60","tx_hash":"8b1abc8710b1257e8086e6df8467244c099d1df1ae235cd0f3139df73a728f2e","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pp0mu82rlztc3mzdz7knpvk9m6t5yrkn5sewsqr9y3","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21581847","spent_by_me":"0.21581847","received_by_me":"0.21579847","my_balance_change":"-0.00002000","block_height":1448978,"timestamp":1623054396,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"8b1abc8710b1257e8086e6df8467244c099d1df1ae235cd0f3139df73a728f2e","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000025511dba5b0ba801ae50d725217a41fb3329678a8f3bee3d4d3f4a2aeacf4cf59010000006a47304402201014b3fbd217d4007008ed9e02ca91b8af6c3b957eefc73dcdd32a1dbba5ebc10220536785bda7bf014b6624b261cced5e09f9db126b993ead405148f7dccc28fdf64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff5511dba5b0ba801ae50d725217a41fb3329678a8f3bee3d4d3f4a2aeacf4cf59020000006b483045022100e75c5bd3717f71f74ef425b59628e496c8268bb279e1d324f8d25106356382da022011f37dc96d083a20b41777b4e83fe95b89e8be7f28c40918afb9140ba6e5b6654121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a9145fbe1d43f89788ec4d17ad30b2c5de97420ed3a48747484901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac72d6bd60","tx_hash":"8b1abc8710b1257e8086e6df8467244c099d1df1ae235cd0f3139df73a728f2e","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pp0mu82rlztc3mzdz7knpvk9m6t5yrkn5sz6hmejkv"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448978,"timestamp":1623054396,"fee_details":null,"coin":"tBCH","internal_id":"c176bd7bbb36515a42c6b6df15006513d2e7cc5f60108e7bd2c11f84bf98fc00","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b3ef43aa024a106908deacccd94302b9076d2c69498a71fcd23a4a6b60fc4e0a010000006a47304402201dd728a677e6ea0412014447ad9acf92fd87a8fb41583aef7647d5b00a5a0bb10220033b57ba2a54ceae4ff27b5018e8333918fae8a9439e8d75ae4cc9adb93f84b14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb3ef43aa024a106908deacccd94302b9076d2c69498a71fcd23a4a6b60fc4e0a020000006b483045022100fc577a2e09251aef54f5810f69a931d0fec7f0fca52714ae81354c4188d23e4a022022c3fc494ef78f9e7fde72a420ea9c910f6f2d4fb85f1c4a65fd5c2d3ef6a0714121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914396a533a23b3700a753359592b3374ade703a9818717504901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1132ba60","tx_hash":"d49e92afd58a1b654e975548588f8e410b6efd459dff902d62bd51d5f68bc12d","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pquk55e6ywehqzn4xdv4j2enwjk7wqafsygyvlrvl6","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21583847","spent_by_me":"0.21583847","received_by_me":"0.21581847","my_balance_change":"-0.00002000","block_height":1448783,"timestamp":1622816281,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"d49e92afd58a1b654e975548588f8e410b6efd459dff902d62bd51d5f68bc12d","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b3ef43aa024a106908deacccd94302b9076d2c69498a71fcd23a4a6b60fc4e0a010000006a47304402201dd728a677e6ea0412014447ad9acf92fd87a8fb41583aef7647d5b00a5a0bb10220033b57ba2a54ceae4ff27b5018e8333918fae8a9439e8d75ae4cc9adb93f84b14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb3ef43aa024a106908deacccd94302b9076d2c69498a71fcd23a4a6b60fc4e0a020000006b483045022100fc577a2e09251aef54f5810f69a931d0fec7f0fca52714ae81354c4188d23e4a022022c3fc494ef78f9e7fde72a420ea9c910f6f2d4fb85f1c4a65fd5c2d3ef6a0714121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914396a533a23b3700a753359592b3374ade703a9818717504901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac1132ba60","tx_hash":"d49e92afd58a1b654e975548588f8e410b6efd459dff902d62bd51d5f68bc12d","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pquk55e6ywehqzn4xdv4j2enwjk7wqafsynstyemd8"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448783,"timestamp":1622816281,"fee_details":null,"coin":"tBCH","internal_id":"9a89ec96d924763c588d9d98a6289d4fccaa0575f6d6dd7834d17ea0d778d7d8","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022dc18bf6d551bd622d90ff9d45fd6e0b418e8f584855974e651b8ad5af929ed401000000b7483045022100918eabe812b517bcaf3d1fa4bbea606d55128214aecf7e638e0c404038f838b702203bb0a8806fff558ad5203eb7162c8c9b4804742f6a3b13e072d77d7b1a1458d241514c6b6304f115ba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff2dc18bf6d551bd622d90ff9d45fd6e0b418e8f584855974e651b8ad5af929ed4020000006b48304502210088f1279901c508834246d9c710976424003c58ce97f0b669d663a3868f740cbf02201e239405ec8bba599e9fde8b5642b08f81afc829f835ff05626b01ae4d73199c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f4c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7b19ba60","tx_hash":"59cff4acaea2f4d3d4e3bef3a8789632b31fa41752720de51a80bab0a5db1155","from":["bchtest:pquk55e6ywehqzn4xdv4j2enwjk7wqafsygyvlrvl6","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21582847","spent_by_me":"0.21581847","received_by_me":"0.21581847","my_balance_change":"0.00000000","block_height":1448783,"timestamp":1622816281,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"59cff4acaea2f4d3d4e3bef3a8789632b31fa41752720de51a80bab0a5db1155","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022dc18bf6d551bd622d90ff9d45fd6e0b418e8f584855974e651b8ad5af929ed401000000b7483045022100918eabe812b517bcaf3d1fa4bbea606d55128214aecf7e638e0c404038f838b702203bb0a8806fff558ad5203eb7162c8c9b4804742f6a3b13e072d77d7b1a1458d241514c6b6304f115ba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff2dc18bf6d551bd622d90ff9d45fd6e0b418e8f584855974e651b8ad5af929ed4020000006b48304502210088f1279901c508834246d9c710976424003c58ce97f0b669d663a3868f740cbf02201e239405ec8bba599e9fde8b5642b08f81afc829f835ff05626b01ae4d73199c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2f4c4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac7b19ba60","tx_hash":"59cff4acaea2f4d3d4e3bef3a8789632b31fa41752720de51a80bab0a5db1155","from":["slptest:pquk55e6ywehqzn4xdv4j2enwjk7wqafsynstyemd8"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448783,"timestamp":1622816281,"fee_details":null,"coin":"tBCH","internal_id":"6e9b3bb36689832aa32b1f7a5f200dc6682cd9ad69e7321a2137eba07a9b93b7","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020189e764ee43a90c8fa31b458741b569ed7501980dd6c1e07766c186872f9bc9010000006b483045022100ba98457a7cf571b70c0fc4e4ae7cfbefdaabf9704233e6f70058317435af42e10220630cf02dae2e705b17cb22fcd8b452159a136a83b7d8efa75ab37d7f88478f234121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0189e764ee43a90c8fa31b458741b569ed7501980dd6c1e07766c186872f9bc9020000006a473044022024e40b8089dd60e3bf0847faaf68f8ae746bc677cf554ddbda97d04ca61e30e902207c9ef17a84e32f1fecd2164d47f330e74a978a3f56d7d9388cdff44cb8077b9f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914521da80525e5bd677da9ff9c60ef2ab67490454987e7574901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac862dba60","tx_hash":"50c387362d62d445be3cb15cd7f0fec9f87aafd0d23198a1dce8358b3648b7d4","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppfpm2q9yhjm6ema48lecc8092m8fyz9fyqr84njrs","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21585847","spent_by_me":"0.21585847","received_by_me":"0.21583847","my_balance_change":"-0.00002000","block_height":1448782,"timestamp":1622815061,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"50c387362d62d445be3cb15cd7f0fec9f87aafd0d23198a1dce8358b3648b7d4","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020189e764ee43a90c8fa31b458741b569ed7501980dd6c1e07766c186872f9bc9010000006b483045022100ba98457a7cf571b70c0fc4e4ae7cfbefdaabf9704233e6f70058317435af42e10220630cf02dae2e705b17cb22fcd8b452159a136a83b7d8efa75ab37d7f88478f234121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff0189e764ee43a90c8fa31b458741b569ed7501980dd6c1e07766c186872f9bc9020000006a473044022024e40b8089dd60e3bf0847faaf68f8ae746bc677cf554ddbda97d04ca61e30e902207c9ef17a84e32f1fecd2164d47f330e74a978a3f56d7d9388cdff44cb8077b9f4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914521da80525e5bd677da9ff9c60ef2ab67490454987e7574901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac862dba60","tx_hash":"50c387362d62d445be3cb15cd7f0fec9f87aafd0d23198a1dce8358b3648b7d4","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppfpm2q9yhjm6ema48lecc8092m8fyz9fymhqwf93d"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448782,"timestamp":1622815061,"fee_details":null,"coin":"tBCH","internal_id":"ca81e22dc430e8556caf905bd4aa4330422732f61c2d39403c0850ff5655a282","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002d4b748368b35e8dca19831d2d0af7af8c9fef0d75cb13cbe45d4622d3687c35001000000b647304402207307b33a6eb87e7fbf4c8fb5b045521904d0b063ba95b9487119f10e449f305102204fdf0e4a64b139d7a6b7323e869e35d25c6723c2dfdff66125a24e13c256c12141514c6b63046511ba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffd4b748368b35e8dca19831d2d0af7af8c9fef0d75cb13cbe45d4622d3687c350020000006b483045022100b30abde7b4e72fc928f361c9e06d0ae57fe8c2f364f5ba5841e5fca38715fb98022023f4b239d54a8fc1f9e962a4c1be54848af10a8be663b88db6c95461051fb3584121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff534901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6511ba60","tx_hash":"0a4efc606b4a3ad2fc718a49692c6d07b90243d9ccacde0869104a02aa43efb3","from":["bchtest:ppfpm2q9yhjm6ema48lecc8092m8fyz9fyqr84njrs","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21584847","spent_by_me":"0.21583847","received_by_me":"0.21583847","my_balance_change":"0.00000000","block_height":1448782,"timestamp":1622815061,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"0a4efc606b4a3ad2fc718a49692c6d07b90243d9ccacde0869104a02aa43efb3","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002d4b748368b35e8dca19831d2d0af7af8c9fef0d75cb13cbe45d4622d3687c35001000000b647304402207307b33a6eb87e7fbf4c8fb5b045521904d0b063ba95b9487119f10e449f305102204fdf0e4a64b139d7a6b7323e869e35d25c6723c2dfdff66125a24e13c256c12141514c6b63046511ba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffd4b748368b35e8dca19831d2d0af7af8c9fef0d75cb13cbe45d4622d3687c350020000006b483045022100b30abde7b4e72fc928f361c9e06d0ae57fe8c2f364f5ba5841e5fca38715fb98022023f4b239d54a8fc1f9e962a4c1be54848af10a8be663b88db6c95461051fb3584121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acff534901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6511ba60","tx_hash":"0a4efc606b4a3ad2fc718a49692c6d07b90243d9ccacde0869104a02aa43efb3","from":["slptest:ppfpm2q9yhjm6ema48lecc8092m8fyz9fymhqwf93d"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448782,"timestamp":1622815061,"fee_details":null,"coin":"tBCH","internal_id":"694e8bcc82f8e41f5c1fa38926dd525925ebadbd45597b69a73865f0002bdf0b","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000020cec14a95a69f699659517bcbac9d01fa0b6407fe117b03e7da9e59782e8b24801000000b6473044022025d7ab1fbdb6e21b6802f8888e2cf46b9367062c81bdc3477a31720a53e3bf1802205b6c7aaadc2ebf50262ee58754d47100211339f2d5cb081711139fe0646b1ff541514c6b63042d0dba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff0cec14a95a69f699659517bcbac9d01fa0b6407fe117b03e7da9e59782e8b248020000006a4730440220785a8f92aeb088579c1620b2767b94fdeaaf20d719c274259e81b03b68cf3dd202203f241a3a7859469590616a8672990f2f9ac570d5f7572971fb7339244fc1c1d34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accf5b4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2d0dba60","tx_hash":"c99b2f8786c16677e0c1d60d980175ed69b54187451ba38f0ca943ee64e78901","from":["bchtest:prqs2sj4f30er06gyu4cy3uz9we5tpg8jvvyv5vjfn","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21586847","spent_by_me":"0.21585847","received_by_me":"0.21585847","my_balance_change":"0.00000000","block_height":1448781,"timestamp":1622813841,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"c99b2f8786c16677e0c1d60d980175ed69b54187451ba38f0ca943ee64e78901","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000020cec14a95a69f699659517bcbac9d01fa0b6407fe117b03e7da9e59782e8b24801000000b6473044022025d7ab1fbdb6e21b6802f8888e2cf46b9367062c81bdc3477a31720a53e3bf1802205b6c7aaadc2ebf50262ee58754d47100211339f2d5cb081711139fe0646b1ff541514c6b63042d0dba60b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffff0cec14a95a69f699659517bcbac9d01fa0b6407fe117b03e7da9e59782e8b248020000006a4730440220785a8f92aeb088579c1620b2767b94fdeaaf20d719c274259e81b03b68cf3dd202203f241a3a7859469590616a8672990f2f9ac570d5f7572971fb7339244fc1c1d34121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88accf5b4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2d0dba60","tx_hash":"c99b2f8786c16677e0c1d60d980175ed69b54187451ba38f0ca943ee64e78901","from":["slptest:prqs2sj4f30er06gyu4cy3uz9we5tpg8jvhst0k9mw"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448781,"timestamp":1622813841,"fee_details":null,"coin":"tBCH","internal_id":"f8e7ddbdd4b2e14abd83f43e9b4e4764dca3ccfc91e0d5dd16b627f8da2b7b73","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022e4b6fb0b5937a3b65db99737d73b3b431226593f8c56a78d0cb07d0e162c0d7010000006a473044022052335a84b7a8665bfc42b5c0e5c13f3adcf502f304df6971881e69203ea6b9a102201a56ebacf179206d5ac20f511fc2f29c400de8c6ed93255b7ca76faac90b953e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff2e4b6fb0b5937a3b65db99737d73b3b431226593f8c56a78d0cb07d0e162c0d7020000006a47304402201f8c809b5b2715553c43334aaec96885342153210efec415775c24572a757e3a022023408a0be6286e0dde33f2114b7c455b3b270f48475bdbfcdc4e2cd23fa247f94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914c10542554c5f91bf48272b8247822bb34585079387b75f4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e29ba60","tx_hash":"48b2e88297e5a97d3eb017e17f40b6a01fd0c9babc17956599f6695aa914ec0c","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:prqs2sj4f30er06gyu4cy3uz9we5tpg8jvvyv5vjfn","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21587847","spent_by_me":"0.21587847","received_by_me":"0.21585847","my_balance_change":"-0.00002000","block_height":1448781,"timestamp":1622813841,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"48b2e88297e5a97d3eb017e17f40b6a01fd0c9babc17956599f6695aa914ec0c","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022e4b6fb0b5937a3b65db99737d73b3b431226593f8c56a78d0cb07d0e162c0d7010000006a473044022052335a84b7a8665bfc42b5c0e5c13f3adcf502f304df6971881e69203ea6b9a102201a56ebacf179206d5ac20f511fc2f29c400de8c6ed93255b7ca76faac90b953e4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff2e4b6fb0b5937a3b65db99737d73b3b431226593f8c56a78d0cb07d0e162c0d7020000006a47304402201f8c809b5b2715553c43334aaec96885342153210efec415775c24572a757e3a022023408a0be6286e0dde33f2114b7c455b3b270f48475bdbfcdc4e2cd23fa247f94121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914c10542554c5f91bf48272b8247822bb34585079387b75f4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4e29ba60","tx_hash":"48b2e88297e5a97d3eb017e17f40b6a01fd0c9babc17956599f6695aa914ec0c","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:prqs2sj4f30er06gyu4cy3uz9we5tpg8jvhst0k9mw"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448781,"timestamp":1622813841,"fee_details":null,"coin":"tBCH","internal_id":"0bed4b0e9513781343bb20b835fe3046d23719142a7576713b391941e5252b17","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002bdb9bc1b680b76eceba6e56d8d738bdeeed122361424c42682478455201d054701000000b7483045022100ceb2aeeeed61be3ab66337458419d0b50dcf980bc3db2445f51ca407ed50ab11022000cd7ef15f715a8fb0d964d5ad4744358c2f65f9193cfb60666c29eaf95e253741514c6b6304b9feb960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffbdb9bc1b680b76eceba6e56d8d738bdeeed122361424c42682478455201d0547020000006b483045022100c486564b03dd6d4021aed95e38694ff8163d2a2c69853820372a783b001e0ed1022073d6679a324352d8dbca4d51837217b787ec49ff284b6703960a086e26dc253b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f634901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb9feb960","tx_hash":"d7c062e1d007cbd0786ac5f893652231b4b3737d7399db653b7a93b5b06f4b2e","from":["bchtest:pqgk69yyj6dzag4mdyur9lykye89ucz9vsddce5q2t","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21588847","spent_by_me":"0.21587847","received_by_me":"0.21587847","my_balance_change":"0.00000000","block_height":1448778,"timestamp":1622810181,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"d7c062e1d007cbd0786ac5f893652231b4b3737d7399db653b7a93b5b06f4b2e","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002bdb9bc1b680b76eceba6e56d8d738bdeeed122361424c42682478455201d054701000000b7483045022100ceb2aeeeed61be3ab66337458419d0b50dcf980bc3db2445f51ca407ed50ab11022000cd7ef15f715a8fb0d964d5ad4744358c2f65f9193cfb60666c29eaf95e253741514c6b6304b9feb960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffbdb9bc1b680b76eceba6e56d8d738bdeeed122361424c42682478455201d0547020000006b483045022100c486564b03dd6d4021aed95e38694ff8163d2a2c69853820372a783b001e0ed1022073d6679a324352d8dbca4d51837217b787ec49ff284b6703960a086e26dc253b4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9f634901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acb9feb960","tx_hash":"d7c062e1d007cbd0786ac5f893652231b4b3737d7399db653b7a93b5b06f4b2e","from":["slptest:pqgk69yyj6dzag4mdyur9lykye89ucz9vskelzwhck"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448778,"timestamp":1622810181,"fee_details":null,"coin":"tBCH","internal_id":"660d57aad6e7807ee99459a77ed6b526771db8567fff99ca055d652913555d08","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002826181fbca65995c3acb4ccc1153fe6aa2514e7fbc52124aa52fe77c861f1af5010000006a4730440220593ebbfb4ae66807d87fe201d216e2f66785fba9f1d0a7494fbc7c30a83cce8a022002c74fe866e5491fedbbe03116c094053bb85bc0d1fb2ab5df1e2f976d92d6ba4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff826181fbca65995c3acb4ccc1153fe6aa2514e7fbc52124aa52fe77c861f1af5020000006a4730440220780d63fbb982c0e1c2d06db19676e6cee1fc3c900ec9c4092f83160deb18c1bc022071ca86381164f0da02a5643c0e3d1b1c0ee5ceb26a19fb71abdaf16cbdfde8ae4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914116d1484969a2ea2bb693832fc96264e5e6045648787674901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd91aba60","tx_hash":"47051d205584478226c424143622d1eede8b738d6de5a6ebec760b681bbcb9bd","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pqgk69yyj6dzag4mdyur9lykye89ucz9vsddce5q2t","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21589847","spent_by_me":"0.21589847","received_by_me":"0.21587847","my_balance_change":"-0.00002000","block_height":1448778,"timestamp":1622810181,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"47051d205584478226c424143622d1eede8b738d6de5a6ebec760b681bbcb9bd","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002826181fbca65995c3acb4ccc1153fe6aa2514e7fbc52124aa52fe77c861f1af5010000006a4730440220593ebbfb4ae66807d87fe201d216e2f66785fba9f1d0a7494fbc7c30a83cce8a022002c74fe866e5491fedbbe03116c094053bb85bc0d1fb2ab5df1e2f976d92d6ba4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff826181fbca65995c3acb4ccc1153fe6aa2514e7fbc52124aa52fe77c861f1af5020000006a4730440220780d63fbb982c0e1c2d06db19676e6cee1fc3c900ec9c4092f83160deb18c1bc022071ca86381164f0da02a5643c0e3d1b1c0ee5ceb26a19fb71abdaf16cbdfde8ae4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914116d1484969a2ea2bb693832fc96264e5e6045648787674901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acd91aba60","tx_hash":"47051d205584478226c424143622d1eede8b738d6de5a6ebec760b681bbcb9bd","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pqgk69yyj6dzag4mdyur9lykye89ucz9vskelzwhck"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448778,"timestamp":1622810181,"fee_details":null,"coin":"tBCH","internal_id":"e46fa0836be0534f7799b2ef5b538551ea25b6f430b7e015a95731efb7a0cd4f","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002ba95a3a80f0f8396d5ed9c8a13b122c4a9f6b338fff2b483e78ee3d9d8b75b0601000000b6473044022031bb6d5f22d205eea401c64bb0e0bf9dc9cce5d4c237a627e4742e2cce91fc6a022035db7a3be1ea37df202fc3f1e054b5b62e2f79d3530fedbd3ba7b579d9e9e89e41514c6b630477d3b960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffba95a3a80f0f8396d5ed9c8a13b122c4a9f6b338fff2b483e78ee3d9d8b75b06020000006a4730440220677b3221e3e2ff3cffe61ee51ae8d11fb8bb420f2a152992e4e02242bdb49fbb022028855abb6aec4ad6007c078ef1f5e9ed7055e7486972200b1fce8089ed7fdee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6f6b4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77d3b960","tx_hash":"f51a1f867ce72fa54a1252bc7f4e51a26afe5311cc4ccb3a5c9965cafb816182","from":["bchtest:pztgwc96yenmmh3jdw7y2h9zk0wjspzldggnphckpq","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21590847","spent_by_me":"0.21589847","received_by_me":"0.21589847","my_balance_change":"0.00000000","block_height":1448769,"timestamp":1622799170,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"f51a1f867ce72fa54a1252bc7f4e51a26afe5311cc4ccb3a5c9965cafb816182","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002ba95a3a80f0f8396d5ed9c8a13b122c4a9f6b338fff2b483e78ee3d9d8b75b0601000000b6473044022031bb6d5f22d205eea401c64bb0e0bf9dc9cce5d4c237a627e4742e2cce91fc6a022035db7a3be1ea37df202fc3f1e054b5b62e2f79d3530fedbd3ba7b579d9e9e89e41514c6b630477d3b960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffba95a3a80f0f8396d5ed9c8a13b122c4a9f6b338fff2b483e78ee3d9d8b75b06020000006a4730440220677b3221e3e2ff3cffe61ee51ae8d11fb8bb420f2a152992e4e02242bdb49fbb022028855abb6aec4ad6007c078ef1f5e9ed7055e7486972200b1fce8089ed7fdee64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac6f6b4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac77d3b960","tx_hash":"f51a1f867ce72fa54a1252bc7f4e51a26afe5311cc4ccb3a5c9965cafb816182","from":["slptest:pztgwc96yenmmh3jdw7y2h9zk0wjspzldgn8xvzpna"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448769,"timestamp":1622799170,"fee_details":null,"coin":"tBCH","internal_id":"2b5965f90654c62f42f0d03bf97e2f4890064012006bbedebf6f7a6cbf23859a","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002cba67d2031c614825447da0b97ca6c4c0192b6eef757ffe3a79f2924a3657860010000006b483045022100d1bbead6d6e72564cebba4fefcf58897e7a959e39ecba5ce0634242c8cf4dd9f02203d946ff23259bbf3501e0a15aad32a64adc162f5cdf6a9c64ce08ae147f6b87c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffcba67d2031c614825447da0b97ca6c4c0192b6eef757ffe3a79f2924a3657860020000006a47304402202a0469e94bb829a314a10ddc0d9e8631e129615cb24ffb03093a1051fd4d4be00220072baeb82d9044edfaac6cc1f9a7614c9ab381f92801b0ec7e15740cc26dd6f54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914968760ba2667bdde326bbc455ca2b3dd28045f6a87576f4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac98efb960","tx_hash":"065bb7d8d9e38ee783b4f2ff38b3f6a9c422b1138a9cedd596830f0fa8a395ba","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pztgwc96yenmmh3jdw7y2h9zk0wjspzldggnphckpq","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21591847","spent_by_me":"0.21591847","received_by_me":"0.21589847","my_balance_change":"-0.00002000","block_height":1448769,"timestamp":1622799170,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"065bb7d8d9e38ee783b4f2ff38b3f6a9c422b1138a9cedd596830f0fa8a395ba","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002cba67d2031c614825447da0b97ca6c4c0192b6eef757ffe3a79f2924a3657860010000006b483045022100d1bbead6d6e72564cebba4fefcf58897e7a959e39ecba5ce0634242c8cf4dd9f02203d946ff23259bbf3501e0a15aad32a64adc162f5cdf6a9c64ce08ae147f6b87c4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffcba67d2031c614825447da0b97ca6c4c0192b6eef757ffe3a79f2924a3657860020000006a47304402202a0469e94bb829a314a10ddc0d9e8631e129615cb24ffb03093a1051fd4d4be00220072baeb82d9044edfaac6cc1f9a7614c9ab381f92801b0ec7e15740cc26dd6f54121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914968760ba2667bdde326bbc455ca2b3dd28045f6a87576f4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac98efb960","tx_hash":"065bb7d8d9e38ee783b4f2ff38b3f6a9c422b1138a9cedd596830f0fa8a395ba","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pztgwc96yenmmh3jdw7y2h9zk0wjspzldgn8xvzpna"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448769,"timestamp":1622799170,"fee_details":null,"coin":"tBCH","internal_id":"d852d3768df093a28c370803bb793b3cead3d7754a961a1d668ab36d96d599ee","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b06721589d2b86bea464fa1ea0463e0ca7c34a740d1aa8f83dd2d5a29585f306010000006b48304502210095949388142ae76b11828ac056c54fbfe1639008a4150ea4448738e4211c884b02203d85bce130c61cea1a507e071a37b68fff046e1b25e6e1e285416959b6cdec374121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb06721589d2b86bea464fa1ea0463e0ca7c34a740d1aa8f83dd2d5a29585f306020000006a473044022041a2e3f5512d0187c64e8ba9f30f6b48c8a2295be5991b825f0754933fabb88902207be81190f92ef2dca4beff8872cdcaefd18dcd8de5d07b6d84b783c310e4b8b64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914bb8b9fc2957a4f3fa71ef1bb5c6d8736e426406387f77e4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9eeab960","tx_hash":"b15e1c55f9a5906d74142becffc53869c022ecea3748aa2028943195a93c456e","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pzach87zj4ay70a8rmcmkhrdsumwgfjqvv22hqa5n7","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21595847","spent_by_me":"0.21595847","received_by_me":"0.21593847","my_balance_change":"-0.00002000","block_height":1448768,"timestamp":1622797945,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"b15e1c55f9a5906d74142becffc53869c022ecea3748aa2028943195a93c456e","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b06721589d2b86bea464fa1ea0463e0ca7c34a740d1aa8f83dd2d5a29585f306010000006b48304502210095949388142ae76b11828ac056c54fbfe1639008a4150ea4448738e4211c884b02203d85bce130c61cea1a507e071a37b68fff046e1b25e6e1e285416959b6cdec374121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffffb06721589d2b86bea464fa1ea0463e0ca7c34a740d1aa8f83dd2d5a29585f306020000006a473044022041a2e3f5512d0187c64e8ba9f30f6b48c8a2295be5991b825f0754933fabb88902207be81190f92ef2dca4beff8872cdcaefd18dcd8de5d07b6d84b783c310e4b8b64121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e80300000000000017a914bb8b9fc2957a4f3fa71ef1bb5c6d8736e426406387f77e4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac9eeab960","tx_hash":"b15e1c55f9a5906d74142becffc53869c022ecea3748aa2028943195a93c456e","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pzach87zj4ay70a8rmcmkhrdsumwgfjqvv37sm8rpr"],"total_amount":"1","spent_by_me":"1","received_by_me":"0","my_balance_change":"-1","block_height":1448768,"timestamp":1622797945,"fee_details":null,"coin":"tBCH","internal_id":"5fcf9bd0019e3d35616b21f872888804d897f74dae2191b6fa3b734ee15aabf1","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000002b62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a01000000b647304402207a5be062e97d9db2426a531bd73320295f0a3a2b36f1c840415360daf37e9d69022051a31dc179df30f9193c1b433c87aaa00e89368cff2f852f8279e657867f1aa541514c6b63042fcfb960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffb62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a030000006b483045022100e9d76e8581c2f17d9131f3078f33c88d90016ad81f6842c19eba9a1eca07b08a0220091d90a4ec9e31d25cceaff5fb8625772af9f5925d57105d56fec23aacea6a6d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3f734901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2fcfb960","tx_hash":"607865a324299fa7e3ff57f7eeb692014c6cca970bda47548214c631207da6cb","from":["bchtest:ppfdp6t2qs7rc79wxjppwv0hwvr776x5vu3d5sdzs2","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21592847","spent_by_me":"0.21591847","received_by_me":"0.21591847","my_balance_change":"0.00000000","block_height":1448768,"timestamp":1622797945,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"607865a324299fa7e3ff57f7eeb692014c6cca970bda47548214c631207da6cb","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000002b62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a01000000b647304402207a5be062e97d9db2426a531bd73320295f0a3a2b36f1c840415360daf37e9d69022051a31dc179df30f9193c1b433c87aaa00e89368cff2f852f8279e657867f1aa541514c6b63042fcfb960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68feffffffb62a5f43d321a4f4e6585e92415747bf38719582b99ea37e0bd3310ce2969a1a030000006b483045022100e9d76e8581c2f17d9131f3078f33c88d90016ad81f6842c19eba9a1eca07b08a0220091d90a4ec9e31d25cceaff5fb8625772af9f5925d57105d56fec23aacea6a6d4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac3f734901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2fcfb960","tx_hash":"607865a324299fa7e3ff57f7eeb692014c6cca970bda47548214c631207da6cb","from":["slptest:ppfdp6t2qs7rc79wxjppwv0hwvr776x5vu2enth4zh"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448768,"timestamp":1622797945,"fee_details":null,"coin":"tBCH","internal_id":"fc666307cafcbf29e4b95ccc261a24603c8168535283c6ed8243d4cd8c2543c8","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af020000006a473044022051d38d2d762d868f00040584b5f7fccf396eccb5d4099ac952ea00f788c672f5022030d0d1a31e15a1935db5f079a898c586b360bc62259ed313156e4913fa6271514121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6e453ca99531942820aa4837eaec22c06938c5ffec2b14746d90a5f9551c5eb1020000006b4830450221009645b0710ac1427a2deba4721d68caccf811bae1f52a29acac2c7b3a6f160ea202206b28cde5ce396abf4d5bb37104cc7d9aef12a9a1ea70aca79b4889d56ac31a2a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000013498e80300000000000017a91452d0e96a043c3c78ae34821731f77307ef68d46787e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac27774901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4febb960","tx_hash":"1a9a96e20c31d30b7ea39eb982957138bf475741925e58e6f4a421d3435f2ab6","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:ppfdp6t2qs7rc79wxjppwv0hwvr776x5vu3d5sdzs2","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21594847","spent_by_me":"0.21594847","received_by_me":"0.21592847","my_balance_change":"-0.00002000","block_height":1448768,"timestamp":1622797945,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"1a9a96e20c31d30b7ea39eb982957138bf475741925e58e6f4a421d3435f2ab6","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af020000006a473044022051d38d2d762d868f00040584b5f7fccf396eccb5d4099ac952ea00f788c672f5022030d0d1a31e15a1935db5f079a898c586b360bc62259ed313156e4913fa6271514121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6e453ca99531942820aa4837eaec22c06938c5ffec2b14746d90a5f9551c5eb1020000006b4830450221009645b0710ac1427a2deba4721d68caccf811bae1f52a29acac2c7b3a6f160ea202206b28cde5ce396abf4d5bb37104cc7d9aef12a9a1ea70aca79b4889d56ac31a2a4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000013498e80300000000000017a91452d0e96a043c3c78ae34821731f77307ef68d46787e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac27774901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac4febb960","tx_hash":"1a9a96e20c31d30b7ea39eb982957138bf475741925e58e6f4a421d3435f2ab6","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:ppfdp6t2qs7rc79wxjppwv0hwvr776x5vu2enth4zh","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"8.9","spent_by_me":"8.9","received_by_me":"7.9","my_balance_change":"-1.0","block_height":1448768,"timestamp":1622797945,"fee_details":null,"coin":"tBCH","internal_id":"fe78e04399219ef75271019f6d5db5d77179e9f310f8364604a6e4e05c4d7563","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"010000000259eb9eb93d9e2a571e44997132248b3e595422375f9f134395fdef1211633ecf020000006b483045022100c8abc9eed50341d8ab008efed4e56080a494999cdc53d173622be59e46e262ea02201077d04e01561af4b14adea0611a52134084385524fa37409c566cb98a39aa914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff59eb9eb93d9e2a571e44997132248b3e595422375f9f134395fdef1211633ecf030000006a473044022049dd947c0b5ccceb1920ef0bb297de0fe287c34a8d7d9ed39209776a191850fe022069d98060c395e61fac90bcecb800e981ab5903fe50eaa0e1073d9efdadf227ce4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000015ba8e80300000000000017a914169fdaecb872081837b47440f82052a0be7b2d8c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc7864901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac00d2b960","tx_hash":"afa7785fdb0e49e649aa9b6467fa183c8185c398095baac2c11df50175a7f92b","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pqtflkhvhpeqsxphk36yp7pq22stu7ed3sqfxsdt7x","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21598847","spent_by_me":"0.21598847","received_by_me":"0.21596847","my_balance_change":"-0.00002000","block_height":1448763,"timestamp":1622791834,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"afa7785fdb0e49e649aa9b6467fa183c8185c398095baac2c11df50175a7f92b","transaction_type":"StandardTransfer"}, +{"tx_hex":"010000000259eb9eb93d9e2a571e44997132248b3e595422375f9f134395fdef1211633ecf020000006b483045022100c8abc9eed50341d8ab008efed4e56080a494999cdc53d173622be59e46e262ea02201077d04e01561af4b14adea0611a52134084385524fa37409c566cb98a39aa914121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff59eb9eb93d9e2a571e44997132248b3e595422375f9f134395fdef1211633ecf030000006a473044022049dd947c0b5ccceb1920ef0bb297de0fe287c34a8d7d9ed39209776a191850fe022069d98060c395e61fac90bcecb800e981ab5903fe50eaa0e1073d9efdadf227ce4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710080000000000015ba8e80300000000000017a914169fdaecb872081837b47440f82052a0be7b2d8c87e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acc7864901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac00d2b960","tx_hash":"afa7785fdb0e49e649aa9b6467fa183c8185c398095baac2c11df50175a7f92b","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pqtflkhvhpeqsxphk36yp7pq22stu7ed3smapthuvm","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"9.9","spent_by_me":"9.9","received_by_me":"8.9","my_balance_change":"-1.0","block_height":1448763,"timestamp":1622791834,"fee_details":null,"coin":"tBCH","internal_id":"97108642f76be5a9f4be8f35ea4057d12240c680ff782badc4a54b32c86c3b92","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000022bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af01000000d7473044022010073013a6fe700b0d8c81a027f32a0d0a35c14511a45f65c57d644531b7f0c602206d070b6fb1bb6d5b8c073e2e10fb7eca0386473b2c88839a99e61f54ec8d855b41200000000000000000000000000000000000000000000000000000000000000000004c6b6304ffd1b960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff2bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af030000006a47304402205278a8722609beb16cf872622224255327238f46b28b90650b8307ce634053ca022003b03a2b1abbe57f6031bcfad7b1ddb31e853dcc275de07728ba45e396bb0bd14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf824901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac00d2b960","tx_hash":"06f38595a2d5d23df8a81a0d744ac3a70c3e46a01efa64a4be862b9d582167b0","from":["bchtest:pqtflkhvhpeqsxphk36yp7pq22stu7ed3sqfxsdt7x","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21596847","spent_by_me":"0.21595847","received_by_me":"0.21595847","my_balance_change":"0.00000000","block_height":1448763,"timestamp":1622791834,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"06f38595a2d5d23df8a81a0d744ac3a70c3e46a01efa64a4be862b9d582167b0","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000022bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af01000000d7473044022010073013a6fe700b0d8c81a027f32a0d0a35c14511a45f65c57d644531b7f0c602206d070b6fb1bb6d5b8c073e2e10fb7eca0386473b2c88839a99e61f54ec8d855b41200000000000000000000000000000000000000000000000000000000000000000004c6b6304ffd1b960b17521036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac6782012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc68821036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cac68ffffffff2bf9a77501f51dc1c2aa5b0998c385813c18fa67649baa49e6490edb5f78a7af030000006a47304402205278a8722609beb16cf872622224255327238f46b28b90650b8307ce634053ca022003b03a2b1abbe57f6031bcfad7b1ddb31e853dcc275de07728ba45e396bb0bd14121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7080000000000002710e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88acdf824901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac00d2b960","tx_hash":"06f38595a2d5d23df8a81a0d744ac3a70c3e46a01efa64a4be862b9d582167b0","from":["slptest:pqtflkhvhpeqsxphk36yp7pq22stu7ed3smapthuvm"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"1","spent_by_me":"0","received_by_me":"1","my_balance_change":"1","block_height":1448763,"timestamp":1622791834,"fee_details":null,"coin":"tBCH","internal_id":"adbef43a6d839be9edbc03620c9e2fdd5ef4292db33d8fee3e554b8beb55438b","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"01000000026eb9e68f3760e787a0924defa136b9d164b789cfb46ccf732c33a22ef29ccc0f010000006b483045022100fd0cba042d5834d2777a0fd1896ce55324375f636e914e654c6489218eb094250220401442f474bc86e63251a24f20c6704e2507b06ba88b84a539ad96a43bbc8d024121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6eb9e68f3760e787a0924defa136b9d164b789cfb46ccf732c33a22ef29ccc0f020000006b483045022100cfe2f7fd47f9178f266c81a51f7dc69f5c16e397bb3f768383f7fff8123d15f002203582254c5f3eee2af4da7ee9600ef1e5a77c811d9353b23c85dd0f230dd83def4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000182b8e80300000000000017a9141fc203324c09e033000eb5914b6341b3dad3128087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac978e4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2bbfb960","tx_hash":"cf3e631112effd9543139f5f372254593e8b24327199441e572a9e3db99eeb59","from":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"to":["bchtest:pq0uyqejfsy7qvcqp66ezjmrgxea45cjsqnw5tuq4p","bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21600847","spent_by_me":"0.21600847","received_by_me":"0.21598847","my_balance_change":"-0.00002000","block_height":1448759,"timestamp":1622786934,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"tBCH","internal_id":"cf3e631112effd9543139f5f372254593e8b24327199441e572a9e3db99eeb59","transaction_type":"StandardTransfer"}, +{"tx_hex":"01000000026eb9e68f3760e787a0924defa136b9d164b789cfb46ccf732c33a22ef29ccc0f010000006b483045022100fd0cba042d5834d2777a0fd1896ce55324375f636e914e654c6489218eb094250220401442f474bc86e63251a24f20c6704e2507b06ba88b84a539ad96a43bbc8d024121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff6eb9e68f3760e787a0924defa136b9d164b789cfb46ccf732c33a22ef29ccc0f020000006b483045022100cfe2f7fd47f9178f266c81a51f7dc69f5c16e397bb3f768383f7fff8123d15f002203582254c5f3eee2af4da7ee9600ef1e5a77c811d9353b23c85dd0f230dd83def4121036879df230663db4cd083c8eeb0f293f46abc460ad3c299b0089b72e6d472202cffffffff040000000000000000406a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000003e80800000000000182b8e80300000000000017a9141fc203324c09e033000eb5914b6341b3dad3128087e8030000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac978e4901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2bbfb960","tx_hash":"cf3e631112effd9543139f5f372254593e8b24327199441e572a9e3db99eeb59","from":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"to":["slptest:pq0uyqejfsy7qvcqp66ezjmrgxea45cjsqg6nsxh8u","slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"10","spent_by_me":"10","received_by_me":"9.9","my_balance_change":"-0.1","block_height":1448759,"timestamp":1622786934,"fee_details":null,"coin":"tBCH","internal_id":"860c0638239fd474aa912ea59e59fa1293f10618248333ad15f6b71e0c3f0467","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}}, +{"tx_hex":"0100000007ef36129aeafbb5b35dbc2338ad48b73104ab776fa4c50bfc2ba5c4dafb76c4be020000006441cbdb096620d569f33a9d474f51736aab010c719f97b6c4603815cc92d11d1bd66c377b833e3c40c6205bbdbe9baa927e7f1280fa3e015fa17bd2c9c5e885b2a0412102d35051b984db235450829ea9a8e4dfde91e27be7ab7153224394eacd97046461feffffff133a04916fe4d25cc36598f7af4c3398f79b1aa3e85d47b857543bf0d1e1fdd2010000006441511f8178c54d56b178aa40293bb72b7556405b8fbd28d343160e8e9ea082710641028d7a1fd8b2c6b9e44cba10e210ab56fc531fc0fff5b79c3e00d810ced7f541210392a76e77f476e89b447c2f1fea192701f6c0fa2f49f04794294746997e8b3536feffffffd3cf85f86c071c3583f33d40c145e7ffd1cc039cfcb12faf2e326638f5fe0048010000006441a1885a66ac77008f5d487e37dba4fe4db222840a5efb3e4c4a7aeb6b7432ec5455e48941cf16ec55c90db91f63e9ad9b785eecb270b4d07de14384bee0fd2536412103dbd12a3753e7863223f8ac82f01ffa590714b8cdb42512153335025e5404dc94feffffffe319a50fda84c5bc87e92e16aebe83789aa7724f23e619087ab516d3f74e40a30100000064419c70094bef4954117c189692c184528946baf09cc5215eb2dd5103f08025f1e1ccb3efc4087b17535a7aa6fa1fd835c3b0e52159d01eba9f165be931f1962e7c4121032ab3389e0b58bbb6962dc804917293b995a25a44e6028e73894ecdfe5ff9f208feffffffa2621f1149fd3f230c051e1b210c6494f32fa398e8335d0894d56e9f2c8d955e010000006441c21f3a04f7c71dd04773fe862ec53193764b5b1eef81f5d3085e565ecb6a0d16a3a213b65ed2137f2f66701aab8f625a1a49b1f128ed87e5ce44b2c7d5363dc44121024b669a41202061b0cb954e17488f6c7191f54e2fe06304a59eaa903be19ff3d0feffffffdf196c6edbac91a9c3d73b385c98c93e01d7dc58e425e6d4d2a5e3164192017501000000644117e9fda726464c2ae70409ee983aacb4888f11335c9fa3ceedb5c2ca4f9c57ec516364c41e6c994691ef98df780e4d7540be9afb2fde5fea20d39d0432f65548412103eb08706246d042f3e76cdf9a87db6d7a3d2432a58043be35f3f6277a6898c1dffeffffff2cbbdd13b3577043cc175d77a82b08e27302703d6d6a0628a7e77a3aa4593ab7000000006441360b9cb442639b313f3c98755c7992b08462ed73e2869468372438af21fbf714e656f27238267125212423e0bd4fcb2dd8131ef3cc752bf234700df46d96203d41210359a24bddf1ebfb6bcf43dbbccc6f59d2bbc3bc836f896aaf28dd67ed3e210a51feffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000186a022020000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2d984901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac351b1600","tx_hash":"0fcc9cf22ea2332c73cf6cb4cf89b764d1b936a1ef4d92a087e760378fe6b96e","from":["bchtest:qp5fphvvj3pvrrv2awhm7dyu8xjueydapg3ju9kwmm","bchtest:qqayyhsx4p9am5gd54sjeelzpqxm0jncs5mgp452d8","bchtest:qqqxycuccwny828aqylsw8uugrpa33gelg8znan59t","bchtest:qr28js92h5gjv2dcau4twu8tma296kqt6yw9490acu","bchtest:qrrh9jq3zkagxnncyv60e94kv4jnt3yw9s63ykwahy","bchtest:qz7yzmqjfx0wa9hvyfjp7sdc8fkevk44svnvtuepnf","bchtest:qzlf6nyj7aag69l5h862w254ftd75anegcxecncczh"],"to":["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66"],"total_amount":"0.21601976","spent_by_me":"0","received_by_me":"0.21600847","my_balance_change":"0.21600847","block_height":1448758,"timestamp":1622785714,"fee_details":{"type":"Utxo","amount":"0.00001129"},"coin":"tBCH","internal_id":"0fcc9cf22ea2332c73cf6cb4cf89b764d1b936a1ef4d92a087e760378fe6b96e","transaction_type":"StandardTransfer"}, +{"tx_hex":"0100000007ef36129aeafbb5b35dbc2338ad48b73104ab776fa4c50bfc2ba5c4dafb76c4be020000006441cbdb096620d569f33a9d474f51736aab010c719f97b6c4603815cc92d11d1bd66c377b833e3c40c6205bbdbe9baa927e7f1280fa3e015fa17bd2c9c5e885b2a0412102d35051b984db235450829ea9a8e4dfde91e27be7ab7153224394eacd97046461feffffff133a04916fe4d25cc36598f7af4c3398f79b1aa3e85d47b857543bf0d1e1fdd2010000006441511f8178c54d56b178aa40293bb72b7556405b8fbd28d343160e8e9ea082710641028d7a1fd8b2c6b9e44cba10e210ab56fc531fc0fff5b79c3e00d810ced7f541210392a76e77f476e89b447c2f1fea192701f6c0fa2f49f04794294746997e8b3536feffffffd3cf85f86c071c3583f33d40c145e7ffd1cc039cfcb12faf2e326638f5fe0048010000006441a1885a66ac77008f5d487e37dba4fe4db222840a5efb3e4c4a7aeb6b7432ec5455e48941cf16ec55c90db91f63e9ad9b785eecb270b4d07de14384bee0fd2536412103dbd12a3753e7863223f8ac82f01ffa590714b8cdb42512153335025e5404dc94feffffffe319a50fda84c5bc87e92e16aebe83789aa7724f23e619087ab516d3f74e40a30100000064419c70094bef4954117c189692c184528946baf09cc5215eb2dd5103f08025f1e1ccb3efc4087b17535a7aa6fa1fd835c3b0e52159d01eba9f165be931f1962e7c4121032ab3389e0b58bbb6962dc804917293b995a25a44e6028e73894ecdfe5ff9f208feffffffa2621f1149fd3f230c051e1b210c6494f32fa398e8335d0894d56e9f2c8d955e010000006441c21f3a04f7c71dd04773fe862ec53193764b5b1eef81f5d3085e565ecb6a0d16a3a213b65ed2137f2f66701aab8f625a1a49b1f128ed87e5ce44b2c7d5363dc44121024b669a41202061b0cb954e17488f6c7191f54e2fe06304a59eaa903be19ff3d0feffffffdf196c6edbac91a9c3d73b385c98c93e01d7dc58e425e6d4d2a5e3164192017501000000644117e9fda726464c2ae70409ee983aacb4888f11335c9fa3ceedb5c2ca4f9c57ec516364c41e6c994691ef98df780e4d7540be9afb2fde5fea20d39d0432f65548412103eb08706246d042f3e76cdf9a87db6d7a3d2432a58043be35f3f6277a6898c1dffeffffff2cbbdd13b3577043cc175d77a82b08e27302703d6d6a0628a7e77a3aa4593ab7000000006441360b9cb442639b313f3c98755c7992b08462ed73e2869468372438af21fbf714e656f27238267125212423e0bd4fcb2dd8131ef3cc752bf234700df46d96203d41210359a24bddf1ebfb6bcf43dbbccc6f59d2bbc3bc836f896aaf28dd67ed3e210a51feffffff030000000000000000376a04534c500001010453454e4420bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb70800000000000186a022020000000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac2d984901000000001976a9148cfffc2409d063437d6aa8b75a009b9ba51b71fc88ac351b1600","tx_hash":"0fcc9cf22ea2332c73cf6cb4cf89b764d1b936a1ef4d92a087e760378fe6b96e","from":["slptest:qp5fphvvj3pvrrv2awhm7dyu8xjueydapg2xm7vefx","slptest:qqayyhsx4p9am5gd54sjeelzpqxm0jncs5quxwwal6","slptest:qqqxycuccwny828aqylsw8uugrpa33gelguk5xfrhk","slptest:qr28js92h5gjv2dcau4twu8tma296kqt6y43j7422p","slptest:qrrh9jq3zkagxnncyv60e94kv4jnt3yw9sp9rd529e","slptest:qz7yzmqjfx0wa9hvyfjp7sdc8fkevk44svgcv8rkp5"],"to":["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8"],"total_amount":"10","spent_by_me":"0","received_by_me":"10","my_balance_change":"10","block_height":1448758,"timestamp":1622785714,"fee_details":null,"coin":"tBCH","internal_id":"fe1e72fc17cda2ad5e8d52e73a65ca89d6ab364311d940f2f0600329ce40de7e","transaction_type":{"TokenTransfer":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7"}} +] diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index ff5734dde4..76e5dda359 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -10,6 +10,7 @@ use crate::utxo::{sat_from_big_decimal, FeePolicy, UtxoCommonOps, UtxoTxGenerati use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageValue, TransactionEnum, TransactionFut, UtxoStandardCoin, ValidateAddressResult, WithdrawFut, WithdrawRequest}; +use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcoin::blockdata::script::Script; use bitcoin::hash_types::Txid; @@ -116,6 +117,7 @@ impl LightningCoin { fn platform_coin(&self) -> &UtxoStandardCoin { &self.platform_fields.platform_coin } } +#[async_trait] impl SwapOps for LightningCoin { fn send_taker_fee(&self, _fee_addr: &[u8], _amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } @@ -232,7 +234,7 @@ impl SwapOps for LightningCoin { unimplemented!() } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, _time_lock: u32, _other_pub: &[u8], @@ -244,7 +246,7 @@ impl SwapOps for LightningCoin { unimplemented!() } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, _time_lock: u32, _other_pub: &[u8], diff --git a/mm2src/coins/lightning/ln_utils.rs b/mm2src/coins/lightning/ln_utils.rs index a57ed5fd55..0c3e27b757 100644 --- a/mm2src/coins/lightning/ln_utils.rs +++ b/mm2src/coins/lightning/ln_utils.rs @@ -159,11 +159,11 @@ impl EventHandler for LightningEventHandler { // Give the funding transaction back to LDK for opening the channel. match self .channel_manager - .funding_transaction_generated(&temporary_channel_id, funding_tx.clone()) + .funding_transaction_generated(temporary_channel_id, funding_tx.clone()) { Ok(_) => { let txid = funding_tx.txid(); - self.filter.register_tx(&txid, &output_script); + self.filter.register_tx(&txid, output_script); let output_to_be_registered = TxOut { value: *channel_value_satoshis, script_pubkey: output_script.clone(), @@ -260,7 +260,7 @@ pub async fn start_lightning( let broadcaster = Arc::new(platform_coin.clone()); // Initialize Persist - let ln_data_dir = my_ln_data_dir(&ctx, &ticker) + let ln_data_dir = my_ln_data_dir(ctx, &ticker) .as_path() .to_str() .ok_or("Data dir is a non-UTF-8 string") @@ -455,7 +455,7 @@ pub async fn start_lightning( // If node is restarting read other nodes data from disk and reconnect to channel nodes/peers if possible. if restarting_node { - let mut nodes_data = read_nodes_data_from_file(&nodes_data_path(&ctx, &ticker))?; + let mut nodes_data = read_nodes_data_from_file(&nodes_data_path(ctx, &ticker))?; for (pubkey, node_addr) in nodes_data.drain() { for chan_info in channel_manager.list_channels() { if pubkey == chan_info.counterparty.node_id { @@ -542,7 +542,7 @@ async fn process_tx_for_unconfirmation(txid: Txid, filter: Arc, .platform_coin .as_ref() .rpc_client - .get_transaction_bytes(H256::from(txid.as_hash().into_inner()).reversed()) + .get_transaction_bytes(&H256::from(txid.as_hash().into_inner()).reversed()) .compat() .await .map_err(|e| e.into_inner()) @@ -597,7 +597,7 @@ async fn process_txs_confirmations( .platform_coin .as_ref() .rpc_client - .get_transaction_bytes(rpc_txid.clone()) + .get_transaction_bytes(&rpc_txid) .compat() .await { diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index da9bcb5afd..4bccc92882 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -19,7 +19,6 @@ #![allow(uncommon_codepoints)] #![feature(integer_atomics)] -#![feature(associated_type_bounds)] #![feature(async_closure)] #![feature(hash_raw_entry)] @@ -38,7 +37,7 @@ use common::mm_ctx::{from_ctx, MmArc, MmWeak}; use common::mm_error::prelude::*; use common::mm_metrics::MetricsWeak; use common::mm_number::MmNumber; -use common::{calc_total_pages, now_ms, HttpStatusCode}; +use common::{calc_total_pages, now_ms, ten, HttpStatusCode}; use derive_more::Display; use futures::compat::Future01CompatExt; use futures::lock::Mutex as AsyncMutex; @@ -102,6 +101,9 @@ use qrc20::{qrc20_coin_from_conf_and_params, Qrc20Coin, Qrc20FeeDetails}; pub mod lightning; +#[cfg(not(target_arch = "wasm32"))] +pub mod sql_tx_history_storage; + #[doc(hidden)] #[allow(unused_variables)] pub mod test_coin; @@ -109,6 +111,9 @@ pub use test_coin::TestCoin; #[cfg(target_arch = "wasm32")] pub mod tx_history_db; +#[cfg_attr(target_arch = "wasm32", allow(dead_code, unused_imports))] +pub mod my_tx_history_v2; + #[cfg(all(not(target_arch = "wasm32"), feature = "zhtlc"))] pub mod z_coin; @@ -232,6 +237,7 @@ pub enum NegotiateSwapContractAddrErr { } /// Swap operations (mostly based on the Hash/Time locked transactions implemented by coin wallets). +#[async_trait] pub trait SwapOps { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut; @@ -328,7 +334,7 @@ pub trait SwapOps { swap_contract_address: &Option, ) -> Box, Error = String> + Send>; - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -338,7 +344,7 @@ pub trait SwapOps { swap_contract_address: &Option, ) -> Result, String>; - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -603,6 +609,7 @@ pub enum TransactionType { StakingDelegation, RemoveDelegation, StandardTransfer, + TokenTransfer(BytesJson), } impl Default for TransactionType { @@ -648,6 +655,12 @@ pub struct TransactionDetails { transaction_type: TransactionType, } +#[derive(Clone, Copy, Debug)] +pub struct BlockHeightAndTime { + height: u64, + timestamp: u64, +} + impl TransactionDetails { /// Whether the transaction details block height should be updated (when tx is confirmed) pub fn should_update_block_height(&self) -> bool { @@ -693,6 +706,12 @@ pub struct CoinBalance { pub unspendable: BigDecimal, } +impl CoinBalance { + pub fn into_total(self) -> BigDecimal { self.spendable + self.unspendable } + + pub fn get_total(&self) -> BigDecimal { &self.spendable + &self.unspendable } +} + /// The approximation is needed to cover the dynamic miner fee changing during a swap. #[derive(Clone, Debug)] pub enum FeeApproxStage { @@ -1266,7 +1285,7 @@ pub trait MmCoin: SwapOps + MarketCoinOps + fmt::Debug + Send + Sync + 'static { let my_address = self.my_address().unwrap_or_default(); // BCH cash address format has colon after prefix, e.g. bitcoincash: // Colon can't be used in file names on Windows so it should be escaped - let my_address = my_address.replace(":", "_"); + let my_address = my_address.replace(':', "_"); ctx.dbdir() .join("TRANSACTIONS") .join(format!("{}_{}.json", self.ticker(), my_address)) @@ -1758,7 +1777,7 @@ pub async fn lp_coininit(ctx: &MmArc, ticker: &str, req: &Json) -> Result { - let params = try_s!(Qrc20ActivationParams::from_legacy_req(&req)); + let params = try_s!(Qrc20ActivationParams::from_legacy_req(req)); let contract_address = try_s!(qtum::contract_addr_from_str(contract_address)); try_s!( @@ -1768,7 +1787,7 @@ pub async fn lp_coininit(ctx: &MmArc, ticker: &str, req: &Json) -> Result { - let prefix = try_s!(CashAddrPrefix::from_str(&slp_prefix)); + let prefix = try_s!(CashAddrPrefix::from_str(slp_prefix)); let params = try_s!(BchActivationRequest::from_legacy_req(req)); let bch = try_s!(bch_coin_from_conf_and_params(ctx, ticker, &coins_en, params, prefix, &secret).await); @@ -1780,7 +1799,7 @@ pub async fn lp_coininit(ctx: &MmArc, ticker: &str, req: &Json) -> Result { - let platform_coin = try_s!(lp_coinfind(ctx, &platform).await); + let platform_coin = try_s!(lp_coinfind(ctx, platform).await); let platform_coin = match platform_coin { Some(MmCoinEnum::Bch(coin)) => coin, Some(_) => return ERR!("Platform coin {} is not BCH", platform), @@ -2042,8 +2061,6 @@ pub enum HistorySyncState { Finished, } -fn ten() -> usize { 10 } - #[derive(Deserialize)] struct MyTxHistoryRequest { coin: String, @@ -2350,7 +2367,7 @@ pub fn address_by_coin_conf_and_pubkey_str( utxo::address_by_conf_and_pubkey_str(coin, conf, pubkey, addr_format) }, CoinProtocol::SLPTOKEN { platform, .. } => { - let platform_conf = coin_conf(&ctx, &platform); + let platform_conf = coin_conf(ctx, &platform); if platform_conf.is_null() { return ERR!("platform {} conf is null", platform); } @@ -2409,7 +2426,7 @@ where T: MmCoin + ?Sized, { let ticker = coin.ticker().to_owned(); - let history_path = coin.tx_history_path(&ctx); + let history_path = coin.tx_history_path(ctx); let ctx = ctx.clone(); let fut = async move { diff --git a/mm2src/coins/my_tx_history_v2.rs b/mm2src/coins/my_tx_history_v2.rs new file mode 100644 index 0000000000..e55d23eacd --- /dev/null +++ b/mm2src/coins/my_tx_history_v2.rs @@ -0,0 +1,386 @@ +#[cfg(not(target_arch = "wasm32"))] +use crate::sql_tx_history_storage::SqliteTxHistoryStorage; +use crate::{lp_coinfind_or_err, BlockHeightAndTime, CoinFindError, HistorySyncState, MarketCoinOps, MmCoinEnum, + Transaction, TransactionDetails, TransactionType, TxFeeDetails}; +use async_trait::async_trait; +use bitcrypto::sha256; +use common::mm_ctx::MmArc; +use common::mm_error::prelude::*; +use common::mm_number::BigDecimal; +use common::{calc_total_pages, ten, HttpStatusCode, NotSame, PagingOptionsEnum, StatusCode}; +use derive_more::Display; +use futures::compat::Future01CompatExt; +use keys::{Address, CashAddress}; +use rpc::v1::types::Bytes as BytesJson; +use std::collections::HashSet; + +#[derive(Debug)] +pub enum RemoveTxResult { + TxRemoved, + TxDidNotExist, +} + +impl RemoveTxResult { + pub fn tx_existed(&self) -> bool { matches!(self, RemoveTxResult::TxRemoved) } +} + +pub struct GetHistoryResult { + pub transactions: Vec, + pub skipped: usize, + pub total: usize, +} + +pub trait TxHistoryStorageError: std::fmt::Debug + NotMmError + NotSame + Send {} + +#[async_trait] +pub trait TxHistoryStorage: Send + Sync + 'static { + type Error: TxHistoryStorageError; + + /// Initializes collection/tables in storage for a specified coin + async fn init(&self, for_coin: &str) -> Result<(), MmError>; + + async fn is_initialized_for(&self, for_coin: &str) -> Result>; + + /// Adds multiple transactions to the selected coin's history + /// Also consider adding tx_hex to the cache during this operation + async fn add_transactions_to_history( + &self, + for_coin: &str, + transactions: impl IntoIterator + Send + 'static, + ) -> Result<(), MmError>; + + /// Removes the transaction by internal_id from the selected coin's history + async fn remove_tx_from_history( + &self, + for_coin: &str, + internal_id: &BytesJson, + ) -> Result>; + + /// Gets the transaction by internal_id from the selected coin's history + async fn get_tx_from_history( + &self, + for_coin: &str, + internal_id: &BytesJson, + ) -> Result, MmError>; + + /// Returns whether the history contains unconfirmed transactions + async fn history_contains_unconfirmed_txes(&self, for_coin: &str) -> Result>; + + /// Gets the unconfirmed transactions from the history + async fn get_unconfirmed_txes_from_history( + &self, + for_coin: &str, + ) -> Result, MmError>; + + /// Updates transaction in the selected coin's history + async fn update_tx_in_history(&self, for_coin: &str, tx: &TransactionDetails) -> Result<(), MmError>; + + async fn history_has_tx_hash(&self, for_coin: &str, tx_hash: &str) -> Result>; + + async fn unique_tx_hashes_num_in_history(&self, for_coin: &str) -> Result>; + + async fn add_tx_to_cache( + &self, + for_coin: &str, + tx_hash: &BytesJson, + tx_hex: &BytesJson, + ) -> Result<(), MmError>; + + async fn tx_bytes_from_cache( + &self, + for_coin: &str, + tx_hash: &BytesJson, + ) -> Result, MmError>; + + async fn get_history( + &self, + coin_type: HistoryCoinType, + paging: PagingOptionsEnum, + limit: usize, + ) -> Result>; +} + +pub trait DisplayAddress { + fn display_address(&self) -> String; +} + +impl DisplayAddress for Address { + fn display_address(&self) -> String { self.to_string() } +} + +impl DisplayAddress for CashAddress { + fn display_address(&self) -> String { self.encode().expect("A valid cash address") } +} + +pub struct TxDetailsBuilder<'a, Addr: DisplayAddress, Tx: Transaction> { + coin: String, + tx: &'a Tx, + my_addresses: HashSet, + total_amount: BigDecimal, + received_by_me: BigDecimal, + spent_by_me: BigDecimal, + from_addresses: HashSet, + to_addresses: HashSet, + transaction_type: TransactionType, + block_height_and_time: Option, + tx_fee: Option, +} + +impl<'a, Addr: Clone + DisplayAddress + Eq + std::hash::Hash, Tx: Transaction> TxDetailsBuilder<'a, Addr, Tx> { + pub fn new( + coin: String, + tx: &'a Tx, + block_height_and_time: Option, + my_addresses: impl IntoIterator, + ) -> Self { + TxDetailsBuilder { + coin, + tx, + my_addresses: my_addresses.into_iter().collect(), + total_amount: Default::default(), + received_by_me: Default::default(), + spent_by_me: Default::default(), + from_addresses: Default::default(), + to_addresses: Default::default(), + block_height_and_time, + transaction_type: TransactionType::StandardTransfer, + tx_fee: None, + } + } + + pub fn set_tx_fee(&mut self, tx_fee: Option) { self.tx_fee = tx_fee; } + + pub fn set_transaction_type(&mut self, tx_type: TransactionType) { self.transaction_type = tx_type; } + + pub fn transferred_to(&mut self, address: Addr, amount: &BigDecimal) { + if self.my_addresses.contains(&address) { + self.received_by_me += amount; + } + self.to_addresses.insert(address); + } + + pub fn transferred_from(&mut self, address: Addr, amount: &BigDecimal) { + if self.my_addresses.contains(&address) { + self.spent_by_me += amount; + } + self.total_amount += amount; + self.from_addresses.insert(address); + } + + pub fn build(self) -> TransactionDetails { + let (block_height, timestamp) = match self.block_height_and_time { + Some(height_with_time) => (height_with_time.height, height_with_time.timestamp), + None => (0, 0), + }; + + let mut from: Vec<_> = self + .from_addresses + .iter() + .map(DisplayAddress::display_address) + .collect(); + from.sort(); + + let mut to: Vec<_> = self.to_addresses.iter().map(DisplayAddress::display_address).collect(); + to.sort(); + + let tx_hash = self.tx.tx_hash(); + let internal_id = match &self.transaction_type { + TransactionType::TokenTransfer(token_id) => { + let mut bytes_for_hash = tx_hash.0.clone(); + bytes_for_hash.extend_from_slice(&token_id.0); + sha256(&bytes_for_hash).to_vec().into() + }, + TransactionType::StakingDelegation + | TransactionType::RemoveDelegation + | TransactionType::StandardTransfer => tx_hash.clone(), + }; + + TransactionDetails { + coin: self.coin, + tx_hex: self.tx.tx_hex().into(), + tx_hash, + from, + to, + total_amount: self.total_amount, + my_balance_change: &self.received_by_me - &self.spent_by_me, + spent_by_me: self.spent_by_me, + received_by_me: self.received_by_me, + block_height, + timestamp, + fee_details: self.tx_fee, + internal_id, + kmd_rewards: None, + transaction_type: self.transaction_type, + } + } +} + +#[derive(Deserialize)] +pub struct MyTxHistoryRequestV2 { + coin: String, + #[serde(default = "ten")] + limit: usize, + #[serde(default)] + paging_options: PagingOptionsEnum, +} + +#[derive(Serialize)] +pub struct MyTxHistoryDetails { + #[serde(flatten)] + details: TransactionDetails, + confirmations: u64, +} + +#[derive(Serialize)] +pub struct MyTxHistoryResponseV2 { + coin: String, + current_block: u64, + transactions: Vec, + sync_status: HistorySyncState, + limit: usize, + skipped: usize, + total: usize, + total_pages: usize, + paging_options: PagingOptionsEnum, +} + +#[derive(Debug, Display, Serialize, SerializeErrorType)] +#[serde(tag = "error_type", content = "error_data")] +pub enum MyTxHistoryErrorV2 { + CoinIsNotActive(String), + StorageIsNotInitialized(String), + StorageError(String), + RpcError(String), + #[cfg(target_arch = "wasm32")] + NotSupportedInWasm, +} + +impl HttpStatusCode for MyTxHistoryErrorV2 { + fn status_code(&self) -> StatusCode { + match self { + MyTxHistoryErrorV2::CoinIsNotActive(_) => StatusCode::PRECONDITION_REQUIRED, + MyTxHistoryErrorV2::StorageIsNotInitialized(_) + | MyTxHistoryErrorV2::StorageError(_) + | MyTxHistoryErrorV2::RpcError(_) => StatusCode::INTERNAL_SERVER_ERROR, + #[cfg(target_arch = "wasm32")] + MyTxHistoryErrorV2::NotSupportedInWasm => StatusCode::BAD_REQUEST, + } + } +} + +impl From for MyTxHistoryErrorV2 { + fn from(err: CoinFindError) -> Self { + match err { + CoinFindError::NoSuchCoin { coin } => MyTxHistoryErrorV2::CoinIsNotActive(coin), + } + } +} + +impl From for MyTxHistoryErrorV2 { + fn from(err: T) -> Self { + let msg = format!("{:?}", err); + MyTxHistoryErrorV2::StorageError(msg) + } +} + +pub enum HistoryCoinType { + Coin(String), + Token { platform: String, token_id: BytesJson }, + // TODO extend with the L2 required info + L2 { platform: String }, +} + +impl HistoryCoinType { + fn storage_ticker(&self) -> &str { + match self { + HistoryCoinType::Coin(ticker) => ticker, + HistoryCoinType::Token { platform, .. } | HistoryCoinType::L2 { platform } => platform, + } + } +} + +trait GetHistoryCoinType { + fn get_history_coin_type(&self) -> HistoryCoinType; +} + +impl GetHistoryCoinType for MmCoinEnum { + fn get_history_coin_type(&self) -> HistoryCoinType { + match self { + MmCoinEnum::Bch(bch) => HistoryCoinType::Coin(bch.ticker().to_owned()), + MmCoinEnum::SlpToken(token) => HistoryCoinType::Token { + platform: token.platform_ticker().to_owned(), + token_id: token.token_id().take().to_vec().into(), + }, + _ => unimplemented!(), + } + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub async fn my_tx_history_v2_rpc( + ctx: MmArc, + request: MyTxHistoryRequestV2, +) -> Result> { + let coin = lp_coinfind_or_err(&ctx, &request.coin).await?; + let tx_history_storage = SqliteTxHistoryStorage( + ctx.sqlite_connection + .ok_or(MmError::new(MyTxHistoryErrorV2::StorageIsNotInitialized( + "sqlite_connection is not initialized".into(), + )))? + .clone(), + ); + let history_coin_type = coin.get_history_coin_type(); + let is_storage_init = tx_history_storage + .is_initialized_for(history_coin_type.storage_ticker()) + .await?; + if !is_storage_init { + let msg = format!("Storage is not initialized for {}", history_coin_type.storage_ticker()); + return MmError::err(MyTxHistoryErrorV2::StorageIsNotInitialized(msg)); + } + let current_block = coin + .current_block() + .compat() + .await + .map_to_mm(MyTxHistoryErrorV2::RpcError)?; + + let history = tx_history_storage + .get_history(history_coin_type, request.paging_options.clone(), request.limit) + .await?; + + let transactions = history + .transactions + .into_iter() + .map(|mut details| { + // it can be the platform ticker instead of the token ticker for a pre-saved record + if details.coin != request.coin { + details.coin = request.coin.clone(); + } + let confirmations = if details.block_height == 0 || details.block_height > current_block { + 0 + } else { + current_block + 1 - details.block_height + }; + MyTxHistoryDetails { confirmations, details } + }) + .collect(); + + Ok(MyTxHistoryResponseV2 { + coin: request.coin, + current_block, + transactions, + sync_status: coin.history_sync_status(), + limit: request.limit, + skipped: history.skipped, + total: history.total, + total_pages: calc_total_pages(history.total, request.limit), + paging_options: request.paging_options, + }) +} + +#[cfg(target_arch = "wasm32")] +pub async fn my_tx_history_v2_rpc( + _ctx: MmArc, + _request: MyTxHistoryRequestV2, +) -> Result> { + MmError::err(MyTxHistoryErrorV2::NotSupportedInWasm) +} diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 4d8358bf31..01e6d514e3 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -19,7 +19,6 @@ use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcrypto::{dhash160, sha256}; use chain::TransactionOutput; -use common::block_on; use common::executor::Timer; use common::jsonrpc_client::{JsonRpcClient, JsonRpcError, JsonRpcRequest, RpcRes}; use common::log::{error, warn}; @@ -684,6 +683,7 @@ impl UtxoCommonOps for Qrc20Coin { } } +#[async_trait] impl SwapOps for Qrc20Coin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let to_address = try_fus!(self.contract_address_from_raw_pubkey(fee_addr)); @@ -935,7 +935,7 @@ impl SwapOps for Qrc20Coin { Box::new(fut.boxed().compat()) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, _other_pub: &[u8], @@ -946,12 +946,11 @@ impl SwapOps for Qrc20Coin { ) -> Result, String> { let tx: UtxoTx = try_s!(deserialize(tx).map_err(|e| ERRL!("{:?}", e))); - let selfi = self.clone(); - let fut = selfi.search_for_swap_tx_spend(time_lock, secret_hash.to_vec(), tx, search_from_block); - block_on(fut) + self.search_for_swap_tx_spend(time_lock, secret_hash.to_vec(), tx, search_from_block) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, _other_pub: &[u8], @@ -962,9 +961,8 @@ impl SwapOps for Qrc20Coin { ) -> Result, String> { let tx: UtxoTx = try_s!(deserialize(tx).map_err(|e| ERRL!("{:?}", e))); - let selfi = self.clone(); - let fut = selfi.search_for_swap_tx_spend(time_lock, secret_hash.to_vec(), tx, search_from_block); - block_on(fut) + self.search_for_swap_tx_spend(time_lock, secret_hash.to_vec(), tx, search_from_block) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { diff --git a/mm2src/coins/qrc20/history.rs b/mm2src/coins/qrc20/history.rs index f8df1cb4a3..9b68d69b25 100644 --- a/mm2src/coins/qrc20/history.rs +++ b/mm2src/coins/qrc20/history.rs @@ -146,7 +146,7 @@ impl Qrc20Coin { })); break; }, - RequestTxHistoryResult::UnknownError(e) => { + RequestTxHistoryResult::CriticalError(e) => { ctx.log.log( "😟", &[&"tx_history", &self.utxo.conf.ticker], @@ -175,8 +175,7 @@ impl Qrc20Coin { // `history_map` has been updated. let mut to_write: Vec = history_map .iter() - .map(|(_, value)| value) - .flatten() + .flat_map(|(_, value)| value) .map(|(_tx_id, tx)| tx.clone()) .collect(); to_write.sort_unstable_by(|a, b| { @@ -207,7 +206,7 @@ impl Qrc20Coin { let miner_fee = { let total_qtum_fee = match qtum_details.fee_details { - Some(TxFeeDetails::Utxo(UtxoFeeDetails { ref amount })) => amount.clone(), + Some(TxFeeDetails::Utxo(UtxoFeeDetails { ref amount, .. })) => amount.clone(), Some(ref fee) => return ERR!("Unexpected fee details {:?}", fee), None => return ERR!("No Qtum fee details"), }; @@ -391,8 +390,7 @@ impl Qrc20Coin { ) -> bool { let need_update = history .iter() - .map(|(_, txs)| txs) - .flatten() + .flat_map(|(_, txs)| txs) .any(|(_, tx)| tx.should_update_timestamp() || tx.should_update_block_height()); match last_balance { Some(last_balance) if last_balance == actual_balance && !need_update => { @@ -828,6 +826,7 @@ fn is_transfer_event_log(log: &LogEntry) -> bool { #[cfg(test)] mod tests { use super::*; + use common::block_on; use common::for_tests::find_metrics_in_json; use common::mm_metrics::{MetricType, MetricsJson, MetricsOps}; use qrc20_tests::qrc20_coin_for_test; diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index f7ebda1b20..193c668cfb 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -3,7 +3,7 @@ use crate::TxFeeDetails; use bigdecimal::Zero; use chain::OutPoint; use common::mm_ctx::MmCtxBuilder; -use common::DEX_FEE_ADDR_RAW_PUBKEY; +use common::{block_on, DEX_FEE_ADDR_RAW_PUBKEY}; use itertools::Itertools; use mocktopus::mocking::{MockResult, Mockable}; diff --git a/mm2src/coins/qrc20/rpc_clients.rs b/mm2src/coins/qrc20/rpc_clients.rs index ddd43be6aa..4feb1848a1 100644 --- a/mm2src/coins/qrc20/rpc_clients.rs +++ b/mm2src/coins/qrc20/rpc_clients.rs @@ -139,6 +139,7 @@ pub struct ExecutionResult { #[derive(Debug, Deserialize)] pub struct ContractCallResult { + #[allow(dead_code)] address: H160Json, #[serde(rename = "executionResult")] pub execution_result: ExecutionResult, diff --git a/mm2src/coins/sql_tx_history_storage.rs b/mm2src/coins/sql_tx_history_storage.rs new file mode 100644 index 0000000000..71596b57a6 --- /dev/null +++ b/mm2src/coins/sql_tx_history_storage.rs @@ -0,0 +1,851 @@ +use crate::my_tx_history_v2::{GetHistoryResult, HistoryCoinType, RemoveTxResult, TxHistoryStorage, + TxHistoryStorageError}; +use crate::{TransactionDetails, TransactionType}; +use async_trait::async_trait; +use common::mm_error::prelude::*; +use common::{async_blocking, PagingOptionsEnum}; +use db_common::sqlite::rusqlite::types::Type; +use db_common::sqlite::rusqlite::{Connection, Error as SqlError, Row, ToSql, NO_PARAMS}; +use db_common::sqlite::sql_builder::SqlBuilder; +use db_common::sqlite::{offset_by_id, validate_table_name}; +use rpc::v1::types::Bytes as BytesJson; +use serde_json::{self as json}; +use std::convert::TryInto; +use std::sync::{Arc, Mutex}; + +const CHECK_TABLE_EXISTS_SQL: &str = "SELECT name FROM sqlite_master WHERE type='table' AND name=?1;"; + +fn tx_history_table(ticker: &str) -> String { ticker.to_owned() + "_tx_history" } + +fn tx_cache_table(ticker: &str) -> String { ticker.to_owned() + "_tx_cache" } + +fn create_tx_history_table_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "CREATE TABLE IF NOT EXISTS ".to_owned() + + &table_name + + " ( + id INTEGER NOT NULL PRIMARY KEY, + tx_hash VARCHAR(255) NOT NULL, + internal_id VARCHAR(255) NOT NULL UNIQUE, + block_height INTEGER NOT NULL, + confirmation_status INTEGER NOT NULL, + token_id VARCHAR(255) NOT NULL, + details_json TEXT + );"; + + Ok(sql) +} + +fn create_tx_cache_table_sql(for_coin: &str) -> Result> { + let table_name = tx_cache_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "CREATE TABLE IF NOT EXISTS ".to_owned() + + &table_name + + " ( + tx_hash VARCHAR(255) NOT NULL UNIQUE, + tx_hex TEXT NOT NULL + );"; + + Ok(sql) +} + +fn insert_tx_in_history_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "INSERT INTO ".to_owned() + + &table_name + + " (tx_hash, internal_id, block_height, confirmation_status, token_id, details_json) VALUES (?1, ?2, ?3, ?4, ?5, ?6);"; + + Ok(sql) +} + +fn insert_tx_in_cache_sql(for_coin: &str) -> Result> { + let table_name = tx_cache_table(for_coin); + validate_table_name(&table_name)?; + + // We can simply ignore the repetitive attempt to insert the same tx_hash + let sql = "INSERT OR IGNORE INTO ".to_owned() + &table_name + " (tx_hash, tx_hex) VALUES (?1, ?2);"; + + Ok(sql) +} + +fn remove_tx_from_table_by_internal_id_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "DELETE FROM ".to_owned() + &table_name + " WHERE internal_id=?1;"; + + Ok(sql) +} + +fn select_tx_from_table_by_internal_id_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT details_json FROM ".to_owned() + &table_name + " WHERE internal_id=?1;"; + + Ok(sql) +} + +fn update_tx_in_table_by_internal_id_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "UPDATE ".to_owned() + + &table_name + + " SET block_height = ?1, confirmation_status = ?2, details_json = ?3 WHERE internal_id=?4;"; + + Ok(sql) +} + +fn contains_unconfirmed_transactions_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT COUNT(id) FROM ".to_owned() + &table_name + " WHERE confirmation_status = 0;"; + + Ok(sql) +} + +fn get_unconfirmed_transactions_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT details_json FROM ".to_owned() + &table_name + " WHERE confirmation_status = 0;"; + + Ok(sql) +} + +fn has_transactions_with_hash_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT COUNT(id) FROM ".to_owned() + &table_name + " WHERE tx_hash = ?1;"; + + Ok(sql) +} + +fn unique_tx_hashes_num_sql(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT COUNT(DISTINCT tx_hash) FROM ".to_owned() + &table_name + ";"; + + Ok(sql) +} + +fn get_tx_hex_from_cache_sql(for_coin: &str) -> Result> { + let table_name = tx_cache_table(for_coin); + validate_table_name(&table_name)?; + + let sql = "SELECT tx_hex FROM ".to_owned() + &table_name + " WHERE tx_hash = ?1 LIMIT 1;"; + + Ok(sql) +} + +fn get_history_builder_preimage(for_coin: &str) -> Result> { + let table_name = tx_history_table(for_coin); + validate_table_name(&table_name)?; + + let mut sql_builder = SqlBuilder::select_from(table_name); + sql_builder.and_where("token_id = ?1"); + Ok(sql_builder) +} + +fn finalize_get_history_sql_builder(sql_builder: &mut SqlBuilder, offset: usize, limit: usize) { + sql_builder.field("details_json"); + sql_builder.offset(offset); + sql_builder.limit(limit); + sql_builder.order_asc("confirmation_status"); + sql_builder.order_desc("block_height"); + sql_builder.order_asc("id"); +} + +#[derive(Clone)] +pub struct SqliteTxHistoryStorage(pub Arc>); + +#[cfg(test)] +impl SqliteTxHistoryStorage { + pub fn in_memory() -> Self { SqliteTxHistoryStorage(Arc::new(Mutex::new(Connection::open_in_memory().unwrap()))) } + + fn is_table_empty(&self, table_name: &str) -> bool { + validate_table_name(table_name).unwrap(); + let sql = "SELECT COUNT(id) FROM ".to_owned() + table_name + ";"; + let conn = self.0.lock().unwrap(); + let rows_count: u32 = conn.query_row(&sql, NO_PARAMS, |row| row.get(0)).unwrap(); + rows_count == 0 + } +} + +impl TxHistoryStorageError for SqlError {} + +fn query_single_row( + conn: &Connection, + query: &str, + params: P, + map_fn: F, +) -> Result, MmError> +where + P: IntoIterator, + P::Item: ToSql, + F: FnOnce(&Row<'_>) -> Result, +{ + let maybe_result = conn.query_row(query, params, map_fn); + if let Err(SqlError::QueryReturnedNoRows) = maybe_result { + return Ok(None); + } + + let result = maybe_result?; + Ok(Some(result)) +} + +fn string_from_row(row: &Row<'_>) -> Result { row.get(0) } + +fn tx_details_from_row(row: &Row<'_>) -> Result { + let json_string: String = row.get(0)?; + json::from_str(&json_string).map_err(|e| SqlError::FromSqlConversionFailure(0, Type::Text, Box::new(e))) +} + +#[async_trait] +impl TxHistoryStorage for SqliteTxHistoryStorage { + type Error = SqlError; + + async fn init(&self, for_coin: &str) -> Result<(), MmError> { + let selfi = self.clone(); + let sql_history = create_tx_history_table_sql(for_coin)?; + let sql_cache = create_tx_cache_table_sql(for_coin)?; + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + conn.execute(&sql_history, NO_PARAMS).map(|_| ())?; + conn.execute(&sql_cache, NO_PARAMS).map(|_| ())?; + Ok(()) + }) + .await + } + + async fn is_initialized_for(&self, for_coin: &str) -> Result> { + let tx_history_table = tx_history_table(for_coin); + validate_table_name(&tx_history_table)?; + + let tx_cache_table = tx_cache_table(for_coin); + validate_table_name(&tx_cache_table)?; + + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let history_initialized = + query_single_row(&conn, CHECK_TABLE_EXISTS_SQL, [tx_history_table], string_from_row)?; + let cache_initialized = query_single_row(&conn, CHECK_TABLE_EXISTS_SQL, [tx_cache_table], string_from_row)?; + Ok(history_initialized.is_some() && cache_initialized.is_some()) + }) + .await + } + + async fn add_transactions_to_history( + &self, + for_coin: &str, + transactions: impl IntoIterator + Send + 'static, + ) -> Result<(), MmError> { + let for_coin = for_coin.to_owned(); + let selfi = self.clone(); + + async_blocking(move || { + let mut conn = selfi.0.lock().unwrap(); + let sql_transaction = conn.transaction()?; + + for tx in transactions { + let tx_hash = format!("{:02x}", tx.tx_hash); + let internal_id = format!("{:02x}", tx.internal_id); + let confirmation_status = if tx.block_height > 0 { 1 } else { 0 }; + let token_id = if let TransactionType::TokenTransfer(token_id) = &tx.transaction_type { + format!("{:02x}", token_id) + } else { + "".to_owned() + }; + let tx_json = json::to_string(&tx).expect("serialization should not fail"); + + let tx_hex = format!("{:02x}", tx.tx_hex); + let tx_cache_params = [&tx_hash, &tx_hex]; + + sql_transaction.execute(&insert_tx_in_cache_sql(&for_coin)?, tx_cache_params)?; + + let params = [ + tx_hash, + internal_id, + tx.block_height.to_string(), + confirmation_status.to_string(), + token_id, + tx_json, + ]; + + sql_transaction.execute(&insert_tx_in_history_sql(&for_coin)?, ¶ms)?; + } + sql_transaction.commit()?; + Ok(()) + }) + .await + } + + async fn remove_tx_from_history( + &self, + for_coin: &str, + internal_id: &BytesJson, + ) -> Result> { + let sql = remove_tx_from_table_by_internal_id_sql(for_coin)?; + let params = [format!("{:02x}", internal_id)]; + let selfi = self.clone(); + + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + conn.execute(&sql, ¶ms) + .map(|rows_num| { + if rows_num > 0 { + RemoveTxResult::TxRemoved + } else { + RemoveTxResult::TxDidNotExist + } + }) + .map_err(MmError::new) + }) + .await + } + + async fn get_tx_from_history( + &self, + for_coin: &str, + internal_id: &BytesJson, + ) -> Result, MmError> { + let params = [format!("{:02x}", internal_id)]; + let sql = select_tx_from_table_by_internal_id_sql(for_coin)?; + let selfi = self.clone(); + + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + query_single_row(&conn, &sql, params, tx_details_from_row) + }) + .await + } + + async fn history_contains_unconfirmed_txes(&self, for_coin: &str) -> Result> { + let sql = contains_unconfirmed_transactions_sql(for_coin)?; + let selfi = self.clone(); + + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let count_unconfirmed = conn.query_row::(&sql, NO_PARAMS, |row| row.get(0))?; + Ok(count_unconfirmed > 0) + }) + .await + } + + async fn get_unconfirmed_txes_from_history( + &self, + for_coin: &str, + ) -> Result, MmError> { + let sql = get_unconfirmed_transactions_sql(for_coin)?; + let selfi = self.clone(); + + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let mut stmt = conn.prepare(&sql)?; + let rows = stmt.query(NO_PARAMS)?; + let result = rows.mapped(tx_details_from_row).collect::>()?; + Ok(result) + }) + .await + } + + async fn update_tx_in_history(&self, for_coin: &str, tx: &TransactionDetails) -> Result<(), MmError> { + let sql = update_tx_in_table_by_internal_id_sql(for_coin)?; + + let block_height = tx.block_height.to_string(); + let confirmation_status = if tx.block_height > 0 { 1 } else { 0 }; + let json_details = json::to_string(tx).unwrap(); + let internal_id = format!("{:02x}", tx.internal_id); + + let params = [block_height, confirmation_status.to_string(), json_details, internal_id]; + + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + conn.execute(&sql, params).map(|_| ()).map_err(MmError::new) + }) + .await + } + + async fn history_has_tx_hash(&self, for_coin: &str, tx_hash: &str) -> Result> { + let sql = has_transactions_with_hash_sql(for_coin)?; + let params = [tx_hash.to_owned()]; + + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let count: u32 = conn.query_row(&sql, params, |row| row.get(0))?; + Ok(count > 0) + }) + .await + } + + async fn unique_tx_hashes_num_in_history(&self, for_coin: &str) -> Result> { + let sql = unique_tx_hashes_num_sql(for_coin)?; + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let count: u32 = conn.query_row(&sql, NO_PARAMS, |row| row.get(0))?; + Ok(count as usize) + }) + .await + } + + async fn add_tx_to_cache( + &self, + for_coin: &str, + tx_hash: &BytesJson, + tx_hex: &BytesJson, + ) -> Result<(), MmError> { + let sql = insert_tx_in_cache_sql(for_coin)?; + let params = [format!("{:02x}", tx_hash), format!("{:02x}", tx_hex)]; + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + conn.execute(&sql, params)?; + Ok(()) + }) + .await + } + + async fn tx_bytes_from_cache( + &self, + for_coin: &str, + tx_hash: &BytesJson, + ) -> Result, MmError> { + let sql = get_tx_hex_from_cache_sql(for_coin)?; + let params = [format!("{:02x}", tx_hash)]; + let selfi = self.clone(); + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let maybe_tx_hex: Result = conn.query_row(&sql, params, |row| row.get(0)); + if let Err(SqlError::QueryReturnedNoRows) = maybe_tx_hex { + return Ok(None); + } + let tx_hex = maybe_tx_hex?; + let tx_bytes = + hex::decode(&tx_hex).map_err(|e| SqlError::FromSqlConversionFailure(0, Type::Text, Box::new(e)))?; + Ok(Some(tx_bytes.into())) + }) + .await + } + + async fn get_history( + &self, + coin_type: HistoryCoinType, + paging: PagingOptionsEnum, + limit: usize, + ) -> Result> { + let selfi = self.clone(); + + async_blocking(move || { + let conn = selfi.0.lock().unwrap(); + let (mut sql_builder, token_id) = match coin_type { + HistoryCoinType::Coin(ticker) => (get_history_builder_preimage(&ticker)?, "".to_owned()), + HistoryCoinType::Token { platform, token_id } => { + (get_history_builder_preimage(&platform)?, format!("{:02x}", token_id)) + }, + HistoryCoinType::L2 { .. } => unimplemented!("Not implemented yet for HistoryCoinType::L2"), + }; + + let mut total_builder = sql_builder.clone(); + total_builder.count("id"); + let total_sql = total_builder.sql().expect("valid sql"); + let total: isize = conn.query_row(&total_sql, [&token_id], |row| row.get(0))?; + let total = total.try_into().expect("count should be always above zero"); + + let offset = match paging { + PagingOptionsEnum::PageNumber(page) => (page.get() - 1) * limit, + PagingOptionsEnum::FromId(id) => { + let id_str = format!("{:02x}", id); + let params = [&token_id, &id_str]; + let maybe_offset = offset_by_id( + &conn, + &sql_builder, + params, + "internal_id", + "confirmation_status ASC, block_height DESC, id ASC", + "internal_id = ?2", + )?; + match maybe_offset { + Some(offset) => offset, + None => { + return Ok(GetHistoryResult { + transactions: vec![], + skipped: 0, + total, + }) + }, + } + }, + }; + + finalize_get_history_sql_builder(&mut sql_builder, offset, limit); + let params = [token_id]; + + let sql = sql_builder.sql().expect("valid sql"); + let mut stmt = conn.prepare(&sql)?; + let rows = stmt.query(params)?; + let transactions = rows.mapped(tx_details_from_row).collect::>()?; + let result = GetHistoryResult { + transactions, + skipped: offset, + total, + }; + Ok(result) + }) + .await + } +} + +#[cfg(test)] +mod sql_tx_history_storage_tests { + use super::*; + use common::block_on; + use std::num::NonZeroUsize; + + #[test] + fn test_init_collection() { + let for_coin = "init_collection"; + let storage = SqliteTxHistoryStorage::in_memory(); + let initialized = block_on(storage.is_initialized_for(for_coin)).unwrap(); + assert!(!initialized); + + block_on(storage.init(for_coin)).unwrap(); + // repetitive init must not fail + block_on(storage.init(for_coin)).unwrap(); + + let initialized = block_on(storage.is_initialized_for(for_coin)).unwrap(); + assert!(initialized); + } + + #[test] + fn test_add_transactions() { + let for_coin = "add_transactions"; + let storage = SqliteTxHistoryStorage::in_memory(); + let table = tx_history_table(for_coin); + + block_on(storage.init(for_coin)).unwrap(); + let tx1_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let tx1: TransactionDetails = json::from_str(&tx1_json).unwrap(); + let transactions = [tx1.clone(), tx1.clone()]; + + // must fail because we are adding transactions with the same internal_id + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap_err(); + assert!(storage.is_table_empty(&table)); + + let tx2_json = r#"{"tx_hex":"0400008085202f890158d6bccb2141e18633171f631f594b7f1ae85985390b534733ea5be4da220426030000006b483045022100895dea201a1dc59480d59790569df8664cf3d1d9332efeea7dcc38b4a96399b402206c183f33a3e87eb473a7d3da1488ee9a7d9580cfc86cc8460c79a69c08818478012102d09f2cb1693be9c0ea73bb48d45ce61805edd1c43590681b02f877206078a5b3ffffffff0400e1f505000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac00c2eb0b000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588aca01f791c000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac500df208ed0000001976a91490a0d8ba62c339ade97a14e81b6f531de03fdbb288ac00000000000000000000000000000000000000","tx_hash":"8d61223938c56ca97e9a0e1a295734c5f7b9dba8e4e0c1c638125190e7e796fa","from":["RNTv4xTLLm26p3SvsQCBy9qNK7s1RgGYSB"],"to":["RNTv4xTLLm26p3SvsQCBy9qNK7s1RgGYSB","RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10188.3504","spent_by_me":"0","received_by_me":"7.777","my_balance_change":"7.777","block_height":793474,"timestamp":1612780908,"fee_details":{"type":"Utxo","amount":"0.0001"},"coin":"RICK","internal_id":"8d61223938c56ca97e9a0e1a295734c5f7b9dba8e4e0c1c638125190e7e796fa"}"#; + let tx2 = json::from_str(tx2_json).unwrap(); + let transactions = [tx1, tx2]; + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap(); + assert!(!storage.is_table_empty(&table)); + } + + #[test] + fn test_remove_transaction() { + let for_coin = "remove_transaction"; + let storage = SqliteTxHistoryStorage::in_memory(); + + block_on(storage.init(for_coin)).unwrap(); + let tx_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + block_on(storage.add_transactions_to_history(for_coin, [json::from_str(tx_json).unwrap()])).unwrap(); + + let remove_res = block_on(storage.remove_tx_from_history( + for_coin, + &"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(), + )) + .unwrap(); + assert!(remove_res.tx_existed()); + + let remove_res = block_on(storage.remove_tx_from_history( + for_coin, + &"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(), + )) + .unwrap(); + assert!(!remove_res.tx_existed()); + } + + #[test] + fn test_get_transaction() { + let for_coin = "get_transaction"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + block_on(storage.add_transactions_to_history(for_coin, [json::from_str(tx_json).unwrap()])).unwrap(); + + let tx = block_on(storage.get_tx_from_history( + for_coin, + &"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(), + )) + .unwrap() + .unwrap(); + println!("{:?}", tx); + + block_on(storage.remove_tx_from_history( + for_coin, + &"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(), + )) + .unwrap(); + + let tx = block_on(storage.get_tx_from_history( + for_coin, + &"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(), + )) + .unwrap(); + assert!(tx.is_none()); + } + + #[test] + fn test_update_transaction() { + let for_coin = "update_transaction"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let mut tx_details: TransactionDetails = json::from_str(tx_json).unwrap(); + block_on(storage.add_transactions_to_history(for_coin, [tx_details.clone()])).unwrap(); + + tx_details.block_height = 12345; + + block_on(storage.update_tx_in_history(for_coin, &tx_details)).unwrap(); + + let updated = block_on(storage.get_tx_from_history(for_coin, &tx_details.internal_id)) + .unwrap() + .unwrap(); + + assert_eq!(12345, updated.block_height); + } + + #[test] + fn test_contains_and_get_unconfirmed_transaction() { + let for_coin = "contains_and_get_unconfirmed_transaction"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let mut tx_details: TransactionDetails = json::from_str(tx_json).unwrap(); + tx_details.block_height = 0; + block_on(storage.add_transactions_to_history(for_coin, [tx_details.clone()])).unwrap(); + + let contains_unconfirmed = block_on(storage.history_contains_unconfirmed_txes(for_coin)).unwrap(); + assert!(contains_unconfirmed); + + let unconfirmed_transactions = block_on(storage.get_unconfirmed_txes_from_history(for_coin)).unwrap(); + assert_eq!(unconfirmed_transactions.len(), 1); + + tx_details.block_height = 12345; + block_on(storage.update_tx_in_history(for_coin, &tx_details)).unwrap(); + + let contains_unconfirmed = block_on(storage.history_contains_unconfirmed_txes(for_coin)).unwrap(); + assert!(!contains_unconfirmed); + + let unconfirmed_transactions = block_on(storage.get_unconfirmed_txes_from_history(for_coin)).unwrap(); + assert!(unconfirmed_transactions.is_empty()); + } + + #[test] + fn test_has_transactions_with_hash() { + let for_coin = "has_transactions_with_hash"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + assert!(!block_on(storage.history_has_tx_hash( + for_coin, + "2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c" + )) + .unwrap()); + + let tx_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let tx_details: TransactionDetails = json::from_str(tx_json).unwrap(); + + block_on(storage.add_transactions_to_history(for_coin, [tx_details])).unwrap(); + + assert!(block_on(storage.history_has_tx_hash( + for_coin, + "2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c" + )) + .unwrap()); + } + + #[test] + fn test_unique_tx_hashes_num() { + let for_coin = "unique_tx_hashes_num"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx1_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let tx1: TransactionDetails = json::from_str(&tx1_json).unwrap(); + + let mut tx2 = tx1.clone(); + tx2.internal_id = BytesJson(vec![1; 32]); + + let tx3_json = r#"{"tx_hex":"0400008085202f890158d6bccb2141e18633171f631f594b7f1ae85985390b534733ea5be4da220426030000006b483045022100895dea201a1dc59480d59790569df8664cf3d1d9332efeea7dcc38b4a96399b402206c183f33a3e87eb473a7d3da1488ee9a7d9580cfc86cc8460c79a69c08818478012102d09f2cb1693be9c0ea73bb48d45ce61805edd1c43590681b02f877206078a5b3ffffffff0400e1f505000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac00c2eb0b000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588aca01f791c000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac500df208ed0000001976a91490a0d8ba62c339ade97a14e81b6f531de03fdbb288ac00000000000000000000000000000000000000","tx_hash":"8d61223938c56ca97e9a0e1a295734c5f7b9dba8e4e0c1c638125190e7e796fa","from":["RNTv4xTLLm26p3SvsQCBy9qNK7s1RgGYSB"],"to":["RNTv4xTLLm26p3SvsQCBy9qNK7s1RgGYSB","RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10188.3504","spent_by_me":"0","received_by_me":"7.777","my_balance_change":"7.777","block_height":793474,"timestamp":1612780908,"fee_details":{"type":"Utxo","amount":"0.0001"},"coin":"RICK","internal_id":"8d61223938c56ca97e9a0e1a295734c5f7b9dba8e4e0c1c638125190e7e796fa"}"#; + let tx3 = json::from_str(tx3_json).unwrap(); + + let transactions = [tx1, tx2, tx3]; + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap(); + + let tx_hashes_num = block_on(storage.unique_tx_hashes_num_in_history(for_coin)).unwrap(); + assert_eq!(2, tx_hashes_num); + } + + #[test] + fn test_add_and_get_tx_from_cache() { + let for_coin = "test_add_and_get_tx_from_cache"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let tx: TransactionDetails = json::from_str(tx).unwrap(); + + block_on(storage.add_tx_to_cache(for_coin, &tx.tx_hash, &tx.tx_hex)).unwrap(); + + let tx_hex = block_on(storage.tx_bytes_from_cache(for_coin, &tx.tx_hash)) + .unwrap() + .unwrap(); + + assert_eq!(tx_hex, tx.tx_hex); + } + + #[test] + fn test_get_raw_tx_bytes_on_add_transactions() { + let for_coin = "test_get_raw_tx_bytes_on_add_transactions"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + + let tx_hash = "2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c".into(); + + let maybe_tx_hex = block_on(storage.tx_bytes_from_cache(for_coin, &tx_hash)).unwrap(); + assert!(maybe_tx_hex.is_none()); + + let tx1_json = r#"{"tx_hex":"0400008085202f890708b189a2d740a74042541fe687a8d698b7a00c1bfdaf0c708b6bb32f8f7307aa000000006946304302201529f09fdf9177e8b5e2d494488da1e49ec7c1b85a457871e1a78df4e3ba0541021f74538866128b21ed0b77701289ad49ee9a74f8349b9670f73cf6babc4a8ce5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff6403323bb3cd025754336cad57ddc36aedb56107a7a1c6f6ddbfbc893c69d556000000006a4730440220560b8d87f3f020856d3e4704be15a307aa8a49290bf7a8e27a66fc0436e3eb9c0220585c1705a701a669b6b53dae2aad2729786590fbbfbb8f7998bb22e38b60c2d5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff1c5f114649d5194b15502f286d337e03ca7fc3eb0798bc91e6006a645c525f96000000006a473044022078439f12c288d9d694820dbff1e1ceb592be28f7b7e9ba91c73af8110b171c3f02200c8a061f3d48daefaeed40e667543693bb5f206e58fa15b93808e2ecf762ec2f012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffff322a446b2373782c727e2f83a914707d5f8af8fd4f4db34243c7223d438f5f5000000006b483045022100dd101b16dfbe02201768eab2bbbd9df40e56a565492b38e7304284385f04cccf02207ac4e8f1aa768162d24a9b1fb73df0771f34942c2120f980228961e9fcb338ea012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d000000006a47304402207c539bcb32efe7a13f1ff6a7b44a5dce4f794a3af7009eb960a65b03214f2fa102204bc3cddc50c8042c2f852a18c0c68107418ac692f0984c3e7ec2f2d1bf23adf5012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d010000006b4830450221009170c72f25f68e9200b398695e9f6edc706b868d75f7a1e194e068ac1377c95e02206265bb27fcf97fa0d13842d49772bd4b37b8661592df6d7fcec5b7e6c828ecf7012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36fafffffffffa96e7e790511238c6c1e0e4a8dbb9f7c53457291a0e9a7ea96cc5383922618d020000006a47304402206dce88dc192623e69a17cc56609872c75e35b5c608ffeaa31f6df70b09ddbd5302206cf9688439b2192ba57d72af024855741bf77a2a58acf10e5eddfcc36fe7be74012103ad6f89abc2e5beaa8a3ac28e22170659b3209fe2ddf439681b4b8f31508c36faffffffff0198e8d440000000001976a914d55f0df6cb82630ad21a4e6049522a6f2b6c9d4588ac59cbb060000000000000000000000000000000","tx_hash":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c","from":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"to":["RUjPst697T7ahtF8EpZ1whpAmJZfqfwW36"],"total_amount":"10.87696","spent_by_me":"10.87696","received_by_me":"10.87695","my_balance_change":"-0.00001","block_height":949554,"timestamp":1622199314,"fee_details":{"type":"Utxo","amount":"0.00001"},"coin":"RICK","internal_id":"2c33baf0c40eebcb70fc22eab0158e315e2176e4a3f20acddcd849186fca492c"}"#; + let tx1: TransactionDetails = json::from_str(tx1_json).unwrap(); + + let mut tx2 = tx1.clone(); + tx2.internal_id = BytesJson(vec![1; 32]); + + let expected_tx_hex = tx1.tx_hex.clone(); + + let transactions = [tx1, tx2]; + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap(); + + let tx_hex = block_on(storage.tx_bytes_from_cache(for_coin, &tx_hash)) + .unwrap() + .unwrap(); + + assert_eq!(tx_hex, expected_tx_hex); + } + + #[test] + fn get_history_page_number() { + let for_coin = "tBCH"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + let tx_details = include_str!("for_tests/tBCH_tx_history_fixtures.json"); + let transactions: Vec = json::from_str(tx_details).unwrap(); + + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap(); + + let coin_type = HistoryCoinType::Coin("tBCH".into()); + let paging = PagingOptionsEnum::PageNumber(NonZeroUsize::new(1).unwrap()); + let limit = 4; + + let result = block_on(storage.get_history(coin_type, paging, limit)).unwrap(); + + let expected_internal_ids: Vec = vec![ + "6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69".into(), + "c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce".into(), + "091877294268b2b1734255067146f15c3ac5e6199e72cd4f68a8d9dec32bb0c0".into(), + "d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7".into(), + ]; + + let actual_ids: Vec<_> = result.transactions.into_iter().map(|tx| tx.internal_id).collect(); + + assert_eq!(0, result.skipped); + assert_eq!(123, result.total); + assert_eq!(expected_internal_ids, actual_ids); + + let coin_type = HistoryCoinType::Token { + platform: "tBCH".into(), + token_id: "bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7".into(), + }; + let paging = PagingOptionsEnum::PageNumber(NonZeroUsize::new(2).unwrap()); + let limit = 5; + + let result = block_on(storage.get_history(coin_type, paging, limit)).unwrap(); + + let expected_internal_ids: Vec = vec![ + "433b641bc89e1b59c22717918583c60ec98421805c8e85b064691705d9aeb970".into(), + "cd6ec10b0cd9747ddc66ac5c97c2d7b493e8cea191bc2d847b3498719d4bd989".into(), + "1c1e68357cf5a6dacb53881f13aa5d2048fe0d0fab24b76c9ec48f53884bed97".into(), + "c4304b5ef4f1b88ed4939534a8ca9eca79f592939233174ae08002e8454e3f06".into(), + "b0035434a1e7be5af2ed991ee2a21a90b271c5852a684a0b7d315c5a770d1b1c".into(), + ]; + + let actual_ids: Vec<_> = result.transactions.into_iter().map(|tx| tx.internal_id).collect(); + + assert_eq!(5, result.skipped); + assert_eq!(121, result.total); + assert_eq!(expected_internal_ids, actual_ids); + } + + #[test] + fn get_history_from_id() { + let for_coin = "tBCH"; + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(for_coin)).unwrap(); + let tx_details = include_str!("for_tests/tBCH_tx_history_fixtures.json"); + let transactions: Vec = json::from_str(tx_details).unwrap(); + + block_on(storage.add_transactions_to_history(for_coin, transactions)).unwrap(); + + let coin_type = HistoryCoinType::Coin("tBCH".into()); + let paging = + PagingOptionsEnum::FromId("6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69".into()); + let limit = 3; + + let result = block_on(storage.get_history(coin_type, paging, limit)).unwrap(); + + let expected_internal_ids: Vec = vec![ + "c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce".into(), + "091877294268b2b1734255067146f15c3ac5e6199e72cd4f68a8d9dec32bb0c0".into(), + "d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7".into(), + ]; + + let actual_ids: Vec<_> = result.transactions.into_iter().map(|tx| tx.internal_id).collect(); + + assert_eq!(expected_internal_ids, actual_ids); + + let coin_type = HistoryCoinType::Token { + platform: "tBCH".into(), + token_id: "bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7".into(), + }; + let paging = + PagingOptionsEnum::FromId("433b641bc89e1b59c22717918583c60ec98421805c8e85b064691705d9aeb970".into()); + let limit = 4; + + let result = block_on(storage.get_history(coin_type, paging, limit)).unwrap(); + + let expected_internal_ids: Vec = vec![ + "cd6ec10b0cd9747ddc66ac5c97c2d7b493e8cea191bc2d847b3498719d4bd989".into(), + "1c1e68357cf5a6dacb53881f13aa5d2048fe0d0fab24b76c9ec48f53884bed97".into(), + "c4304b5ef4f1b88ed4939534a8ca9eca79f592939233174ae08002e8454e3f06".into(), + "b0035434a1e7be5af2ed991ee2a21a90b271c5852a684a0b7d315c5a770d1b1c".into(), + ]; + + let actual_ids: Vec<_> = result.transactions.into_iter().map(|tx| tx.internal_id).collect(); + + assert_eq!(expected_internal_ids, actual_ids); + } +} diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index 0d1aa0429a..b26758db3a 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,6 +1,7 @@ use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum, TransactionFut}; use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, TradePreimageFut, TradePreimageValue, ValidateAddressResult, WithdrawFut, WithdrawRequest}; +use async_trait::async_trait; use bigdecimal::BigDecimal; use common::mm_ctx::MmArc; use common::mm_error::MmError; @@ -71,6 +72,7 @@ impl MarketCoinOps for TestCoin { fn min_trading_vol(&self) -> MmNumber { MmNumber::from("0.00777") } } +#[async_trait] #[mockable] #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] impl SwapOps for TestCoin { @@ -189,7 +191,7 @@ impl SwapOps for TestCoin { unimplemented!() } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -201,7 +203,7 @@ impl SwapOps for TestCoin { unimplemented!() } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 0df114ced8..b75f7adbf6 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -20,11 +20,12 @@ // pub mod bch; -pub mod bchd_grpc; -#[allow(clippy::large_enum_variant)] +pub mod bch_and_slp_tx_history; +mod bchd_grpc; +#[allow(clippy::all)] #[rustfmt::skip] #[path = "utxo/pb.rs"] -pub mod bchd_pb; +mod bchd_pb; pub mod qtum; pub mod rpc_clients; pub mod slp; @@ -632,6 +633,7 @@ impl UtxoCoinFields { } #[derive(Debug, Display)] +#[allow(clippy::large_enum_variant)] pub enum BroadcastTxErr { /// RPC client error Rpc(UtxoRpcError), @@ -873,7 +875,7 @@ pub enum RequestTxHistoryResult { Ok(Vec<(H256Json, u64)>), Retry { error: String }, HistoryTooLarge, - UnknownError(String), + CriticalError(String), } pub enum VerboseTransactionFrom { @@ -910,6 +912,7 @@ pub fn compressed_pub_key_from_priv_raw(raw_priv: &[u8], sum_type: ChecksumType) #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct UtxoFeeDetails { + pub coin: Option, pub amount: BigDecimal, } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 4e0920c56d..0935ca0881 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1,14 +1,17 @@ use super::*; +use crate::my_tx_history_v2::{TxDetailsBuilder, TxHistoryStorage, TxHistoryStorageError}; use crate::utxo::rpc_clients::UtxoRpcFut; -use crate::utxo::slp::{parse_slp_script, SlpTokenInfo, SlpTransaction, SlpUnspent}; +use crate::utxo::slp::{parse_slp_script, ParseSlpScriptError, SlpGenesisParams, SlpTokenInfo, SlpTransaction, + SlpUnspent}; use crate::utxo::utxo_common::big_decimal_from_sat_unsigned; -use crate::{CanRefundHtlc, CoinBalance, CoinProtocol, NegotiateSwapContractAddrErr, SwapOps, TradePreimageValue, - ValidateAddressResult, WithdrawFut}; +use crate::{BlockHeightAndTime, CanRefundHtlc, CoinBalance, CoinProtocol, NegotiateSwapContractAddrErr, SwapOps, + TradePreimageValue, TransactionType, TxFeeDetails, ValidateAddressResult, WithdrawFut}; use common::log::warn; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use derive_more::Display; use futures::{FutureExt, TryFutureExt}; +use itertools::Either as EitherIter; use keys::CashAddress; pub use keys::NetworkPrefix as CashAddrPrefix; use serde_json::{self as json, Value as Json}; @@ -21,7 +24,7 @@ pub struct BchActivationRequest { allow_slp_unsafe_conf: bool, bchd_urls: Vec, #[serde(flatten)] - utxo_params: UtxoActivationParams, + pub utxo_params: UtxoActivationParams, } #[derive(Debug, Display)] @@ -56,6 +59,7 @@ pub struct BchCoin { slp_tokens_infos: Arc>>, } +#[allow(clippy::large_enum_variant)] pub enum IsSlpUtxoError { Rpc(UtxoRpcError), TxDeserialization(serialization::Error), @@ -129,9 +133,52 @@ impl From for IsSlpUtxoError { fn from(err: serialization::Error) -> IsSlpUtxoError { IsSlpUtxoError::TxDeserialization(err) } } +#[derive(Debug)] +#[allow(clippy::large_enum_variant)] +pub enum GetTxDetailsError { + StorageError(E), + AddressesFromScriptError(String), + SlpTokenIdIsNotGenesisTx(H256), + TxDeserializationError(serialization::Error), + RpcError(UtxoRpcError), + ParseSlpScriptError(ParseSlpScriptError), + ToSlpAddressError(String), + InvalidSlpTransaction(H256), + AddressDerivationError(DerivationMethodNotSupported), +} + +impl From for GetTxDetailsError { + fn from(err: UtxoRpcError) -> Self { GetTxDetailsError::RpcError(err) } +} + +impl From for GetTxDetailsError { + fn from(err: E) -> Self { GetTxDetailsError::StorageError(err) } +} + +impl From for GetTxDetailsError { + fn from(err: serialization::Error) -> Self { GetTxDetailsError::TxDeserializationError(err) } +} + +impl From for GetTxDetailsError { + fn from(err: ParseSlpScriptError) -> Self { GetTxDetailsError::ParseSlpScriptError(err) } +} + +impl From for GetTxDetailsError { + fn from(err: DerivationMethodNotSupported) -> Self { GetTxDetailsError::AddressDerivationError(err) } +} + impl BchCoin { pub fn slp_prefix(&self) -> &CashAddrPrefix { &self.slp_addr_prefix } + pub fn slp_address(&self, address: &Address) -> Result { + let conf = &self.as_ref().conf; + address.to_cashaddress( + &self.slp_prefix().to_string(), + conf.pub_addr_prefix, + conf.p2sh_addr_prefix, + ) + } + pub fn bchd_urls(&self) -> &[String] { &self.bchd_urls } async fn utxos_into_bch_unspents(&self, utxos: Vec) -> UtxoRpcResult { @@ -185,15 +232,11 @@ impl BchCoin { None => result.add_standard(unspent), } }, - SlpTransaction::Genesis { - initial_token_mint_quantity, - mint_baton_vout, - .. - } => { + SlpTransaction::Genesis(genesis) => { if unspent.outpoint.index == 1 { let token_id = prev_tx.hash().reversed(); - result.add_slp(token_id, unspent, initial_token_mint_quantity); - } else if Some(unspent.outpoint.index) == mint_baton_vout.map(|u| u as u32) { + result.add_slp(token_id, unspent, genesis.initial_token_mint_quantity); + } else if Some(unspent.outpoint.index) == genesis.mint_baton_vout.map(|u| u as u32) { result.add_slp_baton(unspent); } else { result.add_standard(unspent); @@ -309,6 +352,255 @@ impl BchCoin { )?; Ok(slp_address) } + + async fn tx_from_storage_or_rpc( + &self, + tx_hash: &H256Json, + storage: &T, + ) -> Result>> { + let tx_hash_as_bytes = BytesJson::new(tx_hash.0.to_vec()); + let tx_bytes = match storage.tx_bytes_from_cache(self.ticker(), &tx_hash_as_bytes).await? { + Some(tx_bytes) => tx_bytes, + None => { + let tx_bytes = self.as_ref().rpc_client.get_transaction_bytes(tx_hash).compat().await?; + storage + .add_tx_to_cache(self.ticker(), &tx_hash_as_bytes, &tx_bytes) + .await?; + tx_bytes + }, + }; + let tx = deserialize(tx_bytes.0.as_slice())?; + Ok(tx) + } + + /// Returns multiple details by tx hash if token transfers also occurred in the transaction + pub async fn transaction_details_with_token_transfers( + &self, + tx_hash: &H256Json, + block_height_and_time: Option, + storage: &T, + ) -> Result, MmError>> { + let tx = self.tx_from_storage_or_rpc(tx_hash, storage).await?; + + let bch_tx_details = self + .bch_tx_details(tx_hash, &tx, block_height_and_time, storage) + .await?; + let maybe_op_return: Script = tx.outputs[0].script_pubkey.clone().into(); + if !(maybe_op_return.is_pay_to_public_key_hash() + || maybe_op_return.is_pay_to_public_key() + || maybe_op_return.is_pay_to_script_hash()) + { + if let Ok(slp_details) = parse_slp_script(&maybe_op_return) { + let slp_tx_details = self + .slp_tx_details( + &tx, + slp_details.transaction, + block_height_and_time, + bch_tx_details.fee_details.clone(), + storage, + ) + .await?; + return Ok(vec![bch_tx_details, slp_tx_details]); + } + } + + Ok(vec![bch_tx_details]) + } + + async fn bch_tx_details( + &self, + tx_hash: &H256Json, + tx: &UtxoTx, + height_and_time: Option, + storage: &T, + ) -> Result>> { + let my_address = self.as_ref().derivation_method.iguana_or_err()?; + let my_addresses = [my_address.clone()]; + let mut tx_builder = TxDetailsBuilder::new(self.ticker().to_owned(), tx, height_and_time, my_addresses); + for output in &tx.outputs { + let addresses = match self.addresses_from_script(&output.script_pubkey.clone().into()) { + Ok(a) => a, + Err(_) => continue, + }; + + if addresses.is_empty() { + continue; + } + + if addresses.len() != 1 { + let msg = format!( + "{} tx {:02x} output script resulted into unexpected number of addresses", + self.ticker(), + tx_hash, + ); + return MmError::err(GetTxDetailsError::AddressesFromScriptError(msg)); + } + + let amount = big_decimal_from_sat_unsigned(output.value, self.decimals()); + for address in addresses { + tx_builder.transferred_to(address, &amount); + } + } + + let mut total_input = 0; + for input in &tx.inputs { + let index = input.previous_output.index; + let prev_tx = self + .tx_from_storage_or_rpc(&input.previous_output.hash.reversed().into(), storage) + .await?; + let prev_script = prev_tx.outputs[index as usize].script_pubkey.clone().into(); + let addresses = self + .addresses_from_script(&prev_script) + .map_to_mm(GetTxDetailsError::AddressesFromScriptError)?; + if addresses.len() != 1 { + let msg = format!( + "{} tx {:02x} output script resulted into unexpected number of addresses", + self.ticker(), + tx_hash, + ); + return MmError::err(GetTxDetailsError::AddressesFromScriptError(msg)); + } + + let prev_value = prev_tx.outputs[index as usize].value; + total_input += prev_value; + let amount = big_decimal_from_sat_unsigned(prev_value, self.decimals()); + for address in addresses { + tx_builder.transferred_from(address, &amount); + } + } + + let total_output = tx.outputs.iter().fold(0, |total, output| total + output.value); + let fee = Some(TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(self.ticker().into()), + amount: big_decimal_from_sat_unsigned(total_input - total_output, self.decimals()), + })); + tx_builder.set_tx_fee(fee); + Ok(tx_builder.build()) + } + + async fn get_slp_genesis_params( + &self, + token_id: H256, + storage: &T, + ) -> Result>> { + let token_genesis_tx = self.tx_from_storage_or_rpc(&token_id.into(), storage).await?; + let maybe_genesis_script: Script = token_genesis_tx.outputs[0].script_pubkey.clone().into(); + let slp_details = parse_slp_script(&maybe_genesis_script)?; + match slp_details.transaction { + SlpTransaction::Genesis(params) => Ok(params), + _ => MmError::err(GetTxDetailsError::SlpTokenIdIsNotGenesisTx(token_id)), + } + } + + async fn slp_transferred_amounts( + &self, + utxo_tx: &UtxoTx, + slp_tx: SlpTransaction, + storage: &T, + ) -> Result, MmError>> { + let slp_amounts = match slp_tx { + SlpTransaction::Send { token_id, amounts } => { + let genesis_params = self.get_slp_genesis_params(token_id, storage).await?; + EitherIter::Left( + amounts + .into_iter() + .map(move |amount| big_decimal_from_sat_unsigned(amount, genesis_params.decimals[0])), + ) + }, + SlpTransaction::Mint { + token_id, + additional_token_quantity, + .. + } => { + let slp_genesis_params = self.get_slp_genesis_params(token_id, storage).await?; + EitherIter::Right(std::iter::once(big_decimal_from_sat_unsigned( + additional_token_quantity, + slp_genesis_params.decimals[0], + ))) + }, + SlpTransaction::Genesis(genesis_params) => EitherIter::Right(std::iter::once( + big_decimal_from_sat_unsigned(genesis_params.initial_token_mint_quantity, genesis_params.decimals[0]), + )), + }; + + let mut result = HashMap::new(); + for (i, amount) in slp_amounts.into_iter().enumerate() { + let output_index = i + 1; + match utxo_tx.outputs.get(output_index) { + Some(output) => { + let addresses = self + .addresses_from_script(&output.script_pubkey.clone().into()) + .map_to_mm(GetTxDetailsError::AddressesFromScriptError)?; + if addresses.len() != 1 { + let msg = format!( + "{} tx {:?} output script resulted into unexpected number of addresses", + self.ticker(), + utxo_tx.hash().reversed(), + ); + return MmError::err(GetTxDetailsError::AddressesFromScriptError(msg)); + } + + let slp_address = self + .slp_address(&addresses[0]) + .map_to_mm(GetTxDetailsError::ToSlpAddressError)?; + result.insert(output_index, (slp_address, amount)); + }, + None => return MmError::err(GetTxDetailsError::InvalidSlpTransaction(utxo_tx.hash().reversed())), + } + } + Ok(result) + } + + async fn slp_tx_details( + &self, + tx: &UtxoTx, + slp_tx: SlpTransaction, + height_and_time: Option, + tx_fee: Option, + storage: &Storage, + ) -> Result>> { + let token_id = match slp_tx.token_id() { + Some(id) => id, + None => tx.hash().reversed(), + }; + + let my_address = self.as_ref().derivation_method.iguana_or_err()?; + let slp_address = self + .slp_address(my_address) + .map_to_mm(GetTxDetailsError::ToSlpAddressError)?; + let addresses = [slp_address]; + + let mut slp_tx_details_builder = + TxDetailsBuilder::new(self.ticker().to_owned(), tx, height_and_time, addresses); + let slp_transferred_amounts = self.slp_transferred_amounts(tx, slp_tx, storage).await?; + for (_, (address, amount)) in slp_transferred_amounts { + slp_tx_details_builder.transferred_to(address, &amount); + } + + for input in &tx.inputs { + let prev_tx = self + .tx_from_storage_or_rpc(&input.previous_output.hash.reversed().into(), storage) + .await?; + if let Ok(slp_tx_details) = parse_slp_script(&prev_tx.outputs[0].script_pubkey) { + let mut prev_slp_transferred = self + .slp_transferred_amounts(&prev_tx, slp_tx_details.transaction, storage) + .await?; + let i = input.previous_output.index as usize; + if let Some((address, amount)) = prev_slp_transferred.remove(&i) { + slp_tx_details_builder.transferred_from(address, &amount); + } + } + } + + slp_tx_details_builder.set_transaction_type(TransactionType::TokenTransfer(token_id.take().to_vec().into())); + slp_tx_details_builder.set_tx_fee(tx_fee); + + Ok(slp_tx_details_builder.build()) + } + + pub async fn get_block_timestamp(&self, height: u64) -> Result> { + self.as_ref().rpc_client.get_block_timestamp(height).await + } } impl AsRef for BchCoin { @@ -523,6 +815,7 @@ impl UtxoCommonOps for BchCoin { } } +#[async_trait] impl SwapOps for BchCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) @@ -653,7 +946,7 @@ impl SwapOps for BchCoin { utxo_common::check_if_my_payment_sent(self.clone(), time_lock, other_pub, secret_hash) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -671,9 +964,10 @@ impl SwapOps for BchCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -691,6 +985,7 @@ impl SwapOps for BchCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { @@ -943,3 +1238,110 @@ pub fn bch_coin_for_test() -> BchCoin { )) .unwrap() } + +#[cfg(test)] +mod bch_tests { + use super::*; + use crate::sql_tx_history_storage::SqliteTxHistoryStorage; + use crate::{TransactionType, TxFeeDetails}; + use common::block_on; + + fn init_storage_for(ticker: &str) -> impl TxHistoryStorage { + let storage = SqliteTxHistoryStorage::in_memory(); + block_on(storage.init(ticker)).unwrap(); + storage + } + + #[test] + fn test_get_slp_genesis_params() { + let coin = tbch_coin_for_test(); + let token_id = "bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7".into(); + let storage = init_storage_for(coin.ticker()); + + let slp_params = block_on(coin.get_slp_genesis_params(token_id, &storage)).unwrap(); + assert_eq!("USDF", slp_params.token_ticker); + assert_eq!(4, slp_params.decimals[0]); + } + + #[test] + fn test_plain_bch_tx_details() { + let coin = tbch_coin_for_test(); + let storage = init_storage_for(coin.ticker()); + + let hash = "a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390".into(); + let tx = block_on(coin.tx_from_storage_or_rpc(&hash, &storage)).unwrap(); + + let details = block_on(coin.bch_tx_details(&hash, &tx, None, &storage)).unwrap(); + let expected_total: BigDecimal = "0.11407782".parse().unwrap(); + assert_eq!(expected_total, details.total_amount); + + let expected_received: BigDecimal = "0.11405301".parse().unwrap(); + assert_eq!(expected_received, details.received_by_me); + + let expected_spent: BigDecimal = "0.11407782".parse().unwrap(); + assert_eq!(expected_spent, details.spent_by_me); + + let expected_balance_change: BigDecimal = "-0.00002481".parse().unwrap(); + assert_eq!(expected_balance_change, details.my_balance_change); + + let expected_from = vec!["bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66".to_owned()]; + assert_eq!(expected_from, details.from); + + let expected_to = vec![ + "bchtest:qrhdt5adye8lc68upfj9fctfdgcd3aq9hctf8ft6md".to_owned(), + "bchtest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsnnczzt66".to_owned(), + ]; + assert_eq!(expected_to, details.to); + + let expected_internal_id = BytesJson::from("a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390"); + assert_eq!(expected_internal_id, details.internal_id); + + let expected_fee = Some(TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("BCH".into()), + amount: "0.00001481".parse().unwrap(), + })); + assert_eq!(expected_fee, details.fee_details); + + assert_eq!(coin.ticker(), details.coin); + } + + #[test] + fn test_slp_tx_details() { + let coin = tbch_coin_for_test(); + let storage = init_storage_for(coin.ticker()); + + let hash = "a8dcc3c6776e93e7bd21fb81551e853447c55e2d8ac141b418583bc8095ce390".into(); + let tx = block_on(coin.tx_from_storage_or_rpc(&hash, &storage)).unwrap(); + + let slp_details = parse_slp_script(&tx.outputs[0].script_pubkey).unwrap(); + + let slp_tx_details = block_on(coin.slp_tx_details(&tx, slp_details.transaction, None, None, &storage)).unwrap(); + + let expected_total: BigDecimal = "6.2974".parse().unwrap(); + assert_eq!(expected_total, slp_tx_details.total_amount); + + let expected_spent: BigDecimal = "6.2974".parse().unwrap(); + assert_eq!(expected_spent, slp_tx_details.spent_by_me); + + let expected_received: BigDecimal = "5.2974".parse().unwrap(); + assert_eq!(expected_received, slp_tx_details.received_by_me); + + let expected_balance_change = BigDecimal::from(-1i32); + assert_eq!(expected_balance_change, slp_tx_details.my_balance_change); + + let expected_from = vec!["slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8".to_owned()]; + assert_eq!(expected_from, slp_tx_details.from); + + let expected_to = vec![ + "slptest:qrhdt5adye8lc68upfj9fctfdgcd3aq9hcsaqj3dfs".to_owned(), + "slptest:qzx0llpyp8gxxsmad25twksqnwd62xm3lsg8lecug8".to_owned(), + ]; + assert_eq!(expected_to, slp_tx_details.to); + + let expected_tx_type = + TransactionType::TokenTransfer("bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7".into()); + assert_eq!(expected_tx_type, slp_tx_details.transaction_type); + + assert_eq!(coin.ticker(), slp_tx_details.coin); + } +} diff --git a/mm2src/coins/utxo/bch_and_slp_tx_history.rs b/mm2src/coins/utxo/bch_and_slp_tx_history.rs new file mode 100644 index 0000000000..2375f03875 --- /dev/null +++ b/mm2src/coins/utxo/bch_and_slp_tx_history.rs @@ -0,0 +1,410 @@ +/// This module is named bch_and_slp_tx_history temporary. We will most likely use the same approach for every +/// supported UTXO coin. +use super::RequestTxHistoryResult; +use crate::my_tx_history_v2::TxHistoryStorage; +use crate::utxo::bch::BchCoin; +use crate::utxo::utxo_common; +use crate::utxo::UtxoStandardOps; +use crate::{BlockHeightAndTime, HistorySyncState, MarketCoinOps}; +use async_trait::async_trait; +use common::executor::Timer; +use common::log::{error, info}; +use common::mm_metrics::MetricsArc; +use common::mm_number::BigDecimal; +use common::state_machine::prelude::*; +use futures::compat::Future01CompatExt; +use rpc::v1::types::H256 as H256Json; + +struct BchAndSlpHistoryCtx { + coin: BchCoin, + storage: Storage, + metrics: MetricsArc, + current_balance: BigDecimal, +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct Init { + phantom: std::marker::PhantomData, +} + +impl Init { + fn new() -> Self { + Init { + phantom: Default::default(), + } + } +} + +impl TransitionFrom> for Stopped {} + +#[async_trait] +impl State for Init { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut BchAndSlpHistoryCtx) -> StateResult, ()> { + *ctx.coin.as_ref().history_sync_state.lock().unwrap() = HistorySyncState::NotStarted; + + if let Err(e) = ctx.storage.init(ctx.coin.ticker()).await { + return Self::change_state(Stopped::storage_error(e)); + } + + Self::change_state(FetchingTxHashes::new()) + } +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct FetchingTxHashes { + phantom: std::marker::PhantomData, +} + +impl FetchingTxHashes { + fn new() -> Self { + FetchingTxHashes { + phantom: Default::default(), + } + } +} + +impl TransitionFrom> for FetchingTxHashes {} +impl TransitionFrom> for FetchingTxHashes {} +impl TransitionFrom> for FetchingTxHashes {} + +#[async_trait] +impl State for FetchingTxHashes { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut BchAndSlpHistoryCtx) -> StateResult, ()> { + if let Err(e) = ctx.storage.init(ctx.coin.ticker()).await { + return Self::change_state(Stopped::storage_error(e)); + } + + let maybe_tx_ids = ctx.coin.request_tx_history(ctx.metrics.clone()).await; + match maybe_tx_ids { + RequestTxHistoryResult::Ok(all_tx_ids_with_height) => { + let in_storage = match ctx.storage.unique_tx_hashes_num_in_history(ctx.coin.ticker()).await { + Ok(num) => num, + Err(e) => return Self::change_state(Stopped::storage_error(e)), + }; + if all_tx_ids_with_height.len() > in_storage { + let txes_left = all_tx_ids_with_height.len() - in_storage; + *ctx.coin.as_ref().history_sync_state.lock().unwrap() = + HistorySyncState::InProgress(json!({ "transactions_left": txes_left })); + } + + Self::change_state(UpdatingUnconfirmedTxes::new(all_tx_ids_with_height)) + }, + RequestTxHistoryResult::HistoryTooLarge => Self::change_state(Stopped::::history_too_large()), + RequestTxHistoryResult::Retry { error } => { + error!("Error {} on requesting tx history for {}", error, ctx.coin.ticker()); + Self::change_state(OnIoErrorCooldown::new()) + }, + RequestTxHistoryResult::CriticalError(e) => { + error!( + "Critical error {} on requesting tx history for {}", + e, + ctx.coin.ticker() + ); + Self::change_state(Stopped::::unknown(e)) + }, + } + } +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct OnIoErrorCooldown { + phantom: std::marker::PhantomData, +} + +impl OnIoErrorCooldown { + fn new() -> Self { + OnIoErrorCooldown { + phantom: Default::default(), + } + } +} + +impl TransitionFrom> for OnIoErrorCooldown {} +impl TransitionFrom> for OnIoErrorCooldown {} +impl TransitionFrom> for OnIoErrorCooldown {} + +#[async_trait] +impl State for OnIoErrorCooldown { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, _ctx: &mut BchAndSlpHistoryCtx) -> StateResult, ()> { + Timer::sleep(30.).await; + Self::change_state(FetchingTxHashes::new()) + } +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct WaitForHistoryUpdateTrigger { + phantom: std::marker::PhantomData, +} + +impl WaitForHistoryUpdateTrigger { + fn new() -> Self { + WaitForHistoryUpdateTrigger { + phantom: Default::default(), + } + } +} + +impl TransitionFrom> for WaitForHistoryUpdateTrigger {} + +#[async_trait] +impl State for WaitForHistoryUpdateTrigger { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut BchAndSlpHistoryCtx) -> StateResult { + loop { + Timer::sleep(30.).await; + match ctx.storage.history_contains_unconfirmed_txes(ctx.coin.ticker()).await { + Ok(contains) => { + if contains { + return Self::change_state(FetchingTxHashes::new()); + } + }, + Err(e) => return Self::change_state(Stopped::storage_error(e)), + } + + match ctx.coin.my_balance().compat().await { + Ok(balance) => { + let total_balance = balance.into_total(); + if ctx.current_balance != total_balance { + ctx.current_balance = total_balance; + return Self::change_state(FetchingTxHashes::new()); + } + }, + Err(e) => { + error!("Error {} on balance fetching for the coin {}", e, ctx.coin.ticker()); + }, + } + } + } +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct UpdatingUnconfirmedTxes { + phantom: std::marker::PhantomData, + all_tx_ids_with_height: Vec<(H256Json, u64)>, +} + +impl UpdatingUnconfirmedTxes { + fn new(all_tx_ids_with_height: Vec<(H256Json, u64)>) -> Self { + UpdatingUnconfirmedTxes { + phantom: Default::default(), + all_tx_ids_with_height, + } + } +} + +impl TransitionFrom> for UpdatingUnconfirmedTxes {} + +#[async_trait] +impl State for UpdatingUnconfirmedTxes { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut BchAndSlpHistoryCtx) -> StateResult, ()> { + match ctx.storage.get_unconfirmed_txes_from_history(ctx.coin.ticker()).await { + Ok(unconfirmed) => { + for mut tx in unconfirmed { + let found = self + .all_tx_ids_with_height + .iter() + .find(|(hash, _)| hash.0.as_ref() == tx.tx_hash.0.as_slice()); + match found { + Some((_, height)) => { + if *height > 0 { + match ctx.coin.get_block_timestamp(*height).await { + Ok(time) => tx.timestamp = time, + Err(_) => return Self::change_state(OnIoErrorCooldown::new()), + }; + tx.block_height = *height; + if let Err(e) = ctx.storage.update_tx_in_history(ctx.coin.ticker(), &tx).await { + return Self::change_state(Stopped::storage_error(e)); + } + } + }, + None => { + // This can potentially happen when unconfirmed tx is removed from mempool for some reason. + // We should remove it from storage too. + if let Err(e) = ctx + .storage + .remove_tx_from_history(ctx.coin.ticker(), &tx.internal_id) + .await + { + return Self::change_state(Stopped::storage_error(e)); + } + }, + } + } + Self::change_state(FetchingTransactionsData::new(self.all_tx_ids_with_height)) + }, + Err(e) => Self::change_state(Stopped::storage_error(e)), + } + } +} + +// States have to be generic over storage type because BchAndSlpHistoryCtx is generic over it +struct FetchingTransactionsData { + phantom: std::marker::PhantomData, + all_tx_ids_with_height: Vec<(H256Json, u64)>, +} + +impl TransitionFrom> for FetchingTransactionsData {} + +impl FetchingTransactionsData { + fn new(all_tx_ids_with_height: Vec<(H256Json, u64)>) -> Self { + FetchingTransactionsData { + phantom: Default::default(), + all_tx_ids_with_height, + } + } +} + +#[async_trait] +impl State for FetchingTransactionsData { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut BchAndSlpHistoryCtx) -> StateResult, ()> { + for (tx_hash, height) in self.all_tx_ids_with_height { + let tx_hash_string = format!("{:02x}", tx_hash); + match ctx + .storage + .history_has_tx_hash(ctx.coin.ticker(), &tx_hash_string) + .await + { + Ok(true) => continue, + Ok(false) => (), + Err(e) => return Self::change_state(Stopped::storage_error(e)), + } + + let block_height_and_time = if height > 0 { + let timestamp = match ctx.coin.get_block_timestamp(height).await { + Ok(time) => time, + Err(_) => return Self::change_state(OnIoErrorCooldown::new()), + }; + Some(BlockHeightAndTime { height, timestamp }) + } else { + None + }; + let tx_details = match ctx + .coin + .transaction_details_with_token_transfers(&tx_hash, block_height_and_time, &ctx.storage) + .await + { + Ok(tx) => tx, + Err(e) => { + error!( + "Error {:?} on getting {} tx details for hash {:02x}", + e, + ctx.coin.ticker(), + tx_hash + ); + return Self::change_state(OnIoErrorCooldown::new()); + }, + }; + + if let Err(e) = ctx + .storage + .add_transactions_to_history(ctx.coin.ticker(), tx_details) + .await + { + return Self::change_state(Stopped::storage_error(e)); + } + + // wait for for one second to reduce the number of requests to electrum servers + Timer::sleep(1.).await; + } + info!("Tx history fetching finished for {}", ctx.coin.ticker()); + *ctx.coin.as_ref().history_sync_state.lock().unwrap() = HistorySyncState::Finished; + Self::change_state(WaitForHistoryUpdateTrigger::new()) + } +} + +#[derive(Debug)] +enum StopReason { + HistoryTooLarge, + StorageError(E), + UnknownError(String), +} + +struct Stopped { + phantom: std::marker::PhantomData, + stop_reason: StopReason, +} + +impl Stopped { + fn history_too_large() -> Self { + Stopped { + phantom: Default::default(), + stop_reason: StopReason::HistoryTooLarge, + } + } + + fn storage_error(e: E) -> Self { + Stopped { + phantom: Default::default(), + stop_reason: StopReason::StorageError(e), + } + } + + fn unknown(e: String) -> Self { + Stopped { + phantom: Default::default(), + stop_reason: StopReason::UnknownError(e), + } + } +} + +impl TransitionFrom> for Stopped {} +impl TransitionFrom> for Stopped {} +impl TransitionFrom> for Stopped {} +impl TransitionFrom> for Stopped {} + +#[async_trait] +impl LastState for Stopped { + type Ctx = BchAndSlpHistoryCtx; + type Result = (); + + async fn on_changed(self: Box, ctx: &mut Self::Ctx) -> Self::Result { + info!( + "Stopping tx history fetching for {}. Reason: {:?}", + ctx.coin.ticker(), + self.stop_reason + ); + let new_state_json = match self.stop_reason { + StopReason::HistoryTooLarge => json!({ + "code": utxo_common::HISTORY_TOO_LARGE_ERR_CODE, + "message": "Got `history too large` error from Electrum server. History is not available", + }), + reason => json!({ + "message": format!("{:?}", reason), + }), + }; + *ctx.coin.as_ref().history_sync_state.lock().unwrap() = HistorySyncState::Error(new_state_json); + } +} + +pub async fn bch_and_slp_history_loop( + coin: BchCoin, + storage: impl TxHistoryStorage, + metrics: MetricsArc, + current_balance: BigDecimal, +) { + let ctx = BchAndSlpHistoryCtx { + coin, + storage, + metrics, + current_balance, + }; + let state_machine: StateMachine<_, ()> = StateMachine::from_ctx(ctx); + state_machine.run(Init::new()).await; +} diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 82b073150e..e186dc7a48 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -408,6 +408,7 @@ impl UtxoStandardOps for QtumCoin { } } +#[async_trait] impl SwapOps for QtumCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) @@ -538,7 +539,7 @@ impl SwapOps for QtumCoin { utxo_common::check_if_my_payment_sent(self.clone(), time_lock, other_pub, secret_hash) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -556,9 +557,10 @@ impl SwapOps for QtumCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -576,6 +578,7 @@ impl SwapOps for QtumCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index 2e5dbd3de8..5d00455f6e 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -3,6 +3,7 @@ use crate::utxo::{output_script, sat_from_big_decimal}; use crate::{NumConversError, RpcTransportEventHandler, RpcTransportEventHandlerShared}; +use async_trait::async_trait; use bigdecimal::BigDecimal; use chain::{BlockHeader, BlockHeaderBits, BlockHeaderNonce, OutPoint, Transaction as UtxoTx}; use common::custom_futures::{select_ok_sequential, FutureTimerExt}; @@ -58,6 +59,7 @@ cfg_native! { pub type AddressesByLabelResult = HashMap; #[derive(Debug, Deserialize)] +#[allow(dead_code)] pub struct AddressPurpose { purpose: String, } @@ -248,6 +250,7 @@ impl From for UtxoRpcError { } /// Common operations that both types of UTXO clients have but implement them differently +#[async_trait] pub trait UtxoRpcClientOps: fmt::Debug + Send + Sync + 'static { fn list_unspent(&self, address: &Address, decimals: u8) -> UtxoRpcFut>; @@ -255,7 +258,7 @@ pub trait UtxoRpcClientOps: fmt::Debug + Send + Sync + 'static { fn send_raw_transaction(&self, tx: BytesJson) -> UtxoRpcFut; - fn get_transaction_bytes(&self, txid: H256Json) -> UtxoRpcFut; + fn get_transaction_bytes(&self, txid: &H256Json) -> UtxoRpcFut; fn get_verbose_transaction(&self, txid: &H256Json) -> UtxoRpcFut; @@ -289,6 +292,8 @@ pub trait UtxoRpcClientOps: fmt::Debug + Send + Sync + 'static { count: NonZeroU64, coin_variant: CoinVariant, ) -> UtxoRpcFut; + + async fn get_block_timestamp(&self, height: u64) -> Result>; } #[derive(Clone, Deserialize, Debug)] @@ -373,10 +378,12 @@ pub struct EstimateSmartFeeRes { pub struct ListSinceBlockRes { transactions: Vec, #[serde(rename = "lastblock")] + #[allow(dead_code)] last_block: H256Json, } #[derive(Clone, Debug, Deserialize)] +#[allow(dead_code)] pub struct NetworkInfoLocalAddress { address: String, port: u16, @@ -384,6 +391,7 @@ pub struct NetworkInfoLocalAddress { } #[derive(Clone, Debug, Deserialize)] +#[allow(dead_code)] pub struct NetworkInfoNetwork { name: String, limited: bool, @@ -393,6 +401,7 @@ pub struct NetworkInfoNetwork { } #[derive(Clone, Debug, Deserialize)] +#[allow(dead_code)] pub struct NetworkInfo { connections: u64, #[serde(rename = "localaddresses")] @@ -594,6 +603,8 @@ impl JsonRpcClient for NativeClientImpl { } } +// if mockable is placed before async_trait there is `munmap_chunk(): invalid pointer` error on async fn mocking attempt +#[async_trait] #[cfg_attr(test, mockable)] impl UtxoRpcClientOps for NativeClient { fn list_unspent(&self, address: &Address, decimals: u8) -> UtxoRpcFut> { @@ -633,7 +644,7 @@ impl UtxoRpcClientOps for NativeClient { Box::new(rpc_func!(self, "sendrawtransaction", tx).map_to_mm_fut(UtxoRpcError::from)) } - fn get_transaction_bytes(&self, txid: H256Json) -> UtxoRpcFut { + fn get_transaction_bytes(&self, txid: &H256Json) -> UtxoRpcFut { Box::new(self.get_raw_transaction_bytes(txid).map_to_mm_fut(UtxoRpcError::from)) } @@ -702,7 +713,7 @@ impl UtxoRpcClientOps for NativeClient { .into_iter() .filter(|tx| !tx.is_conflicting()) { - let maybe_spend_tx_bytes = try_s!(selfi.get_raw_transaction_bytes(transaction.txid).compat().await); + let maybe_spend_tx_bytes = try_s!(selfi.get_raw_transaction_bytes(&transaction.txid).compat().await); let maybe_spend_tx: UtxoTx = try_s!(deserialize(maybe_spend_tx_bytes.as_slice()).map_err(|e| ERRL!("{:?}", e))); @@ -751,6 +762,11 @@ impl UtxoRpcClientOps for NativeClient { }; Box::new(fut.boxed().compat()) } + + async fn get_block_timestamp(&self, height: u64) -> Result> { + let block = self.get_block_by_height(height).await?; + Ok(block.time as u64) + } } #[cfg_attr(test, mockable)] @@ -798,7 +814,7 @@ impl NativeClientImpl { txid: H256Json, index: usize, ) -> Box + Send + 'static> { - let fut = self.get_raw_transaction_bytes(txid).map_err(|e| ERRL!("{}", e)); + let fut = self.get_raw_transaction_bytes(&txid).map_err(|e| ERRL!("{}", e)); Box::new(fut.and_then(move |bytes| { let tx: UtxoTx = try_s!(deserialize(bytes.as_slice()).map_err(|e| ERRL!( "Error {:?} trying to deserialize the transaction {:?}", @@ -833,7 +849,7 @@ impl NativeClientImpl { /// https://developer.bitcoin.org/reference/rpc/getrawtransaction.html /// Always returns transaction bytes - pub fn get_raw_transaction_bytes(&self, txid: H256Json) -> RpcRes { + pub fn get_raw_transaction_bytes(&self, txid: &H256Json) -> RpcRes { let verbose = 0; rpc_func!(self, "getrawtransaction", txid, verbose) } @@ -989,6 +1005,7 @@ impl Into for ElectrumNonce { pub struct ElectrumBlockHeadersRes { count: u64, pub hex: BytesJson, + #[allow(dead_code)] max: u64, } @@ -1261,6 +1278,7 @@ pub struct ElectrumConnection { /// The client connected to this SocketAddr addr: String, /// Configuration + #[allow(dead_code)] config: ElectrumConfig, /// The Sender forwarding requests to writing part of underlying stream tx: Arc>>>>, @@ -1615,6 +1633,8 @@ impl ElectrumClient { } } +// if mockable is placed before async_trait there is `munmap_chunk(): invalid pointer` error on async fn mocking attempt +#[async_trait] #[cfg_attr(test, mockable)] impl UtxoRpcClientOps for ElectrumClient { fn list_unspent(&self, address: &Address, _decimals: u8) -> UtxoRpcFut> { @@ -1660,7 +1680,7 @@ impl UtxoRpcClientOps for ElectrumClient { /// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get /// returns transaction bytes by default - fn get_transaction_bytes(&self, txid: H256Json) -> UtxoRpcFut { + fn get_transaction_bytes(&self, txid: &H256Json) -> UtxoRpcFut { let verbose = false; Box::new(rpc_func!(self, "blockchain.transaction.get", txid, verbose).map_to_mm_fut(UtxoRpcError::from)) } @@ -1723,7 +1743,7 @@ impl UtxoRpcClientOps for ElectrumClient { } for item in history.iter() { - let transaction = try_s!(selfi.get_transaction_bytes(item.tx_hash.clone()).compat().await); + let transaction = try_s!(selfi.get_transaction_bytes(&item.tx_hash).compat().await); let maybe_spend_tx: UtxoTx = try_s!(deserialize(transaction.as_slice()).map_err(|e| ERRL!("{:?}", e))); @@ -1771,6 +1791,13 @@ impl UtxoRpcClientOps for ElectrumClient { }), ) } + + async fn get_block_timestamp(&self, height: u64) -> Result> { + let header_bytes = self.blockchain_block_header(height).compat().await?; + let header: BlockHeader = + deserialize(header_bytes.0.as_slice()).map_to_mm(|e| UtxoRpcError::InvalidResponse(format!("{:?}", e)))?; + Ok(header.time as u64) + } } #[cfg_attr(test, mockable)] diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 41560a44a5..b07f2f0d53 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -32,7 +32,7 @@ use futures::{FutureExt, TryFutureExt}; use futures01::Future; use hex::FromHexError; use keys::hash::H160; -use keys::{Address, AddressHashEnum, CashAddrType, CashAddress, NetworkPrefix as CashAddrPrefix, Public}; +use keys::{AddressHashEnum, CashAddrType, CashAddress, NetworkPrefix as CashAddrPrefix, Public}; use primitives::hash::H256; use rpc::v1::types::{Bytes as BytesJson, H256 as H256Json}; use script::bytes::Bytes; @@ -750,16 +750,6 @@ impl SlpToken { pub fn token_id(&self) -> &H256 { &self.conf.token_id } - pub fn slp_address(&self, address: &Address) -> Result { - let platform_conf = &self.platform_coin.as_ref().conf; - let slp_address = try_s!(address.to_cashaddress( - &self.slp_prefix().to_string(), - platform_conf.pub_addr_prefix, - platform_conf.p2sh_addr_prefix - )); - Ok(slp_address) - } - fn platform_conf(&self) -> &UtxoCoinConf { &self.platform_coin.as_ref().conf } async fn my_balance_sat(&self) -> UtxoRpcResult { @@ -787,19 +777,22 @@ impl SlpToken { } } +#[derive(Debug, Eq, PartialEq)] +pub struct SlpGenesisParams { + pub(super) token_ticker: String, + token_name: String, + token_document_url: String, + token_document_hash: Vec, + pub(super) decimals: Vec, + pub(super) mint_baton_vout: Option, + pub(super) initial_token_mint_quantity: u64, +} + /// https://slp.dev/specs/slp-token-type-1/#transaction-detail #[derive(Debug, Eq, PartialEq)] pub enum SlpTransaction { /// https://slp.dev/specs/slp-token-type-1/#genesis-token-genesis-transaction - Genesis { - token_ticker: String, - token_name: String, - token_document_url: String, - token_document_hash: Vec, - decimals: Vec, - mint_baton_vout: Option, - initial_token_mint_quantity: u64, - }, + Genesis(SlpGenesisParams), /// https://slp.dev/specs/slp-token-type-1/#mint-extended-minting-transaction Mint { token_id: H256, @@ -810,6 +803,15 @@ pub enum SlpTransaction { Send { token_id: H256, amounts: Vec }, } +impl SlpTransaction { + pub fn token_id(&self) -> Option { + match self { + SlpTransaction::Send { token_id, .. } | SlpTransaction::Mint { token_id, .. } => Some(*token_id), + SlpTransaction::Genesis(_) => None, + } + } +} + impl Deserializable for SlpTransaction { fn deserialize(reader: &mut Reader) -> Result where @@ -852,7 +854,7 @@ impl Deserializable for SlpTransaction { } let initial_token_mint_quantity = u64::from_be_bytes(bytes.try_into().expect("length is 8 bytes")); - Ok(SlpTransaction::Genesis { + Ok(SlpTransaction::Genesis(SlpGenesisParams { token_ticker, token_name, token_document_url, @@ -860,7 +862,7 @@ impl Deserializable for SlpTransaction { decimals, mint_baton_vout, initial_token_mint_quantity, - }) + })) }, SLP_MINT => { let maybe_id: Vec = reader.read_list()?; @@ -1050,8 +1052,8 @@ impl MarketCoinOps for SlpToken { fn ticker(&self) -> &str { &self.conf.ticker } fn my_address(&self) -> Result { - let my_platform_address = try_s!(self.platform_coin.as_ref().derivation_method.iguana_or_err()); - let slp_address = try_s!(self.slp_address(my_platform_address)); + let my_address = try_s!(self.as_ref().derivation_method.iguana_or_err()); + let slp_address = try_s!(self.platform_coin.slp_address(my_address)); slp_address.encode() } @@ -1121,6 +1123,7 @@ impl MarketCoinOps for SlpToken { fn min_trading_vol(&self) -> MmNumber { big_decimal_from_sat_unsigned(1, self.decimals()).into() } } +#[async_trait] impl SwapOps for SlpToken { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let coin = self.clone(); @@ -1349,7 +1352,7 @@ impl SwapOps for SlpToken { utxo_common::check_if_my_payment_sent(self.platform_coin.clone(), time_lock, other_pub, secret_hash) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -1367,9 +1370,10 @@ impl SwapOps for SlpToken { SLP_SWAP_VOUT, search_from_block, ) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -1387,6 +1391,7 @@ impl SwapOps for SlpToken { SLP_SWAP_VOUT, search_from_block, ) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { @@ -1751,7 +1756,7 @@ mod slp_tests { let slp_data = parse_slp_script(&script).unwrap(); assert_eq!(slp_data.lokad_id, "SLP\0"); let initial_token_mint_quantity = 1000_0000_0000u64; - let expected_transaction = SlpTransaction::Genesis { + let expected_transaction = SlpTransaction::Genesis(SlpGenesisParams { token_ticker: "ADEX".to_string(), token_name: "ADEX".to_string(), token_document_url: "".to_string(), @@ -1759,7 +1764,7 @@ mod slp_tests { decimals: vec![8], mint_baton_vout: None, initial_token_mint_quantity, - }; + }); assert_eq!(expected_transaction, slp_data.transaction); @@ -1769,7 +1774,7 @@ mod slp_tests { let slp_data = parse_slp_script(&script).unwrap(); assert_eq!(slp_data.lokad_id, "SLP\0"); let initial_token_mint_quantity = 10000000000000000u64; - let expected_transaction = SlpTransaction::Genesis { + let expected_transaction = SlpTransaction::Genesis(SlpGenesisParams { token_ticker: "USDT".to_string(), token_name: "Tether Ltd. US dollar backed tokens".to_string(), token_document_url: "https://tether.to/wp-content/uploads/2016/06/TetherWhitePaper.pdf".to_string(), @@ -1778,7 +1783,7 @@ mod slp_tests { decimals: vec![8], mint_baton_vout: Some(2), initial_token_mint_quantity, - }; + }); assert_eq!(expected_transaction, slp_data.transaction); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index b19669de0d..a10f2d88fd 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -15,7 +15,7 @@ use common::mm_ctx::MmArc; use common::mm_error::prelude::*; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; -use common::{block_on, now_ms}; +use common::now_ms; use futures::compat::Future01CompatExt; use futures::future::{FutureExt, TryFutureExt}; use futures01::future::Either; @@ -1288,7 +1288,7 @@ where let history = try_s!(client.scripthash_get_history(&hex::encode(script_hash)).compat().await); match history.first() { Some(item) => { - let tx_bytes = try_s!(client.get_transaction_bytes(item.tx_hash.clone()).compat().await); + let tx_bytes = try_s!(client.get_transaction_bytes(&item.tx_hash).compat().await); let mut tx: UtxoTx = try_s!(deserialize(tx_bytes.0.as_slice()).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.as_ref().tx_hash_algo; Ok(Some(tx.into())) @@ -1313,7 +1313,7 @@ where let received_by_addr = try_s!(client.list_received_by_address(0, true, true).compat().await); for item in received_by_addr { if item.address == target_addr && !item.txids.is_empty() { - let tx_bytes = try_s!(client.get_transaction_bytes(item.txids[0].clone()).compat().await); + let tx_bytes = try_s!(client.get_transaction_bytes(&item.txids[0]).compat().await); let mut tx: UtxoTx = try_s!(deserialize(tx_bytes.0.as_slice()).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.as_ref().tx_hash_algo; return Ok(Some(tx.into())); @@ -1326,7 +1326,7 @@ where Box::new(fut.boxed().compat()) } -pub fn search_for_swap_tx_spend_my( +pub async fn search_for_swap_tx_spend_my( coin: &UtxoCoinFields, time_lock: u32, other_pub: &[u8], @@ -1336,7 +1336,7 @@ pub fn search_for_swap_tx_spend_my( search_from_block: u64, ) -> Result, String> { let my_public = try_s!(coin.priv_key_policy.key_pair_or_err()).public(); - block_on(search_for_swap_output_spend( + search_for_swap_output_spend( coin, time_lock, my_public, @@ -1345,10 +1345,11 @@ pub fn search_for_swap_tx_spend_my( tx, output_index, search_from_block, - )) + ) + .await } -pub fn search_for_swap_tx_spend_other( +pub async fn search_for_swap_tx_spend_other( coin: &UtxoCoinFields, time_lock: u32, other_pub: &[u8], @@ -1358,7 +1359,7 @@ pub fn search_for_swap_tx_spend_other( search_from_block: u64, ) -> Result, String> { let my_public = try_s!(coin.priv_key_policy.key_pair_or_err()).public(); - block_on(search_for_swap_output_spend( + search_for_swap_output_spend( coin, time_lock, &try_s!(Public::from_slice(other_pub)), @@ -1367,7 +1368,8 @@ pub fn search_for_swap_tx_spend_other( tx, output_index, search_from_block, - )) + ) + .await } /// Extract a secret from the `spend_tx`. @@ -1719,7 +1721,7 @@ where })); break; }, - RequestTxHistoryResult::UnknownError(e) => { + RequestTxHistoryResult::CriticalError(e) => { log_tag!( ctx, "", @@ -1791,20 +1793,6 @@ where updated = true; } } - // TODO uncomment this when `update_kmd_rewards` works correctly - // if e.get().should_update_kmd_rewards() && e.get().block_height > 0 { - // mm_counter!(ctx.metrics, "tx.history.update.kmd_rewards", 1); - // match coin.update_kmd_rewards(e.get_mut(), &mut input_transactions).await { - // Ok(()) => updated = true, - // Err(e) => log_tag!( - // ctx, - // "😟", - // "tx_history", - // "coin" => coin.as_ref().conf.ticker; - // fmt = "Error {:?} on updating the KMD rewards of {:?}, skipping the tx", e, txid - // ), - // } - // } }, } if updated { @@ -1857,7 +1845,10 @@ where let my_address = match coin.my_address() { Ok(addr) => addr, Err(e) => { - return RequestTxHistoryResult::UnknownError(ERRL!("Error on getting self address: {}. Stop tx history", e)) + return RequestTxHistoryResult::CriticalError(ERRL!( + "Error on getting self address: {}. Stop tx history", + e + )) }, }; @@ -1905,7 +1896,7 @@ where UtxoRpcClientEnum::Electrum(client) => { let my_address = match coin.as_ref().derivation_method.iguana_or_err() { Ok(my_address) => my_address, - Err(e) => return RequestTxHistoryResult::UnknownError(e.to_string()), + Err(e) => return RequestTxHistoryResult::CriticalError(e.to_string()), }; let script = output_script(my_address, ScriptType::P2PKH); let script_hash = electrum_script_hash(&script); @@ -2073,6 +2064,11 @@ where to_addresses.sort(); to_addresses.dedup(); + let fee_details = UtxoFeeDetails { + coin: Some(coin.as_ref().conf.ticker.clone()), + amount: fee, + }; + Ok(TransactionDetails { from: from_addresses, to: to_addresses, @@ -2082,7 +2078,7 @@ where total_amount: big_decimal_from_sat_unsigned(input_amount, coin.as_ref().decimals), tx_hash: tx.hash().reversed().to_vec().into(), tx_hex: verbose_tx.hex, - fee_details: Some(UtxoFeeDetails { amount: fee }.into()), + fee_details: Some(fee_details.into()), block_height: verbose_tx.height.unwrap_or(0), coin: ticker.clone(), internal_id: tx.hash().reversed().to_vec().into(), @@ -2148,9 +2144,10 @@ where let kmd_rewards = coin.calc_interest_of_tx(&tx, input_transactions).await?; let kmd_rewards = big_decimal_from_sat_unsigned(kmd_rewards, coin.as_ref().decimals); - if let Some(TxFeeDetails::Utxo(UtxoFeeDetails { ref amount })) = tx_details.fee_details { + if let Some(TxFeeDetails::Utxo(UtxoFeeDetails { ref amount, .. })) = tx_details.fee_details { let actual_fee_amount = amount + &kmd_rewards; tx_details.fee_details = Some(TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(coin.as_ref().conf.ticker.clone()), amount: actual_fee_amount, })); } @@ -2688,7 +2685,7 @@ where let tx_from_rpc = match coin .as_ref() .rpc_client - .get_transaction_bytes(tx.hash().reversed().into()) + .get_transaction_bytes(&tx.hash().reversed().into()) .compat() .await { diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 7c08fdb7cc..0ef1b9cc5f 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -219,6 +219,7 @@ impl UtxoStandardOps for UtxoStandardCoin { } } +#[async_trait] impl SwapOps for UtxoStandardCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) @@ -349,7 +350,7 @@ impl SwapOps for UtxoStandardCoin { utxo_common::check_if_my_payment_sent(self.clone(), time_lock, other_pub, secret_hash) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -367,9 +368,10 @@ impl SwapOps for UtxoStandardCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -387,6 +389,7 @@ impl SwapOps for UtxoStandardCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index b558940eee..b241bd6e06 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -438,17 +438,16 @@ fn test_search_for_swap_tx_spend_electrum_was_spent() { .unwrap(); let spend_tx = TransactionEnum::UtxoTx(deserialize(spend_tx_bytes.as_slice()).unwrap()); - let found = coin - .search_for_swap_tx_spend_my( - 1591928233, - &*coin.my_public_key().unwrap(), - &*dhash160(&secret), - &payment_tx_bytes, - 0, - &None, - ) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + 1591928233, + &*coin.my_public_key().unwrap(), + &*dhash160(&secret), + &payment_tx_bytes, + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Spent(spend_tx), found); } @@ -471,17 +470,16 @@ fn test_search_for_swap_tx_spend_electrum_was_refunded() { .unwrap(); let refund_tx = TransactionEnum::UtxoTx(deserialize(refund_tx_bytes.as_slice()).unwrap()); - let found = coin - .search_for_swap_tx_spend_my( - 1591933469, - coin.as_ref().priv_key_policy.key_pair_or_err().unwrap().public(), - &secret, - &payment_tx_bytes, - 0, - &None, - ) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + 1591933469, + coin.as_ref().priv_key_policy.key_pair_or_err().unwrap().public(), + &secret, + &payment_tx_bytes, + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Refunded(refund_tx), found); } @@ -506,7 +504,7 @@ fn test_withdraw_impl_set_fixed_fee() { let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false); let withdraw_req = WithdrawRequest { - amount: 1.into(), + amount: 1u64.into(), from: None, to: "RQq6fWoy8aGGMLjvRfMY5mBNVm2RQxJyLa".to_string(), coin: TEST_COIN_NAME.into(), @@ -517,6 +515,7 @@ fn test_withdraw_impl_set_fixed_fee() { }; let expected = Some( UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.1".parse().unwrap(), } .into(), @@ -546,7 +545,7 @@ fn test_withdraw_impl_sat_per_kb_fee() { let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false); let withdraw_req = WithdrawRequest { - amount: 1.into(), + amount: 1u64.into(), from: None, to: "RQq6fWoy8aGGMLjvRfMY5mBNVm2RQxJyLa".to_string(), coin: TEST_COIN_NAME.into(), @@ -560,6 +559,7 @@ fn test_withdraw_impl_sat_per_kb_fee() { // 0.1 * 245 / 1000 ~ 0.0245 let expected = Some( UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.0245".parse().unwrap(), } .into(), @@ -604,12 +604,13 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max() { // 0.1 * 211 / 1000 = 0.0211 let expected_fee = Some( UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.0211".parse().unwrap(), } .into(), ); assert_eq!(expected_fee, tx_details.fee_details); - let expected_balance_change = BigDecimal::from(-10); + let expected_balance_change = BigDecimal::from(-10i32); assert_eq!(expected_balance_change, tx_details.my_balance_change); } @@ -649,12 +650,13 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max_dust_included_to_fee() // 0.1 * 211 / 1000 = 0.0211 let expected_fee = Some( UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.0211".parse().unwrap(), } .into(), ); assert_eq!(expected_fee, tx_details.fee_details); - let expected_balance_change = BigDecimal::from(-10); + let expected_balance_change = BigDecimal::from(-10i32); assert_eq!(expected_balance_change, tx_details.my_balance_change); } @@ -712,7 +714,7 @@ fn test_withdraw_impl_sat_per_kb_fee_max() { let coin = utxo_coin_for_test(UtxoRpcClientEnum::Native(client), None, false); let withdraw_req = WithdrawRequest { - amount: 0.into(), + amount: 0u64.into(), from: None, to: "RQq6fWoy8aGGMLjvRfMY5mBNVm2RQxJyLa".to_string(), coin: TEST_COIN_NAME.into(), @@ -726,6 +728,7 @@ fn test_withdraw_impl_sat_per_kb_fee_max() { // 0.1 * 211 / 1000 = 0.0211 let expected = Some( UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.0211".parse().unwrap(), } .into(), @@ -780,6 +783,7 @@ fn test_withdraw_kmd_rewards_impl( fee: None, }; let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("KMD".into()), amount: "0.00001".parse().unwrap(), }); let tx_details = coin.withdraw(withdraw_req).wait().unwrap(); @@ -853,6 +857,7 @@ fn test_withdraw_rick_rewards_none() { fee: None, }; let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.00001".parse().unwrap(), }); let tx_details = coin.withdraw(withdraw_req).wait().unwrap(); @@ -2365,7 +2370,7 @@ fn test_find_output_spend_skips_conflicting_transactions() { static mut GET_RAW_TRANSACTION_BYTES_CALLED: usize = 0; NativeClientImpl::get_raw_transaction_bytes.mock_safe(move |_, txid| { unsafe { GET_RAW_TRANSACTION_BYTES_CALLED += 1 }; - assert_eq!(txid, expected_txid); + assert_eq!(*txid, expected_txid); // no matter what we return here let bytes: BytesJson = hex::decode("0400008085202f890347d329798b508dc28ec99d8c6f6c7ced860a19a364e1bafe391cab89aeaac731020000006a47304402203ea8b380d0a7e64348869ef7c4c2bfa966fc7b148633003332fa8d0ab0c1bc5602202cc63fabdd2a6578c52d8f4f549069b16505f2ead48edc2b8de299be15aadf9a012102d8c948c6af848c588517288168faa397d6ba3ea924596d03d1d84f224b5123c2ffffffff1d1fd3a6b01710647a7f4a08c6de6075cb8e78d5069fa50f10c4a2a10ded2a95000000006a47304402203868945edc0f6dc2ee43d70a69ee4ec46ca188dc493173ce58924ba9bf6ee7a50220648ff99ce458ca72800758f6a1bd3800cd05ff9c3122f23f3653c25e09d22c79012102d8c948c6af848c588517288168faa397d6ba3ea924596d03d1d84f224b5123c2ffffffff7932150df8b4a1852b8b84b89b0d5322bf74665fb7f76a728369fd6895d3fd48000000006a4730440220127918c6f79c11f7f2376a6f3b750ed4c7103183181ad1218afcb2625ece9599022028c05e88d3a2f97cebd84a718cda33b62b48b18f16278fa8e531fd2155e61ee8012102d8c948c6af848c588517288168faa397d6ba3ea924596d03d1d84f224b5123c2ffffffff0329fd12000000000017a914cafb62e3e8bdb8db3735c39b92743ac6ebc9ef20870000000000000000166a14a7416b070c9bb98f4bafae55616f005a2a30bd6014b40c00000000001976a91450f4f098306f988d8843004689fae28c83ef16e888ac8cc5925f000000000000000000000000000000").unwrap().into(); MockResult::Return(Box::new(futures01::future::ok(bytes))) @@ -2641,6 +2646,7 @@ fn firo_lelantus_tx_details() { let tx_details = block_on(coin.tx_details_by_hash(&tx_hash, &mut map)).unwrap(); let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.00003793".parse().unwrap(), }); assert_eq!(Some(expected_fee), tx_details.fee_details); @@ -2649,6 +2655,7 @@ fn firo_lelantus_tx_details() { let tx_details = block_on(coin.tx_details_by_hash(&tx_hash, &mut map)).unwrap(); let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: "0.00045778".parse().unwrap(), }); assert_eq!(Some(expected_fee), tx_details.fee_details); @@ -2872,6 +2879,7 @@ fn test_tx_details_kmd_rewards() { let tx_details = block_on(coin.tx_details_by_hash(&hash, &mut input_transactions)).expect("!tx_details_by_hash"); let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("KMD".into()), amount: BigDecimal::from_str("0.00001").unwrap(), }); assert_eq!(tx_details.fee_details, Some(expected_fee)); @@ -2905,6 +2913,7 @@ fn test_tx_details_kmd_rewards_claimed_by_other() { let tx_details = block_on(coin.tx_details_by_hash(&hash, &mut input_transactions)).expect("!tx_details_by_hash"); let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("KMD".into()), amount: BigDecimal::from_str("0.00001").unwrap(), }); assert_eq!(tx_details.fee_details, Some(expected_fee)); @@ -2932,6 +2941,7 @@ fn test_tx_details_bch_no_rewards() { let tx_details = block_on(coin.tx_details_by_hash(&hash, &mut input_transactions)).expect("!tx_details_by_hash"); let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(TEST_COIN_NAME.into()), amount: BigDecimal::from_str("0.00000452").unwrap(), }); assert_eq!(tx_details.fee_details, Some(expected_fee)); @@ -2964,6 +2974,7 @@ fn test_update_kmd_rewards() { assert_eq!(tx_details.kmd_rewards, Some(expected_rewards)); let expected_fee_details = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("KMD".into()), amount: BigDecimal::from_str("0.00001").unwrap(), }); assert_eq!(tx_details.fee_details, Some(expected_fee_details)); @@ -2995,6 +3006,7 @@ fn test_update_kmd_rewards_claimed_not_by_me() { assert_eq!(tx_details.kmd_rewards, Some(expected_rewards)); let expected_fee_details = TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some("KMD".into()), amount: BigDecimal::from_str("0.00001").unwrap(), }); assert_eq!(tx_details.fee_details, Some(expected_fee_details)); diff --git a/mm2src/coins/utxo/utxo_withdraw.rs b/mm2src/coins/utxo/utxo_withdraw.rs index fbabaa42a2..c2c045b4df 100644 --- a/mm2src/coins/utxo/utxo_withdraw.rs +++ b/mm2src/coins/utxo/utxo_withdraw.rs @@ -177,11 +177,11 @@ where match req.fee { Some(WithdrawFee::UtxoFixed { ref amount }) => { - let fixed = sat_from_big_decimal(&amount, decimals)?; + let fixed = sat_from_big_decimal(amount, decimals)?; tx_builder = tx_builder.with_fee(ActualTxFee::FixedPerKb(fixed)); }, Some(WithdrawFee::UtxoPerKbyte { ref amount }) => { - let dynamic = sat_from_big_decimal(&amount, decimals)?; + let dynamic = sat_from_big_decimal(amount, decimals)?; tx_builder = tx_builder.with_fee(ActualTxFee::Dynamic(dynamic)); }, Some(ref fee_policy) => { @@ -205,6 +205,7 @@ where let fee_amount = data.fee_amount + data.unused_change.unwrap_or_default(); let fee_details = UtxoFeeDetails { + coin: Some(self.coin().as_ref().conf.ticker.clone()), amount: big_decimal_from_sat(fee_amount as i64, decimals), }; let tx_hex = match coin.addr_format() { diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index f6d890493f..1144b28868 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -542,7 +542,7 @@ async fn sapling_state_cache_loop(coin: ZCoin) { let mut cmus = Vec::new(); for hash in block.tx { let tx = native_client - .get_transaction_bytes(hash) + .get_transaction_bytes(&hash) .compat() .await .expect("Panic here to avoid storing invalid tree state to the DB"); @@ -707,6 +707,7 @@ impl MarketCoinOps for ZCoin { fn min_trading_vol(&self) -> MmNumber { utxo_common::min_trading_vol(self.as_ref()) } } +#[async_trait] impl SwapOps for ZCoin { fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut { let selfi = self.clone(); @@ -984,7 +985,7 @@ impl SwapOps for ZCoin { utxo_common::check_if_my_payment_sent(self.clone(), time_lock, other_pub, secret_hash) } - fn search_for_swap_tx_spend_my( + async fn search_for_swap_tx_spend_my( &self, time_lock: u32, other_pub: &[u8], @@ -1002,9 +1003,10 @@ impl SwapOps for ZCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } - fn search_for_swap_tx_spend_other( + async fn search_for_swap_tx_spend_other( &self, time_lock: u32, other_pub: &[u8], @@ -1022,6 +1024,7 @@ impl SwapOps for ZCoin { utxo_common::DEFAULT_SWAP_VOUT, search_from_block, ) + .await } fn extract_secret(&self, secret_hash: &[u8], spend_tx: &[u8]) -> Result, String> { @@ -1088,6 +1091,7 @@ impl MmCoin for ZCoin { block_height: 0, timestamp: 0, fee_details: Some(TxFeeDetails::Utxo(UtxoFeeDetails { + coin: Some(coin.utxo_arc.conf.ticker.clone()), amount: big_decimal_from_sat_unsigned(data.fee_amount, coin.decimals()), })), coin: coin.ticker().to_owned(), diff --git a/mm2src/coins/z_coin/z_htlc.rs b/mm2src/coins/z_coin/z_htlc.rs index 8ca770b63c..498c6ca42b 100644 --- a/mm2src/coins/z_coin/z_htlc.rs +++ b/mm2src/coins/z_coin/z_htlc.rs @@ -37,7 +37,7 @@ pub async fn z_send_htlc( amount: BigDecimal, ) -> Result> { let key_pair = coin.utxo_arc.priv_key_policy.key_pair_or_err()?; - let payment_script = payment_script(time_lock, secret_hash, key_pair.public(), &other_pub); + let payment_script = payment_script(time_lock, secret_hash, key_pair.public(), other_pub); let script_hash = dhash160(&payment_script); let htlc_address = Address { prefix: coin.utxo_arc.conf.p2sh_addr_prefix, diff --git a/mm2src/coins_activation/Cargo.toml b/mm2src/coins_activation/Cargo.toml index 70f3a45a34..533b6473bb 100644 --- a/mm2src/coins_activation/Cargo.toml +++ b/mm2src/coins_activation/Cargo.toml @@ -11,6 +11,7 @@ coins = { path = "../coins" } common = { path = "../common" } crypto = { path = "../crypto" } derive_more = "0.99" +futures = { version = "0.3", package = "futures", features = ["compat", "async-await"] } hex = "0.4.2" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } diff --git a/mm2src/coins_activation/src/bch_with_tokens_activation.rs b/mm2src/coins_activation/src/bch_with_tokens_activation.rs index 1df2d1e113..63e18df63f 100644 --- a/mm2src/coins_activation/src/bch_with_tokens_activation.rs +++ b/mm2src/coins_activation/src/bch_with_tokens_activation.rs @@ -1,17 +1,22 @@ -use crate::platform_coin_with_tokens::{EnablePlatformCoinWithTokensError, PlatformWithTokensActivationOps, - RegisterTokenInfo, TokenActivationParams, TokenActivationRequest, - TokenAsMmCoinInitializer, TokenInitializer, TokenOf}; +use crate::platform_coin_with_tokens::*; use crate::prelude::*; use crate::slp_token_activation::SlpActivationRequest; use async_trait::async_trait; +use coins::my_tx_history_v2::TxHistoryStorage; use coins::utxo::bch::{bch_coin_from_conf_and_params, BchActivationRequest, BchCoin, CashAddrPrefix}; +use coins::utxo::bch_and_slp_tx_history::bch_and_slp_history_loop; use coins::utxo::rpc_clients::UtxoRpcError; use coins::utxo::slp::{SlpProtocolConf, SlpToken}; use coins::utxo::UtxoCommonOps; use coins::{CoinBalance, CoinProtocol, DerivationMethodNotSupported, MarketCoinOps, MmCoin, PrivKeyNotAllowed}; +use common::executor::spawn; +use common::log::info; use common::mm_ctx::MmArc; use common::mm_error::prelude::*; +use common::mm_metrics::MetricsArc; +use common::mm_number::BigDecimal; use common::Future01CompatExt; +use futures::future::{abortable, AbortHandle}; use serde_derive::{Deserialize, Serialize}; use serde_json::Value as Json; use std::collections::HashMap; @@ -104,6 +109,10 @@ pub struct BchWithTokensActivationRequest { slp_tokens_requests: Vec>, } +impl TxHistoryEnabled for BchWithTokensActivationRequest { + fn tx_history_enabled(&self) -> bool { self.platform_request.utxo_params.tx_history } +} + pub struct BchProtocolInfo { slp_prefix: String, } @@ -127,6 +136,16 @@ pub struct BchWithTokensActivationResult { slp_addresses_infos: HashMap>, } +impl GetPlatformBalance for BchWithTokensActivationResult { + fn get_platform_balance(&self) -> BigDecimal { + self.bch_addresses_infos + .iter() + .fold(BigDecimal::from(0), |total, (_, addr_info)| { + &total + &addr_info.balances.get_total() + }) + } +} + #[derive(Debug)] pub enum BchWithTokensActivationError { PlatformCoinCreationError { @@ -244,4 +263,25 @@ impl PlatformWithTokensActivationOps for BchCoin { }); Ok(result) } + + fn start_history_background_fetching( + &self, + metrics: MetricsArc, + storage: impl TxHistoryStorage + Send + 'static, + initial_balance: BigDecimal, + ) -> AbortHandle { + let ticker = self.ticker().to_owned(); + let (fut, abort_handle) = abortable(bch_and_slp_history_loop( + self.clone(), + storage, + metrics, + initial_balance, + )); + spawn(async move { + if let Err(e) = fut.await { + info!("bch_and_slp_history_loop stopped for {}, reason {}", ticker, e); + } + }); + abort_handle + } } diff --git a/mm2src/coins_activation/src/init_utxo.rs b/mm2src/coins_activation/src/init_utxo.rs index 919efb42be..f09ea72eb8 100644 --- a/mm2src/coins_activation/src/init_utxo.rs +++ b/mm2src/coins_activation/src/init_utxo.rs @@ -347,9 +347,7 @@ impl InitUtxoTask { .map_to_mm(|e| InitUtxoError::InvalidCoinProtocol(e.to_string()))?; let priv_key_policy = match *crypto_ctx { - CryptoCtx::KeyPair(ref key_pair_ctx) => { - PrivKeyBuildPolicy::PrivKey(&key_pair_ctx.secp256k1_privkey_bytes()) - }, + CryptoCtx::KeyPair(ref key_pair_ctx) => PrivKeyBuildPolicy::PrivKey(key_pair_ctx.secp256k1_privkey_bytes()), CryptoCtx::HardwareWallet(_) => PrivKeyBuildPolicy::HardwareWallet, }; diff --git a/mm2src/coins_activation/src/platform_coin_with_tokens.rs b/mm2src/coins_activation/src/platform_coin_with_tokens.rs index 7afaa8cc7a..d85fd26db0 100644 --- a/mm2src/coins_activation/src/platform_coin_with_tokens.rs +++ b/mm2src/coins_activation/src/platform_coin_with_tokens.rs @@ -1,10 +1,16 @@ use crate::prelude::*; use async_trait::async_trait; +use coins::my_tx_history_v2::TxHistoryStorage; +#[cfg(not(target_arch = "wasm32"))] +use coins::sql_tx_history_storage::SqliteTxHistoryStorage; use coins::{lp_coinfind, CoinProtocol, CoinsContext, MmCoinEnum}; use common::mm_ctx::MmArc; use common::mm_error::prelude::*; +use common::mm_metrics::MetricsArc; +use common::mm_number::BigDecimal; use common::{HttpStatusCode, NotSame, StatusCode}; use derive_more::Display; +use futures::future::AbortHandle; use ser_error_derive::SerializeErrorType; use serde_derive::{Deserialize, Serialize}; use serde_json::Value as Json; @@ -125,11 +131,15 @@ where } } +pub trait GetPlatformBalance { + fn get_platform_balance(&self) -> BigDecimal; +} + #[async_trait] pub trait PlatformWithTokensActivationOps: Into { - type ActivationRequest: Clone + Send + Sync; + type ActivationRequest: Clone + Send + Sync + TxHistoryEnabled; type PlatformProtocolInfo: TryFromCoinProtocol; - type ActivationResult; + type ActivationResult: GetPlatformBalance; type ActivationError: NotMmError; /// Initializes the platform coin itself @@ -147,6 +157,13 @@ pub trait PlatformWithTokensActivationOps: Into { ) -> Vec>>; async fn get_activation_result(&self) -> Result>; + + fn start_history_background_fetching( + &self, + metrics: MetricsArc, + storage: impl TxHistoryStorage + Send + 'static, + initial_balance: BigDecimal, + ) -> AbortHandle; } #[derive(Debug, Deserialize)] @@ -286,6 +303,17 @@ where } let activation_result = platform_coin.get_activation_result().await?; + + #[cfg(not(target_arch = "wasm32"))] + if req.request.tx_history_enabled() { + let abort_handler = platform_coin.start_history_background_fetching( + ctx.metrics.clone(), + SqliteTxHistoryStorage(ctx.sqlite_connection.as_option().unwrap().clone()), + activation_result.get_platform_balance(), + ); + ctx.abort_handlers.lock().unwrap().push(abort_handler); + } + let coins_ctx = CoinsContext::from_ctx(&ctx).unwrap(); coins_ctx .add_platform_with_tokens(platform_coin.into(), mm_tokens) diff --git a/mm2src/coins_activation/src/prelude.rs b/mm2src/coins_activation/src/prelude.rs index 990953bd42..3a44a8ec6f 100644 --- a/mm2src/coins_activation/src/prelude.rs +++ b/mm2src/coins_activation/src/prelude.rs @@ -5,6 +5,10 @@ use serde_derive::Serialize; use serde_json::{self as json, Value as Json}; use std::collections::HashMap; +pub trait TxHistoryEnabled { + fn tx_history_enabled(&self) -> bool; +} + #[derive(Debug, Serialize)] #[serde(tag = "type", content = "data")] pub enum DerivationMethod { @@ -47,7 +51,7 @@ pub fn coin_conf_with_protocol( ctx: &MmArc, coin: &str, ) -> Result<(Json, T), MmError> { - let conf = coin_conf(&ctx, coin); + let conf = coin_conf(ctx, coin); if conf.is_null() { return MmError::err(CoinConfWithProtocolError::ConfigIsNotFound(coin.into())); } diff --git a/mm2src/coins_activation/src/slp_token_activation.rs b/mm2src/coins_activation/src/slp_token_activation.rs index 464ea63ba0..9956e28a7b 100644 --- a/mm2src/coins_activation/src/slp_token_activation.rs +++ b/mm2src/coins_activation/src/slp_token_activation.rs @@ -71,6 +71,7 @@ pub struct SlpInitResult { } #[derive(Debug)] +#[allow(clippy::large_enum_variant)] pub enum SlpInitError { GetBalanceError(UtxoRpcError), MyAddressError(String), diff --git a/mm2src/common/Cargo.toml b/mm2src/common/Cargo.toml index 3df0edff9e..0fc5b3be08 100644 --- a/mm2src/common/Cargo.toml +++ b/mm2src/common/Cargo.toml @@ -23,6 +23,7 @@ bitcrypto = { path = "../mm2_bitcoin/crypto" } bytes = "1.1" cfg-if = "1.0" crossbeam = "0.7" +db_common = { path = "../db_common" } derive_more = "0.99" findshlibs = "0.5" fnv = "1.0.6" @@ -89,7 +90,6 @@ metrics = { version = "0.12" } metrics-runtime = { version = "0.13", default-features = false, features = ["metrics-observer-prometheus"] } metrics-core = { version = "0.5" } metrics-util = { version = "0.3" } -rusqlite = { version = "0.24.2", features = ["bundled"] } tokio = { version = "1.7", features = ["io-util", "rt-multi-thread", "net"] } [build-dependencies] diff --git a/mm2src/common/common.rs b/mm2src/common/common.rs index a28bb843df..584f930420 100644 --- a/mm2src/common/common.rs +++ b/mm2src/common/common.rs @@ -166,8 +166,6 @@ pub mod fs; cfg_native! { pub use gstuff::{now_float, now_ms}; - pub use rusqlite; - #[cfg(not(windows))] use findshlibs::{IterationControl, Segment, SharedLibrary, TargetSharedLibrary}; use libc::{free, malloc}; @@ -1080,8 +1078,7 @@ pub fn var(name: &str) -> Result { #[cfg(target_arch = "wasm32")] pub fn var(_name: &str) -> Result { ERR!("Environment variable not supported in WASM") } -/// TODO make it wasm32 only -/// #[cfg(not(target_arch = "wasm32"))] +#[cfg(not(target_arch = "wasm32"))] pub fn block_on(f: F) -> F::Output where F: Future03, @@ -1092,7 +1089,26 @@ where log!("block_on at\n"(trace)); } - futures::executor::block_on(f) + wio::CORE.0.block_on(f) +} + +#[cfg(target_arch = "wasm32")] +pub fn block_on(_f: F) -> F::Output +where + F: Future03, +{ + panic!("block_on is not supported in WASM!"); +} + +#[cfg(not(target_arch = "wasm32"))] +pub async fn async_blocking(blocking_fn: F) -> R +where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static, +{ + tokio::task::spawn_blocking(blocking_fn) + .await + .expect("spawn_blocking to succeed") } #[cfg(target_arch = "wasm32")] @@ -1366,7 +1382,7 @@ fn test_round_to() { assert_eq!(round_to(&BigDecimal::from(-0), 0), "0"); } -const fn ten() -> usize { 10 } +pub const fn ten() -> usize { 10 } fn one() -> NonZeroUsize { NonZeroUsize::new(1).unwrap() } @@ -1666,3 +1682,13 @@ fn test_is_acceptable_input_on_repeated_characters() { false ); } + +#[derive(Clone, Deserialize, Serialize)] +pub enum PagingOptionsEnum { + FromId(Id), + PageNumber(NonZeroUsize), +} + +impl Default for PagingOptionsEnum { + fn default() -> Self { PagingOptionsEnum::PageNumber(NonZeroUsize::new(1).expect("1 > 0")) } +} diff --git a/mm2src/common/custom_futures.rs b/mm2src/common/custom_futures.rs index 820836b6f9..4b74435300 100644 --- a/mm2src/common/custom_futures.rs +++ b/mm2src/common/custom_futures.rs @@ -297,7 +297,7 @@ where } } -unsafe impl Send for Timeout {} +unsafe impl Send for Timeout where F: Send {} #[test] fn test_timeout() { diff --git a/mm2src/common/duplex_mutex.rs b/mm2src/common/duplex_mutex.rs index 18324449c6..639cd62f85 100644 --- a/mm2src/common/duplex_mutex.rs +++ b/mm2src/common/duplex_mutex.rs @@ -36,13 +36,13 @@ impl fmt::Display for DuplexMutexGuard<'_, T> { fn fmt(&self, ft: &mut fmt::Formatter<'_>) -> fmt::Result { (**self).fmt(ft) } } -struct Impl { +pub struct Impl { locked: AtomicUsize, data: UnsafeCell, } // We're only using `Impl::data` behind an `Arc` and a lock. -unsafe impl Send for Impl {} +unsafe impl Send for Impl where T: Send {} unsafe impl Sync for Impl {} impl Impl { @@ -130,7 +130,7 @@ pub struct DuplexMutex { pimpl: Arc>, } -unsafe impl Send for DuplexMutex {} +unsafe impl Send for DuplexMutex where Arc>: Send {} impl Clone for DuplexMutex { fn clone(&self) -> DuplexMutex { diff --git a/mm2src/common/for_tests.rs b/mm2src/common/for_tests.rs index bd26acb7d8..2f2a04e3e4 100644 --- a/mm2src/common/for_tests.rs +++ b/mm2src/common/for_tests.rs @@ -6,6 +6,7 @@ use rand::Rng; use serde_json::{self as json, Value as Json}; use std::collections::HashMap; use std::net::IpAddr; +use std::num::NonZeroUsize; use std::process::Child; use std::sync::Mutex; use uuid::Uuid; @@ -13,7 +14,7 @@ use uuid::Uuid; use crate::executor::Timer; use crate::mm_ctx::MmArc; use crate::mm_metrics::{MetricType, MetricsJson}; -use crate::{now_float, now_ms}; +use crate::{now_float, now_ms, PagingOptionsEnum}; cfg_wasm32! { use crate::log::LogLevel; @@ -689,7 +690,7 @@ pub async fn common_wait_for_log_re(req: Bytes) -> Result, String> { #[cfg(not(target_arch = "wasm32"))] pub async fn wait_for_log_re(ctx: &MmArc, timeout_sec: f64, re_pred: &str) -> Result<(), String> { let re = try_s!(Regex::new(re_pred)); - wait_for_log(&ctx, timeout_sec, |line| re.is_match(line)).await + wait_for_log(ctx, timeout_sec, |line| re.is_match(line)).await } /// Create RAII variables to the effect of dumping the log and the status dashboard at the end of the scope. @@ -908,7 +909,36 @@ pub async fn enable_slp(mm: &MarketMakerIt, coin: &str) -> Json { json::from_str(&enable.1).unwrap() } -pub async fn enable_bch_with_tokens(mm: &MarketMakerIt, platform_coin: &str, tokens: &[&str]) -> Json { +#[derive(Serialize)] +pub struct ElectrumRpcRequest { + pub url: String, +} + +#[derive(Serialize)] +#[serde(tag = "rpc", content = "rpc_data")] +pub enum UtxoRpcMode { + Native, + Electrum { servers: Vec }, +} + +impl UtxoRpcMode { + pub fn electrum(servers: &[&str]) -> Self { + UtxoRpcMode::Electrum { + servers: servers + .iter() + .map(|url| ElectrumRpcRequest { url: url.to_string() }) + .collect(), + } + } +} + +pub async fn enable_bch_with_tokens( + mm: &MarketMakerIt, + platform_coin: &str, + tokens: &[&str], + mode: UtxoRpcMode, + tx_history: bool, +) -> Json { let slp_requests: Vec<_> = tokens.iter().map(|ticker| json!({ "ticker": ticker })).collect(); let enable = mm @@ -920,18 +950,46 @@ pub async fn enable_bch_with_tokens(mm: &MarketMakerIt, platform_coin: &str, tok "ticker": platform_coin, "allow_slp_unsafe_conf": true, "bchd_urls": [], - "mode": { - "rpc": "Native", - }, + "mode": mode, + "tx_history": tx_history, "slp_tokens_requests": slp_requests, } })) .await .unwrap(); - assert_eq!(enable.0, StatusCode::OK, "'enable_slp' failed: {}", enable.1); + assert_eq!( + enable.0, + StatusCode::OK, + "'enable_bch_with_tokens' failed: {}", + enable.1 + ); json::from_str(&enable.1).unwrap() } +pub async fn my_tx_history_v2( + mm: &MarketMakerIt, + coin: &str, + limit: usize, + paging: Option>, +) -> Json { + let paging = paging.unwrap_or(PagingOptionsEnum::PageNumber(NonZeroUsize::new(1).unwrap())); + let request = mm + .rpc(json! ({ + "userpass": mm.userpass, + "method": "my_tx_history", + "mmrpc": "2.0", + "params": { + "coin": coin, + "limit": limit, + "paging_options": paging, + } + })) + .await + .unwrap(); + assert_eq!(request.0, StatusCode::OK, "'my_tx_history' failed: {}", request.1); + json::from_str(&request.1).unwrap() +} + pub async fn enable_native_bch(mm: &MarketMakerIt, coin: &str, bchd_urls: &[&str]) -> Json { let native = mm .rpc(json! ({ diff --git a/mm2src/common/jsonrpc_client.rs b/mm2src/common/jsonrpc_client.rs index a18dd3c5a2..0868d95af1 100644 --- a/mm2src/common/jsonrpc_client.rs +++ b/mm2src/common/jsonrpc_client.rs @@ -90,9 +90,9 @@ pub struct JsonRpcResponse { pub struct JsonRpcError { /// Additional member contains an instance info that implements the JsonRpcClient trait. /// The info is used in particular to supplement the error info. - client_info: String, + pub client_info: String, /// Source Rpc request. - request: JsonRpcRequest, + pub request: JsonRpcRequest, /// Error type. pub error: JsonRpcErrorType, } diff --git a/mm2src/common/mm_ctx.rs b/mm2src/common/mm_ctx.rs index 891846cab9..f12ac3913a 100644 --- a/mm2src/common/mm_ctx.rs +++ b/mm2src/common/mm_ctx.rs @@ -3,6 +3,7 @@ use crate::executor::Timer; use crate::log::{self, LogState}; use crate::mm_metrics::{MetricsArc, MetricsOps}; use crate::{bits256, small_rng}; +use futures::future::AbortHandle; use gstuff::Constructible; use keys::KeyPair; use primitives::hash::H160; @@ -25,7 +26,7 @@ cfg_wasm32! { cfg_native! { use crate::mm_metrics::prometheus; - use rusqlite::Connection; + use db_common::sqlite::rusqlite::Connection; use std::net::{IpAddr, SocketAddr}; use std::sync::MutexGuard; } @@ -103,9 +104,10 @@ pub struct MmCtx { #[cfg(target_arch = "wasm32")] pub wasm_rpc: Constructible, #[cfg(not(target_arch = "wasm32"))] - pub sqlite_connection: Constructible>, + pub sqlite_connection: Constructible>>, pub mm_version: String, pub mm_init_ctx: Mutex>>, + pub abort_handlers: Mutex>, #[cfg(target_arch = "wasm32")] pub db_namespace: DbNamespaceId, } @@ -142,6 +144,7 @@ impl MmCtx { sqlite_connection: Constructible::default(), mm_version: "".into(), mm_init_ctx: Mutex::new(None), + abort_handlers: Mutex::new(Vec::new()), #[cfg(target_arch = "wasm32")] db_namespace: DbNamespaceId::Main, } @@ -256,7 +259,7 @@ impl MmCtx { let sqlite_file_path = self.dbdir().join("MM2.db"); log::debug!("Trying to open SQLite database file {}", sqlite_file_path.display()); let connection = try_s!(Connection::open(sqlite_file_path)); - try_s!(self.sqlite_connection.pin(Mutex::new(connection))); + try_s!(self.sqlite_connection.pin(Arc::new(Mutex::new(connection)))); Ok(()) } @@ -295,6 +298,7 @@ pub struct MmArc(pub SharedRc); // NB: Explicit `Send` and `Sync` marks here should become unnecessary later, // after we finish the initial port and replace the C values with the corresponding Rust alternatives. +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for MmArc {} unsafe impl Sync for MmArc {} @@ -312,6 +316,7 @@ impl Deref for MmArc { pub struct MmWeak(WeakRc); // Same as `MmArc`. +#[allow(clippy::non_send_fields_in_send_ty)] unsafe impl Send for MmWeak {} unsafe impl Sync for MmWeak {} @@ -363,6 +368,9 @@ impl MmArc { pub fn stop(&self) -> Result<(), String> { try_s!(self.stop.pin(true)); + for handler in self.abort_handlers.lock().unwrap().drain(..) { + handler.abort(); + } let mut stop_listeners = self.stop_listeners.lock().expect("Can't lock stop_listeners"); // NB: It is important that we `drain` the `stop_listeners` rather than simply iterating over them // because otherwise there might be reference counting instances remaining in a listener diff --git a/mm2src/common/mm_error/mm_json_error.rs b/mm2src/common/mm_error/mm_json_error.rs index 07aa462ffc..0a627335c7 100644 --- a/mm2src/common/mm_error/mm_json_error.rs +++ b/mm2src/common/mm_error/mm_json_error.rs @@ -8,7 +8,7 @@ use std::fmt; pub struct MmJsonError(Json); impl fmt::Display for MmJsonError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0.to_string()) } + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } } /// We are sure that `MmJsonError` is constructed from a type that implements `SerializeErrorTypeImpl`. diff --git a/mm2src/common/shared_ref_counter/src/disable.rs b/mm2src/common/shared_ref_counter/src/disable.rs index 188d5b9283..3c93985b9d 100644 --- a/mm2src/common/shared_ref_counter/src/disable.rs +++ b/mm2src/common/shared_ref_counter/src/disable.rs @@ -4,7 +4,7 @@ use std::sync::{Arc, Weak}; pub struct SharedRc(Arc); -unsafe impl Send for SharedRc {} +unsafe impl Send for SharedRc where Arc: Send {} unsafe impl Sync for SharedRc {} impl Deref for SharedRc { @@ -28,7 +28,7 @@ impl SharedRc { pub struct WeakRc(Weak); -unsafe impl Send for WeakRc {} +unsafe impl Send for WeakRc where Weak: Send {} unsafe impl Sync for WeakRc {} impl Clone for WeakRc { diff --git a/mm2src/common/wio.rs b/mm2src/common/wio.rs index dfdba4406c..6fb3e4469a 100644 --- a/mm2src/common/wio.rs +++ b/mm2src/common/wio.rs @@ -156,7 +156,7 @@ impl Timeout { } } -unsafe impl Send for Timeout {} +unsafe impl Send for Timeout where Box>: Send {} /// Initialize the crate. pub fn init() { diff --git a/mm2src/crypto/src/crypto_ctx.rs b/mm2src/crypto/src/crypto_ctx.rs index d33cd6e27d..a4608f3370 100644 --- a/mm2src/crypto/src/crypto_ctx.rs +++ b/mm2src/crypto/src/crypto_ctx.rs @@ -83,9 +83,9 @@ impl CryptoCtx { return MmError::err(CryptoInitError::NullStringPassphrase); } - let secp256k1_key_pair = key_pair_from_seed(&passphrase)?; + let secp256k1_key_pair = key_pair_from_seed(passphrase)?; // We can't clone `secp256k1_key_pair`, but it's used later to initialize legacy `MmCtx` fields. - let secp256k1_key_pair_for_legacy = key_pair_from_seed(&passphrase)?; + let secp256k1_key_pair_for_legacy = key_pair_from_seed(passphrase)?; let rmd160 = secp256k1_key_pair.public().address_hash(); let crypto_ctx = CryptoCtx::KeyPair(KeyPairCtx { secp256k1_key_pair }); diff --git a/mm2src/database.rs b/mm2src/database.rs index 9580d3a984..f6260ce1bb 100644 --- a/mm2src/database.rs +++ b/mm2src/database.rs @@ -1,16 +1,15 @@ /// The module responsible to work with SQLite database /// -#[path = "database/database_common.rs"] -pub mod database_common; -#[path = "database/my_orders.rs"] pub mod my_orders; +#[path = "database/my_orders.rs"] +pub mod my_orders; #[path = "database/my_swaps.rs"] pub mod my_swaps; #[path = "database/stats_nodes.rs"] pub mod stats_nodes; #[path = "database/stats_swaps.rs"] pub mod stats_swaps; use crate::CREATE_MY_SWAPS_TABLE; use common::{log::{debug, error, info}, - mm_ctx::MmArc, - rusqlite::{Result as SqlResult, NO_PARAMS}}; + mm_ctx::MmArc}; +use db_common::sqlite::rusqlite::{Result as SqlResult, NO_PARAMS}; use my_swaps::fill_my_swaps_from_json_statements; use stats_swaps::create_and_fill_stats_swaps_from_json_statements; diff --git a/mm2src/database/database_common.rs b/mm2src/database/database_common.rs deleted file mode 100644 index 703e78c4e9..0000000000 --- a/mm2src/database/database_common.rs +++ /dev/null @@ -1,47 +0,0 @@ -use common::log::debug; -use common::rusqlite::{Connection, Result as SqlResult, ToSql}; -use sql_builder::SqlBuilder; -use std::convert::TryInto; -use uuid::Uuid; - -/// Calculates the offset to skip records by uuid. -/// Expects `query_builder` to have where clauses applied *before* calling this fn. -pub fn offset_by_uuid( - conn: &Connection, - query_builder: &SqlBuilder, - params: &[(&str, String)], - uuid: &Uuid, -) -> SqlResult { - // building following query to determine offset by from_uuid - // select row from ( - // select uuid, ROW_NUMBER() OVER (ORDER BY started_at DESC) AS row - // from my_swaps - // where ... filtering options here ... - // ) where uuid = "from_uuid"; - let subquery = query_builder - .clone() - .field("ROW_NUMBER() OVER (ORDER BY started_at DESC) AS row") - .field("uuid") - .subquery() - .expect("SQL query builder should never fail here"); - - let external_query = SqlBuilder::select_from(subquery) - .field("row") - .and_where("uuid = :uuid") - .sql() - .expect("SQL query builder should never fail here"); - - let mut params_for_offset = params.to_owned(); - params_for_offset.push((":uuid", uuid.to_string())); - let params_as_trait: Vec<_> = params_for_offset - .iter() - .map(|(key, value)| (*key, value as &dyn ToSql)) - .collect(); - debug!( - "Trying to execute SQL query {} with params {:?}", - external_query, params_for_offset - ); - let mut stmt = conn.prepare(&external_query)?; - let offset: isize = stmt.query_row_named(params_as_trait.as_slice(), |row| row.get(0))?; - Ok(offset.try_into().expect("row index should be always above zero")) -} diff --git a/mm2src/database/my_orders.rs b/mm2src/database/my_orders.rs index 15a6c6655b..3e5c62c54f 100644 --- a/mm2src/database/my_orders.rs +++ b/mm2src/database/my_orders.rs @@ -3,14 +3,13 @@ use crate::mm2::lp_ordermatch::{FilteringOrder, MakerOrder, MyOrdersFilter, Rece /// This module contains code to work with my_orders table in MM2 SQLite DB use common::log::debug; use common::mm_ctx::MmArc; -use common::rusqlite::{Connection, Error as SqlError, Result as SqlResult, ToSql}; use common::{now_ms, PagingOptions}; -use sql_builder::SqlBuilder; +use db_common::sqlite::offset_by_uuid; +use db_common::sqlite::rusqlite::{Connection, Error as SqlError, Result as SqlResult, ToSql}; +use db_common::sqlite::sql_builder::SqlBuilder; use std::convert::TryInto; use uuid::Uuid; -use super::database_common::offset_by_uuid; - const MY_ORDERS_TABLE: &str = "my_orders"; pub const CREATE_MY_ORDERS_TABLE: &str = "CREATE TABLE IF NOT EXISTS my_orders ( diff --git a/mm2src/database/my_swaps.rs b/mm2src/database/my_swaps.rs index 9dda3ed51a..608253a082 100644 --- a/mm2src/database/my_swaps.rs +++ b/mm2src/database/my_swaps.rs @@ -2,13 +2,12 @@ use crate::mm2::lp_swap::{MyRecentSwapsUuids, MySwapsFilter, SavedSwap, SavedSwapIo}; use common::log::debug; use common::mm_ctx::MmArc; -use common::rusqlite::{Connection, Error as SqlError, Result as SqlResult, ToSql}; use common::PagingOptions; -use sql_builder::SqlBuilder; +use db_common::sqlite::offset_by_uuid; +use db_common::sqlite::rusqlite::{Connection, Error as SqlError, Result as SqlResult, ToSql}; +use db_common::sqlite::sql_builder::SqlBuilder; use std::convert::TryInto; -use super::database_common::offset_by_uuid; - const MY_SWAPS_TABLE: &str = "my_swaps"; // Using a macro because static variable can't be passed to concat! diff --git a/mm2src/database/stats_nodes.rs b/mm2src/database/stats_nodes.rs index 5240806aea..8f701363b3 100644 --- a/mm2src/database/stats_nodes.rs +++ b/mm2src/database/stats_nodes.rs @@ -2,7 +2,7 @@ use crate::mm2::lp_stats::{NodeInfo, NodeVersionStat}; use common::log::debug; use common::mm_ctx::MmArc; -use common::rusqlite::{Error as SqlError, Result as SqlResult, NO_PARAMS}; +use db_common::sqlite::rusqlite::{Error as SqlError, Result as SqlResult, NO_PARAMS}; use std::collections::hash_map::HashMap; pub const CREATE_NODES_TABLE: &str = "CREATE TABLE IF NOT EXISTS nodes ( diff --git a/mm2src/database/stats_swaps.rs b/mm2src/database/stats_swaps.rs index e35a126ab2..024acc3790 100644 --- a/mm2src/database/stats_swaps.rs +++ b/mm2src/database/stats_swaps.rs @@ -1,7 +1,7 @@ use crate::mm2::lp_swap::{MakerSavedSwap, SavedSwap, SavedSwapIo, TakerSavedSwap}; use common::{log::{debug, error}, - mm_ctx::MmArc, - rusqlite::{Connection, OptionalExtension}}; + mm_ctx::MmArc}; +use db_common::sqlite::rusqlite::{Connection, OptionalExtension}; use std::collections::HashSet; const CREATE_STATS_SWAPS_TABLE: &str = "CREATE TABLE IF NOT EXISTS stats_swaps ( diff --git a/mm2src/db_common/Cargo.toml b/mm2src/db_common/Cargo.toml new file mode 100644 index 0000000000..bd5e18f8c1 --- /dev/null +++ b/mm2src/db_common/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "db_common" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +log = "0.4.8" +uuid = { version = "0.7", features = ["serde", "v4"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +rusqlite = { version = "0.24.2", features = ["bundled"] } +sql-builder = "3.1.1" diff --git a/mm2src/db_common/src/lib.rs b/mm2src/db_common/src/lib.rs new file mode 100644 index 0000000000..4b4ba8a7c0 --- /dev/null +++ b/mm2src/db_common/src/lib.rs @@ -0,0 +1 @@ +#[cfg(not(target_arch = "wasm32"))] pub mod sqlite; diff --git a/mm2src/db_common/src/sqlite.rs b/mm2src/db_common/src/sqlite.rs new file mode 100644 index 0000000000..e1803a841d --- /dev/null +++ b/mm2src/db_common/src/sqlite.rs @@ -0,0 +1,102 @@ +pub use rusqlite; +pub use sql_builder; + +use log::debug; +use rusqlite::{Connection, Error as SqlError, Result as SqlResult, ToSql}; +use sql_builder::SqlBuilder; +use uuid::Uuid; + +pub fn validate_table_name(table_name: &str) -> SqlResult<()> { + // As per https://stackoverflow.com/a/3247553, tables can't be the target of parameter substitution. + // So we have to use a plain concatenation disallowing any characters in the table name that may lead to SQL injection. + if table_name.chars().all(|c| c.is_alphanumeric() || c == '_') { + Ok(()) + } else { + Err(SqlError::InvalidParameterName(table_name.to_string())) + } +} + +/// Calculates the offset to skip records by uuid. +/// Expects `query_builder` to have where clauses applied *before* calling this fn. +pub fn offset_by_uuid( + conn: &Connection, + query_builder: &SqlBuilder, + params: &[(&str, String)], + uuid: &Uuid, +) -> SqlResult { + // building following query to determine offset by from_uuid + // select row from ( + // select uuid, ROW_NUMBER() OVER (ORDER BY started_at DESC) AS row + // from my_swaps + // where ... filtering options here ... + // ) where uuid = "from_uuid"; + let subquery = query_builder + .clone() + .field("ROW_NUMBER() OVER (ORDER BY started_at DESC) AS row") + .field("uuid") + .subquery() + .expect("SQL query builder should never fail here"); + + let external_query = SqlBuilder::select_from(subquery) + .field("row") + .and_where("uuid = :uuid") + .sql() + .expect("SQL query builder should never fail here"); + + let mut params_for_offset = params.to_owned(); + params_for_offset.push((":uuid", uuid.to_string())); + let params_as_trait: Vec<_> = params_for_offset + .iter() + .map(|(key, value)| (*key, value as &dyn ToSql)) + .collect(); + + debug!( + "Trying to execute SQL query {} with params {:?}", + external_query, params_for_offset + ); + + let mut stmt = conn.prepare(&external_query)?; + let offset: isize = stmt.query_row_named(params_as_trait.as_slice(), |row| row.get(0))?; + Ok(offset.try_into().expect("row index should be always above zero")) +} + +/// A more universal offset_by_id query that will replace offset_by_uuid at some point +pub fn offset_by_id

( + conn: &Connection, + query_builder: &SqlBuilder, + params: P, + id_field: &str, + order_by: &str, + where_id: &str, +) -> SqlResult> +where + P: IntoIterator + std::fmt::Debug, + P::Item: ToSql, +{ + let row_number = format!("ROW_NUMBER() OVER (ORDER BY {}) AS row", order_by); + let subquery = query_builder + .clone() + .field(&row_number) + .field(id_field) + .subquery() + .expect("SQL query builder should never fail here"); + + let external_query = SqlBuilder::select_from(subquery) + .field("row") + .and_where(where_id) + .sql() + .expect("SQL query builder should never fail here"); + + debug!( + "Trying to execute SQL query {} with params {:?}", + external_query, params, + ); + + let mut stmt = conn.prepare(&external_query)?; + let maybe_offset = stmt.query_row(params, |row| row.get::<_, isize>(0)); + if let Err(SqlError::QueryReturnedNoRows) = maybe_offset { + return Ok(None); + } + let offset = maybe_offset?; + Ok(Some(offset.try_into().expect("row index should be always above zero"))) +} diff --git a/mm2src/derives/ser_error_derive/src/lib.rs b/mm2src/derives/ser_error_derive/src/lib.rs index 3b79538335..79608cc630 100644 --- a/mm2src/derives/ser_error_derive/src/lib.rs +++ b/mm2src/derives/ser_error_derive/src/lib.rs @@ -64,7 +64,7 @@ fn check_enum_attributes(input: &DeriveInput) -> Result<(), CompileError> { let mut tag = None; let mut content = None; - for meta_item in input.attrs.iter().flat_map(|attr| get_serde_meta_items(attr)) { + for meta_item in input.attrs.iter().flat_map(get_serde_meta_items) { match meta_item { NestedMeta::Meta(NameValue(m)) if m.path.is_ident(TAG_ATTR) => tag = Some(parse_lit_str(TAG_ATTR, m.lit)?), NestedMeta::Meta(NameValue(m)) if m.path.is_ident(CONTENT_ATTR) => { diff --git a/mm2src/docker_tests.rs b/mm2src/docker_tests.rs index cac30d7faa..332151340c 100644 --- a/mm2src/docker_tests.rs +++ b/mm2src/docker_tests.rs @@ -398,12 +398,12 @@ mod docker_tests { #[test] fn test_search_for_swap_tx_spend_native_was_refunded_taker() { let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000.into()); + let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_taker_payment(time_lock, my_public_key, &[0; 20], 1.into(), &None) + .send_taker_payment(time_lock, my_public_key, &[0; 20], 1u64.into(), &None) .wait() .unwrap(); @@ -420,22 +420,28 @@ mod docker_tests { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &[0; 20], &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &[0; 20], + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Refunded(refund_tx), found); } #[test] fn test_search_for_swap_tx_spend_native_was_refunded_maker() { let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000.into()); + let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_maker_payment(time_lock, my_public_key, &[0; 20], 1.into(), &None) + .send_maker_payment(time_lock, my_public_key, &[0; 20], 1u64.into(), &None) .wait() .unwrap(); @@ -452,23 +458,29 @@ mod docker_tests { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &[0; 20], &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &[0; 20], + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Refunded(refund_tx), found); } #[test] fn test_search_for_taker_swap_tx_spend_native_was_spent_by_maker() { let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000.into()); + let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); let secret = [0; 32]; let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_taker_payment(time_lock, my_public_key, &*dhash160(&secret), 1.into(), &None) + .send_taker_payment(time_lock, my_public_key, &*dhash160(&secret), 1u64.into(), &None) .wait() .unwrap(); @@ -485,23 +497,29 @@ mod docker_tests { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &*dhash160(&secret), &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &*dhash160(&secret), + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Spent(spend_tx), found); } #[test] fn test_search_for_maker_swap_tx_spend_native_was_spent_by_taker() { let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000.into()); + let (_ctx, coin, _) = generate_utxo_coin_with_random_privkey("MYCOIN", 1000u64.into()); let secret = [0; 32]; let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_maker_payment(time_lock, my_public_key, &*dhash160(&secret), 1.into(), &None) + .send_maker_payment(time_lock, my_public_key, &*dhash160(&secret), 1u64.into(), &None) .wait() .unwrap(); @@ -518,10 +536,16 @@ mod docker_tests { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &*dhash160(&secret), &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &*dhash160(&secret), + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Spent(spend_tx), found); } diff --git a/mm2src/docker_tests/docker_tests_common.rs b/mm2src/docker_tests/docker_tests_common.rs index 34fb271fde..5e5760a365 100644 --- a/mm2src/docker_tests/docker_tests_common.rs +++ b/mm2src/docker_tests/docker_tests_common.rs @@ -304,7 +304,7 @@ pub fn fill_qrc20_address(coin: &Qrc20Coin, amount: BigDecimal, timeout: u64) { .expect("!transfer_tokens") .txid; - let tx_bytes = client.get_transaction_bytes(hash).wait().unwrap(); + let tx_bytes = client.get_transaction_bytes(&hash).wait().unwrap(); log!({ "{:02x}", tx_bytes }); coin.wait_for_confirmations(&tx_bytes, 1, false, timeout, 1) .wait() @@ -426,7 +426,7 @@ where if let UtxoRpcClientEnum::Native(client) = &coin.as_ref().rpc_client { client.import_address(address, address, false).wait().unwrap(); let hash = client.send_to_address(address, &amount).wait().unwrap(); - let tx_bytes = client.get_transaction_bytes(hash).wait().unwrap(); + let tx_bytes = client.get_transaction_bytes(&hash).wait().unwrap(); coin.wait_for_confirmations(&tx_bytes, 1, false, timeout, 1) .wait() .unwrap(); diff --git a/mm2src/docker_tests/qrc20_tests.rs b/mm2src/docker_tests/qrc20_tests.rs index a2183233bf..8d2708edef 100644 --- a/mm2src/docker_tests/qrc20_tests.rs +++ b/mm2src/docker_tests/qrc20_tests.rs @@ -542,14 +542,14 @@ fn test_search_for_swap_tx_spend_taker_spent() { .wait() .unwrap(); - let actual = maker_coin.search_for_swap_tx_spend_my( + let actual = block_on(maker_coin.search_for_swap_tx_spend_my( timelock, taker_pub, secret_hash, &payment_tx_hex, search_from_block, &maker_coin.swap_contract_address(), - ); + )); let expected = Ok(Some(FoundSwapTxSpend::Spent(spend))); assert_eq!(actual, expected); } @@ -608,14 +608,14 @@ fn test_search_for_swap_tx_spend_maker_refunded() { .wait() .unwrap(); - let actual = maker_coin.search_for_swap_tx_spend_my( + let actual = block_on(maker_coin.search_for_swap_tx_spend_my( timelock, &taker_pub, secret_hash, &payment_tx_hex, search_from_block, &maker_coin.swap_contract_address(), - ); + )); let expected = Ok(Some(FoundSwapTxSpend::Refunded(refund))); assert_eq!(actual, expected); } @@ -654,14 +654,14 @@ fn test_search_for_swap_tx_spend_not_spent() { .wait() .unwrap(); - let actual = maker_coin.search_for_swap_tx_spend_my( + let actual = block_on(maker_coin.search_for_swap_tx_spend_my( timelock, &taker_pub, secret_hash, &payment_tx_hex, search_from_block, &maker_coin.swap_contract_address(), - ); + )); // maker payment hasn't been spent or refunded yet assert_eq!(actual, Ok(None)); } @@ -1314,12 +1314,12 @@ fn test_withdraw_and_send_legacy_to_segwit() { fn test_search_for_segwit_swap_tx_spend_native_was_refunded_maker() { wait_for_estimate_smart_fee(30).expect("!wait_for_estimate_smart_fee"); let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _priv_key) = generate_segwit_qtum_coin_with_random_privkey("QTUM", 1000.into(), Some(0)); + let (_ctx, coin, _priv_key) = generate_segwit_qtum_coin_with_random_privkey("QTUM", 1000u64.into(), Some(0)); let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_maker_payment(time_lock, my_public_key, &[0; 20], 1.into(), &None) + .send_maker_payment(time_lock, my_public_key, &[0; 20], 1u64.into(), &None) .wait() .unwrap(); @@ -1336,10 +1336,16 @@ fn test_search_for_segwit_swap_tx_spend_native_was_refunded_maker() { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &[0; 20], &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &[0; 20], + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Refunded(refund_tx), found); } @@ -1347,12 +1353,12 @@ fn test_search_for_segwit_swap_tx_spend_native_was_refunded_maker() { fn test_search_for_segwit_swap_tx_spend_native_was_refunded_taker() { wait_for_estimate_smart_fee(30).expect("!wait_for_estimate_smart_fee"); let timeout = (now_ms() / 1000) + 120; // timeout if test takes more than 120 seconds to run - let (_ctx, coin, _priv_key) = generate_segwit_qtum_coin_with_random_privkey("QTUM", 1000.into(), Some(0)); + let (_ctx, coin, _priv_key) = generate_segwit_qtum_coin_with_random_privkey("QTUM", 1000u64.into(), Some(0)); let my_public_key = coin.my_public_key().unwrap(); let time_lock = (now_ms() / 1000) as u32 - 3600; let tx = coin - .send_taker_payment(time_lock, my_public_key, &[0; 20], 1.into(), &None) + .send_taker_payment(time_lock, my_public_key, &[0; 20], 1u64.into(), &None) .wait() .unwrap(); @@ -1369,10 +1375,16 @@ fn test_search_for_segwit_swap_tx_spend_native_was_refunded_taker() { .wait() .unwrap(); - let found = coin - .search_for_swap_tx_spend_my(time_lock, my_public_key, &[0; 20], &tx.tx_hex(), 0, &None) - .unwrap() - .unwrap(); + let found = block_on(coin.search_for_swap_tx_spend_my( + time_lock, + &*coin.my_public_key().unwrap(), + &[0; 20], + &tx.tx_hex(), + 0, + &None, + )) + .unwrap() + .unwrap(); assert_eq!(FoundSwapTxSpend::Refunded(refund_tx), found); } diff --git a/mm2src/docker_tests/slp_tests.rs b/mm2src/docker_tests/slp_tests.rs index 14c41b0e96..bfb505641f 100644 --- a/mm2src/docker_tests/slp_tests.rs +++ b/mm2src/docker_tests/slp_tests.rs @@ -1,6 +1,6 @@ use crate::docker_tests::docker_tests_common::*; use bigdecimal::BigDecimal; -use common::for_tests::{enable_bch_with_tokens, enable_slp}; +use common::for_tests::{enable_bch_with_tokens, enable_slp, UtxoRpcMode}; use serde_json::{self as json}; use std::time::Duration; @@ -85,7 +85,14 @@ fn test_bch_and_slp_balance_enable_slp_v2() { fn test_bch_and_slp_balance_enable_bch_with_tokens_v2() { let mm = slp_supplied_node(); - let enable_bch_with_tokens = block_on(enable_bch_with_tokens(&mm, "FORSLP", &["ADEXSLP"])); + let tx_history = false; + let enable_bch_with_tokens = block_on(enable_bch_with_tokens( + &mm, + "FORSLP", + &["ADEXSLP"], + UtxoRpcMode::Native, + tx_history, + )); let enable_bch_with_tokens: RpcV2Response = json::from_value(enable_bch_with_tokens).unwrap(); diff --git a/mm2src/gossipsub/src/config.rs b/mm2src/gossipsub/src/config.rs index cafd0c1ce1..f74343e21d 100644 --- a/mm2src/gossipsub/src/config.rs +++ b/mm2src/gossipsub/src/config.rs @@ -124,18 +124,11 @@ impl Default for GossipsubConfig { } } +#[derive(Default)] pub struct GossipsubConfigBuilder { config: GossipsubConfig, } -impl Default for GossipsubConfigBuilder { - fn default() -> GossipsubConfigBuilder { - GossipsubConfigBuilder { - config: GossipsubConfig::default(), - } - } -} - impl GossipsubConfigBuilder { // set default values pub fn new() -> GossipsubConfigBuilder { GossipsubConfigBuilder::default() } diff --git a/mm2src/lp_native_dex.rs b/mm2src/lp_native_dex.rs index 14743a16b2..f1503b8ac6 100644 --- a/mm2src/lp_native_dex.rs +++ b/mm2src/lp_native_dex.rs @@ -48,7 +48,7 @@ use crate::mm2::{MM_DATETIME, MM_VERSION}; cfg_native! { use common::ip_addr::myipaddr; - use common::rusqlite::Error as SqlError; + use db_common::sqlite::rusqlite::Error as SqlError; } #[path = "lp_init/init_context.rs"] mod init_context; diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 7e4ace2487..9bc098210e 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -38,6 +38,7 @@ use crate::mm2::{lp_ordermatch, lp_stats, lp_swap}; pub type P2PRequestResult = Result>; #[derive(Debug, Display)] +#[allow(clippy::enum_variant_names)] pub enum P2PRequestError { EncodeError(String), DecodeError(String), diff --git a/mm2src/lp_ordermatch.rs b/mm2src/lp_ordermatch.rs index 40423f3442..4ecd6be028 100644 --- a/mm2src/lp_ordermatch.rs +++ b/mm2src/lp_ordermatch.rs @@ -188,7 +188,7 @@ fn process_pubkey_full_trie( .trie_roots .get(alb_pair) .copied() - .unwrap_or_else(H64::default); + .unwrap_or_default(); new_root } @@ -212,11 +212,7 @@ fn process_trie_delta( } let new_root = match orderbook.pubkeys_state.get(pubkey) { - Some(pubkey_state) => pubkey_state - .trie_roots - .get(alb_pair) - .copied() - .unwrap_or_else(H64::default), + Some(pubkey_state) => pubkey_state.trie_roots.get(alb_pair).copied().unwrap_or_default(), None => H64::default(), }; new_root @@ -3047,11 +3043,11 @@ async fn process_maker_reserved(ctx: MmArc, from_pubkey: H256Json, reserved_msg: }; // our base and rel coins should match maker's side tickers for a proper is_coin_protocol_supported check - let (base_coin, rel_coin) = - match find_pair(&ctx, &my_order.maker_coin_ticker(), &my_order.taker_coin_ticker()).await { - Ok(Some(c)) => c, - _ => return, // attempt to match with deactivated coin - }; + let (base_coin, rel_coin) = match find_pair(&ctx, my_order.maker_coin_ticker(), my_order.taker_coin_ticker()).await + { + Ok(Some(c)) => c, + _ => return, // attempt to match with deactivated coin + }; let mut pending_map = ordermatch_ctx.pending_maker_reserved.lock().await; if let Some(mut reserved_messages) = pending_map.remove(&uuid) { reserved_messages.sort_unstable_by_key(|r| r.price()); @@ -3270,12 +3266,15 @@ pub struct AutoBuyInput { volume: MmNumber, timeout: Option, /// Not used. Deprecated. + #[allow(dead_code)] duration: Option, // TODO: remove this field on API refactoring, method should be separated from params method: String, + #[allow(dead_code)] gui: Option, #[serde(rename = "destpubkey")] #[serde(default)] + #[allow(dead_code)] dest_pub_key: H256Json, #[serde(default)] match_by: MatchBy, @@ -3469,7 +3468,7 @@ pub async fn lp_auto_buy( subscribe_to_orderbook_topic( ctx, order.base_orderbook_ticker(), - &order.rel_orderbook_ticker(), + order.rel_orderbook_ticker(), request_orderbook ) .await @@ -4070,9 +4069,9 @@ pub async fn create_maker_order(ctx: &MmArc, req: SetPriceReq) -> Result { @@ -301,7 +301,9 @@ impl EventListener for ArcTradingBotContext { #[derive(Default, Clone, Debug)] pub struct RateInfos { + #[allow(dead_code)] base: String, + #[allow(dead_code)] rel: String, base_price: MmNumber, rel_price: MmNumber, diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index ae296ec6e7..6a32bc09d8 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -365,8 +365,7 @@ pub fn get_locked_amount(ctx: &MmArc, coin: &str) -> MmNumber { swap_lock .iter() .filter_map(|swap| swap.upgrade()) - .map(|swap| swap.locked_amount()) - .flatten() + .flat_map(|swap| swap.locked_amount()) .fold(MmNumber::from(0), |mut total_amount, locked| { if locked.coin == coin { total_amount += locked.amount; @@ -399,8 +398,7 @@ fn get_locked_amount_by_other_swaps(ctx: &MmArc, except_uuid: &Uuid, coin: &str) .iter() .filter_map(|swap| swap.upgrade()) .filter(|swap| swap.uuid() != except_uuid) - .map(|swap| swap.locked_amount()) - .flatten() + .flat_map(|swap| swap.locked_amount()) .fold(MmNumber::from(0), |mut total_amount, locked| { if locked.coin == coin { total_amount += locked.amount; diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index ae1b616b4c..616d69c07e 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -19,7 +19,6 @@ use common::log::{error, warn}; use common::mm_error::prelude::*; use common::{bits256, executor::Timer, mm_ctx::MmArc, mm_number::MmNumber, now_ms, DEX_FEE_ADDR_RAW_PUBKEY}; use futures::{compat::Future01CompatExt, select, FutureExt}; -use futures01::Future; use parking_lot::Mutex as PaMutex; use primitives::hash::H264; use rand::Rng; @@ -932,8 +931,8 @@ impl MakerSwap { Ok((swap, command)) } - pub fn recover_funds(&self) -> Result { - fn try_spend_taker_payment(selfi: &MakerSwap, secret_hash: &[u8]) -> Result { + pub async fn recover_funds(&self) -> Result { + async fn try_spend_taker_payment(selfi: &MakerSwap, secret_hash: &[u8]) -> Result { let taker_payment_hex = &selfi .r() .taker_payment @@ -941,17 +940,29 @@ impl MakerSwap { .ok_or(ERRL!("No info about taker payment, swap is not recoverable"))? .tx_hex; + // have to do this because std::sync::RwLockReadGuard returned by r() is not Send, + // so it can't be used across await let timelock = selfi.taker_payment_lock.load(Ordering::Relaxed) as u32; - let other_pub = &*selfi.r().other_persistent_pub; + let other_pub = selfi.r().other_persistent_pub; + + let taker_coin_start_block = selfi.r().data.taker_coin_start_block; + let taker_coin_swap_contract_address = selfi.r().data.taker_coin_swap_contract_address.clone(); + + let secret = selfi.r().data.secret.0; + // check if the taker payment is not spent yet - match selfi.taker_coin.search_for_swap_tx_spend_other( - timelock, - other_pub, - secret_hash, - taker_payment_hex, - selfi.r().data.taker_coin_start_block, - &selfi.r().data.taker_coin_swap_contract_address, - ) { + match selfi + .taker_coin + .search_for_swap_tx_spend_other( + timelock, + other_pub.as_slice(), + secret_hash, + taker_payment_hex, + taker_coin_start_block, + &taker_coin_swap_contract_address, + ) + .await + { Ok(Some(FoundSwapTxSpend::Spent(tx))) => { return ERR!( "Taker payment was already spent by {} tx {:02x}", @@ -975,11 +986,12 @@ impl MakerSwap { .send_maker_spends_taker_payment( taker_payment_hex, timelock, - other_pub, - &selfi.r().data.secret.0, - &selfi.r().data.taker_coin_swap_contract_address, + other_pub.as_slice(), + &secret, + &taker_coin_swap_contract_address, ) - .wait() + .compat() + .await .map_err(|e| ERRL!("{}", e)) } @@ -1002,19 +1014,29 @@ impl MakerSwap { .clone() .unwrap_or_else(|| dhash160(&self.r().data.secret.0).into()); - let maker_payment = match &self.r().maker_payment { + // have to do this because std::sync::RwLockReadGuard returned by r() is not Send, + // so it can't be used across await + let maker_payment_lock = self.r().data.maker_payment_lock as u32; + let other_persistent_pub = self.r().other_persistent_pub; + let maker_coin_start_block = self.r().data.maker_coin_start_block; + let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); + + let maybe_maker_payment = self.r().maker_payment.clone(); + let maker_payment = match maybe_maker_payment { Some(tx) => tx.tx_hex.0.clone(), None => { - let maybe_maker_payment = try_s!(self - .maker_coin - .check_if_my_payment_sent( - self.r().data.maker_payment_lock as u32, - &*self.r().other_persistent_pub, - &secret_hash.0, - self.r().data.maker_coin_start_block, - &self.r().data.maker_coin_swap_contract_address, - ) - .wait()); + let maybe_maker_payment = try_s!( + self.maker_coin + .check_if_my_payment_sent( + maker_payment_lock, + other_persistent_pub.as_slice(), + &secret_hash.0, + maker_coin_start_block, + &maker_coin_swap_contract_address, + ) + .compat() + .await + ); match maybe_maker_payment { Some(tx) => tx.tx_hex(), None => return ERR!("Maker payment transaction was not found"), @@ -1022,17 +1044,21 @@ impl MakerSwap { }, }; // validate that maker payment is not spent - match self.maker_coin.search_for_swap_tx_spend_my( - self.r().data.maker_payment_lock as u32, - &*self.r().other_persistent_pub, - &secret_hash.0, - &maker_payment, - self.r().data.maker_coin_start_block, - &self.r().data.maker_coin_swap_contract_address, - ) { + match self + .maker_coin + .search_for_swap_tx_spend_my( + maker_payment_lock, + other_persistent_pub.as_slice(), + &secret_hash.0, + &maker_payment, + maker_coin_start_block, + &maker_coin_swap_contract_address, + ) + .await + { Ok(Some(FoundSwapTxSpend::Spent(_))) => { log!("Warning: MakerPayment spent, but TakerPayment is not yet. Trying to spend TakerPayment"); - let transaction = try_s!(try_spend_taker_payment(self, &secret_hash.0)); + let transaction = try_s!(try_spend_taker_payment(self, &secret_hash.0).await); Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.taker_coin.ticker().to_string(), @@ -1054,16 +1080,18 @@ impl MakerSwap { self.r().data.maker_payment_lock + 3700 ); } - let transaction = try_s!(self - .maker_coin - .send_maker_refunds_payment( - &maker_payment, - self.r().data.maker_payment_lock as u32, - &*self.r().other_persistent_pub, - &secret_hash.0, - &self.r().data.maker_coin_swap_contract_address, - ) - .wait()); + let transaction = try_s!( + self.maker_coin + .send_maker_refunds_payment( + &maker_payment, + maker_payment_lock, + other_persistent_pub.as_slice(), + &secret_hash.0, + &maker_coin_swap_contract_address, + ) + .compat() + .await + ); Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, @@ -1781,11 +1809,12 @@ pub async fn calc_max_maker_vol( Ok(vol) } -#[cfg(test)] +#[cfg(all(test, not(target_arch = "wasm32")))] mod maker_swap_tests { use super::*; use coins::eth::{addr_from_str, signed_eth_tx_from_bytes, SignedEthTx}; use coins::{MarketCoinOps, MmCoin, SwapOps, TestCoin}; + use common::block_on; use common::mm_ctx::MmCtxBuilder; use common::privkey::key_pair_from_seed; use mocktopus::mocking::*; @@ -1833,11 +1862,12 @@ mod maker_swap_tests { unsafe { MAKER_REFUND_CALLED = true }; MockResult::Return(Box::new(futures01::future::ok(eth_tx_for_test().into()))) }); - TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_my + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - let actual = maker_swap.recover_funds().unwrap(); + let actual = block_on(maker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: "ticker".to_string(), @@ -1867,11 +1897,12 @@ mod maker_swap_tests { MockResult::Return(Box::new(futures01::future::ok(eth_tx_for_test().into()))) }); - TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_my + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - let actual = maker_swap.recover_funds().unwrap(); + let actual = block_on(maker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: "ticker".to_string(), @@ -1895,12 +1926,14 @@ mod maker_swap_tests { TestCoin::swap_contract_address.mock_safe(|_| MockResult::Return(None)); TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { - MockResult::Return(Ok(Some(FoundSwapTxSpend::Refunded(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Refunded( + eth_tx_for_test().into(), + )))))) }); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - assert!(maker_swap.recover_funds().is_err()); + assert!(block_on(maker_swap.recover_funds()).is_err()); } #[test] @@ -1919,18 +1952,22 @@ mod maker_swap_tests { static mut SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED: bool = true; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent( + eth_tx_for_test().into(), + )))))) }); static mut SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED: bool = true; TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Refunded(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Refunded( + eth_tx_for_test().into(), + )))))) }); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - let err = maker_swap.recover_funds().expect_err("Expected an error"); + let err = block_on(maker_swap.recover_funds()).expect_err("Expected an error"); log!("Error: "(err)); assert!(err.contains("Taker payment was already refunded")); assert!(unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED }); @@ -1956,12 +1993,13 @@ mod maker_swap_tests { unsafe { MY_PAYMENT_SENT_CALLED = true }; MockResult::Return(Box::new(futures01::future::ok(Some(eth_tx_for_test().into())))) }); - TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_my + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); maker_swap.w().data.maker_payment_lock = (now_ms() / 1000) - 3690; - assert!(maker_swap.recover_funds().is_err()); + assert!(block_on(maker_swap.recover_funds()).is_err()); assert!(unsafe { MY_PAYMENT_SENT_CALLED }); } @@ -1987,7 +2025,7 @@ mod maker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - assert!(maker_swap.recover_funds().is_err()); + assert!(block_on(maker_swap.recover_funds()).is_err()); assert!(unsafe { MY_PAYMENT_SENT_CALLED }); } @@ -2006,7 +2044,7 @@ mod maker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - assert!(maker_swap.recover_funds().is_err()); + assert!(block_on(maker_swap.recover_funds()).is_err()); } #[test] @@ -2025,19 +2063,23 @@ mod maker_swap_tests { static mut SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED: bool = true; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent( + eth_tx_for_test().into(), + )))))) }); static mut SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED: bool = true; TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent( + eth_tx_for_test().into(), + )))))) }); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - let err = maker_swap.recover_funds().expect_err("Expected an error"); + let err = block_on(maker_swap.recover_funds()).expect_err("Expected an error"); log!("Error: "(err)); assert!(err.contains("Taker payment was already spent")); assert!(unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED }); @@ -2059,7 +2101,7 @@ mod maker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - assert!(maker_swap.recover_funds().is_err()); + assert!(block_on(maker_swap.recover_funds()).is_err()); } #[test] @@ -2080,13 +2122,15 @@ mod maker_swap_tests { static mut SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent( + eth_tx_for_test().into(), + )))))) }); static mut SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED = true } - MockResult::Return(Ok(None)) + MockResult::Return(Box::pin(futures::future::ready(Ok(None)))) }); static mut SEND_MAKER_SPENDS_TAKER_PAYMENT_CALLED: bool = false; @@ -2103,7 +2147,7 @@ mod maker_swap_tests { action: RecoveredSwapAction::SpentOtherPayment, transaction: eth_tx_for_test().into(), }); - assert_eq!(maker_swap.recover_funds(), expected); + assert_eq!(block_on(maker_swap.recover_funds()), expected); assert!(unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED }); assert!(unsafe { SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED }); assert!(unsafe { SEND_MAKER_SPENDS_TAKER_PAYMENT_CALLED }); @@ -2124,13 +2168,15 @@ mod maker_swap_tests { static mut SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED = true } - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(eth_tx_for_test().into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent( + eth_tx_for_test().into(), + )))))) }); static mut SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED = true } - MockResult::Return(Ok(None)) + MockResult::Return(Box::pin(futures::future::ready(Ok(None)))) }); static mut SEND_MAKER_REFUNDS_PAYMENT_CALLED: bool = false; @@ -2142,7 +2188,7 @@ mod maker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (maker_swap, _) = MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, maker_saved_swap).unwrap(); - let err = maker_swap.recover_funds().unwrap_err(); + let err = block_on(maker_swap.recover_funds()).unwrap_err(); assert!(err.contains("Taker payment spend transaction has been sent and confirmed")); assert!(unsafe { !SEARCH_FOR_SWAP_TX_SPEND_MY_CALLED }); assert!(unsafe { !SEARCH_FOR_SWAP_TX_SPEND_OTHER_CALLED }); diff --git a/mm2src/lp_swap/my_swaps_storage.rs b/mm2src/lp_swap/my_swaps_storage.rs index d8a8f42248..14f08bb1ca 100644 --- a/mm2src/lp_swap/my_swaps_storage.rs +++ b/mm2src/lp_swap/my_swaps_storage.rs @@ -44,7 +44,7 @@ impl MySwapsStorage { mod native_impl { use super::*; use crate::mm2::database::my_swaps::{insert_new_swap, select_uuids_by_my_swaps_filter, SelectRecentSwapsUuidsErr}; - use common::rusqlite::Error as SqlError; + use db_common::sqlite::rusqlite::Error as SqlError; impl From for MySwapsError { fn from(e: SelectRecentSwapsUuidsErr) -> Self { diff --git a/mm2src/lp_swap/recreate_swap_data.rs b/mm2src/lp_swap/recreate_swap_data.rs index d1f2a95d5c..058d33563e 100644 --- a/mm2src/lp_swap/recreate_swap_data.rs +++ b/mm2src/lp_swap/recreate_swap_data.rs @@ -46,6 +46,7 @@ impl RecreateSwapError { /// The input swap can be either tagged by `type` or not. #[derive(Deserialize)] #[serde(untagged)] +#[allow(clippy::enum_variant_names)] pub enum InputSwap { SavedSwap(SavedSwap), MakerSavedSwap(MakerSavedSwap), diff --git a/mm2src/lp_swap/saved_swap.rs b/mm2src/lp_swap/saved_swap.rs index eff6cad0b9..809d508279 100644 --- a/mm2src/lp_swap/saved_swap.rs +++ b/mm2src/lp_swap/saved_swap.rs @@ -100,11 +100,11 @@ impl SavedSwap { match self { SavedSwap::Maker(saved) => { let (maker_swap, _) = try_s!(MakerSwap::load_from_saved(ctx, maker_coin, taker_coin, saved)); - Ok(try_s!(maker_swap.recover_funds())) + Ok(try_s!(maker_swap.recover_funds().await)) }, SavedSwap::Taker(saved) => { let (taker_swap, _) = try_s!(TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, saved)); - Ok(try_s!(taker_swap.recover_funds())) + Ok(try_s!(taker_swap.recover_funds().await)) }, } } diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 359953723c..181db7131f 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -20,7 +20,6 @@ use common::mm_error::prelude::*; use common::mm_number::MmNumber; use common::{bits256, now_ms, DEX_FEE_ADDR_RAW_PUBKEY}; use futures::{compat::Future01CompatExt, select, FutureExt}; -use futures01::Future; use http::Response; use parking_lot::Mutex as PaMutex; use primitives::hash::H264; @@ -1314,7 +1313,7 @@ impl TakerSwap { Ok((swap, command)) } - pub fn recover_funds(&self) -> Result { + pub async fn recover_funds(&self) -> Result { if self.finished_at.load(Ordering::Relaxed) == 0 { return ERR!("Swap must be finished before recover funds attempt"); } @@ -1332,17 +1331,32 @@ impl TakerSwap { None => return ERR!("No info about maker payment, swap is not recoverable"), }; + // have to do this because std::sync::RwLockReadGuard returned by r() is not Send, + // so it can't be used across await + let other_persistent_pub = self.r().other_persistent_pub; + let secret_hash = self.r().secret_hash.0; + let maker_coin_start_block = self.r().data.maker_coin_start_block; + let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); + + let taker_payment_lock = self.r().data.taker_payment_lock; + let taker_coin_start_block = self.r().data.taker_coin_start_block; + let taker_coin_swap_contract_address = self.r().data.taker_coin_swap_contract_address.clone(); + macro_rules! check_maker_payment_is_not_spent { // validate that maker payment is not spent () => { - match self.maker_coin.search_for_swap_tx_spend_other( - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - &*self.r().other_persistent_pub, - &self.r().secret_hash.0, - &maker_payment, - self.r().data.maker_coin_start_block, - &self.r().data.maker_coin_swap_contract_address, - ) { + match self + .maker_coin + .search_for_swap_tx_spend_other( + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_persistent_pub.as_slice(), + &secret_hash, + &maker_payment, + maker_coin_start_block, + &maker_coin_swap_contract_address, + ) + .await + { Ok(Some(FoundSwapTxSpend::Spent(tx))) => { return ERR!( "Maker payment was already spent by {} tx {:02x}", @@ -1363,19 +1377,22 @@ impl TakerSwap { }; } - let taker_payment = match &self.r().taker_payment { + let maybe_taker_payment = self.r().taker_payment.clone(); + let taker_payment = match maybe_taker_payment { Some(tx) => tx.tx_hex.0.clone(), None => { - let maybe_sent = try_s!(self - .taker_coin - .check_if_my_payment_sent( - self.r().data.taker_payment_lock as u32, - &*self.r().other_persistent_pub, - &self.r().secret_hash.0, - self.r().data.taker_coin_start_block, - &self.r().data.taker_coin_swap_contract_address, - ) - .wait()); + let maybe_sent = try_s!( + self.taker_coin + .check_if_my_payment_sent( + taker_payment_lock as u32, + other_persistent_pub.as_slice(), + &secret_hash, + taker_coin_start_block, + &taker_coin_swap_contract_address, + ) + .compat() + .await + ); match maybe_sent { Some(tx) => tx.tx_hex(), None => return ERR!("Taker payment is not found, swap is not recoverable"), @@ -1385,16 +1402,24 @@ impl TakerSwap { if self.r().taker_payment_spend.is_some() { check_maker_payment_is_not_spent!(); - let transaction = try_s!(self - .maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - &*self.r().other_persistent_pub, - &self.r().secret.0, - &self.r().data.maker_coin_swap_contract_address, - ) - .wait()); + // has to do this because std::sync::RwLockReadGuard returned by r() is not Send, + // so it can't be used across await + let other_persistent_pub = self.r().other_persistent_pub; + let secret = self.r().secret.0; + let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); + + let transaction = try_s!( + self.maker_coin + .send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_persistent_pub.as_slice(), + &secret, + &maker_coin_swap_contract_address, + ) + .compat() + .await + ); return Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, @@ -1403,30 +1428,36 @@ impl TakerSwap { }); } - let taker_payment_spend = try_s!(self.taker_coin.search_for_swap_tx_spend_my( - self.r().data.taker_payment_lock as u32, - &*self.r().other_persistent_pub, - &self.r().secret_hash.0, - &taker_payment, - self.r().data.taker_coin_start_block, - &self.r().data.taker_coin_swap_contract_address, - )); + let taker_payment_spend = try_s!( + self.taker_coin + .search_for_swap_tx_spend_my( + taker_payment_lock as u32, + other_persistent_pub.as_slice(), + &secret_hash, + &taker_payment, + taker_coin_start_block, + &taker_coin_swap_contract_address, + ) + .await + ); match taker_payment_spend { Some(spend) => match spend { FoundSwapTxSpend::Spent(tx) => { check_maker_payment_is_not_spent!(); let secret = try_s!(self.taker_coin.extract_secret(&self.r().secret_hash.0, &tx.tx_hex())); - let transaction = try_s!(self - .maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - &*self.r().other_persistent_pub, - &secret, - &self.r().data.maker_coin_swap_contract_address, - ) - .wait()); + let transaction = try_s!( + self.maker_coin + .send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_persistent_pub.as_slice(), + &secret, + &maker_coin_swap_contract_address, + ) + .compat() + .await + ); Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, @@ -1447,16 +1478,18 @@ impl TakerSwap { ); } - let transaction = try_s!(self - .taker_coin - .send_taker_refunds_payment( - &taker_payment, - self.r().data.taker_payment_lock as u32, - &*self.r().other_persistent_pub, - &self.r().secret_hash.0, - &self.r().data.taker_coin_swap_contract_address, - ) - .wait()); + let transaction = try_s!( + self.taker_coin + .send_taker_refunds_payment( + &taker_payment, + taker_payment_lock as u32, + other_persistent_pub.as_slice(), + &secret_hash, + &taker_coin_swap_contract_address, + ) + .compat() + .await + ); Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, @@ -1839,7 +1872,7 @@ pub fn maker_payment_wait(swap_started_at: u64, payment_locktime: u64) -> u64 { swap_started_at + (payment_locktime * 2) / 5 } -#[cfg(test)] +#[cfg(all(test, not(target_arch = "wasm32")))] mod taker_swap_tests { use super::*; use crate::mm2::lp_swap::{dex_fee_amount, get_locked_amount_by_other_swaps}; @@ -1847,8 +1880,8 @@ mod taker_swap_tests { use coins::utxo::UtxoTx; use coins::{FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TestCoin}; use common::mm_ctx::MmCtxBuilder; - use common::new_uuid; use common::privkey::key_pair_from_seed; + use common::{block_on, new_uuid}; use mocktopus::mocking::*; fn eth_tx_for_test() -> SignedEthTx { @@ -1885,11 +1918,12 @@ mod taker_swap_tests { unsafe { MAKER_PAYMENT_SPEND_CALLED = true }; MockResult::Return(Box::new(futures01::future::ok(eth_tx_for_test().into()))) }); - TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_other + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - let actual = taker_swap.recover_funds().unwrap(); + let actual = block_on(taker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: "ticker".to_string(), @@ -1920,7 +1954,7 @@ mod taker_swap_tests { static mut TX_SPEND_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { TX_SPEND_CALLED = true }; - MockResult::Return(Ok(None)) + MockResult::Return(Box::pin(futures::future::ready(Ok(None)))) }); static mut TAKER_PAYMENT_REFUND_CALLED: bool = false; @@ -1931,7 +1965,7 @@ mod taker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - let actual = taker_swap.recover_funds().unwrap(); + let actual = block_on(taker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: "ticker".to_string(), @@ -1966,10 +2000,11 @@ mod taker_swap_tests { TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_TX_SPEND_CALLED = true }; let tx: UtxoTx = "0100000001de7aa8d29524906b2b54ee2e0281f3607f75662cbc9080df81d1047b78e21dbc00000000d7473044022079b6c50820040b1fbbe9251ced32ab334d33830f6f8d0bf0a40c7f1336b67d5b0220142ccf723ddabb34e542ed65c395abc1fbf5b6c3e730396f15d25c49b668a1a401209da937e5609680cb30bff4a7661364ca1d1851c2506fa80c443f00a3d3bf7365004c6b6304f62b0e5cb175210270e75970bb20029b3879ec76c4acd320a8d0589e003636264d01a7d566504bfbac6782012088a9142fb610d856c19fd57f2d0cffe8dff689074b3d8a882103f368228456c940ac113e53dad5c104cf209f2f102a409207269383b6ab9b03deac68ffffffff01d0dc9800000000001976a9146d9d2b554d768232320587df75c4338ecc8bf37d88ac40280e5c".into(); - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(tx.into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent(tx.into())))))) }); - TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_other + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); static mut MAKER_PAYMENT_SPEND_CALLED: bool = false; TestCoin::send_taker_spends_maker_payment.mock_safe(|_, _, _, _, _, _| { @@ -1979,7 +2014,7 @@ mod taker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - let actual = taker_swap.recover_funds().unwrap(); + let actual = block_on(taker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: "ticker".to_string(), @@ -2006,7 +2041,7 @@ mod taker_swap_tests { static mut SEARCH_TX_SPEND_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_TX_SPEND_CALLED = true }; - MockResult::Return(Ok(None)) + MockResult::Return(Box::pin(futures::future::ready(Ok(None)))) }); static mut REFUND_CALLED: bool = false; @@ -2017,7 +2052,7 @@ mod taker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - let actual = taker_swap.recover_funds().unwrap(); + let actual = block_on(taker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: "ticker".to_string(), @@ -2043,13 +2078,13 @@ mod taker_swap_tests { static mut SEARCH_TX_SPEND_CALLED: bool = false; TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_TX_SPEND_CALLED = true }; - MockResult::Return(Ok(None)) + MockResult::Return(Box::pin(futures::future::ready(Ok(None)))) }); let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); taker_swap.w().data.taker_payment_lock = (now_ms() / 1000) - 3690; - assert!(taker_swap.recover_funds().is_err()); + assert!(block_on(taker_swap.recover_funds()).is_err()); assert!(unsafe { SEARCH_TX_SPEND_CALLED }); } @@ -2070,10 +2105,11 @@ mod taker_swap_tests { TestCoin::search_for_swap_tx_spend_my.mock_safe(|_, _, _, _, _, _, _| { unsafe { SEARCH_TX_SPEND_CALLED = true }; let tx: UtxoTx = "0100000001de7aa8d29524906b2b54ee2e0281f3607f75662cbc9080df81d1047b78e21dbc00000000d7473044022079b6c50820040b1fbbe9251ced32ab334d33830f6f8d0bf0a40c7f1336b67d5b0220142ccf723ddabb34e542ed65c395abc1fbf5b6c3e730396f15d25c49b668a1a401209da937e5609680cb30bff4a7661364ca1d1851c2506fa80c443f00a3d3bf7365004c6b6304f62b0e5cb175210270e75970bb20029b3879ec76c4acd320a8d0589e003636264d01a7d566504bfbac6782012088a9142fb610d856c19fd57f2d0cffe8dff689074b3d8a882103f368228456c940ac113e53dad5c104cf209f2f102a409207269383b6ab9b03deac68ffffffff01d0dc9800000000001976a9146d9d2b554d768232320587df75c4338ecc8bf37d88ac40280e5c".into(); - MockResult::Return(Ok(Some(FoundSwapTxSpend::Spent(tx.into())))) + MockResult::Return(Box::pin(futures::future::ready(Ok(Some(FoundSwapTxSpend::Spent(tx.into())))))) }); - TestCoin::search_for_swap_tx_spend_other.mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Ok(None))); + TestCoin::search_for_swap_tx_spend_other + .mock_safe(|_, _, _, _, _, _, _| MockResult::Return(Box::pin(futures::future::ready(Ok(None))))); static mut MAKER_PAYMENT_SPEND_CALLED: bool = false; TestCoin::send_taker_spends_maker_payment.mock_safe(|_, _, _, _, _, _| { @@ -2083,7 +2119,7 @@ mod taker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - let actual = taker_swap.recover_funds().unwrap(); + let actual = block_on(taker_swap.recover_funds()).unwrap(); let expected = RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: "ticker".to_string(), @@ -2109,7 +2145,7 @@ mod taker_swap_tests { let maker_coin = MmCoinEnum::Test(TestCoin::default()); let taker_coin = MmCoinEnum::Test(TestCoin::default()); let (taker_swap, _) = TakerSwap::load_from_saved(ctx, maker_coin, taker_coin, taker_saved_swap).unwrap(); - assert!(taker_swap.recover_funds().is_err()); + assert!(block_on(taker_swap.recover_funds()).is_err()); } #[test] diff --git a/mm2src/mm2.rs b/mm2src/mm2.rs index 0868404daa..1fd338582a 100644 --- a/mm2src/mm2.rs +++ b/mm2src/mm2.rs @@ -22,10 +22,11 @@ #![cfg_attr(target_arch = "wasm32", allow(dead_code))] #![cfg_attr(target_arch = "wasm32", allow(unused_imports))] +#[cfg(not(target_arch = "wasm32"))] use common::block_on; use common::crash_reports::init_crash_reports; +use common::double_panic_crash; use common::log::LogLevel; use common::mm_ctx::MmCtxBuilder; -use common::{block_on, double_panic_crash}; use derive_more::Display; use gstuff::slurp; diff --git a/mm2src/mm2_bitcoin/crypto/src/lib.rs b/mm2src/mm2_bitcoin/crypto/src/lib.rs index 4b29c47c6b..085500f281 100644 --- a/mm2src/mm2_bitcoin/crypto/src/lib.rs +++ b/mm2src/mm2_bitcoin/crypto/src/lib.rs @@ -20,7 +20,7 @@ use std::hash::Hasher; /// GRS uses double groestl512 /// SMART uses keccak #[allow(clippy::upper_case_acronyms)] -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum ChecksumType { DSHA256, DGROESTL512, diff --git a/mm2src/mm2_bitcoin/keys/src/address.rs b/mm2src/mm2_bitcoin/keys/src/address.rs index e28a4807f7..1b37b0f568 100644 --- a/mm2src/mm2_bitcoin/keys/src/address.rs +++ b/mm2src/mm2_bitcoin/keys/src/address.rs @@ -39,7 +39,7 @@ pub enum Type { P2WSH, } -#[derive(Clone, Debug, Display, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, Display, Deserialize, Eq, Hash, PartialEq, Serialize)] #[serde(tag = "format")] pub enum AddressFormat { /// Standard UTXO address format. @@ -78,7 +78,7 @@ impl AddressFormat { // TODO add ScriptType field to this struct for easier use of output_script function /// `AddressHash` with prefix and t addr zcash prefix -#[derive(Debug, PartialEq, Clone)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Address { /// The prefix of the address. pub prefix: u8, @@ -188,7 +188,17 @@ impl fmt::Display for Address { .to_string() .fmt(f) }, - _ => self.layout().to_base58().fmt(f), + AddressFormat::CashAddress { + network, + pub_addr_prefix, + p2sh_addr_prefix, + } => { + let cash_address = self + .to_cashaddress(network, *pub_addr_prefix, *p2sh_addr_prefix) + .expect("A valid address"); + cash_address.encode().expect("A valid address").fmt(f) + }, + AddressFormat::Standard => self.layout().to_base58().fmt(f), } } } diff --git a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs index 9f7c3d750d..80dcdab0f8 100644 --- a/mm2src/mm2_bitcoin/keys/src/cashaddress.rs +++ b/mm2src/mm2_bitcoin/keys/src/cashaddress.rs @@ -4,7 +4,7 @@ use std::str::FromStr; const DEFAULT_PREFIX: NetworkPrefix = NetworkPrefix::BitcoinCash; #[allow(clippy::upper_case_acronyms)] -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum AddressType { /// Pay to PubKey Hash /// https://bitcoin.org/en/glossary/p2pkh-address @@ -14,7 +14,7 @@ pub enum AddressType { P2SH, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum NetworkPrefix { BitcoinCash, BchTest, @@ -73,7 +73,7 @@ impl NetworkPrefix { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct CashAddress { pub prefix: NetworkPrefix, pub hash: Vec, diff --git a/mm2src/mm2_bitcoin/keys/src/lib.rs b/mm2src/mm2_bitcoin/keys/src/lib.rs index bac45a2609..9970790089 100644 --- a/mm2src/mm2_bitcoin/keys/src/lib.rs +++ b/mm2src/mm2_bitcoin/keys/src/lib.rs @@ -45,7 +45,7 @@ pub type Secret = H256; /// 32 bytes long signable message pub type Message = H256; -#[derive(Debug, PartialEq, Clone)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum AddressHashEnum { /// 20 bytes long hash derived from public `ripemd160(sha256(public))` used in P2PKH, P2SH, P2WPKH AddressHash(H160), diff --git a/mm2src/mm2_libp2p/src/peers_exchange.rs b/mm2src/mm2_libp2p/src/peers_exchange.rs index 94501fb87e..465bfdab98 100644 --- a/mm2src/mm2_libp2p/src/peers_exchange.rs +++ b/mm2src/mm2_libp2p/src/peers_exchange.rs @@ -132,7 +132,7 @@ impl PeersExchange { fn forget_peer_addresses(&mut self, peer: &PeerId) { for address in self.request_response.addresses_of_peer(peer) { - if !self.is_reserved_peer(&peer) { + if !self.is_reserved_peer(peer) { self.request_response.remove_address(peer, &address); } } @@ -163,14 +163,14 @@ impl PeersExchange { } } - if !self.reserved_peers.contains(&peer) && !addresses.is_empty() { + if !self.reserved_peers.contains(peer) && !addresses.is_empty() { self.reserved_peers.push(*peer); } let already_reserved = self.request_response.addresses_of_peer(peer); for address in addresses { if !already_reserved.contains(&address) { - self.request_response.add_address(&peer, address); + self.request_response.add_address(peer, address); } } } diff --git a/mm2src/mm2_libp2p/src/relay_address.rs b/mm2src/mm2_libp2p/src/relay_address.rs index 03c0ea1ff0..c1e6b6225a 100644 --- a/mm2src/mm2_libp2p/src/relay_address.rs +++ b/mm2src/mm2_libp2p/src/relay_address.rs @@ -90,8 +90,8 @@ impl RelayAddress { }; match self { - RelayAddress::IPv4(ipv4) => Ok(ipv4_multiaddr(&ipv4, network_ports)), - RelayAddress::Dns(dns) => Ok(dns_multiaddr(&dns, network_ports)), + RelayAddress::IPv4(ipv4) => Ok(ipv4_multiaddr(ipv4, network_ports)), + RelayAddress::Dns(dns) => Ok(dns_multiaddr(dns, network_ports)), RelayAddress::Memory(_) => Err(RelayAddressError::memory_addr_on_distributed_network(self)), } } diff --git a/mm2src/mm2_tests.rs b/mm2src/mm2_tests.rs index fdd50f860a..2ddf8ae92c 100644 --- a/mm2src/mm2_tests.rs +++ b/mm2src/mm2_tests.rs @@ -1,6 +1,5 @@ use super::{lp_main, LpMainParams}; use bigdecimal::BigDecimal; -use common::block_on; use common::executor::Timer; use common::for_tests::{check_my_swap_status, check_recent_swaps, check_stats_swap_status, enable_lightning, enable_native as enable_native_impl, enable_qrc20, find_metrics_in_json, from_env_file, @@ -22,6 +21,7 @@ use std::time::Duration; use uuid::Uuid; cfg_native! { + use common::block_on; use common::for_tests::{get_passphrase, new_mm2_temp_folder_path}; use common::fs::slurp; use hyper::header::ACCESS_CONTROL_ALLOW_ORIGIN; @@ -33,6 +33,25 @@ cfg_wasm32! { wasm_bindgen_test_configure!(run_in_browser); } +#[cfg(not(target_arch = "wasm32"))] +macro_rules! local_start { + ($who: expr) => { + match var("LOCAL_THREAD_MM") { + Ok(ref e) if e == $who => Some(local_start()), + _ => None, + } + }; +} + +#[cfg(target_arch = "wasm32")] +macro_rules! local_start { + ($who: expr) => { + Some(local_start()) + }; +} + +#[path = "mm2_tests/bch_and_slp_tests.rs"] mod bch_and_slp_tests; + #[path = "mm2_tests/electrums.rs"] pub mod electrums; use electrums::*; @@ -41,6 +60,7 @@ use electrums::*; mod lp_bot_tests; #[path = "mm2_tests/structs.rs"] pub mod structs; + use structs::*; // TODO: Consider and/or try moving the integration tests into separate Rust files. @@ -147,6 +167,7 @@ fn test_rpc() { /// This is not a separate test but a helper used by `MarketMakerIt` to run the MarketMaker from the test binary. #[test] +#[cfg(not(target_arch = "wasm32"))] fn test_mm_start() { if let Ok(conf) = var("_MM2_TEST_CONF") { log!("test_mm_start] Starting the MarketMaker..."); @@ -220,23 +241,6 @@ fn local_start() -> LocalStart { local_start_impl } #[cfg(target_arch = "wasm32")] fn local_start() -> LocalStart { wasm_start_impl } -#[cfg(not(target_arch = "wasm32"))] -macro_rules! local_start { - ($who: expr) => { - match var("LOCAL_THREAD_MM") { - Ok(ref e) if e == $who => Some(local_start()), - _ => None, - } - }; -} - -#[cfg(target_arch = "wasm32")] -macro_rules! local_start { - ($who: expr) => { - Some(local_start()) - }; -} - /// https://github.com/artemii235/SuperNET/issues/241 #[test] #[cfg(not(target_arch = "wasm32"))] @@ -681,6 +685,7 @@ fn test_p2wpkh_my_balance() { assert_eq!(my_address, "tb1qssfmay8nnghx7ynlznejnjxn6m4pemz9v7fsxy"); } +#[cfg(not(target_arch = "wasm32"))] fn check_set_price_fails(mm: &MarketMakerIt, base: &str, rel: &str) { let rc = block_on(mm.rpc(json! ({ "userpass": mm.userpass, @@ -698,6 +703,7 @@ fn check_set_price_fails(mm: &MarketMakerIt, base: &str, rel: &str) { ); } +#[cfg(not(target_arch = "wasm32"))] fn check_buy_fails(mm: &MarketMakerIt, base: &str, rel: &str, vol: f64) { let rc = block_on(mm.rpc(json! ({ "userpass": mm.userpass, @@ -711,6 +717,7 @@ fn check_buy_fails(mm: &MarketMakerIt, base: &str, rel: &str, vol: f64) { assert!(rc.0.is_server_error(), "!buy success but should be error: {}", rc.1); } +#[cfg(not(target_arch = "wasm32"))] fn check_sell_fails(mm: &MarketMakerIt, base: &str, rel: &str, vol: f64) { let rc = block_on(mm.rpc(json! ({ "userpass": mm.userpass, @@ -2884,6 +2891,7 @@ fn orderbook_should_display_base_rel_volumes() { assert_eq!(&min_volume * &price, orderbook.bids[0].base_min_volume_rat); } +#[cfg(not(target_arch = "wasm32"))] fn check_priv_key(mm: &MarketMakerIt, coin: &str, expected_priv_key: &str) { let rc = block_on(mm.rpc(json! ({ "userpass": mm.userpass, @@ -3042,6 +3050,7 @@ fn test_electrum_and_enable_response() { assert_eq!(eth_response.get("mature_confirmations"), None); } +#[cfg(not(target_arch = "wasm32"))] fn check_too_low_volume_order_creation_fails(mm: &MarketMakerIt, base: &str, rel: &str) { let rc = block_on(mm.rpc(json! ({ "userpass": mm.userpass, @@ -3813,6 +3822,7 @@ fn test_batch_requests() { assert!(responses[2]["error"].as_str().unwrap().contains("Userpass is invalid!")); } +#[cfg(not(target_arch = "wasm32"))] fn request_metrics(mm: &MarketMakerIt) -> MetricsJson { let (status, metrics, _headers) = block_on(mm.rpc(json!({ "method": "metrics"}))).unwrap(); assert_eq!(status, StatusCode::OK, "RPC «metrics» failed with status «{}»", status); @@ -3968,387 +3978,6 @@ fn spin_n_nodes(seednodes: &[&str], coins: &Json, n: usize) -> Vec<(MarketMakerI mm_nodes } -#[test] -#[cfg(not(target_arch = "wasm32"))] -fn test_withdraw_cashaddresses() { - let coins = json!([ - {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"fork_id": "0x40","protocol":{"type":"UTXO"}, - "address_format":{"format":"cashaddress","network":"bchtest"}}, - ]); - - let mm = MarketMakerIt::start( - json! ({ - "gui": "nogui", - "netid": 9998, - "myipaddr": env::var ("BOB_TRADE_IP") .ok(), - "rpcip": env::var ("BOB_TRADE_IP") .ok(), - "passphrase": "face pin lock number add byte put seek mime test note password sin tab multiple", - "coins": coins, - "i_am_seed": true, - "rpc_password": "pass", - }), - "pass".into(), - local_start!("bob"), - ) - .unwrap(); - let (_dump_log, _dump_dashboard) = mm.mm_dump(); - log!({ "log path: {}", mm.log_path.display() }); - - let electrum = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "electrum", - "coin": "BCH", - "servers": [ - {"url":"electroncash.de:50003"}, - {"url":"tbch.loping.net:60001"}, - {"url":"blackie.c3-soft.com:60001"}, - {"url":"bch0.kister.net:51001"}, - {"url":"testnet.imaginary.cash:50001"} - ], - "mm2": 1, - }))) - .unwrap(); - - assert_eq!( - electrum.0, - StatusCode::OK, - "RPC «electrum» failed with {} {}", - electrum.0, - electrum.1 - ); - let electrum: Json = json::from_str(&electrum.1).unwrap(); - log!([electrum]); - - // make withdraw from cashaddress to cashaddress - let withdraw = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "withdraw", - "coin": "BCH", - "to": "bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597", - "amount": 0.00001, - }))) - .unwrap(); - - assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); - let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); - log!((withdraw_json)); - - // check "from" addresses - let from: Vec<&str> = withdraw_json["from"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(from, vec!["bchtest:qqgp9xh3435xamv7ghct8emer2s2erzj8gx3gnhwkq"]); - - // check "to" addresses - let to: Vec<&str> = withdraw_json["to"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(to, vec!["bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597"]); - - // send the transaction - let send_tx = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "send_raw_transaction", - "coin": "BCH", - "tx_hex": withdraw_json["tx_hex"], - }))) - .unwrap(); - assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); - log!((send_tx.1)); - - // Wait 5 seconds to avoid double spending - thread::sleep(Duration::from_secs(5)); - - // make withdraw from cashaddress to legacy - let withdraw = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "withdraw", - "coin": "BCH", - "to": "1WxswvLF2HdaDr4k77e92VjaXuPQA8Uji", - "amount": 0.00001, - }))) - .unwrap(); - - assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); - let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); - log!((withdraw_json)); - - // check "from" addresses - let from: Vec<&str> = withdraw_json["from"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(from, vec!["bchtest:qqgp9xh3435xamv7ghct8emer2s2erzj8gx3gnhwkq"]); - - // check "to" addresses - let to: Vec<&str> = withdraw_json["to"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(to, vec!["1WxswvLF2HdaDr4k77e92VjaXuPQA8Uji"]); - - // send the transaction - let send_tx = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "send_raw_transaction", - "coin": "BCH", - "tx_hex": withdraw_json["tx_hex"], - }))) - .unwrap(); - assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); - log!((send_tx.1)); - - // Wait 5 seconds to avoid double spending - thread::sleep(Duration::from_secs(5)); - - //Disable BCH to enable in Legacy Mode - let rc = block_on(mm.rpc(json!({ - "userpass": mm.userpass, - "method": "disable_coin", - "coin": "BCH", - }))) - .unwrap(); - assert_eq!(rc.0, StatusCode::OK, "RPC «disable_coin» failed with status «{}»", rc.0); - - let electrum = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "electrum", - "coin": "BCH", - "servers": [ - {"url":"electroncash.de:50003"}, - {"url":"tbch.loping.net:60001"}, - {"url":"blackie.c3-soft.com:60001"}, - {"url":"bch0.kister.net:51001"}, - {"url":"testnet.imaginary.cash:50001"} - ], - "address_format":{"format":"standard"}, - "mm2": 1, - }))) - .unwrap(); - - assert_eq!( - electrum.0, - StatusCode::OK, - "RPC «electrum» failed with {} {}", - electrum.0, - electrum.1 - ); - let electrum: Json = json::from_str(&electrum.1).unwrap(); - log!([electrum]); - - // make withdraw from Legacy to Cashaddress - let withdraw = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "withdraw", - "coin": "BCH", - "to": "bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597", - "amount": 0.00001, - }))) - .unwrap(); - - assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); - let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); - log!((withdraw_json)); - - // check "from" addresses - let from: Vec<&str> = withdraw_json["from"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(from, vec!["12Tz6nWqA7e5tV7m6d1EzMkNs6MQVW4UMw"]); - - // check "to" addresses - let to: Vec<&str> = withdraw_json["to"] - .as_array() - .unwrap() - .iter() - .map(|v| v.as_str().unwrap()) - .collect(); - assert_eq!(to, vec!["bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597"]); - - // send the transaction - let send_tx = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "send_raw_transaction", - "coin": "BCH", - "tx_hex": withdraw_json["tx_hex"], - }))) - .unwrap(); - assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); - log!((send_tx.1)); -} - -#[test] -#[cfg(not(target_arch = "wasm32"))] -fn test_withdraw_to_different_cashaddress_network_should_fail() { - let coins = json!([ - {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"fork_id": "0x40","protocol":{"type":"UTXO"}, - "address_format":{"format":"cashaddress","network":"bchtest"}}, - ]); - - let mm = MarketMakerIt::start( - json! ({ - "gui": "nogui", - "netid": 9998, - "myipaddr": env::var ("BOB_TRADE_IP") .ok(), - "rpcip": env::var ("BOB_TRADE_IP") .ok(), - "passphrase": "face pin lock number add byte put seek mime test note password sin tab multiple", - "coins": coins, - "i_am_seed": true, - "rpc_password": "pass", - }), - "pass".into(), - local_start!("bob"), - ) - .unwrap(); - let (_dump_log, _dump_dashboard) = mm.mm_dump(); - log!({ "log path: {}", mm.log_path.display() }); - - let electrum = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "electrum", - "coin": "BCH", - "servers": [ - {"url":"electroncash.de:50003"}, - {"url":"tbch.loping.net:60001"}, - {"url":"blackie.c3-soft.com:60001"}, - {"url":"bch0.kister.net:51001"}, - {"url":"testnet.imaginary.cash:50001"} - ], - "mm2": 1, - }))) - .unwrap(); - - assert_eq!( - electrum.0, - StatusCode::OK, - "RPC «electrum» failed with {} {}", - electrum.0, - electrum.1 - ); - let electrum: Json = json::from_str(&electrum.1).unwrap(); - log!([electrum]); - - // make withdraw to from bchtest to bitcoincash should fail - let withdraw = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "withdraw", - "coin": "BCH", - "to": "bitcoincash:qqyf96yqdrpa8f6pkf9f00ap068m5tgvly28qsfq9p", - "amount": 0.00001, - }))) - .unwrap(); - - assert!(withdraw.0.is_server_error(), "BCH withdraw: {}", withdraw.1); - log!([withdraw.1]); - - block_on(mm.stop()).unwrap(); -} - -#[test] -#[cfg(not(target_arch = "wasm32"))] -fn test_common_cashaddresses() { - let coins = json!([ - {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"protocol":{"type":"UTXO"}, - "address_format":{"format":"cashaddress","network":"bchtest"}}, - ]); - - let mm = MarketMakerIt::start( - json! ({ - "gui": "nogui", - "netid": 9998, - "myipaddr": env::var ("BOB_TRADE_IP") .ok(), - "rpcip": env::var ("BOB_TRADE_IP") .ok(), - "passphrase": "face pin block number add byte put seek mime test note password sin tab multiple", - "coins": coins, - "i_am_seed": true, - "rpc_password": "pass", - }), - "pass".into(), - local_start!("bob"), - ) - .unwrap(); - let (_dump_log, _dump_dashboard) = mm.mm_dump(); - log!({ "log path: {}", mm.log_path.display() }); - - // Enable BCH electrum client with tx_history loop. - // Enable RICK electrum client with tx_history loop. - let electrum = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "electrum", - "coin": "BCH", - "servers": [ - {"url":"electroncash.de:50003"}, - {"url":"tbch.loping.net:60001"}, - {"url":"blackie.c3-soft.com:60001"}, - {"url":"bch0.kister.net:51001"}, - {"url":"testnet.imaginary.cash:50001"} - ], - "mm2": 1, - }))) - .unwrap(); - - assert_eq!( - electrum.0, - StatusCode::OK, - "RPC «electrum» failed with {} {}", - electrum.0, - electrum.1 - ); - let electrum: Json = json::from_str(&electrum.1).unwrap(); - log!([electrum]); - - assert_eq!( - electrum["address"].as_str().unwrap(), - "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la" - ); - - // check my_balance - let rc = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "my_balance", - "coin": "BCH", - }))) - .unwrap(); - assert_eq!(rc.0, StatusCode::OK, "RPC «my_balance» failed with status «{}»", rc.0); - let json: Json = json::from_str(&rc.1).unwrap(); - let my_balance_address = json["address"].as_str().unwrap(); - assert_eq!(my_balance_address, "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la"); - - // check get_enabled_coins - let rc = block_on(mm.rpc(json! ({ - "userpass": mm.userpass, - "method": "get_enabled_coins", - }))) - .unwrap(); - assert_eq!( - rc.0, - StatusCode::OK, - "RPC «get_enabled_coins» failed with status «{}»", - rc.0 - ); - let json: Json = json::from_str(&rc.1).unwrap(); - - let obj = &json["result"].as_array().unwrap()[0]; - assert_eq!(obj["ticker"].as_str().unwrap(), "BCH"); - assert_eq!( - obj["address"].as_str().unwrap(), - "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la" - ); -} - #[test] #[cfg(not(target_arch = "wasm32"))] fn test_convert_utxo_address() { @@ -8335,6 +7964,7 @@ fn alice_can_see_the_active_order_after_orderbook_sync_segwit() { block_on(mm_alice.stop()).unwrap(); } +#[cfg(not(target_arch = "wasm32"))] fn request_and_check_orderbook_depth(mm_alice: &MarketMakerIt) { let rc = block_on(mm_alice.rpc(json! ({ "userpass": mm_alice.userpass, diff --git a/mm2src/mm2_tests/bch_and_slp_tests.rs b/mm2src/mm2_tests/bch_and_slp_tests.rs new file mode 100644 index 0000000000..0ea9c893a5 --- /dev/null +++ b/mm2src/mm2_tests/bch_and_slp_tests.rs @@ -0,0 +1,466 @@ +use super::*; +use common::for_tests::{enable_bch_with_tokens, enable_slp, my_tx_history_v2, UtxoRpcMode}; + +const T_BCH_ELECTRUMS: &[&str] = &[ + "electroncash.de:50003", + "tbch.loping.net:60001", + "blackie.c3-soft.com:60001", + "bch0.kister.net:51001", + "testnet.imaginary.cash:50001", +]; + +fn t_bch_electrums_legacy_json() -> Vec { T_BCH_ELECTRUMS.into_iter().map(|url| json!({ "url": url })).collect() } + +#[test] +#[cfg(not(target_arch = "wasm32"))] +fn test_withdraw_cashaddresses() { + let coins = json!([ + {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"fork_id": "0x40","protocol":{"type":"UTXO"}, + "address_format":{"format":"cashaddress","network":"bchtest"}}, + ]); + + let mm = MarketMakerIt::start( + json! ({ + "gui": "nogui", + "netid": 9998, + "myipaddr": env::var ("BOB_TRADE_IP") .ok(), + "rpcip": env::var ("BOB_TRADE_IP") .ok(), + "passphrase": "face pin lock number add byte put seek mime test note password sin tab multiple", + "coins": coins, + "i_am_seed": true, + "rpc_password": "pass", + }), + "pass".into(), + local_start!("bob"), + ) + .unwrap(); + let (_dump_log, _dump_dashboard) = mm.mm_dump(); + log!({ "log path: {}", mm.log_path.display() }); + + let electrum = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "electrum", + "coin": "BCH", + "servers": t_bch_electrums_legacy_json(), + "mm2": 1, + }))) + .unwrap(); + + assert_eq!( + electrum.0, + StatusCode::OK, + "RPC «electrum» failed with {} {}", + electrum.0, + electrum.1 + ); + let electrum: Json = json::from_str(&electrum.1).unwrap(); + log!([electrum]); + + // make withdraw from cashaddress to cashaddress + let withdraw = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "withdraw", + "coin": "BCH", + "to": "bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597", + "amount": 0.00001, + }))) + .unwrap(); + + assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); + let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); + log!((withdraw_json)); + + // check "from" addresses + let from: Vec<&str> = withdraw_json["from"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(from, vec!["bchtest:qqgp9xh3435xamv7ghct8emer2s2erzj8gx3gnhwkq"]); + + // check "to" addresses + let to: Vec<&str> = withdraw_json["to"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(to, vec!["bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597"]); + + // send the transaction + let send_tx = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "send_raw_transaction", + "coin": "BCH", + "tx_hex": withdraw_json["tx_hex"], + }))) + .unwrap(); + assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); + log!((send_tx.1)); + + // Wait 5 seconds to avoid double spending + thread::sleep(Duration::from_secs(5)); + + // make withdraw from cashaddress to legacy + let withdraw = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "withdraw", + "coin": "BCH", + "to": "1WxswvLF2HdaDr4k77e92VjaXuPQA8Uji", + "amount": 0.00001, + }))) + .unwrap(); + + assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); + let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); + log!((withdraw_json)); + + // check "from" addresses + let from: Vec<&str> = withdraw_json["from"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(from, vec!["bchtest:qqgp9xh3435xamv7ghct8emer2s2erzj8gx3gnhwkq"]); + + // check "to" addresses + let to: Vec<&str> = withdraw_json["to"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(to, vec!["1WxswvLF2HdaDr4k77e92VjaXuPQA8Uji"]); + + // send the transaction + let send_tx = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "send_raw_transaction", + "coin": "BCH", + "tx_hex": withdraw_json["tx_hex"], + }))) + .unwrap(); + assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); + log!((send_tx.1)); + + // Wait 5 seconds to avoid double spending + thread::sleep(Duration::from_secs(5)); + + //Disable BCH to enable in Legacy Mode + let rc = block_on(mm.rpc(json!({ + "userpass": mm.userpass, + "method": "disable_coin", + "coin": "BCH", + }))) + .unwrap(); + assert_eq!(rc.0, StatusCode::OK, "RPC «disable_coin» failed with status «{}»", rc.0); + + let electrum = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "electrum", + "coin": "BCH", + "servers": t_bch_electrums_legacy_json(), + "address_format":{"format":"standard"}, + "mm2": 1, + }))) + .unwrap(); + + assert_eq!( + electrum.0, + StatusCode::OK, + "RPC «electrum» failed with {} {}", + electrum.0, + electrum.1 + ); + let electrum: Json = json::from_str(&electrum.1).unwrap(); + log!([electrum]); + + // make withdraw from Legacy to Cashaddress + let withdraw = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "withdraw", + "coin": "BCH", + "to": "bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597", + "amount": 0.00001, + }))) + .unwrap(); + + assert!(withdraw.0.is_success(), "BCH withdraw: {}", withdraw.1); + let withdraw_json: Json = json::from_str(&withdraw.1).unwrap(); + log!((withdraw_json)); + + // check "from" addresses + let from: Vec<&str> = withdraw_json["from"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(from, vec!["12Tz6nWqA7e5tV7m6d1EzMkNs6MQVW4UMw"]); + + // check "to" addresses + let to: Vec<&str> = withdraw_json["to"] + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap()) + .collect(); + assert_eq!(to, vec!["bchtest:qr39na5d25wdeecgw3euh9fkd4ygvd4pnsury96597"]); + + // send the transaction + let send_tx = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "send_raw_transaction", + "coin": "BCH", + "tx_hex": withdraw_json["tx_hex"], + }))) + .unwrap(); + assert!(send_tx.0.is_success(), "BCH send_raw_transaction: {}", send_tx.1); + log!((send_tx.1)); +} + +#[test] +#[cfg(not(target_arch = "wasm32"))] +fn test_withdraw_to_different_cashaddress_network_should_fail() { + let coins = json!([ + {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"fork_id": "0x40","protocol":{"type":"UTXO"}, + "address_format":{"format":"cashaddress","network":"bchtest"}}, + ]); + + let mm = MarketMakerIt::start( + json! ({ + "gui": "nogui", + "netid": 9998, + "myipaddr": env::var ("BOB_TRADE_IP") .ok(), + "rpcip": env::var ("BOB_TRADE_IP") .ok(), + "passphrase": "face pin lock number add byte put seek mime test note password sin tab multiple", + "coins": coins, + "i_am_seed": true, + "rpc_password": "pass", + }), + "pass".into(), + local_start!("bob"), + ) + .unwrap(); + let (_dump_log, _dump_dashboard) = mm.mm_dump(); + log!({ "log path: {}", mm.log_path.display() }); + + let electrum = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "electrum", + "coin": "BCH", + "servers": t_bch_electrums_legacy_json(), + "mm2": 1, + }))) + .unwrap(); + + assert_eq!( + electrum.0, + StatusCode::OK, + "RPC «electrum» failed with {} {}", + electrum.0, + electrum.1 + ); + let electrum: Json = json::from_str(&electrum.1).unwrap(); + log!([electrum]); + + // make withdraw to from bchtest to bitcoincash should fail + let withdraw = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "withdraw", + "coin": "BCH", + "to": "bitcoincash:qqyf96yqdrpa8f6pkf9f00ap068m5tgvly28qsfq9p", + "amount": 0.00001, + }))) + .unwrap(); + + assert!(withdraw.0.is_server_error(), "BCH withdraw: {}", withdraw.1); + log!([withdraw.1]); + + block_on(mm.stop()).unwrap(); +} + +#[test] +#[cfg(not(target_arch = "wasm32"))] +fn test_common_cashaddresses() { + let coins = json!([ + {"coin":"BCH","pubtype":0,"p2shtype":5,"mm2":1,"protocol":{"type":"UTXO"}, + "address_format":{"format":"cashaddress","network":"bchtest"}}, + ]); + + let mm = MarketMakerIt::start( + json! ({ + "gui": "nogui", + "netid": 9998, + "myipaddr": env::var ("BOB_TRADE_IP") .ok(), + "rpcip": env::var ("BOB_TRADE_IP") .ok(), + "passphrase": "face pin block number add byte put seek mime test note password sin tab multiple", + "coins": coins, + "i_am_seed": true, + "rpc_password": "pass", + }), + "pass".into(), + local_start!("bob"), + ) + .unwrap(); + let (_dump_log, _dump_dashboard) = mm.mm_dump(); + log!({ "log path: {}", mm.log_path.display() }); + + // Enable BCH electrum client with tx_history loop. + // Enable RICK electrum client with tx_history loop. + let electrum = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "electrum", + "coin": "BCH", + "servers": t_bch_electrums_legacy_json(), + "mm2": 1, + }))) + .unwrap(); + + assert_eq!( + electrum.0, + StatusCode::OK, + "RPC «electrum» failed with {} {}", + electrum.0, + electrum.1 + ); + let electrum: Json = json::from_str(&electrum.1).unwrap(); + log!([electrum]); + + assert_eq!( + electrum["address"].as_str().unwrap(), + "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la" + ); + + // check my_balance + let rc = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "my_balance", + "coin": "BCH", + }))) + .unwrap(); + assert_eq!(rc.0, StatusCode::OK, "RPC «my_balance» failed with status «{}»", rc.0); + let json: Json = json::from_str(&rc.1).unwrap(); + let my_balance_address = json["address"].as_str().unwrap(); + assert_eq!(my_balance_address, "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la"); + + // check get_enabled_coins + let rc = block_on(mm.rpc(json! ({ + "userpass": mm.userpass, + "method": "get_enabled_coins", + }))) + .unwrap(); + assert_eq!( + rc.0, + StatusCode::OK, + "RPC «get_enabled_coins» failed with status «{}»", + rc.0 + ); + let json: Json = json::from_str(&rc.1).unwrap(); + + let obj = &json["result"].as_array().unwrap()[0]; + assert_eq!(obj["ticker"].as_str().unwrap(), "BCH"); + assert_eq!( + obj["address"].as_str().unwrap(), + "bchtest:qze8g4gx3z428jjcxzpycpxl7ke7d947gca2a7n2la" + ); +} + +async fn wait_till_history_has_records( + mm: &MarketMakerIt, + expected_len: usize, + for_coin: &str, + paging: Option>, +) -> MyTxHistoryV2Response { + loop { + let history_json = my_tx_history_v2(mm, for_coin, expected_len, paging.clone()).await; + let history: MyTxHistoryV2Response = json::from_value(history_json["result"].clone()).unwrap(); + if history.transactions.len() >= expected_len { + break history; + } + Timer::sleep(1.).await; + } +} + +#[test] +#[cfg(not(target_arch = "wasm32"))] +fn test_bch_and_slp_testnet_history() { + let coins = json!([ + {"coin":"tBCH","pubtype":0,"p2shtype":5,"mm2":1,"protocol":{"type":"BCH","protocol_data":{"slp_prefix":"slptest"}}, + "address_format":{"format":"cashaddress","network":"bchtest"}}, + {"coin":"USDF","protocol":{"type":"SLPTOKEN","protocol_data":{"decimals":4,"token_id":"bb309e48930671582bea508f9a1d9b491e49b69be3d6f372dc08da2ac6e90eb7","platform":"tBCH","required_confirmations":1}}} + ]); + + let mm = MarketMakerIt::start( + json! ({ + "gui": "nogui", + "netid": 9998, + "myipaddr": env::var ("BOB_TRADE_IP") .ok(), + "rpcip": env::var ("BOB_TRADE_IP") .ok(), + "passphrase": "BCH SLP test", + "coins": coins, + "i_am_seed": true, + "rpc_password": "pass", + }), + "pass".into(), + local_start!("bob"), + ) + .unwrap(); + let (_dump_log, _dump_dashboard) = mm.mm_dump(); + log!({ "log path: {}", mm.log_path.display() }); + + let rpc_mode = UtxoRpcMode::electrum(T_BCH_ELECTRUMS); + let tx_history = true; + let enable_bch = block_on(enable_bch_with_tokens(&mm, "tBCH", &[], rpc_mode, tx_history)); + log!({ "enable_bch: {:?}", enable_bch }); + let history = block_on(wait_till_history_has_records(&mm, 4, "tBCH", None)); + log!({ "bch history: {:?}", history }); + + let expected_internal_ids = vec![ + "6686ee013620d31ba645b27d581fed85437ce00f46b595a576718afac4dd5b69", + "c07836722bbdfa2404d8fe0ea56700d02e2012cb9dc100ccaf1138f334a759ce", + "091877294268b2b1734255067146f15c3ac5e6199e72cd4f68a8d9dec32bb0c0", + "d76723c092b64bc598d5d2ceafd6f0db37dce4032db569d6f26afb35491789a7", + ]; + + let actual_ids: Vec<_> = history + .transactions + .iter() + .map(|tx| tx.tx.internal_id.as_str()) + .collect(); + + assert_eq!(expected_internal_ids, actual_ids); + + let enable_usdf = block_on(enable_slp(&mm, "USDF")); + log!({ "enable_usdf: {:?}", enable_usdf }); + + let paging = + common::PagingOptionsEnum::FromId("433b641bc89e1b59c22717918583c60ec98421805c8e85b064691705d9aeb970".into()); + let slp_history = block_on(wait_till_history_has_records(&mm, 4, "USDF", Some(paging))); + + log!({ "slp history: {:?}", slp_history }); + + let expected_slp_ids = vec![ + "cd6ec10b0cd9747ddc66ac5c97c2d7b493e8cea191bc2d847b3498719d4bd989", + "1c1e68357cf5a6dacb53881f13aa5d2048fe0d0fab24b76c9ec48f53884bed97", + "c4304b5ef4f1b88ed4939534a8ca9eca79f592939233174ae08002e8454e3f06", + "b0035434a1e7be5af2ed991ee2a21a90b271c5852a684a0b7d315c5a770d1b1c", + ]; + + let actual_slp_ids: Vec<_> = slp_history + .transactions + .iter() + .map(|tx| tx.tx.internal_id.as_str()) + .collect(); + + assert_eq!(expected_slp_ids, actual_slp_ids); + + for tx in slp_history.transactions { + assert_eq!("USDF", tx.tx.coin); + + let fee_details: UtxoFeeDetails = json::from_value(tx.tx.fee_details).unwrap(); + assert_eq!(fee_details.coin, Some("tBCH".to_owned())); + } +} diff --git a/mm2src/mm2_tests/structs.rs b/mm2src/mm2_tests/structs.rs index 9b291fcaa4..4469918d36 100644 --- a/mm2src/mm2_tests/structs.rs +++ b/mm2src/mm2_tests/structs.rs @@ -9,6 +9,7 @@ use num_rational::BigRational; use rpc::v1::types::H256 as H256Json; use serde_json::Value as Json; use std::collections::{HashMap, HashSet}; +use std::num::NonZeroUsize; use uuid::Uuid; #[derive(Debug, Deserialize)] @@ -517,6 +518,7 @@ pub enum TransactionType { StakingDelegation, RemoveDelegation, StandardTransfer, + TokenTransfer(String), } #[derive(Debug, Deserialize)] @@ -662,3 +664,39 @@ pub struct EnableBchWithTokensResponse { pub bch_addresses_infos: HashMap>, pub slp_addresses_infos: HashMap>, } + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct HistoryTransactionDetails { + #[serde(flatten)] + pub tx: TransactionDetails, + pub confirmations: u64, +} + +#[derive(Clone, Debug, Deserialize)] +pub enum PagingOptionsEnum { + FromId(String), + PageNumber(NonZeroUsize), +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MyTxHistoryV2Response { + pub coin: String, + pub current_block: u64, + pub transactions: Vec, + pub sync_status: Json, + pub limit: usize, + pub skipped: usize, + pub total: usize, + pub total_pages: usize, + pub paging_options: PagingOptionsEnum, +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct UtxoFeeDetails { + pub r#type: String, + pub coin: Option, + pub amount: BigDecimal, +} diff --git a/mm2src/ordermatch_tests.rs b/mm2src/ordermatch_tests.rs index dc6f803b7a..809169e055 100644 --- a/mm2src/ordermatch_tests.rs +++ b/mm2src/ordermatch_tests.rs @@ -2,11 +2,11 @@ use super::*; use crate::mm2::lp_network::P2PContext; use crate::mm2::lp_ordermatch::new_protocol::{MakerOrderUpdated, PubkeyKeepAlive}; use coins::{MmCoin, TestCoin}; -use common::rusqlite::Connection; use common::{block_on, executor::spawn, mm_ctx::{MmArc, MmCtx, MmCtxBuilder}, privkey::key_pair_from_seed}; +use db_common::sqlite::rusqlite::Connection; use futures::{channel::mpsc, lock::Mutex as AsyncMutex, StreamExt}; use mm2_libp2p::atomicdex_behaviour::AdexBehaviourCmd; use mm2_libp2p::{decode_message, PeerId}; @@ -1019,7 +1019,7 @@ fn test_cancel_by_single_coin() { let rx = prepare_for_cancel_by(&ctx); let connection = Connection::open_in_memory().unwrap(); - let _ = ctx.sqlite_connection.pin(Mutex::new(connection)); + let _ = ctx.sqlite_connection.pin(Arc::new(Mutex::new(connection))); delete_my_maker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); delete_my_taker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); @@ -1040,7 +1040,7 @@ fn test_cancel_by_pair() { let rx = prepare_for_cancel_by(&ctx); let connection = Connection::open_in_memory().unwrap(); - let _ = ctx.sqlite_connection.pin(Mutex::new(connection)); + let _ = ctx.sqlite_connection.pin(Arc::new(Mutex::new(connection))); delete_my_maker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); delete_my_taker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); @@ -1065,7 +1065,7 @@ fn test_cancel_by_all() { let rx = prepare_for_cancel_by(&ctx); let connection = Connection::open_in_memory().unwrap(); - let _ = ctx.sqlite_connection.pin(Mutex::new(connection)); + let _ = ctx.sqlite_connection.pin(Arc::new(Mutex::new(connection))); delete_my_maker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); delete_my_taker_order.mock_safe(|_, _, _| MockResult::Return(Box::new(futures01::future::ok(())))); diff --git a/mm2src/rpc/dispatcher/dispatcher.rs b/mm2src/rpc/dispatcher/dispatcher.rs index 989f2113b2..74dcb7ffa6 100644 --- a/mm2src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/rpc/dispatcher/dispatcher.rs @@ -8,6 +8,7 @@ use crate::{mm2::lp_stats::{add_node_to_version_stat, remove_node_from_version_s mm2::rpc::get_public_key::get_public_key}; use coins::init_withdraw::{init_withdraw, withdraw_status, withdraw_user_action}; use coins::lightning::{connect_to_lightning_node, open_channel, LightningCoin}; +use coins::my_tx_history_v2::my_tx_history_v2_rpc; use coins::utxo::bch::BchCoin; use coins::utxo::slp::SlpToken; use coins::{add_delegation, get_staking_infos, remove_delegation, withdraw}; @@ -115,6 +116,7 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, init_withdraw).await, "mm_init_status" => handle_mmrpc(ctx, request, mm_init_status).await, "mm_init_user_action" => handle_mmrpc(ctx, request, mm_init_user_action).await, + "my_tx_history" => handle_mmrpc(ctx, request, my_tx_history_v2_rpc).await, "open_channel" => handle_mmrpc(ctx, request, open_channel).await, "recreate_swap_data" => handle_mmrpc(ctx, request, recreate_swap_data).await, "remove_delegation" => handle_mmrpc(ctx, request, remove_delegation).await, diff --git a/mm2src/trezor/src/proto/messages_common.rs b/mm2src/trezor/src/proto/messages_common.rs index 67e75fbfff..97fc718595 100644 --- a/mm2src/trezor/src/proto/messages_common.rs +++ b/mm2src/trezor/src/proto/messages_common.rs @@ -23,6 +23,7 @@ pub struct Failure { pub mod failure { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] + #[allow(clippy::enum_variant_names)] pub enum FailureType { FailureUnexpectedMessage = 1, FailureButtonExpected = 2, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 02f1db4edf..4566e0b2cb 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-05-17" +channel = "nightly-2021-12-16" components = ["rustfmt"]