From 0cc0e925569d5105a5b7d8d4b8ab27ac9804badd Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Fri, 1 Dec 2023 11:04:53 +0100 Subject: [PATCH] Fix comments --- src/constants.ts | 41 ++++------- src/did/did-helper.ts | 23 ++----- src/did/did.ts | 29 +++----- src/registration.ts | 94 +++++++++++++++++++------ tests/did.test.ts | 156 +++++++++++++++++++++++++++--------------- 5 files changed, 201 insertions(+), 142 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index c097a12..2eb4df7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -42,9 +42,7 @@ export const Constants = Object.freeze({ GENESIS_LENGTH: 27 }); -export type BlockchainName = 'eth' | 'polygon' | 'zkevm' | 'unknown' | 'readonly' | '' | string; - -export const Blockchain: { [k: BlockchainName]: string } = { +export const Blockchain: { [k: string]: string } = { Ethereum: 'eth', Polygon: 'polygon', ZkEVM: 'zkevm', @@ -53,17 +51,7 @@ export const Blockchain: { [k: BlockchainName]: string } = { ReadOnly: 'readonly' }; -export type NetworkName = - | 'main' - | 'mumbai' - | 'goerli' - | 'sepolia' - | 'test' - | 'unknown' - | '' - | string; - -export const NetworkId: { [k: NetworkName]: NetworkName } = { +export const NetworkId: { [k: string]: string } = { Main: 'main', Mumbai: 'mumbai', Goerli: 'goerli', @@ -73,9 +61,7 @@ export const NetworkId: { [k: NetworkName]: NetworkName } = { NoNetwork: '' }; -export type DidMethodName = 'iden3' | 'polygonid' | '' | string; - -export const DidMethod: { [k: DidMethodName]: DidMethodName } = { +export const DidMethod: { [k: string]: string } = { Iden3: 'iden3', PolygonId: 'polygonid', Other: '' @@ -86,19 +72,16 @@ export const DidMethod: { [k: DidMethodName]: DidMethodName } = { * @type { [key: string]: number } */ export const ChainIds: { [key: string]: number } = { - eth: 1, - 'eth:main': 1, - 'eth:goerli': 5, - 'eth:sepolia': 11155111, - polygon: 137, - 'polygon:main': 137, - 'polygon:mumbai': 80001, - zkevm: 1101, - 'zkevm:main': 1101, - 'zkevm:test': 1442 + [`${Blockchain.Ethereum}:${NetworkId.Main}`]: 1, + [`${Blockchain.Ethereum}:${NetworkId.Goerli}`]: 5, + [`${Blockchain.Ethereum}:${NetworkId.Sepolia}`]: 11155111, + [`${Blockchain.Polygon}:${NetworkId.Main}`]: 137, + [`${Blockchain.Polygon}:${NetworkId.Mumbai}`]: 80001, + [`${Blockchain.ZkEVM}:${NetworkId.Main}`]: 1101, + [`${Blockchain.ZkEVM}:${NetworkId.Test}`]: 1442 }; -export const DidMethodByte: { [key: DidMethodName]: number } = { +export const DidMethodByte: { [key: string]: number } = { [DidMethod.Iden3]: 0b00000001, [DidMethod.PolygonId]: 0b00000010, [DidMethod.Other]: 0b11111111 @@ -106,7 +89,7 @@ export const DidMethodByte: { [key: DidMethodName]: number } = { // DIDMethodNetwork is map for did methods and their blockchain networks export const DidMethodNetwork: { - [k: DidMethodName]: { [k: string]: number }; + [k: string]: { [k: string]: number }; } = { [DidMethod.Iden3]: { [`${Blockchain.ReadOnly}:${NetworkId.NoNetwork}`]: 0b00000000, diff --git a/src/did/did-helper.ts b/src/did/did-helper.ts index 26779be..d4d52d6 100644 --- a/src/did/did-helper.ts +++ b/src/did/did-helper.ts @@ -1,15 +1,8 @@ -import { - BlockchainName, - Constants, - DidMethodByte, - DidMethodName, - DidMethodNetwork, - NetworkName -} from '../constants'; +import { Constants, DidMethodByte, DidMethodNetwork } from '../constants'; // DIDNetworkFlag is a structure to represent DID blockchain and network id export class DIDNetworkFlag { - constructor(public readonly blockchain: BlockchainName, public readonly networkId: NetworkName) {} + constructor(public readonly blockchain: string, public readonly networkId: string) {} toString(): string { return `${this.blockchain}:${this.networkId}`; @@ -46,10 +39,7 @@ export function buildDIDType(method: string, blockchain: string, network: string } // FindNetworkIDForDIDMethodByValue finds network by byte value -export function findNetworkIDForDIDMethodByValue( - method: DidMethodName, - byteNumber: number -): NetworkName { +export function findNetworkIDForDIDMethodByValue(method: string, byteNumber: number): string { const methodMap = DidMethodNetwork[method]; if (!methodMap) { throw Constants.ERRORS.UNSUPPORTED_DID_METHOD; @@ -63,10 +53,7 @@ export function findNetworkIDForDIDMethodByValue( } // findBlockchainForDIDMethodByValue finds blockchain type by byte value -export function findBlockchainForDIDMethodByValue( - method: DidMethodName, - byteNumber: number -): BlockchainName { +export function findBlockchainForDIDMethodByValue(method: string, byteNumber: number): string { const methodMap = DidMethodNetwork[method]; if (!methodMap) { throw new Error( @@ -82,7 +69,7 @@ export function findBlockchainForDIDMethodByValue( } // findDIDMethodByValue finds did method by its byte value -export function findDIDMethodByValue(byteNumber: number): DidMethodName { +export function findDIDMethodByValue(byteNumber: number): string { for (const [key, value] of Object.entries(DidMethodByte)) { if (value === byteNumber) { return key; diff --git a/src/did/did.ts b/src/did/did.ts index 5afb39b..7d4a1aa 100644 --- a/src/did/did.ts +++ b/src/did/did.ts @@ -5,10 +5,7 @@ import { DidMethodByte, DidMethodNetwork, DidMethod, - NetworkId, - DidMethodName, - BlockchainName, - NetworkName + NetworkId } from '../constants'; import { BytesHelper } from '../elemBytes'; import { @@ -110,9 +107,9 @@ export class DID { } static decodePartsFromId(id: Id): { - method: DidMethodName; - blockchain: BlockchainName; - networkId: NetworkName; + method: string; + blockchain: string; + networkId: string; } { const method = findDIDMethodByValue(id.bytes[0]); const blockchain = findBlockchainForDIDMethodByValue(method, id.bytes[1]); @@ -122,22 +119,22 @@ export class DID { return { method, blockchain, networkId }; } - static networkIdFromId(id: Id): NetworkName { + static networkIdFromId(id: Id): string { return DID.throwIfDIDUnsupported(id).networkId; } - static methodFromId(id: Id): DidMethodName { + static methodFromId(id: Id): string { return DID.throwIfDIDUnsupported(id).method; } - static blockchainFromId(id: Id): BlockchainName { + static blockchainFromId(id: Id): string { return DID.throwIfDIDUnsupported(id).blockchain; } private static throwIfDIDUnsupported(id: Id): { - method: DidMethodName; - blockchain: BlockchainName; - networkId: NetworkName; + method: string; + blockchain: string; + networkId: string; } { const { method, blockchain, networkId } = DID.decodePartsFromId(id); @@ -194,11 +191,7 @@ export class DID { return id; } - static isUnsupported( - method: DidMethodName, - blockchain: BlockchainName, - networkId: NetworkName - ): boolean { + static isUnsupported(method: string, blockchain: string, networkId: string): boolean { return ( method == DidMethod.Other && blockchain == Blockchain.Unknown && diff --git a/src/registration.ts b/src/registration.ts index c51ba2a..783eaa0 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -1,40 +1,48 @@ import { Blockchain, - BlockchainName, ChainIds, DidMethod, DidMethodByte, - DidMethodName, DidMethodNetwork, - NetworkId, - NetworkName + NetworkId } from './constants'; +import { DID } from './did'; -const registerDidMethodWithByte = (method: DidMethodName, byte?: number): void => { +const registerDidMethodWithByte = (method: string, byte: number): void => { DidMethod[method] = method; - if (typeof byte !== 'number') { - return; - } if (typeof DidMethodByte[method] === 'number') { - throw new Error(`did method byte ${method} already registered`); + throw new Error(`did method ${method} already registered`); } DidMethodByte[method] = byte; }; -const registerChainId = (blockchain: string, network: string, chainId?: number): void => { - if (!chainId) { - return; - } +/** + * Register chain ID for a blockchain and network. + * + * @param {string} blockchain + * @param {string} network + * @param {number} [chainId] + * @returns {void} + */ +export const registerChainId = (blockchain: string, network: string, chainId: number): void => { + const key = `${blockchain}:${network}`; - if (network) { - blockchain += `:${network}`; + if (typeof ChainIds[key] === 'number') { + throw new Error(`chainId ${blockchain}:${network} already registered`); } - ChainIds[blockchain] = chainId; + ChainIds[key] = chainId; }; +/** + * Get chain ID by a blockchain and network. + * + * @param {string} blockchain + * @param {string} [network] + * @returns {number} + */ export const getChainId = (blockchain: string, network?: string): number => { if (network) { blockchain += `:${network}`; @@ -46,6 +54,46 @@ export const getChainId = (blockchain: string, network?: string): number => { return chainId; }; +/** + * ChainIDfromDID returns chain name from w3c.DID + * + * @param {DID} did + * @returns {number} + */ +export const chainIDfromDID = (did: DID): number => { + const id = DID.idFromDID(did); + + const blockchain = DID.blockchainFromId(id); + + const networkId = DID.networkIdFromId(id); + + const chainId = ChainIds[`${blockchain}:${networkId}`]; + if (typeof chainId !== 'number') { + throw new Error(`chainId not found for ${blockchain}:${networkId}`); + } + + return chainId; +}; + +/** + * Register a DID method with a byte value. + * https://docs.iden3.io/getting-started/identity/identity-types/#regular-identity + * @param {{ + * method: DidMethodName; DID method name + * methodByte?: number; put DID method byte value in case you want to register new DID method + * blockchain: BlockchainName; blockchain name + * network: NetworkName; network name + * networkFlag: number; network flag + * chainId?: number; put chain ID in case you need to use it + * }} { + * method, + * methodByte, + * blockchain, + * network, + * chainId, + * networkFlag + * } + */ export const registerDidMethodNetwork = ({ method, methodByte, @@ -54,22 +102,26 @@ export const registerDidMethodNetwork = ({ chainId, networkFlag }: { - method: DidMethodName; + method: string; methodByte?: number; - blockchain: BlockchainName; - network: NetworkName; + blockchain: string; + network: string; networkFlag: number; chainId?: number; }): void => { Blockchain[blockchain] = blockchain; NetworkId[network] = network; - registerDidMethodWithByte(method, methodByte); + if (typeof methodByte === 'number') { + registerDidMethodWithByte(method, methodByte); + } if (!DidMethodNetwork[method]) { DidMethodNetwork[method] = {}; } - registerChainId(blockchain, network, chainId); + if (typeof chainId === 'number') { + registerChainId(blockchain, network, chainId); + } const key = `${blockchain}:${network}`; if (typeof DidMethodNetwork[method][key] === 'number') { diff --git a/tests/did.test.ts b/tests/did.test.ts index c427928..a83cde3 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -46,63 +46,107 @@ describe('DID tests', () => { expect(Uint8Array.from([DidMethodByte[DidMethod.Iden3], 0b0])).toStrictEqual(id.type()); }); - it('Custom ParseDID', () => { - registerDidMethodNetwork({ - method: 'test_method', - blockchain: 'test_chain', - network: 'test_net', - chainId: 101, - methodByte: 0b00000011, - networkFlag: 0b0001_0001 - }); - - registerDidMethodNetwork({ - method: 'method', - blockchain: 'chain', - network: 'network', - chainId: 102, - methodByte: 0b0000_0100, - networkFlag: 0b0001_0001 - }); - - registerDidMethodNetwork({ - method: DidMethod.Iden3, - blockchain: Blockchain.chain, - network: NetworkId.Test, - chainId: 103, - networkFlag: 0b01000000 | 0b00000011 - }); - - registerDidMethodNetwork({ - method: DidMethod.Iden3, - blockchain: Blockchain.ReadOnly, - network: NetworkId.network, - chainId: 104, - networkFlag: 0b01000000 | 0b00000011 - }); - - expect(() => - registerDidMethodNetwork({ - method: DidMethod.Iden3, - blockchain: Blockchain.ReadOnly, - network: NetworkId.network, - chainId: 104, - networkFlag: 0b01000000 | 0b00000011 - }) - ).toThrowError('did method network readonly:network already registered'); - - registerDidMethodNetwork({ - method: 'method2', - blockchain: 'chain2', - network: 'network2', - chainId: 105, - methodByte: 0b0000_0101, - networkFlag: 0b0001_0001 - }); - - const d = helperBuildDIDFromType('method2', 'chain2', 'network2'); + it('Custom DID Registration', () => { + const testCases = [ + { + description: 'register new did method network', + data: { + method: 'test_method', + blockchain: 'test_chain', + network: 'test_net', + chainId: 101, + methodByte: 0b00000011, + networkFlag: 0b0001_0001 + } + }, + { + description: 'register one more new did method network', + data: { + method: 'method', + blockchain: 'chain', + network: 'network', + chainId: 102, + methodByte: 0b0000_0100, + networkFlag: 0b0001_0001 + } + }, + { + description: 'register oexistind did method byte', + data: { + method: 'method', + blockchain: 'chain', + network: 'network', + chainId: 102, + methodByte: 0b0000_0100, + networkFlag: 0b0001_0001 + }, + error: 'did method method already registered' + }, + { + description: 'register network to existing did method', + data: { + method: DidMethod.Iden3, + blockchain: 'chain', + network: NetworkId.Test, + chainId: 103, + networkFlag: 0b01000000 | 0b00000011 + } + }, + { + description: 'register one more network to existing did method', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: 'network', + chainId: 104, + networkFlag: 0b01000000 | 0b00000011 + } + }, + { + description: 'register already registered did method network', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: 'network', + networkFlag: 0b01000000 | 0b00000011 + }, + error: 'did method network readonly:network already registered' + }, + { + description: 'register exited chain', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: 'network', + chainId: 104, + networkFlag: 0b01000000 | 0b00000011 + }, + error: 'chainId readonly:network already registered' + }, + { + description: 'register known chain id to new did method', + data: { + method: 'method2', + blockchain: Blockchain.Polygon, + network: NetworkId.Mumbai, + methodByte: 0b0000_0101, + networkFlag: 0b0001_0001 + } + } + ]; + + for (let i = 0; i < testCases.length; i++) { + const tc = testCases[i]; + if (tc.error) { + expect(() => registerDidMethodNetwork(tc.data)).toThrowError(tc.error); + } else { + registerDidMethodNetwork(tc.data); + } + } + + const d = helperBuildDIDFromType('method', 'chain', 'network'); // const did = helperBuildDIDFromType('method', 'chain', 'network'); - expect('5UtG9EXvF25j3X5uycwr4uy7Hjhni8bMposv3Lgv8o').toEqual(d.string().split(':').pop()); + expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(d.string().split(':').pop()); // did const didStr = 'did:method:chain:network:4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT';