@@ -14,8 +14,12 @@ import {
1414 getFormattedEthLikeTokenConfig ,
1515 getEthLikeTokens ,
1616 getFormattedTokens ,
17+ getFormattedTokensByNetwork ,
18+ verifyTokens ,
1719 EthLikeTokenConfig ,
1820 TokenTypeEnum ,
21+ BaseTokenConfig ,
22+ BaseContractAddressConfig ,
1923} from '../../src/tokenConfig' ;
2024import { EthLikeERC20Token } from '../../src/account' ;
2125
@@ -552,4 +556,209 @@ describe('EthLike Token Config Functions', function () {
552556 } ) ;
553557 } ) ;
554558 } ) ;
559+
560+ describe ( 'getFormattedTokensByNetwork' , function ( ) {
561+ it ( 'should return tokens for Mainnet network' , function ( ) {
562+ const result = getFormattedTokensByNetwork ( 'Mainnet' , coins ) ;
563+
564+ result . should . be . an . Object ( ) ;
565+ result . should . have . property ( 'eth' ) ;
566+ result . eth . should . have . property ( 'tokens' ) ;
567+ result . eth . should . have . property ( 'nfts' ) ;
568+
569+ // All eth tokens should be Mainnet
570+ result . eth . tokens . forEach ( ( token ) => {
571+ token . network . should . equal ( 'Mainnet' ) ;
572+ } ) ;
573+ } ) ;
574+
575+ it ( 'should return tokens for Testnet network' , function ( ) {
576+ const result = getFormattedTokensByNetwork ( 'Testnet' , coins ) ;
577+
578+ result . should . be . an . Object ( ) ;
579+ result . should . have . property ( 'eth' ) ;
580+ result . eth . should . have . property ( 'tokens' ) ;
581+ result . eth . should . have . property ( 'nfts' ) ;
582+
583+ // All eth tokens should be Testnet
584+ result . eth . tokens . forEach ( ( token ) => {
585+ token . network . should . equal ( 'Testnet' ) ;
586+ } ) ;
587+ } ) ;
588+
589+ it ( 'should return the same chain keys for both networks' , function ( ) {
590+ const mainnetResult = getFormattedTokensByNetwork ( 'Mainnet' , coins ) ;
591+ const testnetResult = getFormattedTokensByNetwork ( 'Testnet' , coins ) ;
592+
593+ const mainnetKeys = Object . keys ( mainnetResult ) . sort ( ) ;
594+ const testnetKeys = Object . keys ( testnetResult ) . sort ( ) ;
595+
596+ mainnetKeys . should . deepEqual ( testnetKeys ) ;
597+ } ) ;
598+
599+ it ( 'should have no duplicate token types within any chain' , function ( ) {
600+ const mainnetResult = getFormattedTokensByNetwork ( 'Mainnet' , coins ) ;
601+ const testnetResult = getFormattedTokensByNetwork ( 'Testnet' , coins ) ;
602+
603+ // Check for duplicates in Mainnet
604+ Object . entries ( mainnetResult ) . forEach ( ( [ chain , chainData ] ) => {
605+ if ( chainData . tokens && chainData . tokens . length > 0 ) {
606+ const tokenTypes = chainData . tokens . map ( ( t ) => t . type ) ;
607+ const uniqueTokenTypes = new Set ( tokenTypes ) ;
608+ const duplicates = tokenTypes . filter ( ( t , i ) => tokenTypes . indexOf ( t ) !== i ) ;
609+ tokenTypes . length . should . equal (
610+ uniqueTokenTypes . size ,
611+ `Mainnet ${ chain } has duplicate token types: ${ duplicates } `
612+ ) ;
613+ }
614+ } ) ;
615+
616+ // Check for duplicates in Testnet
617+ Object . entries ( testnetResult ) . forEach ( ( [ chain , chainData ] ) => {
618+ if ( chainData . tokens && chainData . tokens . length > 0 ) {
619+ const tokenTypes = chainData . tokens . map ( ( t ) => t . type ) ;
620+ const uniqueTokenTypes = new Set ( tokenTypes ) ;
621+ const duplicates = tokenTypes . filter ( ( t , i ) => tokenTypes . indexOf ( t ) !== i ) ;
622+ tokenTypes . length . should . equal (
623+ uniqueTokenTypes . size ,
624+ `Testnet ${ chain } has duplicate token types: ${ duplicates } `
625+ ) ;
626+ }
627+ } ) ;
628+ } ) ;
629+
630+ it ( 'should filter tokens correctly by network type' , function ( ) {
631+ const mainnetResult = getFormattedTokensByNetwork ( 'Mainnet' , coins ) ;
632+ const testnetResult = getFormattedTokensByNetwork ( 'Testnet' , coins ) ;
633+
634+ // Verify no testnet tokens in mainnet result
635+ Object . values ( mainnetResult ) . forEach ( ( chainData ) => {
636+ if ( chainData . tokens && chainData . tokens . length > 0 ) {
637+ chainData . tokens . forEach ( ( token ) => {
638+ if ( token && token . network ) {
639+ token . network . should . equal ( 'Mainnet' ) ;
640+ }
641+ } ) ;
642+ }
643+ if ( 'nfts' in chainData && chainData . nfts && chainData . nfts . length > 0 ) {
644+ chainData . nfts . forEach ( ( nft ) => {
645+ if ( nft && nft . network ) {
646+ nft . network . should . equal ( 'Mainnet' ) ;
647+ }
648+ } ) ;
649+ }
650+ } ) ;
651+
652+ // Verify no mainnet tokens in testnet result
653+ Object . values ( testnetResult ) . forEach ( ( chainData ) => {
654+ if ( chainData . tokens && chainData . tokens . length > 0 ) {
655+ chainData . tokens . forEach ( ( token ) => {
656+ if ( token && token . network ) {
657+ token . network . should . equal ( 'Testnet' ) ;
658+ }
659+ } ) ;
660+ }
661+ if ( 'nfts' in chainData && chainData . nfts && chainData . nfts . length > 0 ) {
662+ chainData . nfts . forEach ( ( nft ) => {
663+ if ( nft && nft . network ) {
664+ nft . network . should . equal ( 'Testnet' ) ;
665+ }
666+ } ) ;
667+ }
668+ } ) ;
669+ } ) ;
670+ } ) ;
671+
672+ describe ( 'verifyTokens' , function ( ) {
673+ it ( 'should return verified tokens record when no duplicates exist' , function ( ) {
674+ const mockTokens : BaseTokenConfig [ ] = [
675+ { type : 'token1' , coin : 'eth' , name : 'Token 1' , decimalPlaces : 18 } ,
676+ { type : 'token2' , coin : 'eth' , name : 'Token 2' , decimalPlaces : 18 } ,
677+ { type : 'token3' , coin : 'eth' , name : 'Token 3' , decimalPlaces : 6 } ,
678+ ] ;
679+
680+ const result = verifyTokens ( mockTokens ) ;
681+
682+ result . should . be . an . Object ( ) ;
683+ result . should . have . property ( 'token1' , true ) ;
684+ result . should . have . property ( 'token2' , true ) ;
685+ result . should . have . property ( 'token3' , true ) ;
686+ } ) ;
687+
688+ it ( 'should throw an error when duplicate token types exist' , function ( ) {
689+ const mockTokensWithDuplicates : BaseTokenConfig [ ] = [
690+ { type : 'token1' , coin : 'eth' , name : 'Token 1' , decimalPlaces : 18 } ,
691+ { type : 'token2' , coin : 'eth' , name : 'Token 2' , decimalPlaces : 18 } ,
692+ { type : 'token1' , coin : 'eth' , name : 'Token 1 Duplicate' , decimalPlaces : 18 } , // Duplicate
693+ ] ;
694+
695+ ( ( ) => {
696+ verifyTokens ( mockTokensWithDuplicates ) ;
697+ } ) . should . throw ( 'token : token1 duplicated.' ) ;
698+ } ) ;
699+
700+ it ( 'should throw an error when token contract address is not lowercase' , function ( ) {
701+ const mockTokensWithUppercaseAddress : BaseContractAddressConfig [ ] = [
702+ {
703+ type : 'token1' ,
704+ coin : 'eth' ,
705+ name : 'Token 1' ,
706+ decimalPlaces : 18 ,
707+ network : 'Mainnet' ,
708+ tokenContractAddress : '0xAbCdEf1234567890AbCdEf1234567890AbCdEf12' , // Mixed case
709+ } ,
710+ ] ;
711+
712+ ( ( ) => {
713+ verifyTokens ( mockTokensWithUppercaseAddress ) ;
714+ } ) . should . throw ( / t o k e n c o n t r a c t : t o k e n 1 i s n o t a l l l o w e r c a s e / ) ;
715+ } ) ;
716+
717+ it ( 'should pass when token contract address is lowercase' , function ( ) {
718+ const mockTokensWithLowercaseAddress : BaseContractAddressConfig [ ] = [
719+ {
720+ type : 'token1' ,
721+ coin : 'eth' ,
722+ name : 'Token 1' ,
723+ decimalPlaces : 18 ,
724+ network : 'Mainnet' ,
725+ tokenContractAddress : '0xabcdef1234567890abcdef1234567890abcdef12' , // All lowercase
726+ } ,
727+ ] ;
728+
729+ const result = verifyTokens ( mockTokensWithLowercaseAddress ) ;
730+ result . should . have . property ( 'token1' , true ) ;
731+ } ) ;
732+
733+ it ( 'should handle empty token array' , function ( ) {
734+ const result = verifyTokens ( [ ] ) ;
735+
736+ result . should . be . an . Object ( ) ;
737+ Object . keys ( result ) . length . should . equal ( 0 ) ;
738+ } ) ;
739+
740+ it ( 'should verify real tokens from getFormattedTokens have no duplicates' , function ( ) {
741+ const formattedTokens = getFormattedTokens ( ) ;
742+
743+ // Test mainnet eth tokens
744+ ( ( ) => {
745+ verifyTokens ( formattedTokens . bitcoin . eth . tokens ) ;
746+ } ) . should . not . throw ( ) ;
747+
748+ // Test testnet eth tokens
749+ ( ( ) => {
750+ verifyTokens ( formattedTokens . testnet . eth . tokens ) ;
751+ } ) . should . not . throw ( ) ;
752+
753+ // Test mainnet xlm tokens
754+ ( ( ) => {
755+ verifyTokens ( formattedTokens . bitcoin . xlm . tokens ) ;
756+ } ) . should . not . throw ( ) ;
757+
758+ // Test testnet xlm tokens
759+ ( ( ) => {
760+ verifyTokens ( formattedTokens . testnet . xlm . tokens ) ;
761+ } ) . should . not . throw ( ) ;
762+ } ) ;
763+ } ) ;
555764} ) ;
0 commit comments