@@ -23,9 +23,7 @@ async def count_unspent_outputs(
2323 session : AsyncSession , address : str , currency : str
2424) -> int :
2525 return await session .scalar (
26- unspent_outputs_filters (
27- select (func .count (Output .id )), address , currency
28- )
26+ unspent_outputs_filters (select (func .count (Output .id )), address , currency )
2927 )
3028
3129
@@ -38,16 +36,55 @@ async def list_unspent_outputs(
3836) -> ScalarResult [Output ]:
3937 return await session .scalars (
4038 unspent_outputs_filters (
41- select (Output )
42- .order_by (Output .amount .desc ())
43- .limit (limit )
44- .offset (offset ),
39+ select (Output ).order_by (Output .amount .desc ()).limit (limit ).offset (offset ),
4540 address ,
4641 currency ,
4742 )
4843 )
4944
5045
46+ def utxo_cte (address : str , currency : str ):
47+ return (
48+ select (
49+ Output ,
50+ func .sum (Output .amount ) # type: ignore
51+ .over (order_by = Output .blockhash )
52+ .label ("cumulative_amount" ),
53+ )
54+ .filter (Output .address == address , Output .currency == currency , ~ Output .spent )
55+ .cte ("cumulative_outputs" )
56+ )
57+
58+
59+ async def count_utxo (
60+ session : AsyncSession , address : str , currency : str , amount : float
61+ ) -> int :
62+ cte = utxo_cte (address , currency )
63+ query = (
64+ select (func .count (1 )).select_from (cte ).where (cte .c .cumulative_amount < amount )
65+ )
66+ return await session .scalar (query ) or 0
67+
68+
69+ async def list_utxo (
70+ session : AsyncSession ,
71+ address : str ,
72+ currency : str ,
73+ amount : float ,
74+ limit : int ,
75+ offset : int ,
76+ ):
77+ cte = utxo_cte (address , currency )
78+ query = (
79+ select (cte )
80+ .select_from (cte )
81+ .where (cte .c .cumulative_amount < amount )
82+ .limit (limit )
83+ .offset (offset )
84+ )
85+ return await session .execute (query )
86+
87+
5188def transactions_filters (query : Select , address : str ) -> Select :
5289 query = query .filter (Transaction .addresses .contains ([address ]))
5390
@@ -74,16 +111,12 @@ async def list_transactions(
74111 address ,
75112 )
76113 ):
77- transactions .append (
78- await load_tx_details (session , transaction , latest_block )
79- )
114+ transactions .append (await load_tx_details (session , transaction , latest_block ))
80115
81116 return transactions
82117
83118
84- async def list_balances (
85- session : AsyncSession , address : str
86- ) -> list [AddressBalance ]:
119+ async def list_balances (session : AsyncSession , address : str ) -> list [AddressBalance ]:
87120 balances = []
88121 for balance in await session .scalars (
89122 select (AddressBalance ).filter (
@@ -97,18 +130,14 @@ async def list_balances(
97130 return balances
98131
99132
100- async def list_address_mempool_transactions (
101- session : AsyncSession , address : str
102- ):
133+ async def list_address_mempool_transactions (session : AsyncSession , address : str ):
103134 mempool = await session .scalar (select (MemPool ).limit (1 ))
104135
105136 if mempool is None :
106137 return []
107138
108139 return [
109- await load_mempool_tx_details (
110- session , transaction , mempool .raw ["outputs" ]
111- )
140+ await load_mempool_tx_details (session , transaction , mempool .raw ["outputs" ])
112141 for transaction in mempool .raw ["transactions" ]
113142 if address in transaction ["addresses" ]
114143 ]
0 commit comments