From 42a5b65fa3795284fc16b06d2a36c4bf4ea87668 Mon Sep 17 00:00:00 2001 From: nklomp Date: Fri, 19 Nov 2021 00:12:10 +0100 Subject: [PATCH] feat: Add ssi-sdk core module --- packages/ssi-sdk-core/api-extractor.json | 3 ++ packages/ssi-sdk-core/package.json | 38 +++++++++++++++++++ packages/ssi-sdk-core/src/index.ts | 1 + .../src/utils/__tests__/encoding.test.ts | 31 +++++++++++++++ packages/ssi-sdk-core/src/utils/encoding.ts | 35 +++++++++++++++++ packages/ssi-sdk-core/src/utils/index.ts | 1 + packages/ssi-sdk-core/tsconfig.json | 7 ++++ 7 files changed, 116 insertions(+) create mode 100644 packages/ssi-sdk-core/api-extractor.json create mode 100644 packages/ssi-sdk-core/package.json create mode 100644 packages/ssi-sdk-core/src/index.ts create mode 100644 packages/ssi-sdk-core/src/utils/__tests__/encoding.test.ts create mode 100644 packages/ssi-sdk-core/src/utils/encoding.ts create mode 100644 packages/ssi-sdk-core/src/utils/index.ts create mode 100644 packages/ssi-sdk-core/tsconfig.json diff --git a/packages/ssi-sdk-core/api-extractor.json b/packages/ssi-sdk-core/api-extractor.json new file mode 100644 index 000000000..94c2c6a9f --- /dev/null +++ b/packages/ssi-sdk-core/api-extractor.json @@ -0,0 +1,3 @@ +{ + "extends": "../include/api-extractor-base.json" +} diff --git a/packages/ssi-sdk-core/package.json b/packages/ssi-sdk-core/package.json new file mode 100644 index 000000000..723acd450 --- /dev/null +++ b/packages/ssi-sdk-core/package.json @@ -0,0 +1,38 @@ +{ + "name": "@sphereon/ssi-sdk-core", + "description": "SSI SDK Core & Interfaces", + "version": "0.0.1", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc" + }, + "dependencies": { + "@sphereon/did-uni-client": "^0.3.3", + "@veramo/core": "^3.1.0", + "@veramo/did-manager": "^3.1.0", + "debug": "^4.1.1", + "did-jwt-vc": "^2.1.7", + "events": "^3.3.0", + "micro-base58": "^0.5.1", + "z-schema": "^5.0.2" + }, + "devDependencies": { + "@types/debug": "4.1.7", + "did-resolver": "3.1.0", + "typescript": "4.4.3" + }, + "files": [ + "dist/**/*", + "plugin.schema.json", + "README.md", + "LICENSE" + ], + "publishConfig": { + "access": "public" + }, + "repository": "git@github.com:Sphereon-OpenSource/ssi-sdk.git", + "author": "Sphereon ", + "license": "Apache-2.0", + "keywords": [] +} diff --git a/packages/ssi-sdk-core/src/index.ts b/packages/ssi-sdk-core/src/index.ts new file mode 100644 index 000000000..9c56149ef --- /dev/null +++ b/packages/ssi-sdk-core/src/index.ts @@ -0,0 +1 @@ +export * from './utils' diff --git a/packages/ssi-sdk-core/src/utils/__tests__/encoding.test.ts b/packages/ssi-sdk-core/src/utils/__tests__/encoding.test.ts new file mode 100644 index 000000000..0e5c7d46b --- /dev/null +++ b/packages/ssi-sdk-core/src/utils/__tests__/encoding.test.ts @@ -0,0 +1,31 @@ +import {hexToMultibase, MultibaseFormat, multibaseToHex} from "../encoding"; + + +describe('@sphereon/ssi-sdk-core:encoding', () => { + const BASE58_EXAMPLE = 'C3CPq7c8PY'; + const MULTIBASE_EXAMPLE = `z${BASE58_EXAMPLE}`; + const HEX_EXAMPLE = '0123456789abcdef'; + + // Hex to multibase + it('should encode hex to multibase base58', () => { + expect(hexToMultibase(HEX_EXAMPLE, MultibaseFormat.BASE58)).toEqual({value: BASE58_EXAMPLE, format: MultibaseFormat.BASE58}) + expect(hexToMultibase(HEX_EXAMPLE.toUpperCase(), MultibaseFormat.BASE58)).toEqual({value: BASE58_EXAMPLE, format: MultibaseFormat.BASE58}) + }) + it('should not encode hex to not supported multibase format', () => { + expect(() => hexToMultibase(HEX_EXAMPLE, 'e' as never)).toThrowError() + }) + it('should not encode hex to not multibase base58 with no input', () => { + expect(() => hexToMultibase(undefined as never, MultibaseFormat.BASE58)).toThrowError() + }) + + // Multibase to hex + it('should encode multibase base58 to hex', () => { + expect(multibaseToHex(MULTIBASE_EXAMPLE)).toEqual({value: HEX_EXAMPLE, format: MultibaseFormat.BASE58}) + }) + it('should not encode unsupported multibase encoding to hex', () => { + expect(() => multibaseToHex(`e${BASE58_EXAMPLE}`)).toThrowError() + }) + it('should not encode multibase base58 encoding to hex with no input', () => { + expect(() => multibaseToHex(undefined as never)).toThrowError() + }) +}) diff --git a/packages/ssi-sdk-core/src/utils/encoding.ts b/packages/ssi-sdk-core/src/utils/encoding.ts new file mode 100644 index 000000000..d5bc25740 --- /dev/null +++ b/packages/ssi-sdk-core/src/utils/encoding.ts @@ -0,0 +1,35 @@ +import * as base58 from 'micro-base58' + + +export enum MultibaseFormat { + BASE58 = 'z' +} + +export function hexToMultibase(hex: string, format: MultibaseFormat): { value: string, format: MultibaseFormat } { + if (format !== MultibaseFormat.BASE58) { + throw new Error('Only base58 supported for now using multibase!') + } + return {value: base58.encode(hexToBytes(hex)), format} + + function hexToBytes(hex: string): Uint8Array { + let bytes: number[] = [] + for (let c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)) + return Uint8Array.of(...bytes) + } +} + +export function multibaseToHex(multibase: string): { value: string, format: MultibaseFormat } { + if (!multibase.startsWith(MultibaseFormat.BASE58)) { + throw new Error('Only base58 supported for now using multibase!') + } + return {value: bytesToHex(base58.decode(multibase.substr(1), 'btc')), format: MultibaseFormat.BASE58} + + function bytesToHex(uint8a: Uint8Array): string { + // pre-caching chars could speed this up 6x. + let hex = '' + for (let i = 0; i < uint8a.length; i++) { + hex += uint8a[i].toString(16).padStart(2, '0') + } + return hex + } +} diff --git a/packages/ssi-sdk-core/src/utils/index.ts b/packages/ssi-sdk-core/src/utils/index.ts new file mode 100644 index 000000000..44e1f835b --- /dev/null +++ b/packages/ssi-sdk-core/src/utils/index.ts @@ -0,0 +1 @@ +export { hexToMultibase, multibaseToHex } from './encoding' diff --git a/packages/ssi-sdk-core/tsconfig.json b/packages/ssi-sdk-core/tsconfig.json new file mode 100644 index 000000000..f3a8aee57 --- /dev/null +++ b/packages/ssi-sdk-core/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../tsconfig-base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + } +}