Skip to content

Commit

Permalink
Merge pull request #4297 from BitGo/WP-1416-implement-hbar-root-keys
Browse files Browse the repository at this point in the history
feat(sdk-coin-hbar): implement hbar root keys
  • Loading branch information
alebusse authored Feb 21, 2024
2 parents f217006 + 1f85407 commit 9aa87a7
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 9 deletions.
10 changes: 10 additions & 0 deletions modules/sdk-coin-hbar/src/hbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,16 @@ export class Hbar extends BaseCoin {
};
}

/** inheritdoc */
generateRootKeyPair(seed?: Buffer): KeyPair {
const keyPair = seed ? new HbarKeyPair({ seed }) : new HbarKeyPair();
const keys = keyPair.getKeys(true);
if (!keys.prv) {
throw new Error('Missing prv in key generation.');
}
return { prv: keys.prv + keys.pub, pub: keys.pub };
}

async parseTransaction(params: ParseTransactionOptions): Promise<ParsedTransaction> {
return {};
}
Expand Down
95 changes: 86 additions & 9 deletions modules/sdk-coin-hbar/test/unit/hbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,9 @@ describe('Hedera Hashgraph:', function () {
});

describe('Sign transaction:', () => {
const destination = '0.0.129369';
const source = '0.0.1234';
const amount = '100000';
/**
* Build an unsigned account-lib multi-signature send transaction
* @param destination The destination address of the transaction
Expand All @@ -511,18 +514,13 @@ describe('Hedera Hashgraph:', function () {
fee: '100000',
});
txBuilder.source({ address: source });
txBuilder.to(destination);
txBuilder.amount(amount);
txBuilder.send({ address: destination, amount });

return await txBuilder.build();
};

it('should sign transaction', async function () {
const key = new KeyPair();
const destination = '0.0.129369';
const source = '0.0.1234';
const amount = '100000';

const unsignedTransaction = await buildUnsignedTransaction({
destination,
source,
Expand All @@ -540,15 +538,68 @@ describe('Hedera Hashgraph:', function () {
const txBuilder = factory.from(tx.halfSigned.txHex);
const signedTx = await txBuilder.build();
const txJson = signedTx.toJson() as TxData;
txJson.to!.should.equal(destination);
txJson.from!.should.equal(source);
txJson.amount!.should.equal(amount);
txJson.should.have.properties('to', 'amount');
txJson.to?.should.equal(destination);
txJson.from.should.equal(source);
txJson.amount?.should.equal(amount);
(txJson.instructionsData as Transfer).params.recipients[0].should.deepEqual({
address: destination,
amount,
});
signedTx.signature.length.should.equal(1);
});

it('should fully sign transaction with root key', async function () {
const key1 = basecoin.generateRootKeyPair();
const key2 = basecoin.generateRootKeyPair();

const unsignedTransaction = await buildUnsignedTransaction({
destination,
source,
amount,
});

const txHalfSigned = await basecoin.signTransaction({
prv: key1.prv,
txPrebuild: {
txHex: unsignedTransaction.toBroadcastFormat(),
},
});

const factory = getBuilderFactory('thbar');
const txBuilderHalfSigned = factory.from(txHalfSigned.halfSigned.txHex);
const halfSignedTx = await txBuilderHalfSigned.build();
const halfSignedTxJson = halfSignedTx.toJson() as TxData;
halfSignedTxJson.should.have.properties('to', 'amount');
halfSignedTxJson.to?.should.equal(destination);
halfSignedTxJson.from.should.equal(source);
halfSignedTxJson.amount?.should.equal(amount);
(halfSignedTxJson.instructionsData as Transfer).params.recipients[0].should.deepEqual({
address: destination,
amount,
});
halfSignedTx.signature.length.should.equal(1);

const txSigned = await basecoin.signTransaction({
prv: key2.prv,
txPrebuild: {
txHex: halfSignedTx.toBroadcastFormat(),
},
});

const txBuilderSigned = factory.from(txSigned.txHex);
const signedTx = await txBuilderSigned.build();
const signedTxJson = signedTx.toJson() as TxData;
signedTxJson.should.have.properties('to', 'amount');
signedTxJson.to?.should.equal(destination);
signedTxJson.from.should.equal(source);
signedTxJson.amount?.should.equal(amount);
(signedTxJson.instructionsData as Transfer).params.recipients[0].should.deepEqual({
address: destination,
amount,
});
signedTx.signature.length.should.equal(2);
});
});

describe('Recovery', function () {
Expand Down Expand Up @@ -947,4 +998,30 @@ describe('Hedera Hashgraph:', function () {
}).should.throw('method deriveKeyWithSeed not supported for eddsa curve');
});
});

describe('Generate wallet Root key pair: ', () => {
it('should generate key pair', () => {
const kp = basecoin.generateRootKeyPair();
basecoin.isValidPub(kp.pub).should.equal(true);
const keypair = new KeyPair({ prv: kp.prv }).getKeys(true);
keypair.should.have.property('prv');
keypair.prv?.should.equal(kp.prv.slice(0, 64));
keypair.pub.should.equal(kp.pub);
});

it('should generate key pair from seed', () => {
const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
const kp = basecoin.generateRootKeyPair(seed);
basecoin.isValidPub(kp.pub).should.equal(true);
kp.pub.should.equal('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a');
kp.prv.should.equal(
'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a'
);

const keypair = new KeyPair({ prv: kp.prv }).getKeys(true);
keypair.should.have.property('prv');
keypair.prv?.should.equal(kp.prv.slice(0, 64));
keypair.pub.should.equal(kp.pub);
});
});
});

0 comments on commit 9aa87a7

Please sign in to comment.