@@ -307,6 +307,26 @@ describe('erc20-commerce-escrow-wrapper', () => {
307307
308308 expect ( typeof encodedData ) . toBe ( 'string' ) ;
309309 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
310+
311+ // Verify it starts with the correct function selector for authorizePayment
312+ // Function signature: authorizePayment(bytes8,address,address,address,address,uint256,uint256,uint256,uint256,uint256,address,bytes)
313+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0x5532a547' ) ; // Actual function selector
314+
315+ // Verify the encoded data contains our test parameters
316+ expect ( encodedData . length ) . toBeGreaterThan ( 10 ) ; // More than just function selector
317+ expect ( encodedData ) . toContain ( mockAuthorizeParams . paymentReference . substring ( 2 ) ) ; // Remove 0x prefix
318+ expect ( encodedData . toLowerCase ( ) ) . toContain (
319+ mockAuthorizeParams . payer . substring ( 2 ) . toLowerCase ( ) ,
320+ ) ;
321+ expect ( encodedData . toLowerCase ( ) ) . toContain (
322+ mockAuthorizeParams . merchant . substring ( 2 ) . toLowerCase ( ) ,
323+ ) ;
324+ expect ( encodedData . toLowerCase ( ) ) . toContain (
325+ mockAuthorizeParams . operator . substring ( 2 ) . toLowerCase ( ) ,
326+ ) ;
327+ expect ( encodedData . toLowerCase ( ) ) . toContain (
328+ mockAuthorizeParams . token . substring ( 2 ) . toLowerCase ( ) ,
329+ ) ;
310330 } ) ;
311331
312332 it ( 'should encode capturePayment function data' , ( ) => {
@@ -318,17 +338,44 @@ describe('erc20-commerce-escrow-wrapper', () => {
318338
319339 expect ( typeof encodedData ) . toBe ( 'string' ) ;
320340 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
341+
342+ // Verify it starts with the correct function selector for capturePayment
343+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0xa2615767' ) ;
344+
345+ // Verify the encoded data contains our test parameters
346+ expect ( encodedData ) . toContain ( mockCaptureParams . paymentReference . substring ( 2 ) ) ;
347+ expect ( encodedData . toLowerCase ( ) ) . toContain (
348+ mockCaptureParams . feeReceiver . substring ( 2 ) . toLowerCase ( ) ,
349+ ) ;
350+
351+ // Verify encoded amounts (as hex)
352+ const captureAmountHex = parseInt ( mockCaptureParams . captureAmount . toString ( ) )
353+ . toString ( 16 )
354+ . padStart ( 64 , '0' ) ;
355+ const feeBpsHex = mockCaptureParams . feeBps . toString ( 16 ) . padStart ( 64 , '0' ) ;
356+ expect ( encodedData . toLowerCase ( ) ) . toContain ( captureAmountHex ) ;
357+ expect ( encodedData . toLowerCase ( ) ) . toContain ( feeBpsHex ) ;
321358 } ) ;
322359
323360 it ( 'should encode voidPayment function data' , ( ) => {
361+ const testPaymentRef = '0x0123456789abcdef' ;
324362 const encodedData = encodeVoidPayment ( {
325- paymentReference : '0x0123456789abcdef' ,
363+ paymentReference : testPaymentRef ,
326364 network,
327365 provider,
328366 } ) ;
329367
330368 expect ( typeof encodedData ) . toBe ( 'string' ) ;
331369 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
370+
371+ // Verify it starts with the correct function selector for voidPayment
372+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0x4eff2760' ) ;
373+
374+ // Verify the encoded data contains the payment reference
375+ expect ( encodedData ) . toContain ( testPaymentRef . substring ( 2 ) ) ;
376+
377+ // Void payment should be relatively short (just function selector + payment reference)
378+ expect ( encodedData . length ) . toBe ( 74 ) ; // 10 chars for selector + 64 chars for padded bytes8
332379 } ) ;
333380
334381 it ( 'should encode chargePayment function data' , ( ) => {
@@ -340,17 +387,55 @@ describe('erc20-commerce-escrow-wrapper', () => {
340387
341388 expect ( typeof encodedData ) . toBe ( 'string' ) ;
342389 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
390+
391+ // Verify it starts with the correct function selector for chargePayment
392+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0x739802a3' ) ;
393+
394+ // Verify the encoded data contains our test parameters
395+ expect ( encodedData ) . toContain ( mockChargeParams . paymentReference . substring ( 2 ) ) ;
396+ expect ( encodedData . toLowerCase ( ) ) . toContain (
397+ mockChargeParams . payer . substring ( 2 ) . toLowerCase ( ) ,
398+ ) ;
399+ expect ( encodedData . toLowerCase ( ) ) . toContain (
400+ mockChargeParams . merchant . substring ( 2 ) . toLowerCase ( ) ,
401+ ) ;
402+ expect ( encodedData . toLowerCase ( ) ) . toContain (
403+ mockChargeParams . operator . substring ( 2 ) . toLowerCase ( ) ,
404+ ) ;
405+ expect ( encodedData . toLowerCase ( ) ) . toContain (
406+ mockChargeParams . token . substring ( 2 ) . toLowerCase ( ) ,
407+ ) ;
408+ expect ( encodedData . toLowerCase ( ) ) . toContain (
409+ mockChargeParams . feeReceiver . substring ( 2 ) . toLowerCase ( ) ,
410+ ) ;
411+ expect ( encodedData . toLowerCase ( ) ) . toContain (
412+ mockChargeParams . tokenCollector . substring ( 2 ) . toLowerCase ( ) ,
413+ ) ;
414+
415+ // Verify encoded fee basis points
416+ const feeBpsHex = mockChargeParams . feeBps . toString ( 16 ) . padStart ( 64 , '0' ) ;
417+ expect ( encodedData . toLowerCase ( ) ) . toContain ( feeBpsHex ) ;
343418 } ) ;
344419
345420 it ( 'should encode reclaimPayment function data' , ( ) => {
421+ const testPaymentRef = '0x0123456789abcdef' ;
346422 const encodedData = encodeReclaimPayment ( {
347- paymentReference : '0x0123456789abcdef' ,
423+ paymentReference : testPaymentRef ,
348424 network,
349425 provider,
350426 } ) ;
351427
352428 expect ( typeof encodedData ) . toBe ( 'string' ) ;
353429 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
430+
431+ // Verify it starts with the correct function selector for reclaimPayment
432+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0xafda9d20' ) ;
433+
434+ // Verify the encoded data contains the payment reference
435+ expect ( encodedData ) . toContain ( testPaymentRef . substring ( 2 ) ) ;
436+
437+ // Reclaim payment should be relatively short (just function selector + payment reference)
438+ expect ( encodedData . length ) . toBe ( 74 ) ; // 10 chars for selector + 64 chars for padded bytes8
354439 } ) ;
355440
356441 it ( 'should encode refundPayment function data' , ( ) => {
@@ -362,6 +447,24 @@ describe('erc20-commerce-escrow-wrapper', () => {
362447
363448 expect ( typeof encodedData ) . toBe ( 'string' ) ;
364449 expect ( encodedData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ; // Should be valid hex string
450+
451+ // Verify it starts with the correct function selector for refundPayment
452+ expect ( encodedData . substring ( 0 , 10 ) ) . toBe ( '0xf9b777ea' ) ;
453+
454+ // Verify the encoded data contains our test parameters
455+ expect ( encodedData ) . toContain ( mockRefundParams . paymentReference . substring ( 2 ) ) ;
456+ expect ( encodedData . toLowerCase ( ) ) . toContain (
457+ mockRefundParams . tokenCollector . substring ( 2 ) . toLowerCase ( ) ,
458+ ) ;
459+
460+ // Verify encoded refund amount (as hex)
461+ const refundAmountHex = parseInt ( mockRefundParams . refundAmount . toString ( ) )
462+ . toString ( 16 )
463+ . padStart ( 64 , '0' ) ;
464+ expect ( encodedData . toLowerCase ( ) ) . toContain ( refundAmountHex ) ;
465+
466+ // Verify collector data is included
467+ expect ( encodedData ) . toContain ( mockRefundParams . collectorData . substring ( 2 ) ) ;
365468 } ) ;
366469
367470 it ( 'should throw for encodeAuthorizePayment when wrapper not found on mainnet' , ( ) => {
@@ -807,12 +910,17 @@ describe('erc20-commerce-escrow-wrapper', () => {
807910
808911 describe ( 'query functions' , ( ) => {
809912 // These tests demonstrate the expected behavior but require actual contract deployment
810- // For now, we'll test that the functions exist and have the right signatures
811- it ( 'should have the correct function signatures' , ( ) => {
913+ it ( 'should have the correct function signatures and expected behavior' , ( ) => {
812914 expect ( typeof getPaymentData ) . toBe ( 'function' ) ;
813915 expect ( typeof getPaymentState ) . toBe ( 'function' ) ;
814916 expect ( typeof canCapture ) . toBe ( 'function' ) ;
815917 expect ( typeof canVoid ) . toBe ( 'function' ) ;
918+
919+ // Verify function arity (number of parameters)
920+ expect ( getPaymentData . length ) . toBe ( 1 ) ; // Takes one parameter object
921+ expect ( getPaymentState . length ) . toBe ( 1 ) ; // Takes one parameter object
922+ expect ( canCapture . length ) . toBe ( 1 ) ; // Takes one parameter object
923+ expect ( canVoid . length ) . toBe ( 1 ) ; // Takes one parameter object
816924 } ) ;
817925
818926 it ( 'should throw for getPaymentData when wrapper not found on mainnet' , async ( ) => {
@@ -835,14 +943,36 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
835943 // 3. Capture payment
836944 // 4. Check payment state
837945
838- // For now, we just test that the functions exist and have the right signatures
946+ // Test that functions exist and validate their expected behavior
839947 expect ( typeof encodeSetCommerceEscrowAllowance ) . toBe ( 'function' ) ;
840948 expect ( typeof encodeAuthorizePayment ) . toBe ( 'function' ) ;
841949 expect ( typeof encodeCapturePayment ) . toBe ( 'function' ) ;
842950 expect ( typeof authorizePayment ) . toBe ( 'function' ) ;
843951 expect ( typeof capturePayment ) . toBe ( 'function' ) ;
844952 expect ( typeof getPaymentData ) . toBe ( 'function' ) ;
845953 expect ( typeof getPaymentState ) . toBe ( 'function' ) ;
954+
955+ // Verify function parameters and return types
956+ expect ( encodeSetCommerceEscrowAllowance . length ) . toBe ( 1 ) ; // Takes parameter object
957+ expect ( encodeAuthorizePayment . length ) . toBe ( 1 ) ; // Takes parameter object
958+ expect ( encodeCapturePayment . length ) . toBe ( 1 ) ; // Takes parameter object
959+ expect ( authorizePayment . length ) . toBe ( 1 ) ; // Takes parameter object
960+ expect ( capturePayment . length ) . toBe ( 1 ) ; // Takes parameter object
961+
962+ // Test that encode functions return valid transaction data
963+ const allowanceTxs = encodeSetCommerceEscrowAllowance ( {
964+ tokenAddress : erc20ContractAddress ,
965+ amount : '1000000000000000000' ,
966+ provider,
967+ network,
968+ } ) ;
969+ expect ( Array . isArray ( allowanceTxs ) ) . toBe ( true ) ;
970+ expect ( allowanceTxs . length ) . toBeGreaterThan ( 0 ) ;
971+ expect ( allowanceTxs [ 0 ] ) . toHaveProperty ( 'to' ) ;
972+ expect ( allowanceTxs [ 0 ] ) . toHaveProperty ( 'data' ) ;
973+ expect ( allowanceTxs [ 0 ] ) . toHaveProperty ( 'value' ) ;
974+ expect ( allowanceTxs [ 0 ] . to ) . toBe ( erc20ContractAddress ) ;
975+ expect ( allowanceTxs [ 0 ] . value ) . toBe ( 0 ) ;
846976 } ) ;
847977
848978 it ( 'should handle void payment flow when contracts are available' , async ( ) => {
@@ -854,6 +984,20 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
854984 expect ( typeof encodeVoidPayment ) . toBe ( 'function' ) ;
855985 expect ( typeof voidPayment ) . toBe ( 'function' ) ;
856986 expect ( typeof canVoid ) . toBe ( 'function' ) ;
987+
988+ // Verify function arity
989+ expect ( encodeVoidPayment . length ) . toBe ( 1 ) ;
990+ expect ( voidPayment . length ) . toBe ( 1 ) ;
991+ expect ( canVoid . length ) . toBe ( 1 ) ;
992+
993+ // Test void encoding returns valid data
994+ const voidData = encodeVoidPayment ( {
995+ paymentReference : '0x0123456789abcdef' ,
996+ network,
997+ provider,
998+ } ) ;
999+ expect ( voidData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1000+ expect ( voidData . substring ( 0 , 10 ) ) . toBe ( '0x4eff2760' ) ; // voidPayment selector
8571001 } ) ;
8581002
8591003 it ( 'should handle charge payment flow when contracts are available' , async ( ) => {
@@ -863,6 +1007,20 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
8631007
8641008 expect ( typeof encodeChargePayment ) . toBe ( 'function' ) ;
8651009 expect ( typeof chargePayment ) . toBe ( 'function' ) ;
1010+
1011+ // Verify function arity
1012+ expect ( encodeChargePayment . length ) . toBe ( 1 ) ;
1013+ expect ( chargePayment . length ) . toBe ( 1 ) ;
1014+
1015+ // Test charge encoding returns valid data with correct selector
1016+ const chargeData = encodeChargePayment ( {
1017+ params : mockChargeParams ,
1018+ network,
1019+ provider,
1020+ } ) ;
1021+ expect ( chargeData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1022+ expect ( chargeData . substring ( 0 , 10 ) ) . toBe ( '0x739802a3' ) ; // chargePayment selector
1023+ expect ( chargeData . length ) . toBeGreaterThan ( 100 ) ; // Should be long due to many parameters
8661024 } ) ;
8671025
8681026 it ( 'should handle reclaim payment flow when contracts are available' , async ( ) => {
@@ -874,6 +1032,20 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
8741032
8751033 expect ( typeof encodeReclaimPayment ) . toBe ( 'function' ) ;
8761034 expect ( typeof reclaimPayment ) . toBe ( 'function' ) ;
1035+
1036+ // Verify function arity
1037+ expect ( encodeReclaimPayment . length ) . toBe ( 1 ) ;
1038+ expect ( reclaimPayment . length ) . toBe ( 1 ) ;
1039+
1040+ // Test reclaim encoding returns valid data
1041+ const reclaimData = encodeReclaimPayment ( {
1042+ paymentReference : '0x0123456789abcdef' ,
1043+ network,
1044+ provider,
1045+ } ) ;
1046+ expect ( reclaimData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1047+ expect ( reclaimData . substring ( 0 , 10 ) ) . toBe ( '0xafda9d20' ) ; // reclaimPayment selector
1048+ expect ( reclaimData . length ) . toBe ( 74 ) ; // Short function with just payment reference
8771049 } ) ;
8781050
8791051 it ( 'should handle refund payment flow when contracts are available' , async ( ) => {
@@ -885,20 +1057,58 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
8851057
8861058 expect ( typeof encodeRefundPayment ) . toBe ( 'function' ) ;
8871059 expect ( typeof refundPayment ) . toBe ( 'function' ) ;
1060+
1061+ // Verify function arity
1062+ expect ( encodeRefundPayment . length ) . toBe ( 1 ) ;
1063+ expect ( refundPayment . length ) . toBe ( 1 ) ;
1064+
1065+ // Test refund encoding returns valid data
1066+ const refundData = encodeRefundPayment ( {
1067+ params : mockRefundParams ,
1068+ network,
1069+ provider,
1070+ } ) ;
1071+ expect ( refundData ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1072+ expect ( refundData . substring ( 0 , 10 ) ) . toBe ( '0xf9b777ea' ) ; // refundPayment selector
1073+ expect ( refundData . length ) . toBeGreaterThan ( 74 ) ; // Longer than simple functions due to multiple parameters
8881074 } ) ;
8891075
8901076 it ( 'should validate payment parameters' , ( ) => {
891- // Test parameter validation
892- const invalidParams = {
893- ...mockAuthorizeParams ,
894- paymentReference : '' , // Invalid empty reference
895- } ;
896-
897- // The actual validation would happen in the contract
898- // Here we just test that the parameters are properly typed
1077+ // Test parameter validation and ensure all expected values are present
8991078 expect ( mockAuthorizeParams . paymentReference ) . toBe ( '0x0123456789abcdef' ) ;
1079+ expect ( mockAuthorizeParams . payer ) . toBe ( wallet . address ) ;
1080+ expect ( mockAuthorizeParams . merchant ) . toBe ( '0x3234567890123456789012345678901234567890' ) ;
1081+ expect ( mockAuthorizeParams . operator ) . toBe ( '0x4234567890123456789012345678901234567890' ) ;
1082+ expect ( mockAuthorizeParams . token ) . toBe ( erc20ContractAddress ) ;
9001083 expect ( mockAuthorizeParams . amount ) . toBe ( '1000000000000000000' ) ;
1084+ expect ( mockAuthorizeParams . maxAmount ) . toBe ( '1100000000000000000' ) ;
1085+ expect ( mockAuthorizeParams . tokenCollector ) . toBe ( '0x5234567890123456789012345678901234567890' ) ;
1086+ expect ( mockAuthorizeParams . collectorData ) . toBe ( '0x1234' ) ;
1087+
1088+ // Validate capture parameters
1089+ expect ( mockCaptureParams . paymentReference ) . toBe ( '0x0123456789abcdef' ) ;
1090+ expect ( mockCaptureParams . captureAmount ) . toBe ( '1000000000000000000' ) ;
9011091 expect ( mockCaptureParams . feeBps ) . toBe ( 250 ) ;
1092+ expect ( mockCaptureParams . feeReceiver ) . toBe ( '0x6234567890123456789012345678901234567890' ) ;
1093+
1094+ // Validate charge parameters (should include all authorize params plus fee info)
1095+ expect ( mockChargeParams . feeBps ) . toBe ( 250 ) ;
1096+ expect ( mockChargeParams . feeReceiver ) . toBe ( '0x6234567890123456789012345678901234567890' ) ;
1097+
1098+ // Validate refund parameters
1099+ expect ( mockRefundParams . paymentReference ) . toBe ( '0x0123456789abcdef' ) ;
1100+ expect ( mockRefundParams . refundAmount ) . toBe ( '500000000000000000' ) ;
1101+ expect ( mockRefundParams . tokenCollector ) . toBe ( '0x7234567890123456789012345678901234567890' ) ;
1102+ expect ( mockRefundParams . collectorData ) . toBe ( '0x5678' ) ;
1103+
1104+ // Validate timestamp parameters are reasonable
1105+ expect ( mockAuthorizeParams . preApprovalExpiry ) . toBeGreaterThan ( Math . floor ( Date . now ( ) / 1000 ) ) ;
1106+ expect ( mockAuthorizeParams . authorizationExpiry ) . toBeGreaterThan (
1107+ mockAuthorizeParams . preApprovalExpiry ,
1108+ ) ;
1109+ expect ( mockAuthorizeParams . refundExpiry ) . toBeGreaterThan (
1110+ mockAuthorizeParams . authorizationExpiry ,
1111+ ) ;
9021112 } ) ;
9031113
9041114 it ( 'should handle different token types' , ( ) => {
@@ -915,6 +1125,18 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
9151125
9161126 expect ( usdtTransactions ) . toHaveLength ( 2 ) ; // Reset to 0, then approve amount
9171127
1128+ // Validate first transaction (reset to 0)
1129+ expect ( usdtTransactions [ 0 ] . to ) . toBe ( usdtAddress ) ;
1130+ expect ( usdtTransactions [ 0 ] . value ) . toBe ( 0 ) ;
1131+ expect ( usdtTransactions [ 0 ] . data ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1132+ expect ( usdtTransactions [ 0 ] . data . substring ( 0 , 10 ) ) . toBe ( '0x095ea7b3' ) ; // approve function selector
1133+
1134+ // Validate second transaction (approve amount)
1135+ expect ( usdtTransactions [ 1 ] . to ) . toBe ( usdtAddress ) ;
1136+ expect ( usdtTransactions [ 1 ] . value ) . toBe ( 0 ) ;
1137+ expect ( usdtTransactions [ 1 ] . data ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1138+ expect ( usdtTransactions [ 1 ] . data . substring ( 0 , 10 ) ) . toBe ( '0x095ea7b3' ) ; // approve function selector
1139+
9181140 const regularTransactions = encodeSetCommerceEscrowAllowance ( {
9191141 tokenAddress : erc20ContractAddress ,
9201142 amount : '1000000000000000000' ,
@@ -924,6 +1146,18 @@ describe('ERC20 Commerce Escrow Wrapper Integration', () => {
9241146 } ) ;
9251147
9261148 expect ( regularTransactions ) . toHaveLength ( 1 ) ; // Just approve amount
1149+
1150+ // Validate regular transaction
1151+ expect ( regularTransactions [ 0 ] . to ) . toBe ( erc20ContractAddress ) ;
1152+ expect ( regularTransactions [ 0 ] . value ) . toBe ( 0 ) ;
1153+ expect ( regularTransactions [ 0 ] . data ) . toMatch ( / ^ 0 x [ a - f A - F 0 - 9 ] + $ / ) ;
1154+ expect ( regularTransactions [ 0 ] . data . substring ( 0 , 10 ) ) . toBe ( '0x095ea7b3' ) ; // approve function selector
1155+
1156+ // Verify the wrapper address is encoded in the transaction data
1157+ const wrapperAddress = getCommerceEscrowWrapperAddress ( network ) ;
1158+ expect ( regularTransactions [ 0 ] . data . toLowerCase ( ) ) . toContain (
1159+ wrapperAddress . substring ( 2 ) . toLowerCase ( ) ,
1160+ ) ;
9271161 } ) ;
9281162
9291163 describe ( 'comprehensive edge case scenarios' , ( ) => {
0 commit comments