Skip to content

Commit

Permalink
Merge pull request #448 from casper-ecosystem/update/publickey
Browse files Browse the repository at this point in the history
update public key for easy conversion to key & account hash
  • Loading branch information
ryo-casper authored Jul 10, 2024
2 parents e460d70 + 7666993 commit 92689ee
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 62 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci-casper-client-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- 'dev'
- 'feat-*'
- 'release-*'
- 'condor'
paths-ignore:
- '**.md'

Expand All @@ -16,6 +17,7 @@ on:
- 'dev'
- 'feat-*'
- 'release-*'
- 'condor'
paths-ignore:
- '**.md'

Expand Down
26 changes: 18 additions & 8 deletions e2e/services/CasperServiceByJsonRPC.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,12 @@ describe('CasperServiceByJsonRPC', () => {
expect(peers).to.have.property('peers');
});

it('state_get_auction_info - newest one', async () => {
xit('state_get_auction_info - newest one', async () => {
const validators = await client.getValidatorsInfo();
expect(validators).to.have.property('auction_state');
});

it('state_get_auction_info - by height', async () => {
xit('state_get_auction_info - by height', async () => {
const validators = await client.getValidatorsInfoByBlockHeight(1);
expect(validators).to.have.property('auction_state');
expect(validators.auction_state.block_height).to.be.eq(1);
Expand Down Expand Up @@ -480,7 +480,10 @@ describe('CasperServiceByJsonRPC', () => {
return balance;
};

const balanceOfFaucet = await balanceOf(cep18, faucetKey.publicKey.toAccountHashType());
const balanceOfFaucet = await balanceOf(
cep18,
faucetKey.publicKey.toAccountHash()
);

assert.equal(tokenName, fetchedTokenName);
assert.equal(tokenSymbol, fetchedTokenSymbol);
Expand All @@ -489,7 +492,7 @@ describe('CasperServiceByJsonRPC', () => {
assert.equal(balanceOfFaucet.toNumber(), tokenTotalSupply);

// Test `callEntrypoint` method: Transfter token
const recipient = Ed25519.new().publicKey.toAccountHashType();
const recipient = Ed25519.new().publicKey.toAccountHash();
const transferAmount = 2_000;
const transferArgs = RuntimeArgs.fromMap({
recipient: CLValueBuilder.key(recipient),
Expand All @@ -513,7 +516,8 @@ describe('CasperServiceByJsonRPC', () => {
expect(result.execution_info!.execution_result!).to.have.property(
'Version2'
);
const amorphicExecutionResult: any = result.execution_info!.execution_result!;
const amorphicExecutionResult: any = result.execution_info!
.execution_result!;
if (amorphicExecutionResult['Version2']) {
expect(amorphicExecutionResult['Version2'].error_message).to.be.null;
}
Expand Down Expand Up @@ -591,7 +595,10 @@ describe('CasperServiceByJsonRPC', () => {
'total_supply'
]);

const balanceOfFaucet = await balanceOf(cep18, faucetKey.publicKey.toAccountHashType());
const balanceOfFaucet = await balanceOf(
cep18,
faucetKey.publicKey.toAccountHash()
);

assert.equal(tokenName, fetchedTokenName);
assert.equal(tokenSymbol, fetchedTokenSymbol);
Expand All @@ -603,7 +610,7 @@ describe('CasperServiceByJsonRPC', () => {
const recipient = Ed25519.new().publicKey;
const transferAmount = 2_000;
const transferArgs = RuntimeArgs.fromMap({
recipient: CLValueBuilder.key(recipient.toAccountHashType()),
recipient: CLValueBuilder.key(recipient.toAccountHash()),
amount: CLValueBuilder.u256(2_000)
});

Expand Down Expand Up @@ -654,7 +661,10 @@ describe('CasperServiceByJsonRPC', () => {
expect(amorphicExecutionResult['Version2'].error_message).to.be.null;
}

const balanceOfRecipient = await balanceOf(cep18, recipient.toAccountHashType());
const balanceOfRecipient = await balanceOf(
cep18,
recipient.toAccountHash()
);
assert.equal(balanceOfRecipient.toNumber(), transferAmount);
});

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "casper-js-sdk",
"version": "3.0.0-rc02",
"version": "3.0.0-rc03",
"license": "Apache 2.0",
"description": "SDK to interact with the Casper blockchain",
"homepage": "https://github.com/casper-ecosystem/casper-js-sdk#README.md",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/CLValue/AccountHash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ACCOUNT_HASH_PREFIX,
KeyTag
} from './index';
import { encodeBase16 } from '../Conversions';

// AccountHash is an alias, not a fully functional CLType so uses the same CLTypeTag as ByteArray
export class CLAccountHashType extends CLByteArrayType {
Expand Down Expand Up @@ -75,7 +76,7 @@ export class CLAccountHash extends CLValue implements CLKeyVariant {

toString(): string {
const bytes = this.data;
return Buffer.from(bytes).toString('hex');
return encodeBase16(bytes);
}

toFormattedString(): string {
Expand Down
27 changes: 14 additions & 13 deletions src/lib/CLValue/KeyVariants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
ENTITY_PREFIX,
SYSTEM_ENTITY_PREFIX,
ACCOUNT_ENTITY_PREFIX,
CONTRACT_ENTITY_PREFIX
CONTRACT_ENTITY_PREFIX,
KEY_DEFAULT_BYTE_LENGTH
} from './index';
import { decodeBase16, encodeBase16 } from '../Conversions';
import { toBytesU64 } from '../ByteConverters';
Expand All @@ -38,33 +39,31 @@ import { toBytesU64 } from '../ByteConverters';
// - internal type creator
// - stores data
// - serialize when inside a Key
export abstract class CLKeyVariant {
export abstract class CLKeyVariant<T = any> {
abstract keyVariant: KeyTag;
abstract data: any;
abstract data: T;

value(): any {
value(): T {
return this.data;
}

abstract toString(): string;

abstract toFormattedString(): string;

static fromFormattedStringing(hexStr: string): CLKeyVariant {
static fromFormattedString(hexStr: string): CLKeyVariant {
throw Error(
`Trying to deserialize KeyVariant - unknown string provided: ${hexStr}`
);
}
}

const KEY_HASH_LENGTH = 32;

export const HashParser = {
fromBytesWithRemainder: (
bytes: Uint8Array
): ResultAndRemainder<KeyHashAddr, CLErrorCodes> => {
const hash = new KeyHashAddr(bytes.subarray(0, KEY_HASH_LENGTH));
return resultHelper(Ok(hash), bytes.subarray(KEY_HASH_LENGTH));
const hash = new KeyHashAddr(bytes.subarray(0, KEY_DEFAULT_BYTE_LENGTH));
return resultHelper(Ok(hash), bytes.subarray(KEY_DEFAULT_BYTE_LENGTH));
}
};

Expand Down Expand Up @@ -542,7 +541,9 @@ export const BidAddrParser = {
);
return resultHelper(Ok(bidAddr), remainder);
} else {
return resultHelper<KeyBidAddr, CLErrorCodes>(Err(delegatorRes.val));
return resultHelper<KeyBidAddr, CLErrorCodes>(
Err(delegatorRes.val)
);
}
} else {
return resultHelper<KeyBidAddr, CLErrorCodes>(Err(validatorRes.val));
Expand Down Expand Up @@ -622,13 +623,13 @@ export class KeyBidAddr implements CLKeyVariant {
if (delegator) {
return new KeyBidAddr({
Delegator: {
validator: validator.toAccountHashType(),
delegator: delegator.toAccountHashType()
validator: validator.toAccountHash(),
delegator: delegator.toAccountHash()
}
});
}

return new KeyBidAddr({ Validator: validator.toAccountHashType() });
return new KeyBidAddr({ Validator: validator.toAccountHash() });
}

static credit(validator: CLAccountHash, eraId: BigNumberish) {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/CLValue/PublicKey.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('CLPublicKey', () => {
});

it('Invalid by construction', () => {
// @ts-ignore
const badFn = () => new CLPublicKey(rawEd25519Account, 4);
expect(badFn).to.throw('Unsupported type of public key');
});
Expand Down Expand Up @@ -118,7 +119,7 @@ describe('CLPublicKey', () => {
130, 235, 172, 98
]);

expect(accountHash).to.be.deep.eq(validResult);
expect(accountHash.value()).to.be.deep.eq(validResult);
});

it('isEd25519() valid result', () => {
Expand Down
85 changes: 58 additions & 27 deletions src/lib/CLValue/PublicKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import {
CLErrorCodes,
resultHelper,
ResultAndRemainder,
ToBytesResult
ToBytesResult,
CLKeyVariant
} from './index';
import { PUBLIC_KEY_TYPE, CLTypeTag } from './constants';
import { PUBLIC_KEY_TYPE, CLTypeTag, KeyTag } from './constants';
import { decodeBase16, encodeBase16 } from '../Conversions';
import { byteHash } from '../ByteConverters';

// TODO: Tidy up almost the same enum in Keys.
import { SignatureAlgorithm } from '../Keys';
import { SignatureAlgorithm, accountHashHelper } from '../Keys';
import { encode, isChecksummed } from '../ChecksummedHex';

const ED25519_LENGTH = 32;
Expand Down Expand Up @@ -70,9 +70,10 @@ export class CLPublicKeyBytesParser extends CLValueBytesParsers {
}
}

export class CLPublicKey extends CLValue {
export class CLPublicKey extends CLValue implements CLKeyVariant<Uint8Array> {
data: Uint8Array;
tag: CLPublicKeyTag;
keyVariant = KeyTag.Account;

constructor(
rawPublicKey: Uint8Array,
Expand Down Expand Up @@ -118,7 +119,7 @@ export class CLPublicKey extends CLValue {
return this.tag === CLPublicKeyTag.SECP256K1;
}

toHex(checksummed = true): string {
toString(checksummed = true): string {
// Updated: Returns checksummed hex string
const rawHex = `0${this.tag}${encodeBase16(this.data)}`;
if (checksummed) {
Expand All @@ -128,36 +129,52 @@ export class CLPublicKey extends CLValue {
return rawHex;
}

toAccountHash(): Uint8Array {
const algorithmIdentifier = CLPublicKeyTag[this.tag];
const separator = Uint8Array.from([0]);
const prefix = Buffer.concat([
Buffer.from(algorithmIdentifier.toLowerCase()),
separator
]);
toFormattedString(checksummed = true): string {
return this.toString(checksummed);
}

if (this.data.length === 0) {
return Uint8Array.from([]);
} else {
return byteHash(concat([prefix, this.data]));
}
/**
* Returns hex string representation of the public key.
* @param checksummed if true, returns checksummed hex string
* @returns
* @deprecated Use {@link CLPublicKey.toFormattedString} instead.
*/
toHex(checksummed = true): string {
console.warn(
`CLPublicKey.toHex is deprecated. Use CLPublicKey.toFormattedString instead.`
);
return this.toFormattedString(checksummed);
}

toAccountHashType(): CLAccountHash {
const hash = this.toAccountHash();
toAccountHash(): CLAccountHash {
const hash = accountHashHelper(this.getSignatureAlgorithm(), this.data);
return new CLAccountHash(hash);
}

/**
* Returns formatted account hash string
* @returns
* @deprecated Use {@link CLPublicKey.toAccountHash} instead.
*/
toAccountHashStr(): string {
const bytes = this.toAccountHash();
const hashHex = Buffer.from(bytes).toString('hex');
return `account-hash-${hashHex}`;
console.warn(
`CLPublicKey.toAccountHashStr is deprecated. Use CLPublicKey.toAccountHash().toFormattedString() instead.`
);

return this.toAccountHash().toFormattedString();
}

/**
* Returns unformatted account hash string
* @returns
* @deprecated Use {@link CLPublicKey.toAccountHash} instead.
*/
toAccountRawHashStr(): string {
const bytes = this.toAccountHash();
const hashHex = Buffer.from(bytes).toString('hex');
return hashHex;
console.warn(
`CLPublicKey.toAccountRawHashStr is deprecated. Use CLPublicKey.toAccountHash().toString() instead.`
);

return this.toAccountHash().toString();
}

value(): Uint8Array {
Expand All @@ -178,7 +195,10 @@ export class CLPublicKey extends CLValue {
* @param publicKeyHex public key hex string contains key tag
* @param checksummed throws an Error if true and given string is not checksummed
*/
static fromHex(publicKeyHex: string, checksummed = false): CLPublicKey {
static fromFormattedString(
publicKeyHex: string,
checksummed = false
): CLPublicKey {
if (publicKeyHex.length < 2) {
throw new Error('Asymmetric key error: too short');
}
Expand All @@ -196,6 +216,17 @@ export class CLPublicKey extends CLValue {
return new CLPublicKey(publicKeyHexBytes.subarray(1), publicKeyHexBytes[0]);
}

/**
* Tries to decode PublicKey from its hex-representation.
* The hex format should be as produced by CLPublicKey.toHex
* @param publicKeyHex public key hex string contains key tag
* @param checksummed throws an Error if true and given string is not checksummed
* @deprecated Use {@link CLPublicKey.fromFormattedString} instead.
*/
static fromHex(publicKeyHex: string, checksummed = false): CLPublicKey {
return this.fromFormattedString(publicKeyHex, checksummed);
}

getTag(): CLPublicKeyTag {
return this.tag;
}
Expand Down
Loading

0 comments on commit 92689ee

Please sign in to comment.