From 95264fcbabc29442339af8ad01b26dbed61d2f90 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Mon, 27 Nov 2023 09:44:43 +0100 Subject: [PATCH 01/10] Custom registration --- src/constants.ts | 192 +++++++++++++++++++++++++++++++++++------- src/did/did-helper.ts | 32 +++---- src/did/did.ts | 29 ++++--- tests/did.test.ts | 48 ++++++++++- 4 files changed, 238 insertions(+), 63 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index f905974..ab3e2ee 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -42,41 +42,92 @@ export const Constants = Object.freeze({ GENESIS_LENGTH: 27 }); -export enum Blockchain { - Ethereum = 'eth', - Polygon = 'polygon', - ZkEVM = 'zkevm', - Unknown = 'unknown', - NoChain = '', - ReadOnly = 'readonly' -} - -export enum NetworkId { - Main = 'main', - Mumbai = 'mumbai', - Goerli = 'goerli', - Sepolia = 'sepolia', - Test = 'test', - Unknown = 'unknown', - NoNetwork = '' -} - -export enum DidMethod { - Iden3 = 'iden3', - PolygonId = 'polygonid', - Other = '' -} - -export const DidMethodByte: { [key: string]: number } = Object.freeze({ +export type BlockChainName = 'eth' | 'polygon' | 'zkevm' | 'unknown' | 'readonly' | '' | string; + +export const Blockchain: { [k: BlockChainName]: string } = { + Ethereum: 'eth', + Polygon: 'polygon', + ZkEVM: 'zkevm', + Unknown: 'unknown', + NoChain: '', + ReadOnly: 'readonly' +}; + +export const registerBlockchain = ( + name: BlockChainName, + value: BlockChainName | null = null +): void => { + if (Blockchain[name]) { + throw new Error(`blockchain ${name} already registered`); + } + Blockchain[name] = value ?? name; +}; + +export type NetworkName = + | 'main' + | 'mumbai' + | 'goerli' + | 'sepolia' + | 'test' + | 'unknown' + | '' + | string; + +export const NetworkId: { [k: NetworkName]: NetworkName } = { + Main: 'main', + Mumbai: 'mumbai', + Goerli: 'goerli', + Sepolia: 'sepolia', + Test: 'test', + Unknown: 'unknown', + NoNetwork: '' +}; + +export const registerNetworkId = (name: NetworkName, value: NetworkName | null = null): void => { + if (NetworkId[name]) { + throw new Error(`network ${name} already registered`); + } + NetworkId[name] = value ?? name; +}; + +export type DidMethodName = 'iden3' | 'polygonid' | '' | string; + +export const DidMethod: { [k: DidMethodName]: DidMethodName } = { + Iden3: 'iden3', + PolygonId: 'polygonid', + Other: '' +}; + +export const registerDidMethod = ( + name: DidMethodName, + value: DidMethodName | null = null +): void => { + if (DidMethod[name]) { + throw new Error(`did method ${name} already registered`); + } + DidMethod[name] = value ?? name; +}; + +export const DidMethodByte: { [key: DidMethodName]: number } = { [DidMethod.Iden3]: 0b00000001, [DidMethod.PolygonId]: 0b00000010, [DidMethod.Other]: 0b11111111 -}); +}; + +export const registerDidMethodByte = (name: DidMethodName, value: number): void => { + if (!DidMethod[name]) { + throw new Error(`did method ${name} not registered`); + } + if (DidMethodByte[name]) { + throw new Error(`did method byte ${name} already registered`); + } + DidMethodByte[name] = value; +}; // DIDMethodNetwork is map for did methods and their blockchain networks export const DidMethodNetwork: { - [k: string]: { [k: string]: number }; -} = Object.freeze({ + [k: DidMethodName]: { [k: string]: number }; +} = { [DidMethod.Iden3]: { [`${Blockchain.ReadOnly}:${NetworkId.NoNetwork}`]: 0b00000000, [`${Blockchain.Polygon}:${NetworkId.Main}`]: 0b00010000 | 0b00000001, @@ -100,4 +151,85 @@ export const DidMethodNetwork: { [DidMethod.Other]: { [`${Blockchain.Unknown}:${NetworkId.Unknown}`]: 0b11111111 } -}); +}; + +export const registerDidMethodNetwork = ( + method: DidMethodName, + blockchain: BlockChainName, + network: NetworkName, + networkFlag: number +): void => { + if (!DidMethod[method]) { + throw new Error(`did method ${method} not registered`); + } + + if (!Blockchain[blockchain]) { + throw new Error(`blockchain ${blockchain} not registered`); + } + + if (!NetworkId[network]) { + throw new Error(`network ${network} not registered`); + } + + if (!DidMethodNetwork[method]) { + DidMethodNetwork[method] = {}; + } + const key = `${blockchain}:${network}`; + if (DidMethodNetwork[method][key]) { + throw new Error(`did method network ${key} already registered`); + } + DidMethodNetwork[method][key] = networkFlag; +}; + +export const registerDidMethodNetworkForce = ( + method: string, + blockchain: string, + network: string +): void => { + if (!DidMethod[method]) { + DidMethod[method] = method; + } + + if (typeof DidMethodByte[method] !== 'number') { + const methodBytes = Object.values(DidMethodByte).sort((sm, big) => big - sm); + // take second of methodBytes because max byte is occupied by [DidMethod.Other]: 0b11111111 + DidMethodByte[method] = methodBytes[1] + 0b1; + if (DidMethodByte[method] > 0b11111111) { + throw new Error(`did method byte ${method} already registered`); + } + } + + if (!Blockchain[blockchain]) { + Blockchain[blockchain] = blockchain; + } + + if (!NetworkId[network]) { + NetworkId[network] = network; + } + + if (!DidMethodNetwork[method]) { + DidMethodNetwork[method] = {}; + } + const key = `${blockchain}:${network}`; + const networkFlag = DidMethodNetwork[method][key]; + if (typeof networkFlag === 'number') { + throw new Error(`did method network ${key} already registered`); + } + // get the biggest network flag + const biggestFlag = Object.values(DidMethodNetwork[method]).sort((sm, big) => big - sm)[0]; + if (typeof biggestFlag !== 'number') { + DidMethodNetwork[method][key] = 0b00010000 | 0b00000001; + } else { + //get binary representation of biggest flag + const biggestFlagBinary = biggestFlag.toString(2).padStart(8, '0'); + const chainPart = parseInt(biggestFlagBinary.slice(0, 4), 2) + 1; + const networkPart = parseInt(biggestFlagBinary.slice(4), 2) + 1; + if (chainPart > 0b1111) { + throw new Error(`Reached max number of blockchains for did method ${method}`); + } + if (networkPart > 0b1111) { + throw new Error(`Reached max number of networks for did method ${method}`); + } + DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; + } +}; diff --git a/src/did/did-helper.ts b/src/did/did-helper.ts index c0a68d4..081f428 100644 --- a/src/did/did-helper.ts +++ b/src/did/did-helper.ts @@ -1,15 +1,15 @@ import { - Blockchain, + BlockChainName, Constants, DidMethodByte, + DidMethodName, DidMethodNetwork, - DidMethod, - NetworkId + NetworkName } from '../constants'; // DIDNetworkFlag is a structure to represent DID blockchain and network id export class DIDNetworkFlag { - constructor(public readonly blockchain: Blockchain, public readonly networkId: NetworkId) {} + constructor(public readonly blockchain: BlockChainName, public readonly networkId: NetworkName) {} toString(): string { return `${this.blockchain}:${this.networkId}`; @@ -17,19 +17,12 @@ export class DIDNetworkFlag { static fromString(s: string): DIDNetworkFlag { const [blockchain, networkId] = s.split(':'); - return new DIDNetworkFlag( - blockchain.replace('_', '') as Blockchain, - networkId.replace('_', '') as NetworkId - ); + return new DIDNetworkFlag(blockchain.replace('_', ''), networkId.replace('_', '')); } } // BuildDIDType builds bytes type from chain and network -export function buildDIDType( - method: DidMethod, - blockchain: Blockchain, - network: NetworkId -): Uint8Array { +export function buildDIDType(method: string, blockchain: string, network: string): Uint8Array { const fb = DidMethodByte[method]; if (!fb) { throw Constants.ERRORS.UNSUPPORTED_DID_METHOD; @@ -53,7 +46,10 @@ export function buildDIDType( } // FindNetworkIDForDIDMethodByValue finds network by byte value -export function findNetworkIDForDIDMethodByValue(method: DidMethod, byteNumber: number): NetworkId { +export function findNetworkIDForDIDMethodByValue( + method: DidMethodName, + byteNumber: number +): NetworkName { const methodMap = DidMethodNetwork[method]; if (!methodMap) { throw Constants.ERRORS.UNSUPPORTED_DID_METHOD; @@ -68,9 +64,9 @@ export function findNetworkIDForDIDMethodByValue(method: DidMethod, byteNumber: // findBlockchainForDIDMethodByValue finds blockchain type by byte value export function findBlockchainForDIDMethodByValue( - method: DidMethod, + method: DidMethodName, byteNumber: number -): Blockchain { +): BlockChainName { const methodMap = DidMethodNetwork[method]; if (!methodMap) { throw new Error( @@ -86,10 +82,10 @@ export function findBlockchainForDIDMethodByValue( } // findDIDMethodByValue finds did method by its byte value -export function findDIDMethodByValue(byteNumber: number): DidMethod { +export function findDIDMethodByValue(byteNumber: number): DidMethodName { for (const [key, value] of Object.entries(DidMethodByte)) { if (value === byteNumber) { - return key as DidMethod; + return key; } } throw Constants.ERRORS.UNSUPPORTED_DID_METHOD; diff --git a/src/did/did.ts b/src/did/did.ts index 3669e53..b687160 100644 --- a/src/did/did.ts +++ b/src/did/did.ts @@ -5,7 +5,10 @@ import { DidMethodByte, DidMethodNetwork, DidMethod, - NetworkId + NetworkId, + DidMethodName, + BlockChainName, + NetworkName } from '../constants'; import { BytesHelper } from '../elemBytes'; import { @@ -107,9 +110,9 @@ export class DID { } static decodePartsFromId(id: Id): { - method: DidMethod; - blockchain: Blockchain; - networkId: NetworkId; + method: DidMethodName; + blockchain: BlockChainName; + networkId: NetworkName; } { const method = findDIDMethodByValue(id.bytes[0]); const blockchain = findBlockchainForDIDMethodByValue(method, id.bytes[1]); @@ -119,22 +122,22 @@ export class DID { return { method, blockchain, networkId }; } - static networkIdFromId(id: Id): NetworkId { + static networkIdFromId(id: Id): NetworkName { return DID.throwIfDIDUnsupported(id).networkId; } - static methodFromId(id: Id): DidMethod { + static methodFromId(id: Id): DidMethodName { return DID.throwIfDIDUnsupported(id).method; } - static blockchainFromId(id: Id): Blockchain { + static blockchainFromId(id: Id): BlockChainName { return DID.throwIfDIDUnsupported(id).blockchain; } private static throwIfDIDUnsupported(id: Id): { - method: DidMethod; - blockchain: Blockchain; - networkId: NetworkId; + method: DidMethodName; + blockchain: BlockChainName; + networkId: NetworkName; } { const { method, blockchain, networkId } = DID.decodePartsFromId(id); @@ -191,7 +194,11 @@ export class DID { return id; } - static isUnsupported(method: DidMethod, blockchain: Blockchain, networkId: NetworkId): boolean { + static isUnsupported( + method: DidMethodName, + blockchain: BlockChainName, + networkId: NetworkName + ): boolean { return ( method == DidMethod.Other && blockchain == Blockchain.Unknown && diff --git a/tests/did.test.ts b/tests/did.test.ts index ab4fbfa..3ff6545 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -1,13 +1,25 @@ import { Hex } from '@iden3/js-crypto'; import { DID, buildDIDType } from '../src/did'; import { Id } from '../src/id'; -import { Blockchain, DidMethodByte, DidMethod, NetworkId, Constants } from './../src/constants'; +import { + Blockchain, + DidMethodByte, + DidMethod, + NetworkId, + Constants, + registerBlockchain, + registerNetworkId, + registerDidMethod, + registerDidMethodByte, + registerDidMethodNetwork, + registerDidMethodNetworkForce +} from './../src/constants'; import { genesisFromEthAddress } from '../src/utils'; export const helperBuildDIDFromType = ( - method: DidMethod, - blockchain: Blockchain, - network: NetworkId + method: string, + blockchain: string, + network: string ): DID => { const typ = buildDIDType(method, blockchain, network); return DID.newFromIdenState(typ, 1n); @@ -45,6 +57,34 @@ describe('DID tests', () => { expect(Uint8Array.from([DidMethodByte[DidMethod.Iden3], 0b0])).toStrictEqual(id.type()); }); + it('Custom ParseDID', () => { + registerBlockchain('linea'); + registerNetworkId('testnet'); + registerDidMethod('linea'); + registerDidMethodByte('linea', 0b00000011); + registerDidMethodNetwork('linea', Blockchain.linea, NetworkId.testnet, 0b0001_0001); + registerDidMethodNetworkForce('linea2', 'linea2', 'test'); + registerDidMethodNetworkForce('linea2', 'linea2', 'test2'); + registerDidMethodNetworkForce('linea2', 'linea2', 'test3'); + + const d = helperBuildDIDFromType('linea2', 'linea2', 'test'); + expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(d.string().split(':').pop()); + + // did + const didStr = 'did:linea:linea:testnet:3iHz4NemFhdiH4MzjTECwnAKX5HuXfSwR79Yezkfa7'; + + const did3 = DID.parse(didStr); + const id = DID.idFromDID(did3); + + expect('3iHz4NemFhdiH4MzjTECwnAKX5HuXfSwR79Yezkfa7').toEqual(id.string()); + const method = DID.methodFromId(id); + expect(DidMethod.linea).toBe(method); + const blockchain = DID.blockchainFromId(id); + expect(Blockchain.linea).toBe(blockchain); + const networkId = DID.networkIdFromId(id); + expect(NetworkId.testnet).toBe(networkId); + }); + it('TestDID_UnmarshalJSON', () => { const parseRes = JSON.parse( `{"obj": "did:iden3:polygon:mumbai:wyFiV4w71QgWPn6bYLsZoysFay66gKtVa9kfu6yMZ"}` From d754c963228e01258dd0f116041cad073bcaa8f2 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Mon, 27 Nov 2023 21:36:10 +0100 Subject: [PATCH 02/10] Apply bitwise operators. fix comment --- src/constants.ts | 42 +++++++++++++++++++++++------------------- src/did/did-helper.ts | 6 +++--- src/did/did.ts | 10 +++++----- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index ab3e2ee..5fac4e0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -42,9 +42,9 @@ export const Constants = Object.freeze({ GENESIS_LENGTH: 27 }); -export type BlockChainName = 'eth' | 'polygon' | 'zkevm' | 'unknown' | 'readonly' | '' | string; +export type BlockchainName = 'eth' | 'polygon' | 'zkevm' | 'unknown' | 'readonly' | '' | string; -export const Blockchain: { [k: BlockChainName]: string } = { +export const Blockchain: { [k: BlockchainName]: string } = { Ethereum: 'eth', Polygon: 'polygon', ZkEVM: 'zkevm', @@ -54,8 +54,8 @@ export const Blockchain: { [k: BlockChainName]: string } = { }; export const registerBlockchain = ( - name: BlockChainName, - value: BlockChainName | null = null + name: BlockchainName, + value: BlockchainName | null = null ): void => { if (Blockchain[name]) { throw new Error(`blockchain ${name} already registered`); @@ -155,7 +155,7 @@ export const DidMethodNetwork: { export const registerDidMethodNetwork = ( method: DidMethodName, - blockchain: BlockChainName, + blockchain: BlockchainName, network: NetworkName, networkFlag: number ): void => { @@ -174,6 +174,7 @@ export const registerDidMethodNetwork = ( if (!DidMethodNetwork[method]) { DidMethodNetwork[method] = {}; } + const key = `${blockchain}:${network}`; if (DidMethodNetwork[method][key]) { throw new Error(`did method network ${key} already registered`); @@ -216,20 +217,23 @@ export const registerDidMethodNetworkForce = ( throw new Error(`did method network ${key} already registered`); } // get the biggest network flag - const biggestFlag = Object.values(DidMethodNetwork[method]).sort((sm, big) => big - sm)[0]; - if (typeof biggestFlag !== 'number') { + const flags = Object.values(DidMethodNetwork[method]); + if (!flags.length) { DidMethodNetwork[method][key] = 0b00010000 | 0b00000001; - } else { - //get binary representation of biggest flag - const biggestFlagBinary = biggestFlag.toString(2).padStart(8, '0'); - const chainPart = parseInt(biggestFlagBinary.slice(0, 4), 2) + 1; - const networkPart = parseInt(biggestFlagBinary.slice(4), 2) + 1; - if (chainPart > 0b1111) { - throw new Error(`Reached max number of blockchains for did method ${method}`); - } - if (networkPart > 0b1111) { - throw new Error(`Reached max number of networks for did method ${method}`); - } - DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; + return; + } + //get binary representation of biggest flag + const biggestFlag = flags.sort((sm, big) => big - sm)[0]; + const chainPart = (biggestFlag >> 4) + 1; + const networkPart = (biggestFlag & 0b0000_1111) + 1; + + if (chainPart >= 0b1111) { + throw new Error(`Reached max number of blockchains for did method ${method}`); + } + + if (networkPart >= 0b1111) { + throw new Error(`Reached max number of networks for did method ${method}`); } + + DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; }; diff --git a/src/did/did-helper.ts b/src/did/did-helper.ts index 081f428..26779be 100644 --- a/src/did/did-helper.ts +++ b/src/did/did-helper.ts @@ -1,5 +1,5 @@ import { - BlockChainName, + BlockchainName, Constants, DidMethodByte, DidMethodName, @@ -9,7 +9,7 @@ import { // 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: BlockchainName, public readonly networkId: NetworkName) {} toString(): string { return `${this.blockchain}:${this.networkId}`; @@ -66,7 +66,7 @@ export function findNetworkIDForDIDMethodByValue( export function findBlockchainForDIDMethodByValue( method: DidMethodName, byteNumber: number -): BlockChainName { +): BlockchainName { const methodMap = DidMethodNetwork[method]; if (!methodMap) { throw new Error( diff --git a/src/did/did.ts b/src/did/did.ts index b687160..5afb39b 100644 --- a/src/did/did.ts +++ b/src/did/did.ts @@ -7,7 +7,7 @@ import { DidMethod, NetworkId, DidMethodName, - BlockChainName, + BlockchainName, NetworkName } from '../constants'; import { BytesHelper } from '../elemBytes'; @@ -111,7 +111,7 @@ export class DID { static decodePartsFromId(id: Id): { method: DidMethodName; - blockchain: BlockChainName; + blockchain: BlockchainName; networkId: NetworkName; } { const method = findDIDMethodByValue(id.bytes[0]); @@ -130,13 +130,13 @@ export class DID { return DID.throwIfDIDUnsupported(id).method; } - static blockchainFromId(id: Id): BlockChainName { + static blockchainFromId(id: Id): BlockchainName { return DID.throwIfDIDUnsupported(id).blockchain; } private static throwIfDIDUnsupported(id: Id): { method: DidMethodName; - blockchain: BlockChainName; + blockchain: BlockchainName; networkId: NetworkName; } { const { method, blockchain, networkId } = DID.decodePartsFromId(id); @@ -196,7 +196,7 @@ export class DID { static isUnsupported( method: DidMethodName, - blockchain: BlockChainName, + blockchain: BlockchainName, networkId: NetworkName ): boolean { return ( From e9ee9d8fb356384f146773866a9059cfd641979b Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Tue, 28 Nov 2023 08:55:37 +0100 Subject: [PATCH 03/10] Split registrations in separate file. Make test more generic --- src/constants.ts | 122 ---------------------------------------- src/registration.ts | 132 ++++++++++++++++++++++++++++++++++++++++++++ tests/did.test.ts | 49 ++++++++-------- 3 files changed, 157 insertions(+), 146 deletions(-) create mode 100644 src/registration.ts diff --git a/src/constants.ts b/src/constants.ts index 5fac4e0..69d791a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -53,16 +53,6 @@ export const Blockchain: { [k: BlockchainName]: string } = { ReadOnly: 'readonly' }; -export const registerBlockchain = ( - name: BlockchainName, - value: BlockchainName | null = null -): void => { - if (Blockchain[name]) { - throw new Error(`blockchain ${name} already registered`); - } - Blockchain[name] = value ?? name; -}; - export type NetworkName = | 'main' | 'mumbai' @@ -83,13 +73,6 @@ export const NetworkId: { [k: NetworkName]: NetworkName } = { NoNetwork: '' }; -export const registerNetworkId = (name: NetworkName, value: NetworkName | null = null): void => { - if (NetworkId[name]) { - throw new Error(`network ${name} already registered`); - } - NetworkId[name] = value ?? name; -}; - export type DidMethodName = 'iden3' | 'polygonid' | '' | string; export const DidMethod: { [k: DidMethodName]: DidMethodName } = { @@ -98,32 +81,12 @@ export const DidMethod: { [k: DidMethodName]: DidMethodName } = { Other: '' }; -export const registerDidMethod = ( - name: DidMethodName, - value: DidMethodName | null = null -): void => { - if (DidMethod[name]) { - throw new Error(`did method ${name} already registered`); - } - DidMethod[name] = value ?? name; -}; - export const DidMethodByte: { [key: DidMethodName]: number } = { [DidMethod.Iden3]: 0b00000001, [DidMethod.PolygonId]: 0b00000010, [DidMethod.Other]: 0b11111111 }; -export const registerDidMethodByte = (name: DidMethodName, value: number): void => { - if (!DidMethod[name]) { - throw new Error(`did method ${name} not registered`); - } - if (DidMethodByte[name]) { - throw new Error(`did method byte ${name} already registered`); - } - DidMethodByte[name] = value; -}; - // DIDMethodNetwork is map for did methods and their blockchain networks export const DidMethodNetwork: { [k: DidMethodName]: { [k: string]: number }; @@ -152,88 +115,3 @@ export const DidMethodNetwork: { [`${Blockchain.Unknown}:${NetworkId.Unknown}`]: 0b11111111 } }; - -export const registerDidMethodNetwork = ( - method: DidMethodName, - blockchain: BlockchainName, - network: NetworkName, - networkFlag: number -): void => { - if (!DidMethod[method]) { - throw new Error(`did method ${method} not registered`); - } - - if (!Blockchain[blockchain]) { - throw new Error(`blockchain ${blockchain} not registered`); - } - - if (!NetworkId[network]) { - throw new Error(`network ${network} not registered`); - } - - if (!DidMethodNetwork[method]) { - DidMethodNetwork[method] = {}; - } - - const key = `${blockchain}:${network}`; - if (DidMethodNetwork[method][key]) { - throw new Error(`did method network ${key} already registered`); - } - DidMethodNetwork[method][key] = networkFlag; -}; - -export const registerDidMethodNetworkForce = ( - method: string, - blockchain: string, - network: string -): void => { - if (!DidMethod[method]) { - DidMethod[method] = method; - } - - if (typeof DidMethodByte[method] !== 'number') { - const methodBytes = Object.values(DidMethodByte).sort((sm, big) => big - sm); - // take second of methodBytes because max byte is occupied by [DidMethod.Other]: 0b11111111 - DidMethodByte[method] = methodBytes[1] + 0b1; - if (DidMethodByte[method] > 0b11111111) { - throw new Error(`did method byte ${method} already registered`); - } - } - - if (!Blockchain[blockchain]) { - Blockchain[blockchain] = blockchain; - } - - if (!NetworkId[network]) { - NetworkId[network] = network; - } - - if (!DidMethodNetwork[method]) { - DidMethodNetwork[method] = {}; - } - const key = `${blockchain}:${network}`; - const networkFlag = DidMethodNetwork[method][key]; - if (typeof networkFlag === 'number') { - throw new Error(`did method network ${key} already registered`); - } - // get the biggest network flag - const flags = Object.values(DidMethodNetwork[method]); - if (!flags.length) { - DidMethodNetwork[method][key] = 0b00010000 | 0b00000001; - return; - } - //get binary representation of biggest flag - const biggestFlag = flags.sort((sm, big) => big - sm)[0]; - const chainPart = (biggestFlag >> 4) + 1; - const networkPart = (biggestFlag & 0b0000_1111) + 1; - - if (chainPart >= 0b1111) { - throw new Error(`Reached max number of blockchains for did method ${method}`); - } - - if (networkPart >= 0b1111) { - throw new Error(`Reached max number of networks for did method ${method}`); - } - - DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; -}; diff --git a/src/registration.ts b/src/registration.ts new file mode 100644 index 0000000..6c90323 --- /dev/null +++ b/src/registration.ts @@ -0,0 +1,132 @@ +import { + Blockchain, + BlockchainName, + DidMethod, + DidMethodByte, + DidMethodName, + DidMethodNetwork, + NetworkId, + NetworkName +} from './constants'; + +export const registerBlockchain = ( + name: BlockchainName, + value: BlockchainName | null = null +): void => { + if (Blockchain[name]) { + throw new Error(`blockchain ${name} already registered`); + } + Blockchain[name] = value ?? name; +}; + +export const registerDidMethodByte = (name: DidMethodName, value: number): void => { + if (!DidMethod[name]) { + throw new Error(`did method ${name} not registered`); + } + if (DidMethodByte[name]) { + throw new Error(`did method byte ${name} already registered`); + } + DidMethodByte[name] = value; +}; + +export const registerDidMethod = ( + name: DidMethodName, + value: DidMethodName | null = null +): void => { + if (DidMethod[name]) { + throw new Error(`did method ${name} already registered`); + } + DidMethod[name] = value ?? name; +}; + +export const registerNetworkId = (name: NetworkName, value: NetworkName | null = null): void => { + if (NetworkId[name]) { + throw new Error(`network ${name} already registered`); + } + NetworkId[name] = value ?? name; +}; + +export const registerDidMethodNetwork = ( + method: DidMethodName, + blockchain: BlockchainName, + network: NetworkName, + networkFlag: number +): void => { + if (!DidMethod[method]) { + throw new Error(`did method ${method} not registered`); + } + + if (!Blockchain[blockchain]) { + throw new Error(`blockchain ${blockchain} not registered`); + } + + if (!NetworkId[network]) { + throw new Error(`network ${network} not registered`); + } + + if (!DidMethodNetwork[method]) { + DidMethodNetwork[method] = {}; + } + + const key = `${blockchain}:${network}`; + if (DidMethodNetwork[method][key]) { + throw new Error(`did method network ${key} already registered`); + } + DidMethodNetwork[method][key] = networkFlag; +}; + +export const registerDidMethodNetworkImplicit = ( + method: string, + blockchain: string, + network: string +): void => { + if (!DidMethod[method]) { + DidMethod[method] = method; + } + + if (typeof DidMethodByte[method] !== 'number') { + const methodBytes = Object.values(DidMethodByte).sort((sm, big) => big - sm); + // take second of methodBytes because max byte is occupied by [DidMethod.Other]: 0b11111111 + DidMethodByte[method] = methodBytes[1] + 0b1; + if (DidMethodByte[method] > 0b11111111) { + throw new Error(`did method byte ${method} already registered`); + } + } + + if (!Blockchain[blockchain]) { + Blockchain[blockchain] = blockchain; + } + + if (!NetworkId[network]) { + NetworkId[network] = network; + } + + if (!DidMethodNetwork[method]) { + DidMethodNetwork[method] = {}; + } + const key = `${blockchain}:${network}`; + const networkFlag = DidMethodNetwork[method][key]; + if (typeof networkFlag === 'number') { + throw new Error(`did method network ${key} already registered`); + } + // get the biggest network flag + const flags = Object.values(DidMethodNetwork[method]); + if (!flags.length) { + DidMethodNetwork[method][key] = 0b00010000 | 0b00000001; + return; + } + //get binary representation of biggest flag + const biggestFlag = flags.sort((sm, big) => big - sm)[0]; + const chainPart = (biggestFlag >> 4) + 1; + const networkPart = (biggestFlag & 0b0000_1111) + 1; + + if (chainPart >= 0b1111) { + throw new Error(`Reached max number of blockchains for did method ${method}`); + } + + if (networkPart >= 0b1111) { + throw new Error(`Reached max number of networks for did method ${method}`); + } + + DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; +}; diff --git a/tests/did.test.ts b/tests/did.test.ts index 3ff6545..c675cf3 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -1,20 +1,16 @@ import { Hex } from '@iden3/js-crypto'; import { DID, buildDIDType } from '../src/did'; import { Id } from '../src/id'; +import { Blockchain, DidMethodByte, DidMethod, NetworkId, Constants } from './../src/constants'; +import { genesisFromEthAddress } from '../src/utils'; import { - Blockchain, - DidMethodByte, - DidMethod, - NetworkId, - Constants, registerBlockchain, registerNetworkId, registerDidMethod, registerDidMethodByte, registerDidMethodNetwork, - registerDidMethodNetworkForce -} from './../src/constants'; -import { genesisFromEthAddress } from '../src/utils'; + registerDidMethodNetworkImplicit +} from '../src/registration'; export const helperBuildDIDFromType = ( method: string, @@ -58,31 +54,36 @@ describe('DID tests', () => { }); it('Custom ParseDID', () => { - registerBlockchain('linea'); - registerNetworkId('testnet'); - registerDidMethod('linea'); - registerDidMethodByte('linea', 0b00000011); - registerDidMethodNetwork('linea', Blockchain.linea, NetworkId.testnet, 0b0001_0001); - registerDidMethodNetworkForce('linea2', 'linea2', 'test'); - registerDidMethodNetworkForce('linea2', 'linea2', 'test2'); - registerDidMethodNetworkForce('linea2', 'linea2', 'test3'); - - const d = helperBuildDIDFromType('linea2', 'linea2', 'test'); - expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(d.string().split(':').pop()); + // explicitly register all the things + registerBlockchain('Test Chain', 'test_chain'); + registerNetworkId('Test Net', 'test_net'); + registerDidMethod('Test method', 'test_method'); + registerDidMethodByte('Test method', 0b00000011); + registerDidMethodNetwork('Test method', 'Test Chain', 'Test Net', 0b0001_0001); + // implicitly register all the things + registerDidMethodNetworkImplicit('method', 'chain', 'network'); + registerDidMethodNetworkImplicit('iden3', 'chain', NetworkId.Test); + registerDidMethodNetworkImplicit('iden3', Blockchain.ReadOnly, 'network'); + registerDidMethodNetworkImplicit('iden3', Blockchain.ReadOnly, NetworkId.Test); + registerDidMethodNetworkImplicit('method2', 'chain2', 'network2'); + + const d = helperBuildDIDFromType('method2', 'chain2', 'network2'); + // const did = helperBuildDIDFromType('method', 'chain', 'network'); + expect('5UtG9EXvF25j3X5uycwr4uy7Hjhni8bMposv3Lgv8o').toEqual(d.string().split(':').pop()); // did - const didStr = 'did:linea:linea:testnet:3iHz4NemFhdiH4MzjTECwnAKX5HuXfSwR79Yezkfa7'; + const didStr = 'did:method:chain:network:4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT'; const did3 = DID.parse(didStr); const id = DID.idFromDID(did3); - expect('3iHz4NemFhdiH4MzjTECwnAKX5HuXfSwR79Yezkfa7').toEqual(id.string()); + expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(id.string()); const method = DID.methodFromId(id); - expect(DidMethod.linea).toBe(method); + expect(DidMethod.method).toBe(method); const blockchain = DID.blockchainFromId(id); - expect(Blockchain.linea).toBe(blockchain); + expect(Blockchain.chain).toBe(blockchain); const networkId = DID.networkIdFromId(id); - expect(NetworkId.testnet).toBe(networkId); + expect(NetworkId.network).toBe(networkId); }); it('TestDID_UnmarshalJSON', () => { From 451d5a52bb0e3dad095a67b16dfe863b5dde0660 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Tue, 28 Nov 2023 09:17:36 +0100 Subject: [PATCH 04/10] Fix registration names --- src/registration.ts | 32 +++++++++++++------------------- tests/did.test.ts | 10 +++++----- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/registration.ts b/src/registration.ts index 6c90323..ae71e1c 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -9,14 +9,11 @@ import { NetworkName } from './constants'; -export const registerBlockchain = ( - name: BlockchainName, - value: BlockchainName | null = null -): void => { - if (Blockchain[name]) { - throw new Error(`blockchain ${name} already registered`); +export const registerBlockchain = (chain: BlockchainName): void => { + if (Blockchain[chain]) { + throw new Error(`blockchain ${chain} already registered`); } - Blockchain[name] = value ?? name; + Blockchain[chain] = chain; }; export const registerDidMethodByte = (name: DidMethodName, value: number): void => { @@ -29,21 +26,18 @@ export const registerDidMethodByte = (name: DidMethodName, value: number): void DidMethodByte[name] = value; }; -export const registerDidMethod = ( - name: DidMethodName, - value: DidMethodName | null = null -): void => { - if (DidMethod[name]) { - throw new Error(`did method ${name} already registered`); +export const registerDidMethod = (method: DidMethodName): void => { + if (DidMethod[method]) { + throw new Error(`did method ${method} already registered`); } - DidMethod[name] = value ?? name; + DidMethod[method] = method; }; -export const registerNetworkId = (name: NetworkName, value: NetworkName | null = null): void => { +export const registerNetworkId = (name: NetworkName): void => { if (NetworkId[name]) { throw new Error(`network ${name} already registered`); } - NetworkId[name] = value ?? name; + NetworkId[name] = name; }; export const registerDidMethodNetwork = ( @@ -76,9 +70,9 @@ export const registerDidMethodNetwork = ( }; export const registerDidMethodNetworkImplicit = ( - method: string, - blockchain: string, - network: string + method: DidMethodName, + blockchain: BlockchainName, + network: NetworkName ): void => { if (!DidMethod[method]) { DidMethod[method] = method; diff --git a/tests/did.test.ts b/tests/did.test.ts index c675cf3..d5fe9de 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -55,11 +55,11 @@ describe('DID tests', () => { it('Custom ParseDID', () => { // explicitly register all the things - registerBlockchain('Test Chain', 'test_chain'); - registerNetworkId('Test Net', 'test_net'); - registerDidMethod('Test method', 'test_method'); - registerDidMethodByte('Test method', 0b00000011); - registerDidMethodNetwork('Test method', 'Test Chain', 'Test Net', 0b0001_0001); + registerBlockchain('test_chain'); + registerNetworkId('test_net'); + registerDidMethod('test_method'); + registerDidMethodByte('test_method', 0b00000011); + registerDidMethodNetwork('test_method', 'test_chain', 'test_net', 0b0001_0001); // implicitly register all the things registerDidMethodNetworkImplicit('method', 'chain', 'network'); registerDidMethodNetworkImplicit('iden3', 'chain', NetworkId.Test); From 8180c6917e9828066ec99d8a8a99c59f1108de79 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Tue, 28 Nov 2023 14:12:11 +0100 Subject: [PATCH 05/10] Remove implicit flow after discussion --- src/registration.ts | 94 +++++++++------------------------------------ tests/did.test.ts | 44 +++++++++++++++------ 2 files changed, 51 insertions(+), 87 deletions(-) diff --git a/src/registration.ts b/src/registration.ts index ae71e1c..18e046b 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -10,34 +10,28 @@ import { } from './constants'; export const registerBlockchain = (chain: BlockchainName): void => { - if (Blockchain[chain]) { + if (Object.values(Blockchain).includes(chain)) { throw new Error(`blockchain ${chain} already registered`); } Blockchain[chain] = chain; }; -export const registerDidMethodByte = (name: DidMethodName, value: number): void => { - if (!DidMethod[name]) { - throw new Error(`did method ${name} not registered`); - } - if (DidMethodByte[name]) { - throw new Error(`did method byte ${name} already registered`); - } - DidMethodByte[name] = value; -}; - -export const registerDidMethod = (method: DidMethodName): void => { - if (DidMethod[method]) { +export const registerDidMethodWithByte = (method: DidMethodName, byte: number): void => { + if (Object.values(DidMethod).includes(method)) { throw new Error(`did method ${method} already registered`); } DidMethod[method] = method; + if (DidMethodByte[method]) { + throw new Error(`did method byte ${method} already registered`); + } + DidMethodByte[method] = byte; }; -export const registerNetworkId = (name: NetworkName): void => { - if (NetworkId[name]) { - throw new Error(`network ${name} already registered`); +export const registerNetworkId = (network: NetworkName): void => { + if (Object.values(NetworkId).includes(network)) { + throw new Error(`network ${network} already registered`); } - NetworkId[name] = name; + NetworkId[network] = network; }; export const registerDidMethodNetwork = ( @@ -46,81 +40,29 @@ export const registerDidMethodNetwork = ( network: NetworkName, networkFlag: number ): void => { - if (!DidMethod[method]) { + if (!Object.values(DidMethod).includes(method)) { throw new Error(`did method ${method} not registered`); } - if (!Blockchain[blockchain]) { + if (!Object.values(Blockchain).includes(blockchain)) { throw new Error(`blockchain ${blockchain} not registered`); } - if (!NetworkId[network]) { + if (!Object.values(NetworkId).includes(network)) { throw new Error(`network ${network} not registered`); } - if (!DidMethodNetwork[method]) { - DidMethodNetwork[method] = {}; - } - - const key = `${blockchain}:${network}`; - if (DidMethodNetwork[method][key]) { - throw new Error(`did method network ${key} already registered`); - } - DidMethodNetwork[method][key] = networkFlag; -}; - -export const registerDidMethodNetworkImplicit = ( - method: DidMethodName, - blockchain: BlockchainName, - network: NetworkName -): void => { - if (!DidMethod[method]) { - DidMethod[method] = method; - } - if (typeof DidMethodByte[method] !== 'number') { - const methodBytes = Object.values(DidMethodByte).sort((sm, big) => big - sm); - // take second of methodBytes because max byte is occupied by [DidMethod.Other]: 0b11111111 - DidMethodByte[method] = methodBytes[1] + 0b1; - if (DidMethodByte[method] > 0b11111111) { - throw new Error(`did method byte ${method} already registered`); - } - } - - if (!Blockchain[blockchain]) { - Blockchain[blockchain] = blockchain; - } - - if (!NetworkId[network]) { - NetworkId[network] = network; + throw new Error(`did method byte for ${method} is not registered`); } if (!DidMethodNetwork[method]) { DidMethodNetwork[method] = {}; } + const key = `${blockchain}:${network}`; - const networkFlag = DidMethodNetwork[method][key]; - if (typeof networkFlag === 'number') { + if (typeof DidMethodNetwork[method][key] === 'number') { throw new Error(`did method network ${key} already registered`); } - // get the biggest network flag - const flags = Object.values(DidMethodNetwork[method]); - if (!flags.length) { - DidMethodNetwork[method][key] = 0b00010000 | 0b00000001; - return; - } - //get binary representation of biggest flag - const biggestFlag = flags.sort((sm, big) => big - sm)[0]; - const chainPart = (biggestFlag >> 4) + 1; - const networkPart = (biggestFlag & 0b0000_1111) + 1; - - if (chainPart >= 0b1111) { - throw new Error(`Reached max number of blockchains for did method ${method}`); - } - - if (networkPart >= 0b1111) { - throw new Error(`Reached max number of networks for did method ${method}`); - } - - DidMethodNetwork[method][key] = (chainPart << 4) | networkPart; + DidMethodNetwork[method][key] = networkFlag; }; diff --git a/tests/did.test.ts b/tests/did.test.ts index d5fe9de..8dc7c22 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -6,10 +6,8 @@ import { genesisFromEthAddress } from '../src/utils'; import { registerBlockchain, registerNetworkId, - registerDidMethod, - registerDidMethodByte, - registerDidMethodNetwork, - registerDidMethodNetworkImplicit + registerDidMethodWithByte, + registerDidMethodNetwork } from '../src/registration'; export const helperBuildDIDFromType = ( @@ -57,15 +55,39 @@ describe('DID tests', () => { // explicitly register all the things registerBlockchain('test_chain'); registerNetworkId('test_net'); - registerDidMethod('test_method'); - registerDidMethodByte('test_method', 0b00000011); + registerDidMethodWithByte('test_method', 0b00000011); registerDidMethodNetwork('test_method', 'test_chain', 'test_net', 0b0001_0001); // implicitly register all the things - registerDidMethodNetworkImplicit('method', 'chain', 'network'); - registerDidMethodNetworkImplicit('iden3', 'chain', NetworkId.Test); - registerDidMethodNetworkImplicit('iden3', Blockchain.ReadOnly, 'network'); - registerDidMethodNetworkImplicit('iden3', Blockchain.ReadOnly, NetworkId.Test); - registerDidMethodNetworkImplicit('method2', 'chain2', 'network2'); + registerDidMethodWithByte('method', 0b0000_0100); + registerBlockchain('chain'); + registerNetworkId('network'); + + registerDidMethodNetwork(DidMethod.method, Blockchain.chain, NetworkId.network, 0b0001_0001); + registerDidMethodNetwork( + DidMethod.Iden3, + Blockchain.chain, + NetworkId.Test, + 0b01000000 | 0b00000011 + ); + registerDidMethodNetwork( + DidMethod.Iden3, + Blockchain.ReadOnly, + NetworkId.network, + 0b01000000 | 0b00000011 + ); + expect(() => + registerDidMethodNetwork( + DidMethod.Iden3, + Blockchain.ReadOnly, + NetworkId.network, + 0b01010000 | 0b00000100 + ) + ).toThrowError('did method network readonly:network already registered'); + + registerDidMethodWithByte('method2', 0b0000_0101); + registerBlockchain('chain2'); + registerNetworkId('network2'); + registerDidMethodNetwork('method2', 'chain2', 'network2', 0b0001_0001); const d = helperBuildDIDFromType('method2', 'chain2', 'network2'); // const did = helperBuildDIDFromType('method', 'chain', 'network'); From 43ce078430301a3b0a4896e9226eaa13fad3de46 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Thu, 30 Nov 2023 11:32:32 +0100 Subject: [PATCH 06/10] Add one method --- src/constants.ts | 17 +++++++++ src/index.ts | 1 + src/registration.ts | 75 ++++++++++++++++++++++---------------- tests/did.test.ts | 89 +++++++++++++++++++++++++-------------------- 4 files changed, 111 insertions(+), 71 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 69d791a..c097a12 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -81,6 +81,23 @@ export const DidMethod: { [k: DidMethodName]: DidMethodName } = { Other: '' }; +/** + * Object containing chain IDs for various blockchains and networks. + * @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 +}; + export const DidMethodByte: { [key: DidMethodName]: number } = { [DidMethod.Iden3]: 0b00000001, [DidMethod.PolygonId]: 0b00000010, diff --git a/src/index.ts b/src/index.ts index 042fe84..489d451 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,3 +5,4 @@ export * from './elemBytes'; export * from './id'; export * from './schemaHash'; export * from './utils'; +export * from './registration'; diff --git a/src/registration.ts b/src/registration.ts index 18e046b..c51ba2a 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -1,6 +1,7 @@ import { Blockchain, BlockchainName, + ChainIds, DidMethod, DidMethodByte, DidMethodName, @@ -9,57 +10,67 @@ import { NetworkName } from './constants'; -export const registerBlockchain = (chain: BlockchainName): void => { - if (Object.values(Blockchain).includes(chain)) { - throw new Error(`blockchain ${chain} already registered`); +const registerDidMethodWithByte = (method: DidMethodName, byte?: number): void => { + DidMethod[method] = method; + if (typeof byte !== 'number') { + return; } - Blockchain[chain] = chain; -}; -export const registerDidMethodWithByte = (method: DidMethodName, byte: number): void => { - if (Object.values(DidMethod).includes(method)) { - throw new Error(`did method ${method} already registered`); - } - DidMethod[method] = method; - if (DidMethodByte[method]) { + if (typeof DidMethodByte[method] === 'number') { throw new Error(`did method byte ${method} already registered`); } + DidMethodByte[method] = byte; }; -export const registerNetworkId = (network: NetworkName): void => { - if (Object.values(NetworkId).includes(network)) { - throw new Error(`network ${network} already registered`); +const registerChainId = (blockchain: string, network: string, chainId?: number): void => { + if (!chainId) { + return; } - NetworkId[network] = network; -}; -export const registerDidMethodNetwork = ( - method: DidMethodName, - blockchain: BlockchainName, - network: NetworkName, - networkFlag: number -): void => { - if (!Object.values(DidMethod).includes(method)) { - throw new Error(`did method ${method} not registered`); + if (network) { + blockchain += `:${network}`; } - if (!Object.values(Blockchain).includes(blockchain)) { - throw new Error(`blockchain ${blockchain} not registered`); - } + ChainIds[blockchain] = chainId; +}; - if (!Object.values(NetworkId).includes(network)) { - throw new Error(`network ${network} not registered`); +export const getChainId = (blockchain: string, network?: string): number => { + if (network) { + blockchain += `:${network}`; } - - if (typeof DidMethodByte[method] !== 'number') { - throw new Error(`did method byte for ${method} is not registered`); + const chainId = ChainIds[blockchain]; + if (!chainId) { + throw new Error(`chainId not found for ${blockchain}`); } + return chainId; +}; + +export const registerDidMethodNetwork = ({ + method, + methodByte, + blockchain, + network, + chainId, + networkFlag +}: { + method: DidMethodName; + methodByte?: number; + blockchain: BlockchainName; + network: NetworkName; + networkFlag: number; + chainId?: number; +}): void => { + Blockchain[blockchain] = blockchain; + NetworkId[network] = network; + registerDidMethodWithByte(method, methodByte); if (!DidMethodNetwork[method]) { DidMethodNetwork[method] = {}; } + registerChainId(blockchain, network, chainId); + const key = `${blockchain}:${network}`; if (typeof DidMethodNetwork[method][key] === 'number') { throw new Error(`did method network ${key} already registered`); diff --git a/tests/did.test.ts b/tests/did.test.ts index 8dc7c22..c427928 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -3,12 +3,7 @@ import { DID, buildDIDType } from '../src/did'; import { Id } from '../src/id'; import { Blockchain, DidMethodByte, DidMethod, NetworkId, Constants } from './../src/constants'; import { genesisFromEthAddress } from '../src/utils'; -import { - registerBlockchain, - registerNetworkId, - registerDidMethodWithByte, - registerDidMethodNetwork -} from '../src/registration'; +import { registerDidMethodNetwork } from '../src/registration'; export const helperBuildDIDFromType = ( method: string, @@ -52,42 +47,58 @@ describe('DID tests', () => { }); it('Custom ParseDID', () => { - // explicitly register all the things - registerBlockchain('test_chain'); - registerNetworkId('test_net'); - registerDidMethodWithByte('test_method', 0b00000011); - registerDidMethodNetwork('test_method', 'test_chain', 'test_net', 0b0001_0001); - // implicitly register all the things - registerDidMethodWithByte('method', 0b0000_0100); - registerBlockchain('chain'); - registerNetworkId('network'); - - registerDidMethodNetwork(DidMethod.method, Blockchain.chain, NetworkId.network, 0b0001_0001); - registerDidMethodNetwork( - DidMethod.Iden3, - Blockchain.chain, - NetworkId.Test, - 0b01000000 | 0b00000011 - ); - registerDidMethodNetwork( - DidMethod.Iden3, - Blockchain.ReadOnly, - NetworkId.network, - 0b01000000 | 0b00000011 - ); + 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( - DidMethod.Iden3, - Blockchain.ReadOnly, - NetworkId.network, - 0b01010000 | 0b00000100 - ) + registerDidMethodNetwork({ + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: NetworkId.network, + chainId: 104, + networkFlag: 0b01000000 | 0b00000011 + }) ).toThrowError('did method network readonly:network already registered'); - registerDidMethodWithByte('method2', 0b0000_0101); - registerBlockchain('chain2'); - registerNetworkId('network2'); - registerDidMethodNetwork('method2', 'chain2', 'network2', 0b0001_0001); + registerDidMethodNetwork({ + method: 'method2', + blockchain: 'chain2', + network: 'network2', + chainId: 105, + methodByte: 0b0000_0101, + networkFlag: 0b0001_0001 + }); const d = helperBuildDIDFromType('method2', 'chain2', 'network2'); // const did = helperBuildDIDFromType('method', 'chain', 'network'); From 0cc0e925569d5105a5b7d8d4b8ab27ac9804badd Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Fri, 1 Dec 2023 11:04:53 +0100 Subject: [PATCH 07/10] 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'; From eae337f76ebb6e192dff7fb2babe44d48dbf1f15 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Tue, 5 Dec 2023 16:48:15 +0100 Subject: [PATCH 08/10] Fix comments --- src/registration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registration.ts b/src/registration.ts index 783eaa0..d8a00c9 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -8,7 +8,7 @@ import { } from './constants'; import { DID } from './did'; -const registerDidMethodWithByte = (method: string, byte: number): void => { +export const registerDidMethod = (method: string, byte: number): void => { DidMethod[method] = method; if (typeof DidMethodByte[method] === 'number') { @@ -112,7 +112,7 @@ export const registerDidMethodNetwork = ({ Blockchain[blockchain] = blockchain; NetworkId[network] = network; if (typeof methodByte === 'number') { - registerDidMethodWithByte(method, methodByte); + registerDidMethod(method, methodByte); } if (!DidMethodNetwork[method]) { From 748af9aaf29ce29ceb4528b3fc6d32e01c4cd72d Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Thu, 7 Dec 2023 13:01:12 +0100 Subject: [PATCH 09/10] Adjust JS Core according to golang --- src/registration.ts | 46 ++++++-- tests/did.test.ts | 272 +++++++++++++++++++++++++------------------- 2 files changed, 191 insertions(+), 127 deletions(-) diff --git a/src/registration.ts b/src/registration.ts index d8a00c9..0c06f1f 100644 --- a/src/registration.ts +++ b/src/registration.ts @@ -8,13 +8,32 @@ import { } from './constants'; import { DID } from './did'; -export const registerDidMethod = (method: string, byte: number): void => { - DidMethod[method] = method; +export const registerBlockchain = (blockchain: string): void => { + Blockchain[blockchain] = blockchain; +}; + +export const registerNetwork = (network: string): void => { + NetworkId[network] = network; +}; - if (typeof DidMethodByte[method] === 'number') { - throw new Error(`did method ${method} already registered`); +export const registerDidMethod = (method: string, byte: number): void => { + const existingByte = DidMethodByte[method]; + if (typeof DidMethodByte[method] === 'number' && existingByte !== byte) { + throw new Error( + `DID method '${method}' already registered with byte '${existingByte.toString(2)}'` + ); + } + const max = DidMethodByte[DidMethod.Other]; + + if (byte >= max) { + throw new Error( + `Can't register DID method byte: current '${byte.toString(2)}', maximum byte allowed: '${( + max - 1 + ).toString(2)}'` + ); } + DidMethod[method] = method; DidMethodByte[method] = byte; }; @@ -29,8 +48,10 @@ export const registerDidMethod = (method: string, byte: number): void => { export const registerChainId = (blockchain: string, network: string, chainId: number): void => { const key = `${blockchain}:${network}`; - if (typeof ChainIds[key] === 'number') { - throw new Error(`chainId ${blockchain}:${network} already registered`); + if (typeof ChainIds[key] === 'number' && ChainIds[key] !== chainId) { + throw new Error( + `chainId '${blockchain}:${network}' already registered with value '${ChainIds[key]}'` + ); } ChainIds[key] = chainId; @@ -109,8 +130,8 @@ export const registerDidMethodNetwork = ({ networkFlag: number; chainId?: number; }): void => { - Blockchain[blockchain] = blockchain; - NetworkId[network] = network; + registerBlockchain(blockchain); + registerNetwork(network); if (typeof methodByte === 'number') { registerDidMethod(method, methodByte); } @@ -124,8 +145,13 @@ export const registerDidMethodNetwork = ({ } const key = `${blockchain}:${network}`; - if (typeof DidMethodNetwork[method][key] === 'number') { - throw new Error(`did method network ${key} already registered`); + const existedFlag = DidMethodNetwork[method][key]; + if (typeof existedFlag === 'number' && existedFlag !== networkFlag) { + throw new Error( + `DID method network '${method}' with blockchain '${blockchain}' and network '${network}' already registered with another flag '${existedFlag.toString( + 2 + )}'` + ); } DidMethodNetwork[method][key] = networkFlag; }; diff --git a/tests/did.test.ts b/tests/did.test.ts index a83cde3..c96e492 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -46,123 +46,6 @@ describe('DID tests', () => { expect(Uint8Array.from([DidMethodByte[DidMethod.Iden3], 0b0])).toStrictEqual(id.type()); }); - 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('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(d.string().split(':').pop()); - - // did - const didStr = 'did:method:chain:network:4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT'; - - const did3 = DID.parse(didStr); - const id = DID.idFromDID(did3); - - expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(id.string()); - const method = DID.methodFromId(id); - expect(DidMethod.method).toBe(method); - const blockchain = DID.blockchainFromId(id); - expect(Blockchain.chain).toBe(blockchain); - const networkId = DID.networkIdFromId(id); - expect(NetworkId.network).toBe(networkId); - }); - it('TestDID_UnmarshalJSON', () => { const parseRes = JSON.parse( `{"obj": "did:iden3:polygon:mumbai:wyFiV4w71QgWPn6bYLsZoysFay66gKtVa9kfu6yMZ"}` @@ -372,4 +255,159 @@ describe('DID tests', () => { "can't get Ethereum address: high bytes of genesis are not zero" ); }); + + it('TestCustomDIDRegistration', () => { + const testCases = [ + { + description: 'register new did method network', + data: { + method: 'test_method', + blockchain: 'test_chain', + network: 'test_net', + networkFlag: 0b0001_0001, + chainId: 101, + methodByte: 0b00000011 + } + }, + { + description: 'register one more new did method network', + data: { + method: 'method', + blockchain: 'chain', + network: 'network', + networkFlag: 0b0001_0001, + chainId: 102, + methodByte: 0b00000100 + } + }, + { + description: 'register the same new did method network', + data: { + method: 'method', + blockchain: 'chain', + network: 'network', + networkFlag: 0b0001_0001, + chainId: 102, + methodByte: 0b00000100 + } + }, + { + description: 'register network to existing did method', + data: { + method: DidMethod.Iden3, + blockchain: 'chain', + network: NetworkId.Test, + networkFlag: 0b01000000 | 0b00000011, + chainId: 103 + } + }, + { + description: 'register network to existing did method and chainId', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: NetworkId.NoNetwork, + networkFlag: 0b00000000, + chainId: 103 + } + }, + { + description: 'register one more network to existing did method', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.ReadOnly, + network: 'network', + networkFlag: 0b01000000 | 0b00000011, + chainId: 104 + } + }, + { + description: 'register known chain id to new did method', + data: { + method: 'method2', + blockchain: Blockchain.Polygon, + network: NetworkId.Mumbai, + networkFlag: 0b0001_0001, + methodByte: 0b0000001 + } + } + ]; + + for (let i = 0; i < testCases.length; i++) { + const tc = testCases[i]; + expect(() => registerDidMethodNetwork(tc.data)).not.toThrow(); + } + + const d = helperBuildDIDFromType('method', 'chain', 'network'); + // const did = helperBuildDIDFromType('method', 'chain', 'network'); + expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(d.string().split(':').pop()); + + // did + const didStr = 'did:method:chain:network:4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT'; + + const did3 = DID.parse(didStr); + const id = DID.idFromDID(did3); + + expect('4bb86obLkMrifHixMY62WM4iQQVr7u29cxWjMAinrT').toEqual(id.string()); + const method = DID.methodFromId(id); + expect(DidMethod.method).toBe(method); + const blockchain = DID.blockchainFromId(id); + expect(Blockchain.chain).toBe(blockchain); + const networkId = DID.networkIdFromId(id); + expect(NetworkId.network).toBe(networkId); + }); + + const testCases = [ + { + description: 'try to overwrite existing chain id', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.Polygon, + network: NetworkId.Mumbai, + networkFlag: 0b0001_0001, + chainId: 1 + }, + err: "chainId 'polygon:mumbai' already registered with value '80001'" + }, + { + description: 'try to overwrite existing DID method byte', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.Ethereum, + network: NetworkId.Main, + networkFlag: 0b00100000 | 0b00000001, + chainId: 1, + methodByte: 0b00000010 + }, + err: "DID method 'iden3' already registered with byte '1'" + }, + { + description: 'try to write max did method byte', + data: { + method: 'method33', + blockchain: Blockchain.Ethereum, + network: NetworkId.Main, + networkFlag: 0b00100000 | 0b00000001, + chainId: 1, + methodByte: 0b11111111 + }, + err: "Can't register DID method byte: current '11111111', maximum byte allowed: '11111110'" + }, + { + description: 'try to rewrite existing DID Method Network Flag', + data: { + method: DidMethod.Iden3, + blockchain: Blockchain.Ethereum, + network: NetworkId.Main, + networkFlag: 0b00100000 | 0b00000011 + }, + err: "DID method network 'iden3' with blockchain 'eth' and network 'main' already registered with another flag '100001'" + } + ]; + for (let i = 0; i < testCases.length; i++) { + const tc = testCases[i]; + it(tc.description, () => { + expect(() => registerDidMethodNetwork(tc.data)).toThrowError(tc.err); + }); + } }); From 299f5ee587dad0f44f0098260e035054d6fc1fa8 Mon Sep 17 00:00:00 2001 From: Dimasik Kolezhniuk Date: Tue, 12 Dec 2023 13:41:26 +0100 Subject: [PATCH 10/10] Update version to 1.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c453a1..b1df681 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@iden3/js-iden3-core", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@iden3/js-iden3-core", - "version": "1.1.0", + "version": "1.2.0", "license": "AGPL-3.0", "devDependencies": { "@iden3/eslint-config": "https://github.com/iden3/eslint-config", diff --git a/package.json b/package.json index b56a0a1..d58eefb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@iden3/js-iden3-core", - "version": "1.1.0", + "version": "1.2.0", "description": "Low level API to create and manipulate iden3 Claims.", "source": "./src/index.ts", "typings": "dist/types/index.d.ts",