Skip to content

Commit f59f680

Browse files
authored
fix: do not fallback evm address to starknet (#1162)
* test: add more getFormattedAddress casing test * test: update test to test the error message * fix: consider 42 chars address as evm address * chore: remove comment
1 parent 8bb09a1 commit f59f680

File tree

2 files changed

+253
-50
lines changed

2 files changed

+253
-50
lines changed

src/utils.spec.js

Lines changed: 247 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -505,66 +505,267 @@ describe('utils', () => {
505505

506506
describe('getFormattedAddress', () => {
507507
describe('when explicitly passing an address type', () => {
508-
test('returns a checksummed EVM address', () => {
509-
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
510-
expect(getFormattedAddress(address, 'evm')).toEqual(
511-
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
512-
);
513-
});
508+
describe('EVM type parsing', () => {
509+
test('should return checksummed EVM address when given checksummed input', () => {
510+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
511+
expect(getFormattedAddress(address, 'evm')).toEqual(
512+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
513+
);
514+
});
514515

515-
test('returns a padded and lowercased starknet address', () => {
516-
const address =
517-
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
518-
expect(getFormattedAddress(address, 'starknet')).toEqual(
519-
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
520-
);
521-
});
516+
test('should return checksummed EVM address when given lowercase input', () => {
517+
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
518+
expect(getFormattedAddress(address, 'evm')).toEqual(
519+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
520+
);
521+
});
522522

523-
test('returns an EVM address as starknet address', () => {
524-
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
525-
expect(getFormattedAddress(address, 'starknet')).toEqual(
526-
'0x00000000000000000000000091fd2c8d24767db4ece7069aa27832ffaf8590f3'
527-
);
528-
});
523+
test('should return checksummed EVM address when given uppercase input', () => {
524+
const uppercaseAddress = '0x91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
525+
expect(getFormattedAddress(uppercaseAddress, 'evm')).toEqual(
526+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
527+
);
528+
});
529+
530+
test('should throw error when forcing EVM parsing on address with uppercase 0X prefix', () => {
531+
const uppercaseHexPrefix =
532+
'0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
533+
expect(() => getFormattedAddress(uppercaseHexPrefix, 'evm')).toThrow(
534+
'Invalid evm address: 0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3'
535+
);
536+
});
537+
538+
test('should throw error when forcing EVM parsing on invalid mixed case address', () => {
539+
const invalidMixedCaseAddress =
540+
'0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3';
541+
expect(() =>
542+
getFormattedAddress(invalidMixedCaseAddress, 'evm')
543+
).toThrow(
544+
'Invalid evm address: 0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3'
545+
);
546+
});
529547

530-
test('throws an error when the address is not a starknet address', () => {
531-
const address = 'hello';
532-
expect(() => getFormattedAddress(address, 'starknet')).toThrow();
548+
test('should throw error when address is not an EVM address', () => {
549+
const address =
550+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
551+
expect(() => getFormattedAddress(address, 'evm')).toThrow(
552+
'Invalid evm address: 0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
553+
);
554+
});
533555
});
534556

535-
test('throws an error when the address is not an EVM address', () => {
536-
const address =
537-
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
538-
expect(() => getFormattedAddress(address, 'evm')).toThrow();
557+
describe('Starknet type parsing', () => {
558+
test('should return padded and lowercased starknet address when given unpadded input', () => {
559+
const address =
560+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
561+
expect(getFormattedAddress(address, 'starknet')).toEqual(
562+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
563+
);
564+
});
565+
566+
test('should return padded and lowercased starknet address when given lowercase input', () => {
567+
const address =
568+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
569+
expect(getFormattedAddress(address, 'starknet')).toEqual(
570+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
571+
);
572+
});
573+
574+
test('should return padded and lowercased starknet address when given uppercase Starknet input', () => {
575+
const uppercaseAddress =
576+
'0x02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
577+
expect(getFormattedAddress(uppercaseAddress, 'starknet')).toEqual(
578+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
579+
);
580+
});
581+
582+
test('should return padded and lowercased starknet address when given checksum Starknet input', () => {
583+
const checksumAddress =
584+
'0x02a0a8F3B6097e7A6bd7649DEB30715323072A159c0E6B71B689Bd245c146cC0';
585+
expect(getFormattedAddress(checksumAddress, 'starknet')).toEqual(
586+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
587+
);
588+
});
589+
590+
test('should return padded and lowercased starknet address when given mixed case Starknet input', () => {
591+
const mixedCaseAddress =
592+
'0x02A0a8F3B6097e7A6bD7649DEB30715323072a159C0e6b71B689BD245c146Cc0';
593+
expect(getFormattedAddress(mixedCaseAddress, 'starknet')).toEqual(
594+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
595+
);
596+
});
597+
598+
test('should return EVM address as starknet address when explicitly formatted', () => {
599+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
600+
expect(getFormattedAddress(address, 'starknet')).toEqual(
601+
'0x00000000000000000000000091fd2c8d24767db4ece7069aa27832ffaf8590f3'
602+
);
603+
});
604+
605+
test('should throw error when given invalid Starknet address with explicit format', () => {
606+
const invalidStarknetAddress = '0xinvalidstarknetaddresshere';
607+
expect(() =>
608+
getFormattedAddress(invalidStarknetAddress, 'starknet')
609+
).toThrow('Invalid starknet address: 0xinvalidstarknetaddresshere');
610+
});
539611
});
540612
});
541613

542614
describe('when not passing an address type', () => {
543-
test('returns a checksummed EVM address for an EVM input', () => {
544-
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
545-
expect(getFormattedAddress(address)).toEqual(
546-
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
547-
);
548-
});
615+
describe('EVM address auto-detection', () => {
616+
test('should auto-detect and format valid 42-char lowercase EVM address', () => {
617+
const address = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
618+
expect(getFormattedAddress(address)).toEqual(
619+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
620+
);
621+
});
549622

550-
test('returns a padded and lowercased starknet address for a Starknet input', () => {
551-
const address =
552-
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
553-
expect(getFormattedAddress(address)).toEqual(
554-
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
555-
);
623+
test('should auto-detect and format valid 42-char uppercase EVM address', () => {
624+
const address = '0x91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
625+
expect(getFormattedAddress(address)).toEqual(
626+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
627+
);
628+
});
629+
630+
test('should auto-detect and format valid 42-char checksummed EVM address', () => {
631+
const address = '0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3';
632+
expect(getFormattedAddress(address)).toEqual(
633+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
634+
);
635+
});
636+
637+
test('should throw error when auto-detecting invalid mixed case EVM address', () => {
638+
const invalidMixedCaseAddress =
639+
'0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3';
640+
expect(() => getFormattedAddress(invalidMixedCaseAddress)).toThrow(
641+
'Invalid evm address: 0x91Fd2C8d24767Db4eCe7069aA27832FfaF8590F3'
642+
);
643+
});
644+
645+
test('should throw error when auto-detecting 42-char invalid hex address', () => {
646+
const invalidHexAddress =
647+
'0xgggggggggggggggggggggggggggggggggggggggg';
648+
expect(() => getFormattedAddress(invalidHexAddress)).toThrow(
649+
'Invalid evm address: 0xgggggggggggggggggggggggggggggggggggggggg'
650+
);
651+
});
652+
653+
test('should throw error when auto-detecting EVM address with uppercase 0X prefix', () => {
654+
const uppercaseHexPrefix =
655+
'0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3';
656+
expect(() => getFormattedAddress(uppercaseHexPrefix)).toThrow(
657+
'Invalid evm address: 0X91FD2C8D24767DB4ECE7069AA27832FFAF8590F3'
658+
);
659+
});
556660
});
557661

558-
test('throws an error when the input is not address-like', () => {
559-
const address = 'hello';
560-
expect(() => getFormattedAddress(address)).toThrow();
662+
describe('Starknet address auto-detection', () => {
663+
test('should auto-detect and format valid unpadded Starknet address', () => {
664+
const address =
665+
'0x2a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
666+
expect(getFormattedAddress(address)).toEqual(
667+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
668+
);
669+
});
670+
671+
test('should auto-detect and format valid padded Starknet address', () => {
672+
const address =
673+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0';
674+
expect(getFormattedAddress(address)).toEqual(
675+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
676+
);
677+
});
678+
679+
test('should auto-detect and format uppercase Starknet address', () => {
680+
const address =
681+
'0x02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
682+
expect(getFormattedAddress(address)).toEqual(
683+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
684+
);
685+
});
686+
687+
test('should return padded and lowercased address when input has uppercase 0X prefix', () => {
688+
const fullyUppercaseAddress =
689+
'0X02A0A8F3B6097E7A6BD7649DEB30715323072A159C0E6B71B689BD245C146CC0';
690+
expect(getFormattedAddress(fullyUppercaseAddress)).toEqual(
691+
'0x02a0a8f3b6097e7a6bd7649deb30715323072a159c0e6b71b689bd245c146cc0'
692+
);
693+
});
694+
695+
test('should return padded and lowercased address when given short input', () => {
696+
const address = '0x1';
697+
expect(getFormattedAddress(address)).toEqual(
698+
'0x0000000000000000000000000000000000000000000000000000000000000001'
699+
);
700+
});
701+
702+
test('should auto-detect actual 41-char address as Starknet', () => {
703+
const address = '0x123456789012345678901234567890123456789';
704+
expect(getFormattedAddress(address)).toEqual(
705+
'0x0000000000000000000000000123456789012345678901234567890123456789'
706+
);
707+
});
708+
709+
test('should auto-detect 43+ char address as Starknet', () => {
710+
const address = '0x123456789012345678901234567890123456789012';
711+
expect(getFormattedAddress(address)).toEqual(
712+
'0x0000000000000000000000123456789012345678901234567890123456789012'
713+
);
714+
});
561715
});
562716

563-
test('returns a padded and lowercased starknet address for any non-EVM like address input', () => {
564-
const address = '0x1';
565-
expect(getFormattedAddress(address)).toEqual(
566-
'0x0000000000000000000000000000000000000000000000000000000000000001'
567-
);
717+
describe('Invalid address format', () => {
718+
test('should throw error when passing invalid format argument', () => {
719+
const validAddress = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
720+
expect(() => getFormattedAddress(validAddress, 'invalid')).toThrow(
721+
'Invalid invalid address: 0x91fd2c8d24767db4ece7069aa27832ffaf8590f3'
722+
);
723+
});
724+
725+
test('should treat undefined format parameter as auto-detection', () => {
726+
const evmAddress = '0x91fd2c8d24767db4ece7069aa27832ffaf8590f3';
727+
expect(getFormattedAddress(evmAddress, undefined)).toEqual(
728+
'0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3'
729+
);
730+
});
731+
732+
test('should throw error when parsing invalid string', () => {
733+
const invalidString = 'hello';
734+
expect(() => getFormattedAddress(invalidString)).toThrow(
735+
'Invalid address: hello'
736+
);
737+
});
738+
739+
test('should throw error when parsing empty string', () => {
740+
const emptyString = '';
741+
expect(() => getFormattedAddress(emptyString)).toThrow(
742+
'Invalid address: '
743+
);
744+
});
745+
746+
test('should throw error when parsing null input', () => {
747+
expect(() => getFormattedAddress(null)).toThrow(
748+
'Invalid address: null'
749+
);
750+
});
751+
752+
test('should throw error when parsing undefined input', () => {
753+
expect(() => getFormattedAddress(undefined)).toThrow(
754+
'Invalid address: undefined'
755+
);
756+
});
757+
758+
test('should throw error when parsing number input', () => {
759+
expect(() => getFormattedAddress(123)).toThrow(
760+
'Invalid address: 123'
761+
);
762+
});
763+
764+
test('should throw error when parsing object input', () => {
765+
expect(() => getFormattedAddress({})).toThrow(
766+
'Invalid address: [object Object]'
767+
);
768+
});
568769
});
569770
});
570771
});

src/utils.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -830,16 +830,18 @@ export function getFormattedAddress(
830830
address: string,
831831
format?: 'evm' | 'starknet'
832832
): string {
833-
// Consider non-evm addresses as Starknet by default
834-
// as there's no other way to differentiate them
835-
const addressType = format ?? (isEvmAddress(address) ? 'evm' : 'starknet');
833+
if (typeof address !== 'string' || !/^0[xX]/.test(address)) {
834+
throw new Error(`Invalid address: ${address}`);
835+
}
836+
837+
const addressType = format ?? (address.length === 42 ? 'evm' : 'starknet');
836838

837839
if (addressType === 'evm' && isEvmAddress(address))
838840
return getAddress(address);
839841
if (addressType === 'starknet' && isStarknetAddress(address))
840842
return validateAndParseAddress(address);
841843

842-
throw new Error(`Invalid address: ${address}`);
844+
throw new Error(`Invalid ${addressType} address: ${address}`);
843845
}
844846

845847
function inputError(message: string) {

0 commit comments

Comments
 (0)