nostr-keypair.spec.ts raw

   1  import { NostrKeyPair, InvalidNostrKeyError } from './nostr-keypair';
   2  
   3  describe('NostrKeyPair Value Object', () => {
   4    // Known test vectors
   5    const TEST_PRIVATE_KEY_HEX = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
   6  
   7    describe('generate', () => {
   8      it('should generate a valid keypair', () => {
   9        const keyPair = NostrKeyPair.generate();
  10  
  11        expect(keyPair.publicKeyHex).toBeTruthy();
  12        expect(keyPair.publicKeyHex.length).toBe(64);
  13      });
  14  
  15      it('should generate unique keypairs each time', () => {
  16        const keyPair1 = NostrKeyPair.generate();
  17        const keyPair2 = NostrKeyPair.generate();
  18  
  19        expect(keyPair1.publicKeyHex).not.toEqual(keyPair2.publicKeyHex);
  20      });
  21    });
  22  
  23    describe('fromPrivateKey', () => {
  24      it('should create keypair from valid hex private key', () => {
  25        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  26  
  27        expect(keyPair.publicKeyHex).toBeTruthy();
  28        expect(keyPair.publicKeyHex.length).toBe(64);
  29      });
  30  
  31      it('should throw InvalidNostrKeyError for empty string', () => {
  32        expect(() => NostrKeyPair.fromPrivateKey('')).toThrowError(InvalidNostrKeyError);
  33      });
  34  
  35      it('should throw InvalidNostrKeyError for invalid hex', () => {
  36        expect(() => NostrKeyPair.fromPrivateKey('not-valid-hex')).toThrowError(InvalidNostrKeyError);
  37      });
  38  
  39      it('should throw InvalidNostrKeyError for hex that is too short', () => {
  40        const shortHex = '0123456789abcdef';
  41        expect(() => NostrKeyPair.fromPrivateKey(shortHex)).toThrowError(InvalidNostrKeyError);
  42      });
  43    });
  44  
  45    describe('public key formats', () => {
  46      it('should return hex public key', () => {
  47        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  48  
  49        expect(keyPair.publicKeyHex).toMatch(/^[0-9a-f]{64}$/);
  50      });
  51  
  52      it('should return npub format', () => {
  53        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  54  
  55        expect(keyPair.npub).toMatch(/^npub1[a-z0-9]+$/);
  56      });
  57  
  58      it('should return nsec format', () => {
  59        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  60  
  61        expect(keyPair.nsec).toMatch(/^nsec1[a-z0-9]+$/);
  62      });
  63    });
  64  
  65    describe('getPrivateKeyBytes', () => {
  66      it('should return 32-byte Uint8Array', () => {
  67        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  68        const bytes = keyPair.getPrivateKeyBytes();
  69  
  70        expect(bytes).toBeInstanceOf(Uint8Array);
  71        expect(bytes.length).toBe(32);
  72      });
  73    });
  74  
  75    describe('toStorageHex', () => {
  76      it('should return the hex private key for storage', () => {
  77        const keyPair = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  78  
  79        expect(keyPair.toStorageHex()).toEqual(TEST_PRIVATE_KEY_HEX);
  80      });
  81    });
  82  
  83    describe('deterministic derivation', () => {
  84      it('should derive the same public key from the same private key', () => {
  85        const keyPair1 = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  86        const keyPair2 = NostrKeyPair.fromPrivateKey(TEST_PRIVATE_KEY_HEX);
  87  
  88        expect(keyPair1.publicKeyHex).toEqual(keyPair2.publicKeyHex);
  89      });
  90    });
  91  });
  92