Skip to content

Commit 048b2b7

Browse files
author
Kirill Maksimov
committed
Introduce Signer to better manage keys
1 parent 20f6f1b commit 048b2b7

File tree

7 files changed

+54
-34
lines changed

7 files changed

+54
-34
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "orbs-client-sdk",
3-
"version": "1.3.1",
3+
"version": "2.0.0",
44
"description": "orbs-client-sdk",
55
"main": "dist/orbs-client-sdk.js",
66
"browser": "dist/orbs-client-sdk-web.js",

src/codec/OpRunQuery.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ import { RequestStatus, requestStatusDecode } from "./RequestStatus";
1616
import { ExecutionResult, executionResultDecode } from "./ExecutionResult";
1717
import { Argument, packedArgumentsDecode, packedArgumentsEncode } from "./Arguments";
1818
import { Event, packedEventsDecode } from "./Events";
19+
import { Signer } from "../crypto/Signature";
1920

2021
export interface RunQueryRequest {
2122
protocolVersion: number;
2223
virtualChainId: number;
2324
timestamp: Date;
2425
networkType: NetworkType;
25-
publicKey: Uint8Array;
2626
contractName: string;
2727
methodName: string;
2828
inputArguments: Argument[];
@@ -37,15 +37,11 @@ export interface RunQueryResponse {
3737
blockTimestamp: Date;
3838
}
3939

40-
export function encodeRunQueryRequest(req: RunQueryRequest): Uint8Array {
40+
export function encodeRunQueryRequest(req: RunQueryRequest, signer: Signer): Uint8Array {
4141
// validate
4242
if (req.protocolVersion != 1) {
4343
throw new Error(`expected ProtocolVersion 1, ${req.protocolVersion} given`);
4444
}
45-
if (req.publicKey.byteLength != Keys.ED25519_PUBLIC_KEY_SIZE_BYTES) {
46-
throw new Error(`expected PublicKey length ${Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, ${req.publicKey.byteLength} given`);
47-
}
48-
4945
// encode method arguments
5046
const inputArgumentArray = packedArgumentsEncode(req.inputArguments);
5147

@@ -63,7 +59,7 @@ export function encodeRunQueryRequest(req: RunQueryRequest): Uint8Array {
6359
scheme: 0,
6460
eddsa: new Protocol.EdDSA01SignerBuilder({
6561
networkType: networkType,
66-
signerPublicKey: req.publicKey,
62+
signerPublicKey: signer.getPublicKey(),
6763
}),
6864
}),
6965
contractName: req.contractName,

src/codec/OpSendTransaction.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import { Event, packedEventsDecode } from "./Events";
1818
import { RequestStatus, requestStatusDecode } from "./RequestStatus";
1919
import { ExecutionResult, executionResultDecode } from "./ExecutionResult";
2020
import { TransactionStatus, transactionStatusDecode } from "./TransactionStatus";
21+
import { Signer } from "../crypto/Signature";
2122

2223
export interface SendTransactionRequest {
2324
protocolVersion: number;
2425
virtualChainId: number;
2526
timestamp: Date;
2627
networkType: NetworkType;
27-
publicKey: Uint8Array;
2828
contractName: string;
2929
methodName: string;
3030
inputArguments: Argument[];
@@ -41,17 +41,11 @@ export interface SendTransactionResponse {
4141
blockTimestamp: Date;
4242
}
4343

44-
export function encodeSendTransactionRequest(req: SendTransactionRequest, privateKey: Uint8Array): [Uint8Array, Uint8Array] {
44+
export function encodeSendTransactionRequest(req: SendTransactionRequest, signer: Signer): [Uint8Array, Uint8Array] {
4545
// validate
4646
if (req.protocolVersion != 1) {
4747
throw new Error(`expected ProtocolVersion 1, ${req.protocolVersion} given`);
4848
}
49-
if (req.publicKey.byteLength != Keys.ED25519_PUBLIC_KEY_SIZE_BYTES) {
50-
throw new Error(`expected PublicKey length ${Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, ${req.publicKey.byteLength} given`);
51-
}
52-
if (privateKey.byteLength != Keys.ED25519_PRIVATE_KEY_SIZE_BYTES) {
53-
throw new Error(`expected PublicKey length ${Keys.ED25519_PRIVATE_KEY_SIZE_BYTES}, ${privateKey.byteLength} given`);
54-
}
5549

5650
// encode method arguments
5751
const inputArgumentArray = packedArgumentsEncode(req.inputArguments);
@@ -73,7 +67,7 @@ export function encodeSendTransactionRequest(req: SendTransactionRequest, privat
7367
scheme: 0,
7468
eddsa: new Protocol.EdDSA01SignerBuilder({
7569
networkType: networkType,
76-
signerPublicKey: req.publicKey,
70+
signerPublicKey: signer.getPublicKey(),
7771
}),
7872
}),
7973
contractName: req.contractName,
@@ -93,7 +87,7 @@ export function encodeSendTransactionRequest(req: SendTransactionRequest, privat
9387

9488
// sign
9589
const txHash = Digest.calcTxHash(transactionBuf);
96-
const sig = Signature.signEd25519(privateKey, txHash);
90+
const sig = signer.signEd25519(txHash);
9791
signedTransactionMsg.setBytes(1, sig);
9892

9993
// return

src/codec/contract.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { decodeGetTransactionReceiptProofResponse, encodeGetTransactionReceiptPr
1414
import { decodeGetTransactionStatusResponse, encodeGetTransactionStatusRequest } from "./OpGetTransactionStatus";
1515
import { decodeRunQueryResponse, encodeRunQueryRequest } from "./OpRunQuery";
1616
import { decodeSendTransactionResponse, encodeSendTransactionRequest } from "./OpSendTransaction";
17+
import { DefaultSigner } from "../crypto/Signature";
1718

1819
describe("Codec contract", () => {
1920
let contractInput: any;
@@ -33,19 +34,17 @@ describe("Codec contract", () => {
3334
test(`Test Id: ${inputScenario.Test}`, () => {
3435
// SendTransactionRequest
3536
if (inputScenario.SendTransactionRequest) {
37+
const signer = new DefaultSigner({publicKey: jsonUnmarshalBase64Bytes(inputScenario.PublicKey), privateKey: jsonUnmarshalBase64Bytes(inputScenario.PrivateKey)});
3638
const [encoded, txId] = encodeSendTransactionRequest(
3739
{
3840
protocolVersion: jsonUnmarshalNumber(inputScenario.SendTransactionRequest.ProtocolVersion),
3941
virtualChainId: jsonUnmarshalNumber(inputScenario.SendTransactionRequest.VirtualChainId),
4042
timestamp: new Date(inputScenario.SendTransactionRequest.Timestamp),
4143
networkType: inputScenario.SendTransactionRequest.NetworkType,
42-
publicKey: jsonUnmarshalBase64Bytes(inputScenario.SendTransactionRequest.PublicKey),
4344
contractName: inputScenario.SendTransactionRequest.ContractName,
4445
methodName: inputScenario.SendTransactionRequest.MethodName,
4546
inputArguments: jsonUnmarshalArguments(inputScenario.SendTransactionRequest.InputArguments, inputScenario.SendTransactionRequest.InputArgumentsTypes),
46-
},
47-
jsonUnmarshalBase64Bytes(inputScenario.PrivateKey),
48-
);
47+
}, signer);
4948
const expected = jsonUnmarshalBase64Bytes(outputScenario.SendTransactionRequest);
5049
expect(encoded).toBeEqualToUint8Array(expected);
5150
const expectedTxId = jsonUnmarshalBase64Bytes(outputScenario.TxId);
@@ -55,16 +54,17 @@ describe("Codec contract", () => {
5554

5655
// RunQueryRequest
5756
if (inputScenario.RunQueryRequest) {
57+
const signer = new DefaultSigner({publicKey: jsonUnmarshalBase64Bytes(inputScenario.PublicKey), privateKey: jsonUnmarshalBase64Bytes(inputScenario.PrivateKey)});
58+
5859
const encoded = encodeRunQueryRequest({
5960
protocolVersion: jsonUnmarshalNumber(inputScenario.RunQueryRequest.ProtocolVersion),
6061
virtualChainId: jsonUnmarshalNumber(inputScenario.RunQueryRequest.VirtualChainId),
6162
timestamp: new Date(inputScenario.RunQueryRequest.Timestamp),
6263
networkType: inputScenario.RunQueryRequest.NetworkType,
63-
publicKey: jsonUnmarshalBase64Bytes(inputScenario.RunQueryRequest.PublicKey),
6464
contractName: inputScenario.RunQueryRequest.ContractName,
6565
methodName: inputScenario.RunQueryRequest.MethodName,
6666
inputArguments: jsonUnmarshalArguments(inputScenario.RunQueryRequest.InputArguments, inputScenario.RunQueryRequest.InputArgumentsTypes),
67-
});
67+
}, signer);
6868
const expected = jsonUnmarshalBase64Bytes(outputScenario.RunQueryRequest);
6969
expect(encoded).toBeEqualToUint8Array(expected);
7070
return;

src/crypto/Signature.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,36 @@ import elliptic from "elliptic";
1111

1212
export const ED25519_SIGNATURE_SIZE_BYTES = 64;
1313

14+
export interface Signer {
15+
getPublicKey(): Uint8Array;
16+
signEd25519(data: Uint8Array): Uint8Array;
17+
}
18+
19+
export class DefaultSigner implements Signer {
20+
constructor(
21+
private fields: {
22+
publicKey: Uint8Array;
23+
privateKey: Uint8Array;
24+
}
25+
) {
26+
if (this.fields.publicKey.byteLength != Keys.ED25519_PUBLIC_KEY_SIZE_BYTES) {
27+
throw new Error(`expected PublicKey length ${Keys.ED25519_PUBLIC_KEY_SIZE_BYTES}, ${this.fields.publicKey.byteLength} given`);
28+
}
29+
30+
if (this.fields.privateKey.byteLength != Keys.ED25519_PRIVATE_KEY_SIZE_BYTES) {
31+
throw new Error(`expected PublicKey length ${Keys.ED25519_PRIVATE_KEY_SIZE_BYTES}, ${this.fields.privateKey.byteLength} given`);
32+
}
33+
}
34+
35+
signEd25519(data: Uint8Array): Uint8Array {
36+
return signEd25519(this.fields.privateKey, data);
37+
}
38+
39+
getPublicKey(): Uint8Array {
40+
return this.fields.publicKey;
41+
}
42+
}
43+
1444
export function signEd25519(privateKey: Uint8Array, data: Uint8Array): Uint8Array {
1545
if (privateKey.byteLength != Keys.ED25519_PRIVATE_KEY_SIZE_BYTES) {
1646
throw new Error(`cannot sign with ed25519, private key invalid with length ${privateKey.byteLength}`);

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ export { Client, PROCESSOR_TYPE_NATIVE, PROCESSOR_TYPE_JAVASCRIPT } from "./orbs
1313
export { calcClientAddressOfEd25519PublicKey, contractNameToAddressAsBytes } from "./crypto/Digest";
1414
export { encodeHex, decodeHex } from "./crypto/Encoding";
1515
export { argUint32, argUint64, argString, argBytes, argAddress } from "./codec/Arguments";
16-
export { NetworkType } from "./codec/NetworkType";
16+
export { NetworkType } from "./codec/NetworkType";
17+
export { DefaultSigner } from "./crypto/Signature";

src/orbs/Client.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { decodeGetTransactionReceiptProofResponse, encodeGetTransactionReceiptPr
1616
import { decodeGetBlockResponse, encodeGetBlockRequest, GetBlockResponse } from "../codec/OpGetBlock";
1717
import axios, { AxiosResponse } from "axios";
1818
import { getTextDecoder } from "../membuffers/text";
19+
import { Signer } from "../crypto/Signature";
1920

2021
const PROTOCOL_VERSION = 1;
2122
const CONTENT_TYPE_MEMBUFFERS = "application/membuffers";
@@ -29,46 +30,44 @@ export const PROCESSOR_TYPE_NATIVE = 1;
2930
export const PROCESSOR_TYPE_JAVASCRIPT = 2;
3031

3132
export class Client {
32-
constructor(private endpoint: string, private virtualChainId: number, private networkType: NetworkType) {}
33+
constructor(private endpoint: string, private virtualChainId: number, private networkType: NetworkType, private signer: Signer) {}
3334

34-
createTransaction(publicKey: Uint8Array, privateKey: Uint8Array, contractName: string, methodName: string, inputArguments: Argument[]): [Uint8Array, string] {
35+
createTransaction(contractName: string, methodName: string, inputArguments: Argument[]): [Uint8Array, string] {
3536
const [req, rawTxId] = encodeSendTransactionRequest(
3637
{
3738
protocolVersion: PROTOCOL_VERSION,
3839
virtualChainId: this.virtualChainId,
3940
timestamp: new Date(),
4041
networkType: this.networkType,
41-
publicKey: publicKey,
4242
contractName: contractName,
4343
methodName: methodName,
4444
inputArguments: inputArguments,
4545
},
46-
privateKey,
46+
this.signer,
4747
);
4848
return [req, Encoding.encodeHex(rawTxId)];
4949
}
5050

51-
createDeployTransaction(publicKey: Uint8Array, privateKey: Uint8Array, contractName: string, processorType: number, ...sources: Uint8Array[]): [Uint8Array, string] {
51+
createDeployTransaction(contractName: string, processorType: number, ...sources: Uint8Array[]): [Uint8Array, string] {
5252
const inputArguments: Argument[] = [
5353
argString(contractName),
5454
argUint32(processorType),
5555
...sources.map(argBytes)
5656
];
5757

58-
return this.createTransaction(publicKey, privateKey, "_Deployments", "deployService", inputArguments);
58+
return this.createTransaction("_Deployments", "deployService", inputArguments);
5959
}
6060

61-
createQuery(publicKey: Uint8Array, contractName: string, methodName: string, inputArguments: Argument[]): Uint8Array {
61+
createQuery(contractName: string, methodName: string, inputArguments: Argument[]): Uint8Array {
6262
return encodeRunQueryRequest({
6363
protocolVersion: PROTOCOL_VERSION,
6464
virtualChainId: this.virtualChainId,
6565
timestamp: new Date(),
6666
networkType: this.networkType,
67-
publicKey: publicKey,
6867
contractName: contractName,
6968
methodName: methodName,
7069
inputArguments: inputArguments,
71-
});
70+
}, this.signer);
7271
}
7372

7473
protected createGetTransactionStatusPayload(txId: string): Uint8Array {

0 commit comments

Comments
 (0)