Skip to content

Commit 61b31b1

Browse files
author
Wes Biggs
committed
Make packageable
1 parent a82adf5 commit 61b31b1

File tree

9 files changed

+155
-186
lines changed

9 files changed

+155
-186
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# CONTRIBUTING
2+
3+
For contributing guidelines see the [Project Liberty Contributing Guidelines](https://github.com/LibertyDSNP/meta/blob/main/CONTRIBUTING.md).

frequency.ts

Lines changed: 0 additions & 80 deletions
This file was deleted.

index.test.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
1-
import { getResolver } from "@dsnp/did-resolver";
2-
import { Resolver } from "did-resolver";
31
import { expect, jest, test } from "@jest/globals";
4-
import { pluginInit, pluginDestroy } from "./index.js";
2+
import { FrequencyResolver } from "./index.js";
53

64
describe("dsnp-did-resolver-plugin-frequency", () => {
7-
it("currently contains no tests", () => {});
8-
9-
/*
10-
TODO: Needs mocking
11-
12-
it("registers as a DSNP resolver", async () => {
13-
await pluginInit({
5+
it("can be constructed", async () => {
6+
const _resolver = new FrequencyResolver({
147
providerUri: "ws://127.0.0.1:9944",
158
frequencyNetwork: "local",
169
});
17-
18-
const resolver = new Resolver(getResolver());
1910
});
2011

12+
/* Need to mock for this...
2113
it("resolves did:dsnp:13972", async () => {
2214
const myDid = "did:dsnp:13972";
2315
const result = await resolver.resolve(myDid);
2416
});
2517
2618
afterAll(async () => {
2719
// Shut down Frequency client
28-
await pluginDestroy();
20+
await resolver.disconnect();
2921
});
3022
*/
3123
});

index.ts

Lines changed: 104 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,13 @@
11
import { VerificationMethod, DIDDocument } from "did-resolver";
22
import { base58btc } from "multiformats/bases/base58";
3-
import { init, getApi, getChainType, ChainType, disconnectApi } from "./frequency.js";
43
import { dsnp } from "@dsnp/frequency-schemas";
4+
import { DSNPResolver } from "@dsnp/did-resolver";
55
import avro from "avro-js";
6-
import { registerDSNPResolver } from "@dsnp/did-resolver";
7-
import { ApiPromise } from "@polkadot/api";
6+
import { options } from "@frequency-chain/api-augment";
7+
import { WsProvider, ApiPromise } from "@polkadot/api";
88

99
const publicKeyAvroSchema = avro.parse(dsnp.publicKey);
1010

11-
export async function pluginInit(options: {
12-
providerUri: string;
13-
frequencyNetwork: string;
14-
}) {
15-
init(options);
16-
api = await getApi();
17-
// Register this resolver
18-
registerDSNPResolver(resolveFrequency);
19-
}
20-
21-
export async function pluginDestroy() {
22-
await disconnectApi();
23-
}
24-
25-
let api: ApiPromise;
26-
27-
async function getPublicKeysForSchema(
28-
dsnpUserId: BigInt,
29-
schemaId: number,
30-
): Promise<string[]> {
31-
const { items } = await api.rpc.statefulStorage.getItemizedStorage(
32-
dsnpUserId,
33-
schemaId,
34-
);
35-
36-
type ItemType = {
37-
payload: Uint8Array;
38-
};
39-
40-
return items.map((item: ItemType) => {
41-
const payloadAvro = item.payload;
42-
const publicKeyMulticodec = publicKeyAvroSchema.fromBuffer(
43-
Buffer.from(payloadAvro),
44-
).publicKey;
45-
return base58btc.encode(publicKeyMulticodec);
46-
});
47-
}
48-
4911
function makeVerificationMethod(
5012
controller: string,
5113
publicKeyMultibase: string,
@@ -59,47 +21,107 @@ function makeVerificationMethod(
5921
};
6022
}
6123

62-
async function resolveFrequency(
63-
dsnpUserId: BigInt,
64-
): Promise<DIDDocument | null> {
65-
const controller = `did:dsnp:${dsnpUserId}`;
66-
67-
// Attempt to retrieve public key(s)
68-
let keyAgreementSchemaId: number;
69-
let assertionMethodSchemaId: number;
70-
71-
switch (getChainType()) {
72-
case ChainType.Testnet:
73-
keyAgreementSchemaId = 18;
74-
assertionMethodSchemaId = 100;
75-
break;
76-
default:
77-
keyAgreementSchemaId = 7;
78-
assertionMethodSchemaId = 11;
79-
break;
24+
export class FrequencyResolver implements DSNPResolver {
25+
private providerUri: string;
26+
private frequencyNetwork: string;
27+
private _singletonApi: Promise<ApiPromise> | null = null;
28+
29+
constructor(options: { providerUri: string; frequencyNetwork: string }) {
30+
this.providerUri = options.providerUri;
31+
32+
if (!this.providerUri) {
33+
throw new Error("providerUri is required");
34+
}
35+
36+
this.frequencyNetwork = options.frequencyNetwork;
37+
if (
38+
!this.frequencyNetwork ||
39+
!["local", "testnet", "mainnet"].includes(this.frequencyNetwork)
40+
) {
41+
throw new Error(
42+
'frequencyNetwork must be one of: "local", "testnet", "mainnet"',
43+
);
44+
}
8045
}
8146

82-
const assertionMethodKeys = await getPublicKeysForSchema(
83-
dsnpUserId,
84-
assertionMethodSchemaId,
85-
);
86-
const assertionMethod = assertionMethodKeys.map((publicKeyMultibase) => {
87-
return makeVerificationMethod(controller, publicKeyMultibase);
88-
});
89-
90-
const keyAgreementKeys = await getPublicKeysForSchema(
91-
dsnpUserId,
92-
keyAgreementSchemaId,
93-
);
94-
const keyAgreement = keyAgreementKeys.map((publicKeyMultibase) => {
95-
return makeVerificationMethod(controller, publicKeyMultibase);
96-
});
97-
98-
// Return the DIDDocument object
99-
return {
100-
"@context": ["https://www.w3.org/ns/did/v1"],
101-
id: `did:dsnp:${dsnpUserId}`,
102-
assertionMethod,
103-
keyAgreement,
104-
};
47+
async getApi(): Promise<ApiPromise> {
48+
if (this._singletonApi == null) {
49+
this._singletonApi = ApiPromise.create({
50+
provider: new WsProvider(this.providerUri),
51+
throwOnConnect: true,
52+
...options,
53+
});
54+
}
55+
56+
return this._singletonApi;
57+
}
58+
59+
async disconnect() {
60+
if (this._singletonApi === null) return;
61+
const api = await this.getApi();
62+
await api.disconnect();
63+
this._singletonApi = null;
64+
}
65+
66+
private async getPublicKeysForSchema(
67+
dsnpUserId: bigint,
68+
schemaId: number,
69+
): Promise<string[]> {
70+
const { items } = await (
71+
await this.getApi()
72+
).rpc.statefulStorage.getItemizedStorage(dsnpUserId, schemaId);
73+
74+
return items.map((item: { payload: Uint8Array }) => {
75+
const payloadAvro = item.payload;
76+
const publicKeyMulticodec = publicKeyAvroSchema.fromBuffer(
77+
Buffer.from(payloadAvro),
78+
).publicKey;
79+
return base58btc.encode(publicKeyMulticodec);
80+
});
81+
}
82+
83+
async resolve(dsnpUserId: bigint): Promise<DIDDocument | null> {
84+
const controller = `did:dsnp:${dsnpUserId}`;
85+
86+
// Attempt to retrieve public key(s)
87+
let keyAgreementSchemaId: number;
88+
let assertionMethodSchemaId: number;
89+
90+
switch (this.frequencyNetwork) {
91+
case "testnet":
92+
keyAgreementSchemaId = 18;
93+
assertionMethodSchemaId = 100;
94+
break;
95+
default:
96+
keyAgreementSchemaId = 7;
97+
assertionMethodSchemaId = 11;
98+
break;
99+
}
100+
101+
const assertionMethodKeys = await this.getPublicKeysForSchema(
102+
dsnpUserId,
103+
assertionMethodSchemaId,
104+
);
105+
const assertionMethod = assertionMethodKeys.map(
106+
(publicKeyMultibase: string) => {
107+
return makeVerificationMethod(controller, publicKeyMultibase);
108+
},
109+
);
110+
111+
const keyAgreementKeys = await this.getPublicKeysForSchema(
112+
dsnpUserId,
113+
keyAgreementSchemaId,
114+
);
115+
const keyAgreement = keyAgreementKeys.map((publicKeyMultibase) => {
116+
return makeVerificationMethod(controller, publicKeyMultibase);
117+
});
118+
119+
// Return the DIDDocument object
120+
return {
121+
"@context": ["https://www.w3.org/ns/did/v1"],
122+
id: `did:dsnp:${dsnpUserId}`,
123+
assertionMethod,
124+
keyAgreement,
125+
};
126+
}
105127
}

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
"main": "dist/index.js",
66
"type": "module",
77
"scripts": {
8-
"build": "tsc",
8+
"build": "npm run clean && tsc",
9+
"postbuild": "npm run package",
10+
"clean": "rm -Rf dist",
11+
"prepackage": "cp CONTRIBUTING.md README.md LICENSE ./dist",
12+
"package": "node --no-warnings scripts/package.js",
913
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
1014
"format": "tsc --noEmit --pretty && eslint --fix \"**/*.ts\"",
1115
"lint": "tsc --noEmit --pretty && eslint \"**/*.ts\"",
@@ -22,7 +26,7 @@
2226
},
2327
"homepage": "https://github.com/AmplicaLabs/dsnp-did-resolver-plugin-frequency#readme",
2428
"dependencies": {
25-
"@dsnp/did-resolver": "^0.0.1",
29+
"@dsnp/did-resolver": "^0.0.3",
2630
"@dsnp/frequency-schemas": "^1.0.2",
2731
"@frequency-chain/api-augment": "^1.8.1",
2832
"@polkadot/api": "^10.9.1",

scripts/package.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Build the package.json for the actual publishing
3+
*/
4+
// eslint-disable-next-line
5+
import fs from "fs";
6+
import path from "path";
7+
import * as url from 'url';
8+
const __filename = url.fileURLToPath(import.meta.url);
9+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
10+
11+
// eslint-disable-next-line
12+
import rootPackage from "../package.json" assert { type: "json" };
13+
14+
// Don't keep scripts
15+
delete rootPackage["scripts"];
16+
17+
// Don't keep dev dependencies
18+
delete rootPackage["devDependencies"];
19+
20+
// Setup the main and types correctly
21+
rootPackage["main"] = "index.js";
22+
rootPackage["module"] = "./index.js";
23+
rootPackage["types"] = "index.d.ts";
24+
25+
// Write it out
26+
fs.writeFileSync(`${path.join(__dirname, "../dist", "package.json")}`, JSON.stringify(rootPackage, null, 2), (err) => {
27+
if (err) throw new Error(err);
28+
});

0 commit comments

Comments
 (0)