@@ -677,7 +677,7 @@ describe('Tempo coin - parseTransaction / verifyTransaction', () => {
677677 ] ,
678678 } ,
679679 } ) ,
680- / c a l l \( s \) /
680+ / o p e r a t i o n \( s \) /
681681 ) ;
682682 } ) ;
683683
@@ -819,6 +819,21 @@ describe('Raw Contract Call Builder', () => {
819819 assert . throws ( ( ) => builder . addRawCall ( { to : mockContract , data : 'a9059cbb' } ) , / I n v a l i d c a l l d a t a / ) ;
820820 } ) ;
821821
822+ it ( 'should throw for odd-length hex calldata' , ( ) => {
823+ const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
824+ assert . throws ( ( ) => builder . addRawCall ( { to : mockContract , data : '0xabc' } ) , / I n v a l i d c a l l d a t a / ) ;
825+ } ) ;
826+
827+ it ( 'should throw for invalid value string' , ( ) => {
828+ const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
829+ assert . throws ( ( ) => builder . addRawCall ( { to : mockContract , data : mockCalldata , value : '1e18' } ) , / I n v a l i d v a l u e / ) ;
830+ } ) ;
831+
832+ it ( 'should throw for negative value' , ( ) => {
833+ const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
834+ assert . throws ( ( ) => builder . addRawCall ( { to : mockContract , data : mockCalldata , value : '-1' } ) , / I n v a l i d v a l u e / ) ;
835+ } ) ;
836+
822837 it ( 'should allow raw-call-only transaction (no operations)' , async ( ) => {
823838 const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
824839 builder
@@ -906,61 +921,19 @@ describe('Raw Contract Call Builder', () => {
906921 } ) ;
907922 } ) ;
908923
909- describe ( 'Mixed: operations + raw calls' , ( ) => {
910- it ( 'should build and round-trip a transaction with both operations and raw calls' , async ( ) => {
911- const tokenAddress = ethers . utils . getAddress ( TESTNET_TOKENS . alphaUSD . address ) ;
912- const recipientAddress = ethers . utils . getAddress ( TEST_RECIPIENT_ADDRESS ) ;
913-
924+ describe ( 'Raw call toJson and outputs' , ( ) => {
925+ it ( 'should expose raw call contract address as output' , async ( ) => {
914926 const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
915927 builder
916- . addOperation ( { token : tokenAddress , to : recipientAddress , amount : '10.0' , memo : '1' } )
917- . addRawCall ( { to : mockContract , data : mockCalldata } )
918- . nonce ( 1 )
919- . gas ( 200000n )
920- . maxFeePerGas ( TX_PARAMS . defaultMaxFeePerGas )
921- . maxPriorityFeePerGas ( TX_PARAMS . defaultMaxPriorityFeePerGas ) ;
922-
923- const originalTx = ( await builder . build ( ) ) as Tip20Transaction ;
924- assert . strictEqual ( originalTx . getOperations ( ) . length , 1 ) ;
925- assert . strictEqual ( originalTx . getRawCalls ( ) . length , 1 ) ;
926- assert . strictEqual ( originalTx . getOperationCount ( ) , 2 ) ;
927-
928- const serialized = await originalTx . serialize ( ) ;
929-
930- const builder2 = new Tip20TransactionBuilder ( mockCoinConfig ) ;
931- builder2 . from ( serialized ) ;
932- const restoredTx = ( await builder2 . build ( ) ) as Tip20Transaction ;
933-
934- assert . strictEqual ( restoredTx . getOperations ( ) . length , 1 ) ;
935- assert . strictEqual ( restoredTx . getRawCalls ( ) . length , 1 ) ;
936- assert . strictEqual ( restoredTx . getOperationCount ( ) , 2 ) ;
937-
938- const ops = restoredTx . getOperations ( ) ;
939- assert . strictEqual ( ops [ 0 ] . to . toLowerCase ( ) , recipientAddress . toLowerCase ( ) ) ;
940- assert . strictEqual ( ops [ 0 ] . amount , '10.0' ) ;
941-
942- const rawCalls = restoredTx . getRawCalls ( ) ;
943- assert . strictEqual ( rawCalls [ 0 ] . to . toLowerCase ( ) , mockContract . toLowerCase ( ) ) ;
944- assert . strictEqual ( rawCalls [ 0 ] . data . toLowerCase ( ) , mockCalldata . toLowerCase ( ) ) ;
945- } ) ;
946-
947- it ( 'should expose outputs for both operations and raw calls' , async ( ) => {
948- const tokenAddress = ethers . utils . getAddress ( TESTNET_TOKENS . alphaUSD . address ) ;
949- const recipientAddress = ethers . utils . getAddress ( TEST_RECIPIENT_ADDRESS ) ;
950-
951- const builder = new Tip20TransactionBuilder ( mockCoinConfig ) ;
952- builder
953- . addOperation ( { token : tokenAddress , to : recipientAddress , amount : '5.0' } )
954928 . addRawCall ( { to : mockContract , data : mockCalldata , value : '0' } )
955929 . nonce ( 2 )
956930 . gas ( 200000n )
957931 . maxFeePerGas ( TX_PARAMS . defaultMaxFeePerGas )
958932 . maxPriorityFeePerGas ( TX_PARAMS . defaultMaxPriorityFeePerGas ) ;
959933
960934 const tx = ( await builder . build ( ) ) as Tip20Transaction ;
961- assert . strictEqual ( tx . outputs . length , 2 ) ;
962- assert . strictEqual ( tx . outputs [ 0 ] . address . toLowerCase ( ) , recipientAddress . toLowerCase ( ) ) ;
963- assert . strictEqual ( tx . outputs [ 1 ] . address . toLowerCase ( ) , mockContract . toLowerCase ( ) ) ;
935+ assert . strictEqual ( tx . outputs . length , 1 ) ;
936+ assert . strictEqual ( tx . outputs [ 0 ] . address . toLowerCase ( ) , mockContract . toLowerCase ( ) ) ;
964937 } ) ;
965938
966939 it ( 'should include rawCalls in toJson() output' , async ( ) => {
0 commit comments