Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

Commit

Permalink
Merge e80c368 into 77a21b3
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarcia360 committed May 26, 2020
2 parents 77a21b3 + e80c368 commit 92d9b10
Show file tree
Hide file tree
Showing 8 changed files with 387 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ import { TransactionSignatureOptions } from '../../services/transaction.signatur
export class CommandOptions extends AnnounceTransactionsOptions {
@option({
flag: 'u',
description: 'Remote account public key.',
description: 'Linked Public Key.',
})
publicKey: string;
linkedPublicKey: string;

@option({
flag: 'a',
Expand All @@ -41,7 +41,7 @@ export class CommandOptions extends AnnounceTransactionsOptions {
}

@command({
description: 'Delegate the account importance to a proxy account',
description: 'Delegate the account importance to a proxy account. Required for all accounts willing to activate delegated harvesting.',
})
export default class extends AnnounceTransactionsCommand {
constructor() {
Expand All @@ -53,14 +53,19 @@ export default class extends AnnounceTransactionsCommand {
const profile = this.getProfile(options);
const password = await new PasswordResolver().resolve(options);
const account = profile.decrypt(password);
const publicKey = (
await new PublicKeyResolver().resolve(options, profile.networkType, 'Enter the public key of the remote account: ')
const linkedPublicKey = (
await new PublicKeyResolver().resolve(
options,
profile.networkType,
'Enter the public key of the remote account: ',
'linkedPublicKey',
)
).publicKey;
const action = await new LinkActionResolver().resolve(options);
const maxFee = await new MaxFeeResolver().resolve(options);
const signerMultisigInfo = await this.getSignerMultisigInfo(options);

const transaction = AccountKeyLinkTransaction.create(Deadline.create(), publicKey, action, profile.networkType, maxFee);
const transaction = AccountKeyLinkTransaction.create(Deadline.create(), linkedPublicKey, action, profile.networkType, maxFee);

const signatureOptions: TransactionSignatureOptions = {
account,
Expand Down
75 changes: 75 additions & 0 deletions src/commands/transaction/nodekeylink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { command, metadata, option } from 'clime';
import { Deadline, NodeKeyLinkTransaction } from 'symbol-sdk';

import { AnnounceTransactionsCommand } from '../../interfaces/announce.transactions.command';
import { AnnounceTransactionsOptions } from '../../interfaces/announceTransactions.options';
import { LinkActionResolver } from '../../resolvers/action.resolver';
import { MaxFeeResolver } from '../../resolvers/maxFee.resolver';
import { PasswordResolver } from '../../resolvers/password.resolver';
import { PublicKeyResolver } from '../../resolvers/publicKey.resolver';
import { TransactionSignatureOptions } from '../../services/transaction.signature.service';

export class CommandOptions extends AnnounceTransactionsOptions {
@option({
flag: 'u',
description: 'Linked Public Key.',
})
linkedPublicKey: string;

@option({
flag: 'a',
description: 'Alias action (Link, Unlink).',
})
action: string;
}

@command({
description: 'Link an account with a public key used by TLS to create sessions. Required for node operators.',
})
export default class extends AnnounceTransactionsCommand {
constructor() {
super();
}

@metadata
async execute(options: CommandOptions) {
const profile = this.getProfile(options);
const password = await new PasswordResolver().resolve(options);
const account = profile.decrypt(password);
const linkedPublicKey = (
await new PublicKeyResolver().resolve(options, profile.networkType, 'Enter the public key to link: ', 'linkedPublicKey')
).publicKey;
const action = await new LinkActionResolver().resolve(options);
const maxFee = await new MaxFeeResolver().resolve(options);
const signerMultisigInfo = await this.getSignerMultisigInfo(options);

const transaction = NodeKeyLinkTransaction.create(Deadline.create(), linkedPublicKey, action, profile.networkType, maxFee);

const signatureOptions: TransactionSignatureOptions = {
account,
transactions: [transaction],
maxFee,
signerMultisigInfo,
};

const signedTransactions = await this.signTransactions(signatureOptions, options);
this.announceTransactions(options, signedTransactions);
}
}
73 changes: 73 additions & 0 deletions src/commands/transaction/votingkeylink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { command, metadata, option } from 'clime';
import { Deadline, VotingKeyLinkTransaction } from 'symbol-sdk';

import { AnnounceTransactionsCommand } from '../../interfaces/announce.transactions.command';
import { AnnounceTransactionsOptions } from '../../interfaces/announceTransactions.options';
import { LinkActionResolver } from '../../resolvers/action.resolver';
import { BLSPublicKeyResolver } from '../../resolvers/bls.resolver';
import { MaxFeeResolver } from '../../resolvers/maxFee.resolver';
import { PasswordResolver } from '../../resolvers/password.resolver';
import { TransactionSignatureOptions } from '../../services/transaction.signature.service';

export class CommandOptions extends AnnounceTransactionsOptions {
@option({
flag: 'u',
description: 'BLS Linked Public Key.',
})
linkedPublicKey: string;

@option({
flag: 'a',
description: 'Alias action (Link, Unlink).',
})
action: string;
}

@command({
description: 'Link an account with a BLS public key. Required for node operators willing to vote finalized blocks. ',
})
export default class extends AnnounceTransactionsCommand {
constructor() {
super();
}

@metadata
async execute(options: CommandOptions) {
const profile = this.getProfile(options);
const password = await new PasswordResolver().resolve(options);
const account = profile.decrypt(password);
const linkedPublicKey = await new BLSPublicKeyResolver().resolve(options);
const action = await new LinkActionResolver().resolve(options);
const maxFee = await new MaxFeeResolver().resolve(options);
const signerMultisigInfo = await this.getSignerMultisigInfo(options);

const transaction = VotingKeyLinkTransaction.create(Deadline.create(), linkedPublicKey, action, profile.networkType, maxFee);

const signatureOptions: TransactionSignatureOptions = {
account,
transactions: [transaction],
maxFee,
signerMultisigInfo,
};

const signedTransactions = await this.signTransactions(signatureOptions, options);
this.announceTransactions(options, signedTransactions);
}
}
75 changes: 75 additions & 0 deletions src/commands/transaction/vrfkeylink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { command, metadata, option } from 'clime';
import { Deadline, VrfKeyLinkTransaction } from 'symbol-sdk';

import { AnnounceTransactionsCommand } from '../../interfaces/announce.transactions.command';
import { AnnounceTransactionsOptions } from '../../interfaces/announceTransactions.options';
import { LinkActionResolver } from '../../resolvers/action.resolver';
import { MaxFeeResolver } from '../../resolvers/maxFee.resolver';
import { PasswordResolver } from '../../resolvers/password.resolver';
import { PublicKeyResolver } from '../../resolvers/publicKey.resolver';
import { TransactionSignatureOptions } from '../../services/transaction.signature.service';

export class CommandOptions extends AnnounceTransactionsOptions {
@option({
flag: 'u',
description: 'Linked Public Key.',
})
linkedPublicKey: string;

@option({
flag: 'a',
description: 'Alias action (Link, Unlink).',
})
action: string;
}

@command({
description: 'Link an account with a VRF public key. Required for all harvesting eligible accounts.',
})
export default class extends AnnounceTransactionsCommand {
constructor() {
super();
}

@metadata
async execute(options: CommandOptions) {
const profile = this.getProfile(options);
const password = await new PasswordResolver().resolve(options);
const account = profile.decrypt(password);
const linkedPublicKey = (
await new PublicKeyResolver().resolve(options, profile.networkType, 'Enter the public key to link: ', 'linkedPublicKey')
).publicKey;
const action = await new LinkActionResolver().resolve(options);
const maxFee = await new MaxFeeResolver().resolve(options);
const signerMultisigInfo = await this.getSignerMultisigInfo(options);

const transaction = VrfKeyLinkTransaction.create(Deadline.create(), linkedPublicKey, action, profile.networkType, maxFee);

const signatureOptions: TransactionSignatureOptions = {
account,
transactions: [transaction],
maxFee,
signerMultisigInfo,
};

const signedTransactions = await this.signTransactions(signatureOptions, options);
this.announceTransactions(options, signedTransactions);
}
}
47 changes: 47 additions & 0 deletions src/resolvers/bls.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

import { Options } from 'clime';

import { OptionsResolver } from '../options-resolver';
import { BLSPublicKeyValidator } from '../validators/bls.validator';
import { Resolver } from './resolver';

/**
* BLS public key resolver
*/
export class BLSPublicKeyResolver implements Resolver {
/**
* Resolves a BLS public key provided by the user.
* @param {Options} options - Command options.
* @param {string} altText - Alternative text.
* @param {string} altKey - Alternative key.
* @returns {Promise<PublicAccount>}
*/
async resolve(options: Options, altText?: string, altKey?: string): Promise<string> {
const resolution = await OptionsResolver(
options,
altKey ? altKey : 'linkedPublicKey',
() => undefined,
altText ? altText : 'Enter the BLS public key: ',
'text',
new BLSPublicKeyValidator(),
);
return resolution;
}
}
32 changes: 32 additions & 0 deletions src/validators/bls.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { Validator } from './validator';

/**
* BLS public key validator
*/
export class BLSPublicKeyValidator implements Validator<string> {
/**
* Validates a BLS public key format.
* @param {string} value - Private key.
* @returns {true | string}
*/
validate(value: string): boolean | string {
return value.length !== 96 || !/^[0-9a-fA-F]+$/.test(value) ? 'BLS public key should be a 96 characters hexadecimal string' : true;
}
}
34 changes: 34 additions & 0 deletions test/resolvers/bls.resolver.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect } from 'chai';

/*
*
* Copyright 2018-present NEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { BLSPublicKeyResolver } from '../../src/resolvers/bls.resolver';

describe('BLS public key resolver', () => {
it('should return public key', async () => {
const linkedPublicKey = '0'.repeat(96);
const options = { linkedPublicKey } as any;
expect(await new BLSPublicKeyResolver().resolve(options)).to.be.equal(linkedPublicKey);
});

it('should return public key (alternative)', async () => {
const publicKey = '0'.repeat(96);
const options = { publicKey } as any;
expect(await new BLSPublicKeyResolver().resolve(options, 'test', 'publicKey')).to.be.equal(publicKey);
});
});

0 comments on commit 92d9b10

Please sign in to comment.