diff --git a/package.json b/package.json index a0bd8ea321..45953fdef6 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,16 @@ "prepare": "husky install" }, "dependencies": { + "bignumber.js": "^9.0.1", "bn.js": "^5.2.0", "buffer": "^6.0.3", + "cbor": "^7.0.5", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "events": "^3.3.0", "js-sha256": "^0.9.0", + "multibase": "^4.0.4", + "multihashes": "^4.0.2", "reflect-metadata": "^0.1.13", "node-fetch": "^2.6.1", "tsyringe": "^4.5.0", diff --git a/src/decorators/attachment/Attachment.ts b/src/decorators/attachment/Attachment.ts index 792649a68f..75f444772d 100644 --- a/src/decorators/attachment/Attachment.ts +++ b/src/decorators/attachment/Attachment.ts @@ -15,7 +15,7 @@ export interface AttachmentOptions { export interface AttachmentDataOptions { base64?: string json?: Record - links?: [] + links?: string[] jws?: Record sha256?: string } diff --git a/src/utils/BufferEncoder.ts b/src/utils/BufferEncoder.ts index 5ffd28fa26..fc61d3297b 100644 --- a/src/utils/BufferEncoder.ts +++ b/src/utils/BufferEncoder.ts @@ -28,4 +28,17 @@ export class BufferEncoder { public static fromBase64(base64: string) { return Buffer.from(base64, 'base64') } + + /** + * Decode string into buffer. + * + * @param str the string to decode into buffer format + */ + public static fromString(str: string): Uint8Array { + return Buffer.from(str) + } + + public static toUtf8String(buffer: Buffer | Uint8Array) { + return Buffer.from(buffer).toString() + } } diff --git a/src/utils/MultibaseEncoder.ts b/src/utils/MultibaseEncoder.ts new file mode 100644 index 0000000000..0f585fefa6 --- /dev/null +++ b/src/utils/MultibaseEncoder.ts @@ -0,0 +1,43 @@ +import multibase from 'multibase' +import { Buffer } from './buffer' + +export type BaseName = multibase.BaseName + +export class MultibaseEncoder { + /** + * + * Encodes a buffer into a multibase + * + * @param {Uint8Array} buffer the buffer that has to be encoded + * @param {multibase.BaseName} baseName the encoding algorithm + */ + public static encode(buffer: Uint8Array, baseName: multibase.BaseName = 'base58btc') { + return multibase.encode(baseName, buffer) + } + + /** + * + * Decodes a multibase into a Uint8Array + * + * @param {string} data the multibase that has to be decoded + * + * @returns {Uint8array} data the decoded multibase + * @returns {string} encodingAlgorithm name of the encoding algorithm + */ + public static decode(data: string | Uint8Array): { data: Uint8Array; baseName: string } { + const baseName = multibase.encodingFromData(data).name + return { data: multibase.decode(data), baseName } + } + + /** + * + * Validates if it is a valid multibase encoded value + * + * @param {Uint8Array} data the multibase that needs to be validated + * + * @returns {boolean} bool wether the multibase value is encoded + */ + public static validate(data: string | Uint8Array): boolean { + return multibase.isEncoded(data) ? true : false + } +} diff --git a/src/utils/MultihashEncoder.ts b/src/utils/MultihashEncoder.ts new file mode 100644 index 0000000000..7b08922ac3 --- /dev/null +++ b/src/utils/MultihashEncoder.ts @@ -0,0 +1,41 @@ +import multihash from 'multihashes' +import { Buffer } from './buffer' + +export class MultihashEncoder { + /** + * + * Encodes a buffer into a hash + * + * @param {Uint8Array} buffer the buffer that has to be encoded + * @param {string} hashName the hashing algorithm, 'sha2-256' + */ + public static encode(buffer: Uint8Array, hashName: 'sha2-256') { + return multihash.encode(buffer, hashName) + } + + /** + * + * Decodes the multihash + * + * @param {Uint8Array} data the multihash that has to be decoded + */ + public static decode(data: Uint8Array): { data: Uint8Array; hashName: string } { + const decodedHash = multihash.decode(data) + return { data: decodedHash.digest, hashName: decodedHash.name } + } + + /** + * + * Validates if it is a valid mulithash + * + * @param {Uint8Array} data the multihash that needs to be validated + */ + public static validate(data: Uint8Array) { + try { + multihash.validate(data) + return true + } catch (e) { + return false + } + } +} diff --git a/src/utils/__tests__/MultibaseEncoder.test.ts b/src/utils/__tests__/MultibaseEncoder.test.ts new file mode 100644 index 0000000000..2d8662d21f --- /dev/null +++ b/src/utils/__tests__/MultibaseEncoder.test.ts @@ -0,0 +1,36 @@ +import { MultibaseEncoder } from '../MultibaseEncoder' +import { Buffer } from 'buffer' +import { BufferEncoder } from '../BufferEncoder' + +const validData = Buffer.from('Hello World!') +const validMultibase = 'zKWfinQuRQ3ekD1danFHqvKRg9koFp8vpokUeREEgjSyHwweeKDFaxVHi' +const invalidMultibase = 'gKWfinQuRQ3ekD1danFHqvKRg9koFp8vpokUeREEgjSyHwweeKDFaxVHi' + +describe('multibase', () => { + it('Encodes multibase', () => { + const multibase = BufferEncoder.toUtf8String(MultibaseEncoder.encode(validData, 'base58btc')) + expect(multibase).toEqual('z2NEpo7TZRRrLZSi2U') + }) + + it('Decodes multibase', () => { + const { data, baseName } = MultibaseEncoder.decode(validMultibase) + expect(BufferEncoder.toUtf8String(data)).toEqual('This is a valid base58btc encoded string!') + expect(baseName).toEqual('base58btc') + }) + + it('Validates valid multibase', () => { + const bool = MultibaseEncoder.validate(validMultibase) + expect(bool).toEqual(true) + }) + + it('Validates invalid multibase', () => { + const bool = MultibaseEncoder.validate(invalidMultibase) + expect(bool).toEqual(false) + }) + + it('Decodes invalid multibase', () => { + expect(() => { + MultibaseEncoder.decode(invalidMultibase) + }).toThrow(/^Unsupported encoding: g/) + }) +}) diff --git a/src/utils/__tests__/MultihashEncoder.test.ts b/src/utils/__tests__/MultihashEncoder.test.ts new file mode 100644 index 0000000000..47e1a1a97c --- /dev/null +++ b/src/utils/__tests__/MultihashEncoder.test.ts @@ -0,0 +1,36 @@ +import { MultihashEncoder } from '../MultihashEncoder' +import { Buffer } from 'buffer' +import { BufferEncoder } from '../BufferEncoder' + +const validData = Buffer.from('Hello World!') +const validMultihash = new Uint8Array([18, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]) +const invalidMultihash = new Uint8Array([99, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]) + +describe('multihash', () => { + it('encodes multihash', () => { + const multihash = MultihashEncoder.encode(validData, 'sha2-256') + expect(multihash).toEqual(new Uint8Array([18, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])) + }) + + it('Decodes multihash', () => { + const { data, hashName } = MultihashEncoder.decode(validMultihash) + expect(hashName).toEqual('sha2-256') + expect(BufferEncoder.toUtf8String(data)).toEqual('Hello World!') + }) + + it('Validates valid multihash', () => { + const bool = MultihashEncoder.validate(validMultihash) + expect(bool).toEqual(true) + }) + + it('Validates invalid multihash', () => { + const bool = MultihashEncoder.validate(invalidMultihash) + expect(bool).toEqual(false) + }) + + it('Decodes invalid multihash', () => { + expect(() => { + MultihashEncoder.decode(invalidMultihash) + }).toThrow() + }) +}) diff --git a/src/utils/__tests__/hashlink.test.ts b/src/utils/__tests__/hashlink.test.ts new file mode 100644 index 0000000000..98abc1b50d --- /dev/null +++ b/src/utils/__tests__/hashlink.test.ts @@ -0,0 +1,65 @@ +import { Buffer } from 'buffer' +import { Hashlink } from '../hashlink' + +const validData = { + data: Buffer.from('Hello World!'), + metaData: { + urls: ['https://example.org/hw.txt'], + contentType: 'text/plain', + }, +} + +const invalidData = { + data: Buffer.from('Hello World!'), + metaData: { + unknownKey: 'unkownValue', + contentType: 'image/png', + }, +} + +const validHashlink = + 'hl:zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e:zCwQVpeF6FPqFyc4pvisK5cpW4kc358NTX6ZbhqfawZTBmXm372zoAj5oLSh' + +const invalidHashlink = + 'hl:zQmWvQxTqbqwlkhhhhh9w8e7rJenbyYTWkjgF3e:z51a94WAQfNv1KEcPeoV3V2isZFPFqSzE9ghNFQ8DuQu4hTHtFRug8SDgug14Ff' + +const invalidMetadata = + 'hl:zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e:zHCwSqQisPgCc2sMSNmHWyQtCKu4kgQVD6Q1Nhxff7uNRqN6r' + +describe('Hashlink', () => { + it('Encodes string to hashlink', () => { + const hashlink = Hashlink.encode(validData.data, 'sha2-256') + expect(hashlink).toEqual('hl:zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e') + }) + + it('Encodes string and metadata to hashlink', () => { + const hashlink = Hashlink.encode(validData.data, 'sha2-256', 'base58btc', validData.metaData) + expect(hashlink).toEqual(validHashlink) + }) + + it('Decodes hashlink', () => { + const decodedHashlink = Hashlink.decode(validHashlink) + expect(decodedHashlink).toEqual({ + checksum: 'zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e', + metadata: { contentType: 'text/plain', urls: ['https://example.org/hw.txt'] }, + }) + }) + + it('Decodes invalid hashlink', () => { + expect(() => { + Hashlink.decode(invalidHashlink) + }).toThrow(/^invalid character 'l' in /) + }) + + it('Encodes invalid metadata in hashlink', () => { + expect(() => { + Hashlink.encode(validData.data, 'sha2-256', 'base58btc', invalidData.metaData) + }).toThrow(/^Metadata, /) + }) + + it('Decodes invalid metadata in hashlink', () => { + expect(() => { + Hashlink.decode(invalidMetadata) + }).toThrow(/^Metadata, /) + }) +}) diff --git a/src/utils/hashlink.ts b/src/utils/hashlink.ts new file mode 100644 index 0000000000..288cf87823 --- /dev/null +++ b/src/utils/hashlink.ts @@ -0,0 +1,118 @@ +import cbor from 'cbor' +import { sha256 } from 'js-sha256' +import { BufferEncoder } from './BufferEncoder' +import { Buffer } from './buffer' +import { MultibaseEncoder, BaseName } from './MultibaseEncoder' +import { MultihashEncoder } from './MultihashEncoder' +import multibase from 'multibase' + +type Metadata = { + urls?: string[] + contentType?: string +} + +export type HashlinkData = { + checksum: string + metadata?: Metadata +} + +const URLS = 0x0f +const CONTENTTYPE = 0x0e + +export class Hashlink { + /** + * + * Encodes a buffer, with optional metadata, into a hashlink + * + * @param {Buffer} buffer the buffer to encode into a hashlink + * @param {string} hashName the name of the hashing algorithm 'sha2-256' + * @param {BaseName} baseName the name of the base encoding algorithm 'base58btc' + * @param {Metadata} metadata the optional metadata in the hashlink + */ + public static encode(buffer: Buffer, hashName: 'sha2-256', baseName: BaseName = 'base58btc', metadata?: Metadata) { + const checksum = this.encodeMultihashEncoder(buffer, hashName, baseName) + const mbMetadata = metadata ? this.encodeMetadata(metadata, baseName) : null + return mbMetadata ? `hl:${checksum}:${mbMetadata}` : `hl:${checksum}` + } + + /** + * + * Decodes a hashlink into HashlinkData object + * + * @param {string} hashlink the hashlink that needs decoding + */ + public static decode(hashlink: string): HashlinkData { + const hashlinkList = hashlink.split(':') + if (this.validate(hashlink)) { + const checksum = hashlinkList[1] + const metadata = hashlinkList[2] ? this.decodeMetadata(hashlinkList[2]) : null + + return metadata ? { checksum, metadata } : { checksum } + } else { + throw new Error(`Hashlink, ${hashlink}, is invalid`) + } + } + + public static validate(hashlink: string): boolean { + const hashlinkList = hashlink.split(':') + const validMultibase = MultibaseEncoder.validate(hashlinkList[1]) + const { data } = MultibaseEncoder.decode(hashlinkList[1]) + const validMultihash = MultihashEncoder.validate(data) + return validMultibase && validMultihash ? true : false + } + + private static encodeMultihashEncoder(buffer: Buffer, hashName: 'sha2-256', baseName: BaseName): string { + // TODO: Support more hashing algorithms + const hash = new Uint8Array(sha256.array(buffer)) + const mh = MultihashEncoder.encode(hash, hashName) + const mb = MultibaseEncoder.encode(mh, baseName) + return BufferEncoder.toUtf8String(mb) + } + + private static encodeMetadata(metadata: Metadata, baseName: BaseName): string { + const metadataMap = new Map() + + for (const key of Object.keys(metadata)) { + switch (key) { + case 'urls': + metadataMap.set(URLS, metadata.urls) + break + case 'contentType': + metadataMap.set(CONTENTTYPE, metadata.contentType) + break + default: + throw new Error(`Metadata, ${metadata}, is invalid`) + } + } + + const cborData = cbor.encode(metadataMap) + + const multibaseMetadata = MultibaseEncoder.encode(cborData, baseName) + + return BufferEncoder.toUtf8String(multibaseMetadata) + } + + private static decodeMetadata(mb: string): Metadata { + const obj = { urls: [], contentType: '' } + const { data } = MultibaseEncoder.decode(mb) + try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const cborData: Map = cbor.decode(data) + cborData.forEach((value, key) => { + switch (key) { + case URLS: + obj.urls = value + break + case CONTENTTYPE: + obj.contentType = value + break + default: + throw new Error(`Metadata, ${key}:${value}, is invalid`) + } + }) + return obj + } catch (error) { + throw new Error(`Metadata, ${mb}, is invalid: ${error}`) + } + } +} diff --git a/yarn.lock b/yarn.lock index fca5a3050d..a35a4c3041 100644 --- a/yarn.lock +++ b/yarn.lock @@ -303,6 +303,11 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@cto.af/textdecoder@^0.0.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@cto.af/textdecoder/-/textdecoder-0.0.0.tgz#e1e8d84c936c30a0f4619971f19ca41941af9fdc" + integrity sha512-sJpx3F5xcVV/9jNYJQtvimo4Vfld/nD3ph+ZWtQzZ03Zo8rJC7QKQTRcIGS13Rcz80DwFNthCWMrd58vpY4ZAQ== + "@eslint/eslintrc@^0.4.0": version "0.4.0" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz" @@ -510,6 +515,11 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@multiformats/base-x@^4.0.1": + version "4.0.1" + resolved "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz" + integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz" @@ -989,7 +999,7 @@ abab@^2.0.3, abab@^2.0.5: abbrev@1: version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== accepts@~1.3.7: @@ -1069,12 +1079,12 @@ ansi-escapes@^4.2.1: ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-regex@^4.1.0: @@ -1119,12 +1129,12 @@ anymatch@^3.0.3, anymatch@~3.1.1: aproba@^1.0.3: version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz" integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== dependencies: delegates "^1.0.0" @@ -1322,6 +1332,11 @@ before-after-hook@^2.2.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.1.tgz" integrity sha512-/6FKxSTWoJdbsLDF8tdIjaRiFXiE6UHsEHE3OPI/cwPURCVi1ukP0gmLn7XWEiFk5TcwQjjY5PWsU+j+tgXgmw== +bignumber.js@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" + integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" @@ -1329,7 +1344,7 @@ binary-extensions@^2.0.0: bindings@^1.3.1: version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" @@ -1564,6 +1579,14 @@ caseless@~0.12.0: resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +cbor@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-7.0.5.tgz#ed54cdbc19fa7352bb328d00a5393aa7ce45a10f" + integrity sha512-0aaAPgW92lLmypb9iCd22k7tSD1FbF6dps8VQzmIBKY6ych2gO09b2vo/SbaLTmezJuB8Kh88Rvpl/Uq52mNZg== + dependencies: + "@cto.af/textdecoder" "^0.0.0" + nofilter "^2.0.3" + chalk@4.1.0, chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz" @@ -1608,7 +1631,7 @@ chokidar@^3.5.1: chownr@^1.1.1: version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== ci-info@^2.0.0: @@ -1700,7 +1723,7 @@ co@^4.6.0: code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= collect-v8-coverage@^1.0.0: @@ -1776,7 +1799,7 @@ configstore@^5.0.1: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= content-disposition@0.5.3: @@ -2026,7 +2049,7 @@ delayed-stream@~1.0.0: delegates@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= depd@~1.1.2: @@ -2601,7 +2624,7 @@ file-entry-cache@^6.0.1: file-uri-to-path@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== fill-range@^4.0.0: @@ -2737,7 +2760,7 @@ fresh@0.5.2: fs-minipass@^1.2.5: version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz" integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: minipass "^2.6.0" @@ -2749,7 +2772,7 @@ fs.realpath@^1.0.0: fsevents@^2.1.2, fsevents@~2.3.1: version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: @@ -2764,7 +2787,7 @@ functional-red-black-tree@^1.0.1: gauge@~2.7.3: version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" @@ -2987,7 +3010,7 @@ has-symbols@^1.0.1, has-symbols@^1.0.2: has-unicode@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has-value@^0.3.1: @@ -3180,7 +3203,7 @@ indent-string@^2.1.0: indy-sdk@^1.16.0: version "1.16.0" - resolved "https://registry.yarnpkg.com/indy-sdk/-/indy-sdk-1.16.0.tgz#034385ec5016388b0b52914f49d6334e372bb6c5" + resolved "https://registry.npmjs.org/indy-sdk/-/indy-sdk-1.16.0.tgz" integrity sha512-ATDzxBfHzFvHMiEXZSvmPjdswa3H4/X4npP4SV8yvzR18K/w0u/P4zp9TmEisAWA9of/hy1Fd1ziKMn+phHw+g== dependencies: bindings "^1.3.1" @@ -3379,7 +3402,7 @@ is-finite@^1.0.0: is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" @@ -4434,7 +4457,7 @@ minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + resolved "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz" integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" @@ -4442,7 +4465,7 @@ minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: minizlib@^1.2.1: version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + resolved "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz" integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: minipass "^2.9.0" @@ -4462,7 +4485,7 @@ mkdirp@1.x, mkdirp@^1.0.4: mkdirp@^0.5.0: version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" @@ -4482,6 +4505,22 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +multibase@^4.0.1, multibase@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.4.tgz#55ef53e6acce223c5a09341a8a3a3d973871a577" + integrity sha512-8/JmrdSGzlw6KTgAJCOqUBSGd1V6186i/X8dDCGy/lbCKrQ+1QB6f3HE+wPr7Tpdj4U3gutaj9jG2rNX6UpiJg== + dependencies: + "@multiformats/base-x" "^4.0.1" + +multihashes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-4.0.2.tgz#d76aeac3a302a1bed9fe1ec964fb7a22fa662283" + integrity sha512-xpx++1iZr4ZQHjN1mcrXS6904R36LWLxX/CBifczjtmrtCXEX623DMWOF1eiNSg+pFpiZDFVBgou/4v6ayCHSQ== + dependencies: + multibase "^4.0.1" + uint8arrays "^2.1.3" + varint "^5.0.2" + mute-stream@0.0.8: version "0.0.8" resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" @@ -4489,7 +4528,7 @@ mute-stream@0.0.8: nan@^2.11.1: version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + resolved "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanomatch@^1.2.9: @@ -4531,7 +4570,7 @@ node-fetch@^2.6.1: node-gyp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-4.0.0.tgz#972654af4e5dd0cd2a19081b4b46fe0442ba6f45" + resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz" integrity sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA== dependencies: glob "^7.0.3" @@ -4573,9 +4612,16 @@ node-releases@^1.1.70: resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +nofilter@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-2.0.3.tgz#f5460f3cb33147005883e3f5d4476239501fa187" + integrity sha512-FbuXC+lK+GU2+63D1kC1ETiZo+Z7SIi7B+mxKTCH1byrh6WFvfBCN/wpherFz0a0bjGd7EKTst/cz0yLeNngug== + dependencies: + "@cto.af/textdecoder" "^0.0.0" + "nopt@2 || 3": version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + resolved "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz" integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" @@ -4643,7 +4689,7 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: "npmlog@0 || 1 || 2 || 3 || 4": version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" @@ -4653,7 +4699,7 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= nwsapi@^2.2.0: @@ -4776,7 +4822,7 @@ ora@5.4.0: os-homedir@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + resolved "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-name@4.0.0: @@ -4794,7 +4840,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: osenv@0: version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + resolved "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== dependencies: os-homedir "^1.0.0" @@ -5083,7 +5129,7 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== progress@^2.0.0: @@ -5251,7 +5297,7 @@ read-pkg@^5.2.0: readable-stream@^2.0.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -5618,7 +5664,7 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: semver@~5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + resolved "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= send@0.17.1: @@ -5913,7 +5959,7 @@ string-length@^4.0.1: string-width@^1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" @@ -5922,7 +5968,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2": version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + resolved "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" @@ -5980,21 +6026,21 @@ string_decoder@^1.1.1: string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz" integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" @@ -6101,7 +6147,7 @@ table@^6.0.4: tar@^4.4.8: version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + resolved "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz" integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" @@ -6389,6 +6435,13 @@ typescript@^4.2.3: resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz" integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== +uint8arrays@^2.1.3: + version "2.1.5" + resolved "https://registry.npmjs.org/uint8arrays/-/uint8arrays-2.1.5.tgz" + integrity sha512-CSR7AO+4AHUeSOnZ/NBNCElDeWfRh9bXtOck27083kc7SznmmHIhNEkEOCQOn0wvrIMjS3IH0TNLR16vuc46mA== + dependencies: + multibase "^4.0.1" + unbox-primitive@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz" @@ -6535,6 +6588,11 @@ validator@^13.5.2: resolved "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz" integrity sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ== +varint@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" @@ -6640,7 +6698,7 @@ which@^2.0.1, which@^2.0.2: wide-align@^1.1.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== dependencies: string-width "^1.0.2 || 2" @@ -6729,7 +6787,7 @@ y18n@^4.0.0: yallist@^3.0.0, yallist@^3.0.3: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: