1
1
import { VerificationMethod , DIDDocument } from "did-resolver" ;
2
2
import { base58btc } from "multiformats/bases/base58" ;
3
- import { init , getApi , getChainType , ChainType , disconnectApi } from "./frequency.js" ;
4
3
import { dsnp } from "@dsnp/frequency-schemas" ;
4
+ import { DSNPResolver } from "@dsnp/did-resolver" ;
5
5
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" ;
8
8
9
9
const publicKeyAvroSchema = avro . parse ( dsnp . publicKey ) ;
10
10
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
-
49
11
function makeVerificationMethod (
50
12
controller : string ,
51
13
publicKeyMultibase : string ,
@@ -59,47 +21,107 @@ function makeVerificationMethod(
59
21
} ;
60
22
}
61
23
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
+ }
80
45
}
81
46
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
+ }
105
127
}
0 commit comments