2828 TRANSFER_WITH_MEMO_SELECTOR ,
2929 TRANSFER_WITH_MEMO_TOPIC ,
3030 ChargeIntent ,
31- Transfer ,
3231 _match_single_transfer_calldata ,
3332 _match_transfer_calldata ,
3433 _parse_memo_bytes ,
@@ -2498,23 +2497,54 @@ def test_empty_splits_returns_single_transfer(self) -> None:
24982497 assert len (transfers ) == 1
24992498
25002499 def test_single_split (self ) -> None :
2501- splits = [Split (amount = "300000" , recipient = "0x1111111111111111111111111111111111111111" )]
2502- transfers = get_transfers (1_000_000 , "0x2222222222222222222222222222222222222222" , None , splits )
2500+ splits = [
2501+ Split (
2502+ amount = "300000" ,
2503+ recipient = "0x1111111111111111111111111111111111111111" ,
2504+ )
2505+ ]
2506+ transfers = get_transfers (
2507+ 1_000_000 ,
2508+ "0x2222222222222222222222222222222222222222" ,
2509+ None ,
2510+ splits ,
2511+ )
25032512 assert len (transfers ) == 2
25042513 assert transfers [0 ].amount == 700_000 # primary gets remainder
25052514 assert transfers [1 ].amount == 300_000
25062515
25072516 def test_primary_inherits_memo (self ) -> None :
25082517 memo = "0x" + "ab" * 32
2509- splits = [Split (amount = "100000" , recipient = "0x1111111111111111111111111111111111111111" )]
2510- transfers = get_transfers (1_000_000 , "0x2222222222222222222222222222222222222222" , memo , splits )
2518+ splits = [
2519+ Split (
2520+ amount = "100000" ,
2521+ recipient = "0x1111111111111111111111111111111111111111" ,
2522+ )
2523+ ]
2524+ transfers = get_transfers (
2525+ 1_000_000 ,
2526+ "0x2222222222222222222222222222222222222222" ,
2527+ memo ,
2528+ splits ,
2529+ )
25112530 assert transfers [0 ].memo is not None
25122531 assert transfers [1 ].memo is None
25132532
25142533 def test_split_with_memo (self ) -> None :
25152534 split_memo = "0x" + "cd" * 32
2516- splits = [Split (amount = "100000" , recipient = "0x1111111111111111111111111111111111111111" , memo = split_memo )]
2517- transfers = get_transfers (1_000_000 , "0x2222222222222222222222222222222222222222" , None , splits )
2535+ splits = [
2536+ Split (
2537+ amount = "100000" ,
2538+ recipient = "0x1111111111111111111111111111111111111111" ,
2539+ memo = split_memo ,
2540+ )
2541+ ]
2542+ transfers = get_transfers (
2543+ 1_000_000 ,
2544+ "0x2222222222222222222222222222222222222222" ,
2545+ None ,
2546+ splits ,
2547+ )
25182548 assert transfers [1 ].memo is not None
25192549 assert transfers [1 ].memo [0 ] == 0xCD
25202550
@@ -2524,7 +2554,12 @@ def test_multiple_splits_preserve_order(self) -> None:
25242554 Split (amount = "200000" , recipient = "0x2222222222222222222222222222222222222222" ),
25252555 Split (amount = "50000" , recipient = "0x3333333333333333333333333333333333333333" ),
25262556 ]
2527- transfers = get_transfers (1_000_000 , "0x4444444444444444444444444444444444444444" , None , splits )
2557+ transfers = get_transfers (
2558+ 1_000_000 ,
2559+ "0x4444444444444444444444444444444444444444" ,
2560+ None ,
2561+ splits ,
2562+ )
25282563 assert len (transfers ) == 4
25292564 assert transfers [0 ].amount == 650_000 # primary
25302565 assert transfers [1 ].amount == 100_000
@@ -2548,18 +2583,21 @@ def test_rejects_zero_split_amount(self) -> None:
25482583
25492584 def test_rejects_too_many_splits (self ) -> None :
25502585 splits = [
2551- Split (amount = "1000" , recipient = f"0x{ hex (i + 2 )[2 :].zfill (40 )} " )
2552- for i in range (11 )
2586+ Split (amount = "1000" , recipient = f"0x{ hex (i + 2 )[2 :].zfill (40 )} " ) for i in range (11 )
25532587 ]
25542588 with pytest .raises (VerificationError , match = "Too many splits" ):
25552589 get_transfers (1_000_000 , "0x0000000000000000000000000000000000000001" , None , splits )
25562590
25572591 def test_max_splits_allowed (self ) -> None :
25582592 splits = [
2559- Split (amount = "1000" , recipient = f"0x{ hex (i + 2 )[2 :].zfill (40 )} " )
2560- for i in range (10 )
2593+ Split (amount = "1000" , recipient = f"0x{ hex (i + 2 )[2 :].zfill (40 )} " ) for i in range (10 )
25612594 ]
2562- transfers = get_transfers (1_000_000 , "0x0000000000000000000000000000000000000001" , None , splits )
2595+ transfers = get_transfers (
2596+ 1_000_000 ,
2597+ "0x0000000000000000000000000000000000000001" ,
2598+ None ,
2599+ splits ,
2600+ )
25632601 assert len (transfers ) == 11
25642602 assert transfers [0 ].amount == 990_000
25652603
@@ -2778,18 +2816,50 @@ class TestMatchSingleTransferCalldata:
27782816 AMOUNT = 1000000
27792817 MEMO = bytes .fromhex ("ab" * 32 )
27802818
2781- def _build_calldata (self , selector : str , recipient : str , amount : int , memo_hex : str = "" ) -> str :
2819+ def _build_calldata (
2820+ self ,
2821+ selector : str ,
2822+ recipient : str ,
2823+ amount : int ,
2824+ memo_hex : str = "" ,
2825+ ) -> str :
27822826 to_padded = recipient [2 :].lower ().zfill (64 )
27832827 amount_padded = hex (amount )[2 :].zfill (64 )
27842828 return f"{ selector } { to_padded } { amount_padded } { memo_hex } "
27852829
27862830 def test_memo_requires_transfer_with_memo_selector (self ) -> None :
2787- calldata = self ._build_calldata (TRANSFER_SELECTOR , self .RECIPIENT , self .AMOUNT , "ab" * 32 )
2788- assert _match_single_transfer_calldata (calldata , self .RECIPIENT , self .AMOUNT , self .MEMO ) is False
2831+ calldata = self ._build_calldata (
2832+ TRANSFER_SELECTOR ,
2833+ self .RECIPIENT ,
2834+ self .AMOUNT ,
2835+ "ab" * 32 ,
2836+ )
2837+ assert (
2838+ _match_single_transfer_calldata (
2839+ calldata ,
2840+ self .RECIPIENT ,
2841+ self .AMOUNT ,
2842+ self .MEMO ,
2843+ )
2844+ is False
2845+ )
27892846
27902847 def test_memo_accepts_correct_selector (self ) -> None :
2791- calldata = self ._build_calldata (TRANSFER_WITH_MEMO_SELECTOR , self .RECIPIENT , self .AMOUNT , "ab" * 32 )
2792- assert _match_single_transfer_calldata (calldata , self .RECIPIENT , self .AMOUNT , self .MEMO ) is True
2848+ calldata = self ._build_calldata (
2849+ TRANSFER_WITH_MEMO_SELECTOR ,
2850+ self .RECIPIENT ,
2851+ self .AMOUNT ,
2852+ "ab" * 32 ,
2853+ )
2854+ assert (
2855+ _match_single_transfer_calldata (
2856+ calldata ,
2857+ self .RECIPIENT ,
2858+ self .AMOUNT ,
2859+ self .MEMO ,
2860+ )
2861+ is True
2862+ )
27932863
27942864 def test_no_memo_rejects_transfer_with_memo_selector (self ) -> None :
27952865 """When no memo expected, transferWithMemo calldata must be rejected."""
@@ -2832,10 +2902,14 @@ def test_single_transfer_rejects_transfer_with_memo_log(self) -> None:
28322902 methodDetails = MethodDetails (),
28332903 )
28342904 receipt = {
2835- "logs" : [self ._make_log (
2836- TRANSFER_WITH_MEMO_TOPIC , self .RECIPIENT , self .AMOUNT ,
2837- memo = "0x" + "ff" * 32 ,
2838- )],
2905+ "logs" : [
2906+ self ._make_log (
2907+ TRANSFER_WITH_MEMO_TOPIC ,
2908+ self .RECIPIENT ,
2909+ self .AMOUNT ,
2910+ memo = "0x" + "ff" * 32 ,
2911+ )
2912+ ],
28392913 }
28402914 assert intent ._verify_transfer_logs (receipt , request ) is False
28412915
@@ -2856,7 +2930,9 @@ def test_multi_split_rejects_transfer_with_memo_log_for_memoless(self) -> None:
28562930 self ._make_log (TRANSFER_TOPIC , self .RECIPIENT , 700000 ),
28572931 # split as TransferWithMemo (should be rejected)
28582932 self ._make_log (
2859- TRANSFER_WITH_MEMO_TOPIC , self .SPLIT_RECIPIENT , 300000 ,
2933+ TRANSFER_WITH_MEMO_TOPIC ,
2934+ self .SPLIT_RECIPIENT ,
2935+ 300000 ,
28602936 memo = "0x" + "ff" * 32 ,
28612937 ),
28622938 ],
@@ -2869,8 +2945,8 @@ class TestSplitsFeePayerRejection:
28692945
28702946 @pytest .mark .anyio
28712947 async def test_splits_with_fee_payer_raises (self , monkeypatch : pytest .MonkeyPatch ) -> None :
2872- from mpp .server import Mpp
28732948 from mpp .methods .tempo import tempo
2949+ from mpp .server import Mpp
28742950
28752951 monkeypatch .setenv ("MPP_SECRET_KEY" , "test-secret-key" )
28762952 server = Mpp .create (
@@ -2883,7 +2959,12 @@ async def test_splits_with_fee_payer_raises(self, monkeypatch: pytest.MonkeyPatc
28832959 await server .charge (
28842960 authorization = None ,
28852961 amount = "1.00" ,
2886- splits = [{"amount" : "300000" , "recipient" : "0x1111111111111111111111111111111111111111" }],
2962+ splits = [
2963+ {
2964+ "amount" : "300000" ,
2965+ "recipient" : "0x1111111111111111111111111111111111111111" ,
2966+ }
2967+ ],
28872968 fee_payer = True ,
28882969 )
28892970
@@ -2900,11 +2981,23 @@ def test_short_primary_memo_raises(self) -> None:
29002981 get_transfers (1_000_000 , "0x01" , "0x" + "ab" * 10 , None )
29012982
29022983 def test_invalid_split_memo_raises (self ) -> None :
2903- splits = [Split (amount = "100000" , recipient = "0x1111111111111111111111111111111111111111" , memo = "badhex" )]
2984+ splits = [
2985+ Split (
2986+ amount = "100000" ,
2987+ recipient = "0x1111111111111111111111111111111111111111" ,
2988+ memo = "badhex" ,
2989+ )
2990+ ]
29042991 with pytest .raises (VerificationError , match = "Invalid memo hex" ):
29052992 get_transfers (1_000_000 , "0x01" , None , splits )
29062993
29072994 def test_short_split_memo_raises (self ) -> None :
2908- splits = [Split (amount = "100000" , recipient = "0x1111111111111111111111111111111111111111" , memo = "0x" + "ab" * 5 )]
2995+ splits = [
2996+ Split (
2997+ amount = "100000" ,
2998+ recipient = "0x1111111111111111111111111111111111111111" ,
2999+ memo = "0x" + "ab" * 5 ,
3000+ )
3001+ ]
29093002 with pytest .raises (VerificationError , match = "exactly 32 bytes" ):
29103003 get_transfers (1_000_000 , "0x01" , None , splits )
0 commit comments