Skip to content

Commit 2dd7578

Browse files
authored
update dependencies, ledger improvements (openwallet-foundation#208)
* remove await-poll * update dependencies * improve ledger reponse handling, catch errors * remove get schema and cred def after create * sleep between ledger operations Signed-off-by: Timo Glastra <[email protected]>
1 parent d89653f commit 2dd7578

File tree

10 files changed

+938
-901
lines changed

10 files changed

+938
-901
lines changed

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ module.exports = {
22
parser: '@typescript-eslint/parser',
33
extends: [
44
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
5-
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
65
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
76
],
87
plugins: ['@typescript-eslint'],

.husky/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
yarn validate

package.json

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,54 +14,49 @@
1414
"format": "yarn prettier --write",
1515
"check-format": "yarn prettier --list-different",
1616
"test": "jest --verbose",
17-
"dev": "ts-node-dev --respawn --transpileOnly ./src/samples/mediator.ts",
17+
"dev": "ts-node-dev --respawn --transpile-only ./src/samples/mediator.ts",
1818
"prod:start": "node ./build/samples/mediator.js",
1919
"prod:build": "rm -rf build && yarn compile",
2020
"validate": "npm-run-all --parallel lint compile",
21-
"prepack": "rm -rf build && yarn compile"
21+
"prepack": "rm -rf build && yarn compile",
22+
"prepare": "husky install"
2223
},
2324
"dependencies": {
24-
"await-poll": "^1.0.2",
25-
"bn.js": "^5.1.3",
26-
"buffer": "^6.0.2",
27-
"class-transformer": "0.3.2",
28-
"class-validator": "^0.12.2",
29-
"events": "^3.2.0",
25+
"bn.js": "^5.2.0",
26+
"buffer": "^6.0.3",
27+
"class-transformer": "^0.4.0",
28+
"class-validator": "^0.13.1",
29+
"events": "^3.3.0",
3030
"js-sha256": "^0.9.0",
3131
"reflect-metadata": "^0.1.13",
3232
"uuid": "^8.3.0"
3333
},
3434
"devDependencies": {
35-
"@types/bn.js": "^4.11.6",
36-
"@types/cors": "^2.8.7",
37-
"@types/express": "^4.17.7",
38-
"@types/indy-sdk": "^1.15.1",
39-
"@types/jest": "^26.0.10",
40-
"@types/node-fetch": "^2.5.7",
35+
"@types/bn.js": "^5.1.0",
36+
"@types/cors": "^2.8.10",
37+
"@types/express": "4.17.8",
38+
"@types/indy-sdk": "^1.15.2",
39+
"@types/jest": "^26.0.20",
40+
"@types/node-fetch": "^2.5.8",
4141
"@types/uuid": "^8.3.0",
42-
"@typescript-eslint/eslint-plugin": "^3.10.1",
43-
"@typescript-eslint/parser": "^3.10.1",
42+
"@typescript-eslint/eslint-plugin": "^4.17.0",
43+
"@typescript-eslint/parser": "^4.17.0",
4444
"cors": "^2.8.5",
4545
"dotenv": "^8.2.0",
46-
"eslint": "^7.7.0",
47-
"eslint-config-prettier": "^6.11.0",
48-
"eslint-plugin-prettier": "^3.1.4",
46+
"eslint": "^7.21.0",
47+
"eslint-config-prettier": "^8.1.0",
48+
"eslint-plugin-prettier": "^3.3.1",
4949
"express": "^4.17.1",
50-
"husky": "^4.2.5",
51-
"indy-sdk": "^1.15.0",
52-
"jest": "^26.4.2",
50+
"husky": "^5.1.3",
51+
"indy-sdk": "^1.16.0",
52+
"jest": "^26.6.3",
5353
"node-fetch": "^2.6.1",
5454
"npm-run-all": "^4.1.5",
55-
"prettier": "^2.1.0",
56-
"rxjs": "^6.6.2",
57-
"ts-jest": "^26.3.0 ",
58-
"ts-node-dev": "^1.0.0-pre.61",
59-
"tslog": "^3.1.1",
60-
"typescript": "^4.0.2"
61-
},
62-
"husky": {
63-
"hooks": {
64-
"pre-push": "yarn validate"
65-
}
55+
"prettier": "^2.2.1",
56+
"rxjs": "^6.6.6",
57+
"ts-jest": "^26.5.3",
58+
"ts-node-dev": "^1.1.6",
59+
"tslog": "^3.1.2",
60+
"typescript": "^4.2.3"
6661
}
6762
}

src/lib/__tests__/credentials.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import indy from 'indy-sdk';
33
import type { CredDefId } from 'indy-sdk';
44
import { Subject } from 'rxjs';
5-
import path from 'path';
65
import { Agent, ConnectionRecord } from '..';
76
import {
87
ensurePublicDidIsOnLedger,
@@ -12,6 +11,7 @@ import {
1211
SubjectInboundTransporter,
1312
SubjectOutboundTransporter,
1413
waitForCredentialRecord,
14+
genesisPath,
1515
} from './helpers';
1616
import {
1717
CredentialRecord,
@@ -23,10 +23,6 @@ import { InitConfig } from '../types';
2323

2424
import testLogger from './logger';
2525

26-
const genesisPath = process.env.GENESIS_TXN_PATH
27-
? path.resolve(process.env.GENESIS_TXN_PATH)
28-
: path.join(__dirname, '../../../network/genesis/local-genesis.txn');
29-
3026
const faberConfig: InitConfig = {
3127
label: 'Faber',
3228
walletConfig: { id: 'credentials-test-faber' },

src/lib/__tests__/helpers.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export const genesisPath = process.env.GENESIS_TXN_PATH
2121
? path.resolve(process.env.GENESIS_TXN_PATH)
2222
: path.join(__dirname, '../../../network/genesis/local-genesis.txn');
2323

24+
export const sleep = (ms: number) => new Promise(res => setTimeout(res, ms));
25+
2426
// Custom matchers which can be used to extend Jest matchers via extend, e. g. `expect.extend({ toBeConnectedWith })`.
2527

2628
export function toBeConnectedWith(received: ConnectionRecord, connection: ConnectionRecord) {
@@ -153,8 +155,7 @@ export async function makeConnection(agentA: Agent, agentB: Agent) {
153155
}
154156

155157
export async function registerSchema(agent: Agent, schemaTemplate: SchemaTemplate): Promise<[SchemaId, Schema]> {
156-
const [schemaId] = await agent.ledger.registerSchema(schemaTemplate);
157-
const ledgerSchema = await agent.ledger.getSchema(schemaId);
158+
const [schemaId, ledgerSchema] = await agent.ledger.registerSchema(schemaTemplate);
158159
testLogger.test(`created schema with id ${schemaId}`, ledgerSchema);
159160
return [schemaId, ledgerSchema];
160161
}
@@ -163,8 +164,7 @@ export async function registerDefinition(
163164
agent: Agent,
164165
definitionTemplate: CredDefTemplate
165166
): Promise<[CredDefId, CredDef]> {
166-
const [credDefId] = await agent.ledger.registerCredentialDefinition(definitionTemplate);
167-
const ledgerCredDef = await agent.ledger.getCredentialDefinition(credDefId);
167+
const [credDefId, ledgerCredDef] = await agent.ledger.registerCredentialDefinition(definitionTemplate);
168168
testLogger.test(`created credential definition with id ${credDefId}`, ledgerCredDef);
169169
return [credDefId, ledgerCredDef];
170170
}

src/lib/__tests__/ledger.test.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import indy from 'indy-sdk';
22
import type { SchemaId } from 'indy-sdk';
33
import { Agent, InboundTransporter, OutboundTransporter } from '..';
4-
import path from 'path';
5-
import { DidInfo } from '../wallet/Wallet';
64
import { DID_IDENTIFIER_REGEX, VERKEY_REGEX, isFullVerkey, isAbbreviatedVerkey } from '../utils/did';
5+
import { genesisPath, sleep } from './helpers';
76
import { InitConfig } from '../types';
87
import testLogger from './logger';
98

10-
const genesisPath = process.env.GENESIS_TXN_PATH
11-
? path.resolve(process.env.GENESIS_TXN_PATH)
12-
: path.join(__dirname, '../../../network/genesis/local-genesis.txn');
13-
149
const faberConfig: InitConfig = {
1510
label: 'Faber',
1611
walletConfig: { id: 'faber' },
@@ -25,7 +20,6 @@ const faberConfig: InitConfig = {
2520
describe('ledger', () => {
2621
let faberAgent: Agent;
2722
let schemaId: SchemaId;
28-
let faberAgentPublicDid: DidInfo | undefined;
2923

3024
beforeAll(async () => {
3125
faberAgent = new Agent(faberConfig, new DummyInboundTransporter(), new DummyOutboundTransporter());
@@ -37,10 +31,10 @@ describe('ledger', () => {
3731
});
3832

3933
test(`initialization of agent's public DID`, async () => {
40-
faberAgentPublicDid = faberAgent.publicDid;
41-
testLogger.test('faberAgentPublicDid', faberAgentPublicDid!);
34+
const publicDid = faberAgent.publicDid;
35+
testLogger.test('faberAgentPublicDid', publicDid);
4236

43-
expect(faberAgentPublicDid).toEqual(
37+
expect(publicDid).toEqual(
4438
expect.objectContaining({
4539
did: expect.stringMatching(DID_IDENTIFIER_REGEX),
4640
verkey: expect.stringMatching(VERKEY_REGEX),
@@ -49,30 +43,30 @@ describe('ledger', () => {
4943
});
5044

5145
test('get public DID from ledger', async () => {
52-
if (!faberAgentPublicDid) {
46+
if (!faberAgent.publicDid) {
5347
throw new Error('Agent does not have public did.');
5448
}
5549

56-
const result = await faberAgent.ledger.getPublicDid(faberAgentPublicDid.did);
50+
const result = await faberAgent.ledger.getPublicDid(faberAgent.publicDid.did);
5751

58-
let { verkey } = faberAgentPublicDid;
52+
let { verkey } = faberAgent.publicDid;
5953
// Agent’s public did stored locally in Indy wallet and created from public did seed during
6054
// its initialization always returns full verkey. Therefore we need to align that here.
6155
if (isFullVerkey(verkey) && isAbbreviatedVerkey(result.verkey)) {
62-
verkey = await indy.abbreviateVerkey(faberAgentPublicDid.did, verkey);
56+
verkey = await indy.abbreviateVerkey(faberAgent.publicDid.did, verkey);
6357
}
6458

6559
expect(result).toEqual(
6660
expect.objectContaining({
67-
did: faberAgentPublicDid.did,
61+
did: faberAgent.publicDid.did,
6862
verkey: verkey,
6963
role: '101',
7064
})
7165
);
7266
});
7367

7468
test('register schema on ledger', async () => {
75-
if (!faberAgentPublicDid) {
69+
if (!faberAgent.publicDid) {
7670
throw new Error('Agent does not have public did.');
7771
}
7872

@@ -87,14 +81,16 @@ describe('ledger', () => {
8781
schemaId = schemaResponse[0];
8882
const schema = schemaResponse[1];
8983

84+
await sleep(2000);
85+
9086
const ledgerSchema = await faberAgent.ledger.getSchema(schemaId);
9187

92-
expect(schemaId).toBe(`${faberAgentPublicDid.did}:2:${schemaName}:1.0`);
88+
expect(schemaId).toBe(`${faberAgent.publicDid.did}:2:${schemaName}:1.0`);
9389

9490
expect(ledgerSchema).toEqual(
9591
expect.objectContaining({
9692
attrNames: expect.arrayContaining(schemaTemplate.attributes),
97-
id: `${faberAgentPublicDid.did}:2:${schemaName}:1.0`,
93+
id: `${faberAgent.publicDid.did}:2:${schemaName}:1.0`,
9894
name: schemaName,
9995
seqNo: schema.seqNo,
10096
ver: schemaTemplate.version,
@@ -104,7 +100,7 @@ describe('ledger', () => {
104100
});
105101

106102
test('register definition on ledger', async () => {
107-
if (!faberAgentPublicDid) {
103+
if (!faberAgent.publicDid) {
108104
throw new Error('Agent does not have public did.');
109105
}
110106
const schema = await faberAgent.ledger.getSchema(schemaId);
@@ -116,9 +112,12 @@ describe('ledger', () => {
116112
};
117113

118114
const [credDefId] = await faberAgent.ledger.registerCredentialDefinition(credentialDefinitionTemplate);
115+
116+
await sleep(2000);
117+
119118
const ledgerCredDef = await faberAgent.ledger.getCredentialDefinition(credDefId);
120119

121-
const credDefIdRegExp = new RegExp(`${faberAgentPublicDid.did}:3:CL:[0-9]+:TAG`);
120+
const credDefIdRegExp = new RegExp(`${faberAgent.publicDid.did}:3:CL:[0-9]+:TAG`);
122121
expect(credDefId).toEqual(expect.stringMatching(credDefIdRegExp));
123122
expect(ledgerCredDef).toEqual(
124123
expect.objectContaining({

src/lib/modules/ledger/services/LedgerService.ts

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
import type Indy from 'indy-sdk';
2-
import type { CredDef, CredDefId, Did, LedgerRequest, PoolConfig, PoolHandle, Schema, SchemaId } from 'indy-sdk';
2+
import type {
3+
CredDef,
4+
CredDefId,
5+
Did,
6+
LedgerRequest,
7+
PoolConfig,
8+
PoolHandle,
9+
Schema,
10+
SchemaId,
11+
LedgerReadReplyResponse,
12+
LedgerWriteReplyResponse,
13+
} from 'indy-sdk';
314
import { AgentConfig } from '../../../agent/AgentConfig';
415
import { Logger } from '../../../logger';
516
import { isIndyError } from '../../../utils/indyError';
@@ -67,16 +78,10 @@ export class LedgerService {
6778

6879
const request = await this.indy.buildSchemaRequest(did, schema);
6980

70-
const requestWithTaa = await this.appendTaa(request);
71-
const signedRequest = await this.wallet.signRequest(did, requestWithTaa);
72-
73-
const response = await this.indy.submitRequest(this.poolHandle, signedRequest);
81+
const response = await this.submitWriteRequest(request, did);
7482
this.logger.debug(`Registered schema '${schemaId}' on ledger`, { response, schema });
7583

76-
const seqNo = response.result.txnMetadata?.seqNo;
77-
78-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
79-
schema.seqNo = seqNo!;
84+
schema.seqNo = response.result.txnMetadata.seqNo;
8085

8186
return [schemaId, schema];
8287
} catch (error) {
@@ -98,7 +103,7 @@ export class LedgerService {
98103
const request = await this.indy.buildGetSchemaRequest(null, schemaId);
99104

100105
this.logger.debug(`Submitting get schema request for schema '${schemaId}' to ledger`);
101-
const response = await this.indy.submitRequest(this.poolHandle, request);
106+
const response = await this.submitReadRequest(request);
102107

103108
const [, schema] = await this.indy.parseGetSchemaResponse(response);
104109
this.logger.debug(`Got schema '${schemaId}' from ledger`, { response, schema });
@@ -129,10 +134,8 @@ export class LedgerService {
129134

130135
const request = await this.indy.buildCredDefRequest(did, credDef);
131136

132-
const requestWithTaa = await this.appendTaa(request);
133-
const signedRequest = await this.wallet.signRequest(did, requestWithTaa);
137+
const response = await this.submitWriteRequest(request, did);
134138

135-
const response = await this.indy.submitRequest(this.poolHandle, signedRequest);
136139
this.logger.debug(`Registered credential definition '${credDefId}' on ledger`, {
137140
response,
138141
credentialDefinition: credDef,
@@ -163,7 +166,7 @@ export class LedgerService {
163166
this.logger.debug(
164167
`Submitting get credential definition request for credential definition '${credentialDefinitionId}' to ledger`
165168
);
166-
const response = await this.indy.submitRequest(this.poolHandle, request);
169+
const response = await this.submitReadRequest(request);
167170

168171
const [, credentialDefinition] = await this.indy.parseGetCredDefResponse(response);
169172
this.logger.debug(`Got credential definition '${credentialDefinitionId}' from ledger`, {
@@ -182,6 +185,29 @@ export class LedgerService {
182185
}
183186
}
184187

188+
private async submitWriteRequest(request: LedgerRequest, signDid: string): Promise<LedgerWriteReplyResponse> {
189+
const requestWithTaa = await this.appendTaa(request);
190+
const signedRequestWithTaa = await this.wallet.signRequest(signDid, requestWithTaa);
191+
192+
const response = await this.indy.submitRequest(this.poolHandle, signedRequestWithTaa);
193+
194+
if (response.op === 'REJECT') {
195+
throw Error(`Ledger rejected transaction request: ${response.reason}`);
196+
}
197+
198+
return response as LedgerWriteReplyResponse;
199+
}
200+
201+
private async submitReadRequest(request: LedgerRequest): Promise<LedgerReadReplyResponse> {
202+
const response = await this.indy.submitRequest(this.poolHandle, request);
203+
204+
if (response.op === 'REJECT') {
205+
throw Error(`Ledger rejected transaction request: ${response.reason}`);
206+
}
207+
208+
return response as LedgerReadReplyResponse;
209+
}
210+
185211
private async appendTaa(request: LedgerRequest) {
186212
const authorAgreement = await this.getTransactionAuthorAgreement();
187213

@@ -211,9 +237,9 @@ export class LedgerService {
211237
}
212238

213239
const taaRequest = await this.indy.buildGetTxnAuthorAgreementRequest(null);
214-
const taaResponse = await this.indy.submitRequest(this.poolHandle, taaRequest);
240+
const taaResponse = await this.submitReadRequest(taaRequest);
215241
const acceptanceMechanismRequest = await this.indy.buildGetAcceptanceMechanismsRequest(null);
216-
const acceptanceMechanismResponse = await this.indy.submitRequest(this.poolHandle, acceptanceMechanismRequest);
242+
const acceptanceMechanismResponse = await this.submitReadRequest(acceptanceMechanismRequest);
217243

218244
// TAA can be null
219245
if (taaResponse.result.data == null) {

0 commit comments

Comments
 (0)