Skip to content

Commit 768c4cc

Browse files
committed
feat(besu): add keychain reference signing support
Also 1. increases test coverage 2. updates the test contract to have state altering methods Signed-off-by: Peter Somogyvari <[email protected]>
1 parent 00b7e62 commit 768c4cc

File tree

8 files changed

+744
-75
lines changed

8 files changed

+744
-75
lines changed

packages/cactus-plugin-ledger-connector-besu/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"web3-eea": "0.10.0"
7979
},
8080
"devDependencies": {
81+
"@hyperledger/cactus-plugin-keychain-memory": "^0.2.0",
8182
"@hyperledger/cactus-test-tooling": "0.2.0",
8283
"@types/express": "4.17.8",
8384
"@types/joi": "14.3.4"

packages/cactus-plugin-ledger-connector-besu/src/main/json/generated/openapi-spec.json

+37
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
{
4040
"$ref": "#/components/schemas/Web3SigningCredentialGethKeychainPassword"
4141
},
42+
{
43+
"$ref": "#/components/schemas/Web3SigningCredentialCactusKeychainRef"
44+
},
4245
{
4346
"$ref": "#/components/schemas/Web3SigningCredentialPrivateKeyHex"
4447
},
@@ -78,6 +81,39 @@
7881
}
7982
}
8083
},
84+
"Web3SigningCredentialCactusKeychainRef": {
85+
"type": "object",
86+
"required": [
87+
"type",
88+
"ethAccount",
89+
"keychainId",
90+
"keychainEntryKey"
91+
],
92+
"properties": {
93+
"type": {
94+
"$ref": "#/components/schemas/Web3SigningCredentialType"
95+
},
96+
"ethAccount": {
97+
"type": "string",
98+
"description": "The ethereum account (public key) that the credential belongs to. Basically the username in the traditional terminology of authentication.",
99+
"minLength": 64,
100+
"maxLength": 64,
101+
"nullable": false
102+
},
103+
"keychainEntryKey": {
104+
"type": "string",
105+
"description": "The key to use when looking up the the keychain entry holding the secret pointed to by the keychainEntryKey parameter.",
106+
"minLength": 0,
107+
"maxLength": 1024
108+
},
109+
"keychainId": {
110+
"type": "string",
111+
"description": "The keychain ID to use when looking up the the keychain plugin instance that will be used to retrieve the secret pointed to by the keychainEntryKey parameter.",
112+
"minLength": 0,
113+
"maxLength": 1024
114+
}
115+
}
116+
},
81117
"Web3SigningCredentialPrivateKeyHex": {
82118
"type": "object",
83119
"required": [
@@ -119,6 +155,7 @@
119155
"Web3SigningCredentialType": {
120156
"type": "string",
121157
"enum": [
158+
"CACTUS_KEYCHAIN_REF",
122159
"GETH_KEYCHAIN_PASSWORD",
123160
"PRIVATE_KEY_HEX",
124161
"NONE"

packages/cactus-plugin-ledger-connector-besu/src/main/typescript/generated/openapi/typescript-axios/api.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,39 @@ export interface SolidityContractJsonArtifact {
319319
* @type Web3SigningCredential
320320
* @export
321321
*/
322-
export type Web3SigningCredential = Web3SigningCredentialGethKeychainPassword | Web3SigningCredentialNone | Web3SigningCredentialPrivateKeyHex;
322+
export type Web3SigningCredential = Web3SigningCredentialCactusKeychainRef | Web3SigningCredentialGethKeychainPassword | Web3SigningCredentialNone | Web3SigningCredentialPrivateKeyHex;
323323

324+
/**
325+
*
326+
* @export
327+
* @interface Web3SigningCredentialCactusKeychainRef
328+
*/
329+
export interface Web3SigningCredentialCactusKeychainRef {
330+
/**
331+
*
332+
* @type {Web3SigningCredentialType}
333+
* @memberof Web3SigningCredentialCactusKeychainRef
334+
*/
335+
type: Web3SigningCredentialType;
336+
/**
337+
* The ethereum account (public key) that the credential belongs to. Basically the username in the traditional terminology of authentication.
338+
* @type {string}
339+
* @memberof Web3SigningCredentialCactusKeychainRef
340+
*/
341+
ethAccount: string;
342+
/**
343+
* The key to use when looking up the the keychain entry holding the secret pointed to by the keychainEntryKey parameter.
344+
* @type {string}
345+
* @memberof Web3SigningCredentialCactusKeychainRef
346+
*/
347+
keychainEntryKey: string;
348+
/**
349+
* The keychain ID to use when looking up the the keychain plugin instance that will be used to retrieve the secret pointed to by the keychainEntryKey parameter.
350+
* @type {string}
351+
* @memberof Web3SigningCredentialCactusKeychainRef
352+
*/
353+
keychainId: string;
354+
}
324355
/**
325356
*
326357
* @export
@@ -390,6 +421,7 @@ export interface Web3SigningCredentialPrivateKeyHex {
390421
* @enum {string}
391422
*/
392423
export enum Web3SigningCredentialType {
424+
CACTUSKEYCHAINREF = 'CACTUS_KEYCHAIN_REF',
393425
GETHKEYCHAINPASSWORD = 'GETH_KEYCHAIN_PASSWORD',
394426
PRIVATEKEYHEX = 'PRIVATE_KEY_HEX',
395427
NONE = 'NONE'

packages/cactus-plugin-ledger-connector-besu/src/main/typescript/openapi-spec.ts

+46-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ export const CACTUS_OPEN_API_JSON: OpenAPIV3.Document = {
4343
$ref:
4444
"#/components/schemas/Web3SigningCredentialGethKeychainPassword",
4545
},
46+
{
47+
$ref: "#/components/schemas/Web3SigningCredentialCactusKeychainRef",
48+
},
4649
{ $ref: "#/components/schemas/Web3SigningCredentialPrivateKeyHex" },
4750
{ $ref: "#/components/schemas/Web3SigningCredentialNone" },
4851
],
@@ -76,6 +79,43 @@ export const CACTUS_OPEN_API_JSON: OpenAPIV3.Document = {
7679
},
7780
},
7881
},
82+
Web3SigningCredentialCactusKeychainRef: {
83+
type: "object",
84+
required: ["type", "ethAccount", "keychainId", "keychainEntryKey"],
85+
properties: {
86+
type: {
87+
$ref: "#/components/schemas/Web3SigningCredentialType",
88+
},
89+
ethAccount: {
90+
type: "string",
91+
description:
92+
"The ethereum account (public key) that the credential " +
93+
" belongs to. Basically the username in the traditional " +
94+
" terminology of authentication.",
95+
minLength: 64,
96+
maxLength: 64,
97+
nullable: false,
98+
},
99+
keychainEntryKey: {
100+
type: "string",
101+
description:
102+
"The key to use when looking up the" +
103+
" the keychain entry holding the secret pointed to by the " +
104+
" keychainEntryKey parameter.",
105+
minLength: 0,
106+
maxLength: 1024,
107+
},
108+
keychainId: {
109+
type: "string",
110+
description:
111+
"The keychain ID to use when looking up the" +
112+
" the keychain plugin instance that will be used to retrieve" +
113+
" the secret pointed to by the keychainEntryKey parameter.",
114+
minLength: 0,
115+
maxLength: 1024,
116+
},
117+
},
118+
},
79119
Web3SigningCredentialPrivateKeyHex: {
80120
type: "object",
81121
required: ["type", "ethAccount", "secret"],
@@ -114,7 +154,12 @@ export const CACTUS_OPEN_API_JSON: OpenAPIV3.Document = {
114154
},
115155
Web3SigningCredentialType: {
116156
type: "string",
117-
enum: ["GETH_KEYCHAIN_PASSWORD", "PRIVATE_KEY_HEX", "NONE"],
157+
enum: [
158+
"CACTUS_KEYCHAIN_REF",
159+
"GETH_KEYCHAIN_PASSWORD",
160+
"PRIVATE_KEY_HEX",
161+
"NONE",
162+
],
118163
},
119164
EthContractInvocationType: {
120165
type: "string",

packages/cactus-plugin-ledger-connector-besu/src/main/typescript/plugin-ledger-connector-besu.ts

+43
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
PluginAspect,
1818
ICactusPlugin,
1919
ICactusPluginOptions,
20+
PluginRegistry,
21+
IPluginKeychain,
2022
} from "@hyperledger/cactus-core-api";
2123

2224
import {
@@ -36,6 +38,7 @@ import {
3638
InvokeContractV1Response,
3739
RunTransactionRequest,
3840
RunTransactionResponse,
41+
Web3SigningCredentialCactusKeychainRef,
3942
Web3SigningCredentialGethKeychainPassword,
4043
Web3SigningCredentialPrivateKeyHex,
4144
Web3SigningCredentialType,
@@ -48,6 +51,7 @@ import { isWeb3SigningCredentialNone } from "./model-type-guards";
4851
export interface IPluginLedgerConnectorBesuOptions
4952
extends ICactusPluginOptions {
5053
rpcApiHttpHost: string;
54+
pluginRegistry: PluginRegistry;
5155
logLevel?: LogLevelDesc;
5256
}
5357

@@ -64,6 +68,7 @@ export class PluginLedgerConnectorBesu
6468
private readonly instanceId: string;
6569
private readonly log: Logger;
6670
private readonly web3: Web3;
71+
private readonly pluginRegistry: PluginRegistry;
6772
private httpServer: Server | SecureServer | null = null;
6873

6974
public static readonly CLASS_NAME = "PluginLedgerConnectorBesu";
@@ -77,6 +82,7 @@ export class PluginLedgerConnectorBesu
7782
Checks.truthy(options, `${fnTag} arg options`);
7883
Checks.truthy(options.rpcApiHttpHost, `${fnTag} options.rpcApiHttpHost`);
7984
Checks.truthy(options.instanceId, `${fnTag} options.instanceId`);
85+
Checks.truthy(options.pluginRegistry, `${fnTag} options.pluginRegistry`);
8086

8187
const level = this.options.logLevel || "INFO";
8288
const label = this.className;
@@ -87,6 +93,7 @@ export class PluginLedgerConnectorBesu
8793
);
8894
this.web3 = new Web3(web3Provider);
8995
this.instanceId = options.instanceId;
96+
this.pluginRegistry = options.pluginRegistry;
9097
}
9198

9299
public getInstanceId(): string {
@@ -203,6 +210,9 @@ export class PluginLedgerConnectorBesu
203210
const fnTag = `${this.className}#transact()`;
204211

205212
switch (req.web3SigningCredential.type) {
213+
case Web3SigningCredentialType.CACTUSKEYCHAINREF: {
214+
return this.transactCactusKeychainRef(req);
215+
}
206216
case Web3SigningCredentialType.GETHKEYCHAINPASSWORD: {
207217
return this.transactGethKeychain(req);
208218
}
@@ -290,6 +300,39 @@ export class PluginLedgerConnectorBesu
290300
}
291301
}
292302

303+
public async transactCactusKeychainRef(
304+
req: RunTransactionRequest
305+
): Promise<RunTransactionResponse> {
306+
const fnTag = `${this.className}#transactCactusKeychainRef()`;
307+
const { transactionConfig, web3SigningCredential } = req;
308+
const {
309+
ethAccount,
310+
keychainEntryKey,
311+
keychainId,
312+
} = web3SigningCredential as Web3SigningCredentialCactusKeychainRef;
313+
314+
// locate the keychain plugin that has access to the keychain backend
315+
// denoted by the keychainID from the request.
316+
const keychainPlugin = this.pluginRegistry
317+
.findManyByAspect<IPluginKeychain>(PluginAspect.KEYCHAIN)
318+
.find((k) => k.getKeychainId() === keychainId);
319+
320+
Checks.truthy(keychainPlugin, `${fnTag} keychain for ID:"${keychainId}"`);
321+
322+
// Now use the found keychain plugin to actually perform the lookup of
323+
// the private key that we need to run the transaction.
324+
const privateKeyHex = await keychainPlugin?.get<string>(keychainEntryKey);
325+
326+
return this.transactPrivateKey({
327+
transactionConfig,
328+
web3SigningCredential: {
329+
ethAccount,
330+
type: Web3SigningCredentialType.PRIVATEKEYHEX,
331+
secret: privateKeyHex,
332+
},
333+
});
334+
}
335+
293336
public async pollForTxReceipt(
294337
txHash: string,
295338
timeoutMs: number = 60000

0 commit comments

Comments
 (0)