bitcoinwatcher 1.0.1__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,12 @@
1
1
  from unittest import TestCase
2
2
 
3
- from bitcoin.address_listener.address_listener import AbstractAddressListener, AddressTxData, AddressTxType
3
+ from bitcoin.address_listener.address_listener import AbstractAddressListener, AddressTxData
4
+ from bitcoin.models.address_tx_data import AddressTxType
4
5
 
5
6
 
6
7
  class DummyAddressListener(AbstractAddressListener):
7
- def consume(self, address_tx_data):
8
+
9
+ def consume(self, subscribed_address, address_tx_data: [AddressTxData]):
8
10
  pass
9
11
 
10
12
  def __init__(self, address_to_listen: [str]):
@@ -0,0 +1,32 @@
1
+ from unittest import TestCase
2
+
3
+ from bitcoinlib.transactions import Transaction
4
+
5
+ from bitcoin.tests.data.transactions import batch_airdrop_tx_hex, tx_hex, non_reveal_tx_hex
6
+ from bitcoin.utils.bitcoin_utils import is_reveal_tx, count_reveal_inputs
7
+
8
+
9
+ class Test(TestCase):
10
+ def test_is_reveal_tx(self):
11
+ tx = Transaction.parse_hex(tx_hex, strict=False)
12
+ self.assertTrue(is_reveal_tx(tx))
13
+
14
+ def test_is_reveal_tx_in_second_input(self):
15
+ tx = Transaction.parse_hex(batch_airdrop_tx_hex, strict=False)
16
+ self.assertTrue(is_reveal_tx(tx))
17
+
18
+ def test_is_not_reveal_tx(self):
19
+ tx = Transaction.parse_hex(non_reveal_tx_hex, strict=False)
20
+ self.assertFalse(is_reveal_tx(tx))
21
+
22
+ def test_count_reveal_inputs(self):
23
+ tx = Transaction.parse_hex(tx_hex, strict=False)
24
+ self.assertEqual(count_reveal_inputs(tx), 1)
25
+
26
+ def test_count_reveal_inputs_not_reveal(self):
27
+ tx = Transaction.parse_hex(non_reveal_tx_hex, strict=False)
28
+ self.assertEqual(count_reveal_inputs(tx), 0)
29
+
30
+ def test_count_reveal_in_airdrop_tx(self):
31
+ tx = Transaction.parse_hex(batch_airdrop_tx_hex, strict=False)
32
+ self.assertEqual(count_reveal_inputs(tx), 1420)
@@ -0,0 +1,33 @@
1
+ # benchmark between mempool and bitcoinrcp get transaction info
2
+ import os
3
+ import time
4
+ import requests
5
+ from ordipool.ordipool.mempoolio import Mempool
6
+
7
+ from bitcoin.utils.bitcoin_rpc import BitcoinRPC
8
+ from bitcoin.utils.constants import default_host
9
+
10
+ host = os.environ.get("RPC_HOST", default_host)
11
+ base_url = f"http://{host}:3006/api"
12
+
13
+ mempool = Mempool(base_url)
14
+ bitcoinrpc = BitcoinRPC()
15
+
16
+ if __name__ == '__main__':
17
+
18
+ txid = 'a6293e898b056fbea0329d071b1b237e4449ff464cdbc7a9ed8a770b97aafd4c'
19
+ times = 1000
20
+ start = time.time()
21
+ print("mempool starting")
22
+ for i in range(times):
23
+ print(i)
24
+ mempool.get_transaction(txid)
25
+ end = time.time()
26
+ print(f"mempool took: {end - start}")
27
+
28
+ start = time.time()
29
+ for i in range(times):
30
+ bitcoinrpc.get_transaction(txid)
31
+ end = time.time()
32
+ print(f"bitcoinrpc took: {end - start}")
33
+
@@ -0,0 +1,31 @@
1
+ import os
2
+
3
+ from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
4
+
5
+ from bitcoin.utils.constants import default_host
6
+
7
+
8
+ class BitcoinRPC:
9
+ rpc_user = os.environ.get("RPC_USER")
10
+ rpc_password = os.environ.get("RPC_PASSWORD")
11
+ rpc_host = os.environ.get("RPC_HOST", default_host)
12
+ rpc_port = os.environ.get("RPC_PORT", 8332)
13
+ rpc_connection: AuthServiceProxy
14
+
15
+ def __init__(self):
16
+ rpc_string = f"http://{self.rpc_user}:{self.rpc_password}@{self.rpc_host}:{self.rpc_port}"
17
+ print("rpc_string: ", rpc_string)
18
+ self.rpc_connection = AuthServiceProxy(rpc_string)
19
+
20
+ def get_transaction(self, txid: str) -> dict:
21
+ return self.rpc_connection.getrawtransaction(txid, True)
22
+
23
+
24
+ if __name__ == '__main__':
25
+ rpc = BitcoinRPC()
26
+ txid = 'a6293e898b056fbea0329d071b1b237e4449ff464cdbc7a9ed8a770b97aafd4c'
27
+ try:
28
+ transaction = rpc.get_transaction(txid)
29
+ print(transaction)
30
+ except JSONRPCException as e:
31
+ print(f"An error occurred: {e}")
@@ -1,16 +1,18 @@
1
- from bitcoin.core import CTransaction
2
- from bitcoinutils.keys import PublicKey
3
- from bitcoinutils.transactions import TxOutput
1
+ from bitcoinlib.transactions import Transaction, Input
2
+ from ordipool.utils.utils import convert_to_hex
4
3
 
5
4
 
6
- def get_tx_id_from_tx(tx: CTransaction) -> str:
7
- tx_id = tx.GetTxid()
8
- # convert it to hex
9
- txid_hex = tx_id[::-1].hex()
10
- return txid_hex
5
+ def count_inscriptions(vin: Input) -> int:
6
+ ord_hex = convert_to_hex('ord')
7
+ # count occurences of ord in the witness script
8
+ return sum([witness.hex().count(ord_hex) for witness in vin.witnesses])
11
9
 
12
10
 
13
- def get_address_from_output(output: TxOutput):
14
- public_key = output.script_pubkey.to_hex()
15
- address = PublicKey(public_key)
16
- print(address)
11
+ def count_reveal_inputs(tx: Transaction) -> int:
12
+ return sum([count_inscriptions(vin) for vin in tx.inputs])
13
+
14
+
15
+ def is_reveal_tx(tx: Transaction) -> bool:
16
+ count_of_inscriptions = count_reveal_inputs(tx)
17
+ return count_of_inscriptions > 0
18
+ # check if any of the witness contains ord, convert witness to hex
@@ -0,0 +1,76 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ from bitcoinlib.transactions import Transaction
5
+ from ordipool.ordipool.mempoolio import Mempool
6
+
7
+ from bitcoin.address_listener.address_listener import AddressTxData
8
+ from bitcoin.models.address_tx_data import AddressTxType, TransactionStatus
9
+ from bitcoin.utils.bitcoin_utils import is_reveal_tx, count_reveal_inputs
10
+
11
+
12
+ class AbstractTxAddressDataExtractor(ABC):
13
+ @abstractmethod
14
+ def extract(self, tx: Transaction) -> [AddressTxData]:
15
+ pass
16
+
17
+
18
+ class MempoolTxAddressDataExtractor(AbstractTxAddressDataExtractor):
19
+ mempool: Mempool
20
+
21
+ def __init__(self, mempool: Mempool):
22
+ self.mempool = mempool
23
+
24
+ def extract(self, tx: Transaction) -> [AddressTxData]:
25
+ outputs = tx.outputs
26
+ tx_id = tx.txid
27
+ has_inscriptions = is_reveal_tx(tx)
28
+
29
+ tx = self.mempool.get_transaction(tx_id)
30
+ tx_status = TransactionStatus.CONFIRMED if tx.confirmed else TransactionStatus.UNCONFIRMED
31
+ address_tx_data = []
32
+ # getting inputs data separately from mempool
33
+ # as current library doesn't provide rich data like previous outputs and its value
34
+ for vin in tx.vins:
35
+ address = vin.prev_out.address
36
+ amount = vin.prev_out.value
37
+ address_tx_data.append(AddressTxData(tx_status=tx_status.value,
38
+ address=address,
39
+ is_reveal_tx=has_inscriptions,
40
+ type=AddressTxType.INPUT,
41
+ _amount=amount,
42
+ tx_id=tx_id))
43
+ for output in outputs:
44
+ amount = output.value
45
+ address_tx_data.append(AddressTxData(tx_status=tx_status.value,
46
+ address=output.address,
47
+ _amount=amount,
48
+ is_reveal_tx=has_inscriptions,
49
+ type=AddressTxType.OUTPUT,
50
+ tx_id=tx_id))
51
+
52
+ return address_tx_data
53
+
54
+
55
+ class DefaultTxAddressDataExtractor(AbstractTxAddressDataExtractor):
56
+ def extract(self, tx: Transaction) -> [AddressTxData]:
57
+ outputs = tx.outputs
58
+ address_tx_data = []
59
+ inputs = tx.inputs
60
+ tx_status = tx.status
61
+ for input in inputs:
62
+ address = input.address
63
+ amount = 0
64
+ address_tx_data.append(AddressTxData(tx_status=tx_status,
65
+ address=address,
66
+ type=AddressTxType.INPUT,
67
+ _amount=amount,
68
+ tx_id=tx.txid))
69
+ for output in outputs:
70
+ amount = output.value
71
+ address_tx_data.append(AddressTxData(tx_status=tx_status,
72
+ address=output.address,
73
+ _amount=amount,
74
+ type=AddressTxType.OUTPUT,
75
+ tx_id=tx.txid))
76
+ return address_tx_data
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bitcoinwatcher
3
- Version: 1.0.1
3
+ Version: 1.2.0
4
4
  Summary: bitcoinwatcher is a Python library that implements a ZMQ subscriber and provides abstractions to build custom address watchers. This library is designed to make it easy for developers to monitor Bitcoin addresses and react to changes in their state.
5
5
  Author: twosatsmaxi
6
6
  License: Apache License
@@ -227,6 +227,7 @@ Requires-Dist: six ==1.16.0
227
227
  Requires-Dist: urllib3 ==2.2.1
228
228
  Requires-Dist: bitcoinlib ==0.6.14
229
229
  Requires-Dist: ordipool ==1.2.0
230
+ Requires-Dist: python-bitcoinrpc ==1.0
230
231
 
231
232
  # bitcoinwatcher
232
233
 
@@ -0,0 +1,26 @@
1
+ bitcoin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ bitcoin/address_listener/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ bitcoin/address_listener/address_listener.py,sha256=sK0hrhPrYg8z6AC8MqNbF3UoaqvbhdhVcoyMLj8x4MQ,2223
4
+ bitcoin/address_listener/simple_address_listener.py,sha256=iSMPBUzl9d4s8_ee2LAXz83zBiGfs1KhwSH_7FvxwKY,1609
5
+ bitcoin/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ bitcoin/models/address_tx_data.py,sha256=0zIleuEHern42zk1Pp7IteR5jQqVdAM1l4Gvy6YzGe0,754
7
+ bitcoin/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ bitcoin/tests/test_address_listener.py,sha256=oqVfJ_lQNHgRxCnDteUpkaUyHff5Wa8J2oYJnwQ-QaE,3113
9
+ bitcoin/tests/test_bitcoin_utils.py,sha256=NYRHWfqaOgLO8osOYVqRudk9ksuhC3LC9HGrxj-VGu4,1213
10
+ bitcoin/tests/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ bitcoin/tests/data/transactions.py,sha256=To0FCF4JDdjZTV9H900WCuV8_mGPItk5bEiYgUj0KiY,394877
12
+ bitcoin/tx_listener/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ bitcoin/tx_listener/abstract_tx_listener.py,sha256=rGp9na-aOSl_aPaIqf44RTZaFF3SvrxIhZBujTnWqao,189
14
+ bitcoin/tx_listener/zmq_listener.py,sha256=_edaee2PYj9T1jxLenv68ekZRTM8-LUN3DloDLNQ5Bc,999
15
+ bitcoin/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ bitcoin/utils/benchmark.py,sha256=ZCfhIe4_meUNpQ7NEioZj3_uudCisg7J8d_LTMoRFto,875
17
+ bitcoin/utils/bitcoin_rpc.py,sha256=Uq3eZnLaGOgltybEWeBRubnUhTHyB8gVI_L_SnrZ-ug,1012
18
+ bitcoin/utils/bitcoin_utils.py,sha256=mrnRPqUa2U2EMKu7rrPV_bW1sL2CJUfbAom0Zdamydk,631
19
+ bitcoin/utils/constants.py,sha256=irZLlArgica2VckyckEYxH5D5KjvdF52dtBMWswqw8k,52
20
+ bitcoin/utils/inscription_utils.py,sha256=8QbOJ1o1n1bMFsPREGLzwFjnGzfuARgJCPr6ORhP44o,193
21
+ bitcoin/utils/tx_address_data_extractor.py,sha256=M_WvBNNXYwd2qBG6oyfu8Vn6P8F0Rt5w1FnfvFO6IZc,3321
22
+ bitcoinwatcher-1.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
23
+ bitcoinwatcher-1.2.0.dist-info/METADATA,sha256=i4U1BiZn-KQ9TQDPKGaKkctAFpgx1lRGaLywjvz5qoc,14940
24
+ bitcoinwatcher-1.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
25
+ bitcoinwatcher-1.2.0.dist-info/top_level.txt,sha256=YdUgzLdCiMlrwaKyDqHA1acEd23QFko5bv7D6nBANJ0,8
26
+ bitcoinwatcher-1.2.0.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- bitcoin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- bitcoin/address_listener/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- bitcoin/address_listener/address_listener.py,sha256=WKDG8gtB9_2K-v0nYhkKDkaqxPz2uE2uVtwWRNzg7H8,3000
4
- bitcoin/address_listener/simple_address_listener.py,sha256=2qR012t3rHTNHkit6TvkYP9Co4IVySKG8YyzmxKc0cU,1499
5
- bitcoin/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- bitcoin/tests/test_address_listener.py,sha256=_8ic7ldHaeICfYTepAkqcWFzZPhEKzbIkAfrAZ1ZdCs,3033
7
- bitcoin/tx_listener/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- bitcoin/tx_listener/abstract_tx_listener.py,sha256=rGp9na-aOSl_aPaIqf44RTZaFF3SvrxIhZBujTnWqao,189
9
- bitcoin/tx_listener/zmq_listener.py,sha256=_edaee2PYj9T1jxLenv68ekZRTM8-LUN3DloDLNQ5Bc,999
10
- bitcoin/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- bitcoin/utils/bitcoin_utils.py,sha256=ehzfwiuln_lPia6urtUSVE3zXC1zyZEKiNM36e7N00k,428
12
- bitcoin/utils/constants.py,sha256=irZLlArgica2VckyckEYxH5D5KjvdF52dtBMWswqw8k,52
13
- bitcoin/utils/inscription_utils.py,sha256=8QbOJ1o1n1bMFsPREGLzwFjnGzfuARgJCPr6ORhP44o,193
14
- bitcoinwatcher-1.0.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
- bitcoinwatcher-1.0.1.dist-info/METADATA,sha256=qpqrssZZ60vtfPxx3vziTyZ5krWFVQz1Y86PYs8JmH4,14901
16
- bitcoinwatcher-1.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
17
- bitcoinwatcher-1.0.1.dist-info/top_level.txt,sha256=YdUgzLdCiMlrwaKyDqHA1acEd23QFko5bv7D6nBANJ0,8
18
- bitcoinwatcher-1.0.1.dist-info/RECORD,,