Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create Cip1854ExtendedAccountPublicKey core type #1346

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions packages/core/src/Cardano/types/Cip1854ExtendedAccountPublicKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as BaseEncoding from '@scure/base';
import { Bip32PublicKeyHex } from '@cardano-sdk/crypto';
import { InvalidStringError, OpaqueString, assertIsBech32WithPrefix } from '@cardano-sdk/util';

const MAX_BECH32_LENGTH_LIMIT = 1023;
const bip32PublicKeyPrefix = 'acct_shared_xvk';

/** This key is a bech32 encoded string with the prefix `acct_shared_xvk`. */
export type Cip1854ExtendedAccountPublicKey = OpaqueString<'Cip1854PublicKey'>;
mkazlauskas marked this conversation as resolved.
Show resolved Hide resolved

export const Cip1854ExtendedAccountPublicKey = (value: string): Cip1854ExtendedAccountPublicKey => {
try {
assertIsBech32WithPrefix(value, [bip32PublicKeyPrefix]);
} catch {
throw new InvalidStringError(value, 'Expected key to be a bech32 encoded string');
}

return value as Cip1854ExtendedAccountPublicKey;
};

Cip1854ExtendedAccountPublicKey.fromBip32PublicKeyHex = (value: Bip32PublicKeyHex): Cip1854ExtendedAccountPublicKey => {
const words = BaseEncoding.bech32.toWords(Buffer.from(value, 'hex'));
return Cip1854ExtendedAccountPublicKey(
BaseEncoding.bech32.encode(bip32PublicKeyPrefix, words, MAX_BECH32_LENGTH_LIMIT)
);
};

Cip1854ExtendedAccountPublicKey.toBip32PublicKeyHex = (value: Cip1854ExtendedAccountPublicKey): Bip32PublicKeyHex => {
const { words } = BaseEncoding.bech32.decode(value, MAX_BECH32_LENGTH_LIMIT);
return Bip32PublicKeyHex(Buffer.from(BaseEncoding.bech32.fromWords(words)).toString('hex'));
};
1 change: 1 addition & 0 deletions packages/core/src/Cardano/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export * from './ProtocolParameters';
export * from './PlutusData';
export * from './UtilityTypes';
export * from './Governance';
export * from './Cip1854ExtendedAccountPublicKey';
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Bip32PublicKeyHex } from '@cardano-sdk/crypto';
import { Cip1854ExtendedAccountPublicKey } from '../../../src/Cardano';

const bip32PublicKeyPrefix = 'acct_shared_xvk';

describe('Cardano/types/Cip1854ExtendedAccountPublicKey', () => {
const publicKeyHex = Bip32PublicKeyHex(
'979693650bb44f26010e9f7b3b550b0602c748d1d00981747bac5c34cf5b945fe01a39317b9b701e58ee16b5ed16aa4444704b98cc997bdd6c5a9502a8b7d70d'
);

describe('Cip1854ExtendedAccountPublicKey', () => {
it('Accepts a valid bech32-encoded CIP1854 public key', () => {
const bip32PublicKey =
'acct_shared_xvk1q395kywke7mufrysg33nsm6ggjxswu4g8q8ag7ks9kdyaczchtemd5d2armrfstfa32lamhxfl3sskgcmxm4zdhtvut362796ez4ecqx6vnht';
expect(Cip1854ExtendedAccountPublicKey(bip32PublicKey)).toEqual(bip32PublicKey);
});

it('Throws an error when an invalid bech32-encoded CIP1854 public key is passed', () => {
expect(() => Cip1854ExtendedAccountPublicKey(publicKeyHex)).toThrow();
expect(() =>
Cip1854ExtendedAccountPublicKey(
'addr_test1qpfhhfy2qgls50r9u4yh0l7z67xpg0a5rrhkmvzcuqrd0znuzcjqw982pcftgx53fu5527z2cj2tkx2h8ux2vxsg475q9gw0lz'
)
).toThrow();
expect(() => Cip1854ExtendedAccountPublicKey('invalid')).toThrow();
});
});

it('fromBip32PublicKeyHex encodes a valid CIP1854 bip32 public key according to CIP5 specification', () => {
const cip1854PublicKey = Cip1854ExtendedAccountPublicKey.fromBip32PublicKeyHex(publicKeyHex);
expect(cip1854PublicKey.startsWith(bip32PublicKeyPrefix)).toBe(true);
});

it('toBip32PublicKeyHex decodes a bech32-encoded CIP1854 bip32 public key to a hex string', () => {
const cip1854PublicKey = Cip1854ExtendedAccountPublicKey.fromBip32PublicKeyHex(publicKeyHex);
const originalHex = Cip1854ExtendedAccountPublicKey.toBip32PublicKeyHex(cip1854PublicKey);
expect(originalHex).toEqual(publicKeyHex);
});
});
Loading