diff --git a/.changeset/breezy-islands-play.md b/.changeset/breezy-islands-play.md new file mode 100644 index 00000000..eb2ecca0 --- /dev/null +++ b/.changeset/breezy-islands-play.md @@ -0,0 +1,11 @@ +--- +"@tbdex/http-client": minor +"@tbdex/http-server": minor +"@tbdex/protocol": minor +--- + +Upgrade packages web5/dids@0.4.0, web5/credentials@0.4.2, web5/crypto@0.4.0, web5/common@0.2.3 + +* Deprecate did:ion and did:key in favour of did:jwk and did:dht +* Migrate from `PortableDid` to `BearerDid` with the latest @web5/dids upgrade +* Replaces dependency on `Web5Crypto` with `BearerDid` signer abstraction for signing operations diff --git a/packages/http-client/package.json b/packages/http-client/package.json index 6fe652ad..4107897f 100644 --- a/packages/http-client/package.json +++ b/packages/http-client/package.json @@ -50,10 +50,10 @@ }, "dependencies": { "@tbdex/protocol": "workspace:*", - "@web5/common": "0.2.2", - "@web5/credentials": "0.4.1", - "@web5/crypto": "0.2.4", - "@web5/dids": "0.2.4", + "@web5/common": "0.2.3", + "@web5/credentials": "0.4.2", + "@web5/crypto": "0.4.0", + "@web5/dids": "0.4.0", "ms": "2.1.3", "query-string": "8.1.0", "typeid-js": "0.3.0" diff --git a/packages/http-client/src/client.ts b/packages/http-client/src/client.ts index e171cddd..bcf775ea 100644 --- a/packages/http-client/src/client.ts +++ b/packages/http-client/src/client.ts @@ -1,6 +1,6 @@ import type { JwtPayload } from '@web5/crypto' import type { ErrorDetail } from './types.js' -import type { DidDocument, PortableDid } from '@web5/dids' +import type { DidDocument, BearerDid } from '@web5/dids' import { MessageModel, Parser, @@ -30,7 +30,7 @@ import ms from 'ms' * @beta */ export type GenerateRequestTokenParams = { - requesterDid: PortableDid + requesterDid: BearerDid pfiDid: string } @@ -251,19 +251,20 @@ export class TbdexHttpClient { * @throws {@link RequestTokenSigningError} If an error occurs during the token generation. */ static async generateRequestToken(params: GenerateRequestTokenParams): Promise { + const { pfiDid, requesterDid } = params const now = Date.now() const exp = (now + ms('1m')) const jwtPayload: JwtPayload = { - aud : params.pfiDid, - iss : params.requesterDid.did, + aud : pfiDid, + iss : requesterDid.uri, exp : Math.floor(exp / 1000), iat : Math.floor(now / 1000), jti : typeid().getSuffix() } try { - return await Jwt.sign({ signerDid: params.requesterDid, payload: jwtPayload }) + return await Jwt.sign({ signerDid: requesterDid, payload: jwtPayload }) } catch(e) { throw new RequestTokenSigningError({ message: e.message, cause: e }) } @@ -351,7 +352,7 @@ export type GetExchangeOptions = { /** the exchange you want to fetch */ exchangeId: string /** the message author's DID */ - did: PortableDid + did: BearerDid } /** @@ -361,7 +362,7 @@ export type GetExchangeOptions = { export type GetExchangesOptions = { /** the DID of the PFI from whom you want to get offerings */ pfiDid: string - did: PortableDid, + did: BearerDid, filter?: { id: string | string[] } diff --git a/packages/http-client/tests/client.spec.ts b/packages/http-client/tests/client.spec.ts index e3d2eba1..3f183389 100644 --- a/packages/http-client/tests/client.spec.ts +++ b/packages/http-client/tests/client.spec.ts @@ -1,5 +1,5 @@ import { expect } from 'chai' -import { DidDhtMethod, DidKeyMethod, PortableDid } from '@web5/dids' +import { DidDht, DidJwk, BearerDid } from '@web5/dids' import { TbdexHttpClient, requestTokenRequiredClaims } from '../src/client.js' import { RequestError,ResponseError, @@ -12,19 +12,22 @@ import { } from '../src/errors/index.js' import { DevTools } from '@tbdex/protocol' import * as sinon from 'sinon' -import { JwtHeaderParams, JwtPayload, PrivateKeyJwk, Secp256k1 } from '@web5/crypto' +import { JwtHeaderParams, JwtPayload } from '@web5/crypto' import { Convert } from '@web5/common' import { Jwt } from '@web5/credentials' -const dhtDid = await DidDhtMethod.create({ - publish : true, - services : [{ - type : 'PFI', - id : 'pfi', - serviceEndpoint : 'https://localhost:9000' - }] +const pfiDid: BearerDid = await DidDht.create({ + options: { + services: [{ + type : 'PFI', + id : 'pfi', + serviceEndpoint : 'https://localhost:9000' + }] + } }) +const aliceDid: BearerDid = await DidJwk.create() + // TODO : Instead of stubbing fetch, consider using libraries like msw const fetchStub = sinon.stub(globalThis, 'fetch') const getPfiServiceEndpointStub = sinon.stub(TbdexHttpClient, 'getPfiServiceEndpoint') @@ -33,13 +36,6 @@ describe('client', () => { beforeEach(() => getPfiServiceEndpointStub.resolves('https://localhost:9000')) describe('sendMessage', () => { - let aliceDid: PortableDid - let pfiDid: PortableDid - - beforeEach(async () => { - aliceDid = await DevTools.createDid() - pfiDid = await DevTools.createDid() - }) it('throws RequestError if service endpoint url is garbage', async () => { getPfiServiceEndpointStub.resolves('garbage') @@ -80,7 +76,7 @@ describe('client', () => { expect(e).to.be.instanceof(ResponseError) expect(e.statusCode).to.exist expect(e.details).to.exist - expect(e.recipientDid).to.equal(pfiDid.did) + expect(e.recipientDid).to.equal(pfiDid.uri) expect(e.url).to.equal(`https://localhost:9000/exchanges/${rfq.metadata.exchangeId}/rfq`) } }) @@ -124,7 +120,7 @@ describe('client', () => { fetchStub.rejects({message: 'Failed to fetch on URL'}) try { - await TbdexHttpClient.getOfferings({ pfiDid: dhtDid.did }) + await TbdexHttpClient.getOfferings({ pfiDid: pfiDid.uri }) expect.fail() } catch(e) { expect(e.name).to.equal('RequestError') @@ -145,14 +141,14 @@ describe('client', () => { } as Response) try { - await TbdexHttpClient.getOfferings({ pfiDid: dhtDid.did }) + await TbdexHttpClient.getOfferings({ pfiDid: pfiDid.uri }) expect.fail() } catch(e) { expect(e.name).to.equal('ResponseError') expect(e).to.be.instanceof(ResponseError) expect(e.statusCode).to.exist expect(e.details).to.exist - expect(e.recipientDid).to.equal(dhtDid.did) + expect(e.recipientDid).to.equal(pfiDid.uri) expect(e.url).to.equal('https://localhost:9000/offerings') } }) @@ -163,7 +159,7 @@ describe('client', () => { json : () => Promise.resolve({ data: [] }) } as Response) - const offerings = await TbdexHttpClient.getOfferings({ pfiDid: dhtDid.did }) + const offerings = await TbdexHttpClient.getOfferings({ pfiDid: pfiDid.uri }) expect(offerings).to.have.length(0) }) }) @@ -174,7 +170,7 @@ describe('client', () => { fetchStub.rejects({message: 'Failed to fetch on URL'}) try { - await TbdexHttpClient.getExchange({ pfiDid: dhtDid.did, exchangeId: '123', did: dhtDid }) + await TbdexHttpClient.getExchange({ pfiDid: pfiDid.uri, exchangeId: '123', did: pfiDid }) expect.fail() } catch(e) { expect(e.name).to.equal('RequestError') @@ -195,14 +191,14 @@ describe('client', () => { } as Response) try { - await TbdexHttpClient.getExchange({ pfiDid: dhtDid.did, exchangeId: '123', did: dhtDid }) + await TbdexHttpClient.getExchange({ pfiDid: pfiDid.uri, exchangeId: '123', did: pfiDid }) expect.fail() } catch(e) { expect(e.name).to.equal('ResponseError') expect(e).to.be.instanceof(ResponseError) expect(e.statusCode).to.exist expect(e.details).to.exist - expect(e.recipientDid).to.equal(dhtDid.did) + expect(e.recipientDid).to.equal(pfiDid.uri) expect(e.url).to.equal('https://localhost:9000/exchanges/123') } }) @@ -213,7 +209,7 @@ describe('client', () => { json : () => Promise.resolve({ data: [] }) } as Response) - const exchanges = await TbdexHttpClient.getExchange({ pfiDid: dhtDid.did, exchangeId: '123', did: dhtDid }) + const exchanges = await TbdexHttpClient.getExchange({ pfiDid: pfiDid.uri, exchangeId: '123', did: pfiDid }) expect(exchanges).to.have.length(0) }) }) @@ -224,7 +220,7 @@ describe('client', () => { fetchStub.rejects({message: 'Failed to fetch on URL'}) try { - await TbdexHttpClient.getExchanges({ pfiDid: dhtDid.did, did: dhtDid }) + await TbdexHttpClient.getExchanges({ pfiDid: pfiDid.uri, did: pfiDid }) expect.fail() } catch(e) { expect(e.name).to.equal('RequestError') @@ -245,14 +241,14 @@ describe('client', () => { } as Response) try { - await TbdexHttpClient.getExchanges({ pfiDid: dhtDid.did, did: dhtDid }) + await TbdexHttpClient.getExchanges({ pfiDid: pfiDid.uri, did: pfiDid }) expect.fail() } catch(e) { expect(e.name).to.equal('ResponseError') expect(e).to.be.instanceof(ResponseError) expect(e.statusCode).to.exist expect(e.details).to.exist - expect(e.recipientDid).to.equal(dhtDid.did) + expect(e.recipientDid).to.equal(pfiDid.uri) expect(e.url).to.equal('https://localhost:9000/exchanges') } }) @@ -263,7 +259,7 @@ describe('client', () => { json : () => Promise.resolve({ data: [] }) } as Response) - const exchanges = await TbdexHttpClient.getExchanges({ pfiDid: dhtDid.did, did: dhtDid }) + const exchanges = await TbdexHttpClient.getExchanges({ pfiDid: pfiDid.uri, did: pfiDid }) expect(exchanges).to.have.length(0) }) }) @@ -285,10 +281,8 @@ describe('client', () => { } }) it('throws MissingServiceEndpointError if did has no PFI service endpoint', async () => { - const keyDid = await DidKeyMethod.create() - try { - await TbdexHttpClient.getPfiServiceEndpoint(keyDid.did) + await TbdexHttpClient.getPfiServiceEndpoint(aliceDid.uri) expect.fail() } catch(e) { expect(e.name).to.equal('MissingServiceEndpointError') @@ -297,73 +291,75 @@ describe('client', () => { } }) it('returns pfi service endpoint if all is well', async () => { - const serviceEndpoint = await TbdexHttpClient.getPfiServiceEndpoint(dhtDid.did) + const serviceEndpoint = await TbdexHttpClient.getPfiServiceEndpoint(pfiDid.uri) expect(serviceEndpoint).to.equal('https://localhost:9000') }) }) describe('generateRequestToken', () => { - let requesterPortableDid: PortableDid + let requesterBearerDid: BearerDid before(async () => { - requesterPortableDid = await DidKeyMethod.create({ keyAlgorithm: 'secp256k1' }) - }) - it('throws a RequestTokenSigningError if requesterDid is not a valid PortableDid', async () => { - try { - await TbdexHttpClient.generateRequestToken({ requesterDid: {did: '', document: { id: '' }, keySet: {}}, pfiDid: '' }) - expect.fail() - } catch (e) { - expect(e).to.be.instanceOf(RequestTokenSigningError) - } + requesterBearerDid = await DidJwk.create() }) it('includes all expected claims', async () => { - const requestToken = await TbdexHttpClient.generateRequestToken({ requesterDid: requesterPortableDid, pfiDid: 'did:key:1234' }) + const requestToken = await TbdexHttpClient.generateRequestToken({ requesterDid: requesterBearerDid, pfiDid: 'did:key:1234' }) const decodedToken = await Jwt.verify({ jwt: requestToken }) expect(decodedToken.payload).to.have.all.keys(requestTokenRequiredClaims) }) // TODO: decide if we want to ensure that the expiration date is not longer than 1 minute after the issuance date it('sets expiration seconds to 1 minute after the time at which it was issued', async () => { - const requestToken = await TbdexHttpClient.generateRequestToken({ requesterDid: requesterPortableDid, pfiDid: 'did:key:1234' }) + const requestToken = await TbdexHttpClient.generateRequestToken({ requesterDid: requesterBearerDid, pfiDid: 'did:key:1234' }) const decodedToken = await Jwt.verify({ jwt: requestToken }) expect(decodedToken.payload.exp! - decodedToken.payload.iat!).to.equal(60) }) }) describe('verifyRequestToken', () => { - let pfiPortableDid: PortableDid let header: JwtHeaderParams let payload: JwtPayload + /* + ** helper function to help alice generate a valid request token to send to a pfi + */ async function createRequestTokenFromPayload(payload: JwtPayload) { - const privateKeyJwk = pfiPortableDid.keySet.verificationMethodKeys![0].privateKeyJwk + const signer = await pfiDid.getSigner() + header = { typ: 'JWT', alg: signer.algorithm, kid: signer.keyId } const base64UrlEncodedHeader = Convert.object(header).toBase64Url() const base64UrlEncodedPayload = Convert.object(payload).toBase64Url() const toSign = `${base64UrlEncodedHeader}.${base64UrlEncodedPayload}` const toSignBytes = Convert.string(toSign).toUint8Array() - const signatureBytes = await Secp256k1.sign({ key: privateKeyJwk as PrivateKeyJwk, data: toSignBytes }) + const signatureBytes = await signer.sign({ data: toSignBytes }) const base64UrlEncodedSignature = Convert.uint8Array(signatureBytes).toBase64Url() return `${toSign}.${base64UrlEncodedSignature}` } - before(async () => { - pfiPortableDid = await DidKeyMethod.create({ keyAlgorithm: 'secp256k1' }) - header = { typ: 'JWT', alg: 'ES256K', kid: pfiPortableDid.document.verificationMethod![0].id } - }) - beforeEach(() => { payload = { iat : Math.floor(Date.now() / 1000), - aud : pfiPortableDid.did, + aud : pfiDid.uri, iss : 'did:key:1234', exp : Math.floor(Date.now() / 1000 + 60), jti : 'randomnonce' } }) + it('throws a RequestTokenSigningError if token cannot be signed', async () => { + const jwtSigner = sinon.stub(Jwt, 'sign') + jwtSigner.throws() + try { + await TbdexHttpClient.generateRequestToken({ requesterDid: aliceDid, pfiDid: ''}) + expect.fail() + } catch (e) { + expect(e).to.be.instanceOf(RequestTokenSigningError) + } + jwtSigner.restore() + }) + it('throws RequestTokenVerificationError if request token is not a valid jwt', async () => { try { - await TbdexHttpClient.verifyRequestToken({ requestToken: '', pfiDid: pfiPortableDid.did }) + await TbdexHttpClient.verifyRequestToken({ requestToken: '', pfiDid: pfiDid.uri }) expect.fail() } catch(e) { expect(e).to.be.instanceof(RequestTokenVerificationError) @@ -375,7 +371,7 @@ describe('client', () => { try { delete payload[claim] const requestToken = await createRequestTokenFromPayload(payload) - await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiPortableDid.did }) + await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiDid.uri }) expect.fail() } catch(e) { expect(e).to.be.instanceof(RequestTokenMissingClaimsError) @@ -388,7 +384,7 @@ describe('client', () => { try { payload.aud = 'squirtle' const requestToken = await createRequestTokenFromPayload(payload) - await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiPortableDid.did }) + await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiDid.uri }) expect.fail() } catch(e) { expect(e).to.be.instanceof(RequestTokenAudienceMismatchError) @@ -397,7 +393,7 @@ describe('client', () => { }) it('returns requester\'s DID if request token is valid', async () => { const requestToken = await createRequestTokenFromPayload(payload) - const iss = await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiPortableDid.did }) + const iss = await TbdexHttpClient.verifyRequestToken({ requestToken, pfiDid: pfiDid.uri }) expect(iss).to.equal('did:key:1234') }) }) diff --git a/packages/http-server/package.json b/packages/http-server/package.json index 471a104d..cd690641 100644 --- a/packages/http-server/package.json +++ b/packages/http-server/package.json @@ -23,7 +23,7 @@ "dependencies": { "@tbdex/http-client": "workspace:*", "@tbdex/protocol": "workspace:*", - "@web5/dids": "0.2.2", + "@web5/dids": "0.4.0", "cors": "2.8.5", "express": "4.18.2" }, diff --git a/packages/http-server/tests/create-exchange.spec.ts b/packages/http-server/tests/create-exchange.spec.ts index d64d4d78..14f64a64 100644 --- a/packages/http-server/tests/create-exchange.spec.ts +++ b/packages/http-server/tests/create-exchange.spec.ts @@ -50,7 +50,7 @@ describe('POST /exchanges/:exchangeId/rfq', () => { it('returns a 400 if create exchange request contains a replyTo which is not a valid URL', async () => { const aliceDid = await DevTools.createDid() - const pfiDid = await DevTools.createDid() + const pfiDid = await DevTools.createDid('dht') const rfq = await DevTools.createRfq({ sender: aliceDid, receiver: pfiDid }) await rfq.sign(aliceDid) diff --git a/packages/http-server/tests/get-exchanges.spec.ts b/packages/http-server/tests/get-exchanges.spec.ts index 4c7f8cd1..a4373846 100644 --- a/packages/http-server/tests/get-exchanges.spec.ts +++ b/packages/http-server/tests/get-exchanges.spec.ts @@ -2,7 +2,7 @@ import type { ExchangesApi, GetExchangesFilter, Message } from '../src/main.js' import type { Server } from 'http' import { TbdexHttpServer, Rfq, Quote, Order, OrderStatus, Close, TbdexHttpClient } from '../src/main.js' -import { DidKeyMethod } from '@web5/dids' +import { DidJwk } from '@web5/dids' import { expect } from 'chai' let api = new TbdexHttpServer() @@ -32,13 +32,13 @@ describe('GET /exchanges', () => { it(`passes the requester's did to getExchanges method`, async () => { let functionReached = false - const alice = await DidKeyMethod.create() + const alice = await DidJwk.create() const exchangesApi: ExchangesApi = { getExchanges: async function (opts: { filter: GetExchangesFilter }): Promise { functionReached = true expect(opts.filter.from).to.exist - expect(opts.filter.from).to.equal(alice.did) + expect(opts.filter.from).to.equal(alice.uri) return [] }, diff --git a/packages/http-server/tests/submit-close.spec.ts b/packages/http-server/tests/submit-close.spec.ts index 73db1b19..62395959 100644 --- a/packages/http-server/tests/submit-close.spec.ts +++ b/packages/http-server/tests/submit-close.spec.ts @@ -57,8 +57,8 @@ describe('POST /exchanges/:exchangeId/close', () => { it(`returns a 404 if the exchange doesn't exist`, async () => { const close = Close.create({ metadata: { - from : did.did, - to : did.did, + from : did.uri, + to : did.uri, exchangeId : '123' }, data: {} @@ -82,8 +82,8 @@ describe('POST /exchanges/:exchangeId/close', () => { it(`returns a 409 if close is not allowed based on the exchange's current state`, async () => { const close = Close.create({ metadata: { - from : did.did, - to : did.did, + from : did.uri, + to : did.uri, exchangeId : '123' }, data: {} @@ -95,8 +95,8 @@ describe('POST /exchanges/:exchangeId/close', () => { const close2 = Close.create({ metadata: { - from : did.did, - to : did.did, + from : did.uri, + to : did.uri, exchangeId : '123' }, data: {} diff --git a/packages/http-server/tests/submit-order.spec.ts b/packages/http-server/tests/submit-order.spec.ts index 6d6f49b2..a94f3fc6 100644 --- a/packages/http-server/tests/submit-order.spec.ts +++ b/packages/http-server/tests/submit-order.spec.ts @@ -52,8 +52,8 @@ describe('POST /exchanges/:exchangeId/order', () => { it(`returns a 404 if the exchange doesn't exist`, async () => { const order = Order.create({ metadata: { - from : did.did, - to : did.did, + from : did.uri, + to : did.uri, exchangeId : '123' } }) diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 3c379627..962abcdc 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -51,10 +51,10 @@ "dependencies": { "@noble/hashes": "1.3.3", "@types/node": "^7.0.5", - "@web5/common": "0.2.2", - "@web5/credentials": "0.4.1", - "@web5/crypto": "0.2.4", - "@web5/dids": "0.2.4", + "@web5/common": "0.2.3", + "@web5/credentials": "0.4.2", + "@web5/crypto": "0.4.0", + "@web5/dids": "0.4.0", "ajv": "8.12.0", "bignumber.js": "^9.1.2", "canonicalize": "2.0.0", diff --git a/packages/protocol/src/crypto.ts b/packages/protocol/src/crypto.ts index 25582eb9..e8536440 100644 --- a/packages/protocol/src/crypto.ts +++ b/packages/protocol/src/crypto.ts @@ -1,22 +1,20 @@ import type { - CryptoAlgorithm, - Web5Crypto, JwsHeaderParams, - JwkParamsEcPrivate, - JwkParamsOkpPrivate, JwkParamsEcPublic, JwkParamsOkpPublic, PrivateKeyJwk, - PublicKeyJwk + PublicKeyJwk, } from '@web5/crypto' import { sha256 } from '@noble/hashes/sha256' import { Convert } from '@web5/common' -import { EcdsaAlgorithm, EdDsaAlgorithm } from '@web5/crypto' +import { LocalKeyManager } from '@web5/crypto' import { DidResolver, isVerificationMethod } from './did-resolver.js' import canonicalize from 'canonicalize' -import { PortableDid, VerificationMethod } from '@web5/dids' +import { BearerDid, DidVerificationMethod } from '@web5/dids' + +const keyManager = new LocalKeyManager() /** * Options passed to {@link Crypto.sign} @@ -28,7 +26,7 @@ export type SignOptions = { /** The payload to be signed. */ payload: Uint8Array, /** the DID to sign with */ - did: PortableDid, + did: BearerDid, } /** @@ -41,44 +39,11 @@ export type VerifyOptions = { signature: string } -/** - * Used as value for each supported named curved listed in {@link Crypto.algorithms} - * @beta - */ -type SignerValue = { - signer: CryptoAlgorithm, - options: T, - alg: JwsHeader['alg'], - crv: JsonWebKey['crv'] -} - -const secp256k1Signer: SignerValue = { - signer : new EcdsaAlgorithm(), - options : { name: 'ECDSA' }, - alg : 'ES256K', - crv : 'secp256k1' -} - -const ed25519Signer: SignerValue = { - signer : new EdDsaAlgorithm(), - options : { name: 'EdDSA' }, - alg : 'EdDSA', - crv : 'Ed25519' -} - /** * Cryptographic utility functions, such as hashing, signing, and verifying * @beta */ export class Crypto { - /** supported cryptographic algorithms. keys are `${alg}:${crv}`. */ - static algorithms: { [alg: string]: SignerValue } = { - 'ES256K:' : secp256k1Signer, - 'ES256K:secp256k1' : secp256k1Signer, - ':secp256k1' : secp256k1Signer, - 'EdDSA:Ed25519' : ed25519Signer - } - /** * Computes a digest of the payload by: * * JSON serializing the payload as per [RFC-8785: JSON Canonicalization Scheme](https://www.rfc-editor.org/rfc/rfc8785) @@ -104,30 +69,23 @@ export class Crypto { static async sign(opts: SignOptions) { const { did, payload, detached } = opts - const privateKeyJwk = did.keySet.verificationMethodKeys?.[0]?.privateKeyJwk as JwkParamsEcPrivate | JwkParamsOkpPrivate + const signer = await did.getSigner() - const algorithmName = privateKeyJwk?.['alg'] || '' - let namedCurve = Crypto.extractNamedCurve(privateKeyJwk) - const algorithmId = `${algorithmName}:${namedCurve}` - - const algorithm = this.algorithms[algorithmId] - if (!algorithm) { - throw new Error(`Algorithm (${algorithmId}) not supported`) - } - - let verificationMethodId = did.document.verificationMethod?.[0]?.id || '' + let verificationMethodId = signer.keyId if (verificationMethodId.startsWith('#')) { - verificationMethodId = `${did.did}${verificationMethodId}` + verificationMethodId = `${did.uri}${verificationMethodId}` } - const jwsHeader: JwsHeader = { alg: algorithm.alg, kid: verificationMethodId } + + + const jwsHeader: JwsHeader = { alg: signer.algorithm, kid: verificationMethodId } const base64UrlEncodedJwsHeader = Convert.object(jwsHeader).toBase64Url() const base64urlEncodedJwsPayload = Convert.uint8Array(payload).toBase64Url() const toSign = `${base64UrlEncodedJwsHeader}.${base64urlEncodedJwsPayload}` const toSignBytes = Convert.string(toSign).toUint8Array() - const signatureBytes = await algorithm.signer.sign({ key: privateKeyJwk, data: toSignBytes, algorithm: algorithm.options }) + const signatureBytes = await signer.sign({ data: toSignBytes }) const base64UrlEncodedSignature = Convert.uint8Array(signatureBytes).toBase64Url() if (detached) { @@ -171,9 +129,9 @@ export class Crypto { throw new Error('Signature verification failed: Expected JWS header to contain alg and kid') } - const dereferenceResult = await DidResolver.dereference({ didUrl: jwsHeader.kid }) + const dereferenceResult = await DidResolver.dereference(jwsHeader.kid) - const verificationMethod = dereferenceResult.contentStream as VerificationMethod + const verificationMethod = dereferenceResult.contentStream as DidVerificationMethod if (!isVerificationMethod(verificationMethod)) { // ensure that appropriate verification method was found throw new Error('Signature verification failed: Expected kid in JWS header to dereference to a DID Document Verification Method') } @@ -190,10 +148,7 @@ export class Crypto { const signatureBytes = Convert.base64Url(base64UrlEncodedSignature).toUint8Array() - const algorithmId = `${jwsHeader['alg']}:${Crypto.extractNamedCurve(publicKeyJwk)}` - const { signer, options } = Crypto.algorithms[algorithmId] - - const isLegit = await signer.verify({ algorithm: options, key: publicKeyJwk, data: signedDataBytes, signature: signatureBytes }) + const isLegit = await keyManager.verify({ key: publicKeyJwk, data: signedDataBytes, signature: signatureBytes }) if (!isLegit) { throw new Error('Signature verification failed: Integrity mismatch') diff --git a/packages/protocol/src/dev-tools.ts b/packages/protocol/src/dev-tools.ts index 98c6b8db..38f84116 100644 --- a/packages/protocol/src/dev-tools.ts +++ b/packages/protocol/src/dev-tools.ts @@ -1,8 +1,8 @@ import type { OfferingData, QuoteData, RfqData } from './types.js' -import type { PortableDid } from '@web5/dids' +import type { BearerDid } from '@web5/dids' -import { DidDhtMethod, DidIonMethod, DidKeyMethod } from '@web5/dids' +import { DidDht, DidJwk } from '@web5/dids' import { Offering } from './resource-kinds/index.js' import { Order, Rfq } from './message-kinds/index.js' import { Resource } from './resource.js' @@ -13,7 +13,7 @@ import { VerifiableCredential } from '@web5/credentials' * Supported DID Methods * @beta */ -export type DidMethodOptions = 'key' | 'ion' | 'dht' +export type DidMethodOptions = 'dht' | 'jwk' /** * Options passed to {@link DevTools.createRfq} @@ -21,14 +21,14 @@ export type DidMethodOptions = 'key' | 'ion' | 'dht' */ export type MessageOptions = { /** - * {@link @web5/dids#PortableDid} of the message sender. When generating RFQ, it is used to generate a random credential that fulfills the vcRequirements + * {@link @web5/dids#BearerDid} of the message sender. When generating RFQ, it is used to generate a random credential that fulfills the vcRequirements * of the offering returned by {@link DevTools.createOffering} */ - sender: PortableDid + sender: BearerDid /** - * {@link @web5/dids#PortableDid} of the rfq receiver. + * {@link @web5/dids#BearerDid} of the rfq receiver. */ - receiver?: PortableDid + receiver?: BearerDid } /** @@ -38,15 +38,13 @@ export type MessageOptions = { export class DevTools { /** * creates and returns a DID - * @param didMethod - the type of DID to create. defaults to did:key + * @param didMethod - the type of DID to create. defaults to did:jwk */ - static async createDid(didMethod: DidMethodOptions = 'key') { - if (didMethod === 'key') { - return await DidKeyMethod.create() - } else if (didMethod === 'ion') { - return DidIonMethod.create() + static async createDid(didMethod: DidMethodOptions = 'jwk'): Promise { + if (didMethod === 'jwk') { + return await DidJwk.create() } else if (didMethod === 'dht') { - return DidDhtMethod.create() + return await DidDht.create() } else { throw new Error(`${didMethod} method not implemented.`) } @@ -182,7 +180,7 @@ export class DevTools { const rfqData: RfqData = await DevTools.createRfqData(opts) return Rfq.create({ - metadata : { from: sender.did, to: receiver?.did ?? 'did:ex:pfi' }, + metadata : { from: sender.uri, to: receiver?.uri ?? 'did:ex:pfi' }, data : rfqData }) } @@ -197,8 +195,8 @@ export class DevTools { return Order.create({ metadata: { - from : sender.did, - to : receiver?.did ?? 'did:ex:pfi', + from : sender.uri, + to : receiver?.uri ?? 'did:ex:pfi', exchangeId : Message.generateId('rfq') } }) @@ -213,8 +211,8 @@ export class DevTools { if (opts?.sender) { const vc = await VerifiableCredential.create({ type : 'YoloCredential', - issuer : opts.sender.did, - subject : opts.sender.did, + issuer : opts.sender.uri, + subject : opts.sender.uri, data : { 'beep': 'boop' } diff --git a/packages/protocol/src/did-resolver.ts b/packages/protocol/src/did-resolver.ts index ddb960a7..3e899e84 100644 --- a/packages/protocol/src/did-resolver.ts +++ b/packages/protocol/src/did-resolver.ts @@ -1,6 +1,6 @@ -import type { DidDocument, DidService, VerificationMethod } from '@web5/dids' +import type { DidDocument, DidService, DidVerificationMethod } from '@web5/dids' -import { DidResolver as Web5DidResolver, DidKeyMethod, DidIonMethod, DidDhtMethod } from '@web5/dids' +import { DidResolver as Web5DidResolver, DidDht, DidJwk, DidWeb } from '@web5/dids' /** * Can be used to resolve did:ion and did:key DIDs @@ -8,7 +8,7 @@ import { DidResolver as Web5DidResolver, DidKeyMethod, DidIonMethod, DidDhtMetho * @beta */ export const DidResolver = new Web5DidResolver({ - didResolvers: [DidIonMethod, DidKeyMethod, DidDhtMethod] + didResolvers: [DidDht, DidJwk, DidWeb] }) /** @@ -34,7 +34,7 @@ export async function resolveDid(did: string): Promise { * A DID Resource is either a DID Document, a DID Verification method or a DID Service * @beta */ -export type DidResource = DidDocument | VerificationMethod | DidService +export type DidResource = DidDocument | DidVerificationMethod | DidService /** * type guard for {@link @web5/dids#VerificationMethod} @@ -42,6 +42,6 @@ export type DidResource = DidDocument | VerificationMethod | DidService * @returns true if the didResource is a `VerificationMethod` * @beta */ -export function isVerificationMethod(didResource: DidResource | null): didResource is VerificationMethod { +export function isVerificationMethod(didResource: DidResource | null): didResource is DidVerificationMethod { return !!didResource && 'id' in didResource && 'type' in didResource && 'controller' in didResource } \ No newline at end of file diff --git a/packages/protocol/src/message.ts b/packages/protocol/src/message.ts index e7de5660..a9b0447c 100644 --- a/packages/protocol/src/message.ts +++ b/packages/protocol/src/message.ts @@ -3,7 +3,7 @@ import { Rfq, Quote, Order, OrderStatus, Close } from './message-kinds/index.js' import { Crypto } from './crypto.js' import { typeid } from 'typeid-js' -import { PortableDid } from '@web5/dids' +import { BearerDid } from '@web5/dids' import { validate } from './validator.js' /** @@ -49,8 +49,8 @@ export abstract class Message { * @param did - the signer's DID * @throws If the signature could not be produced */ - async sign(did: PortableDid): Promise { - this._signature = await Crypto.sign({ did: did, payload: this.digest(), detached: true }) + async sign(did: BearerDid): Promise { + this._signature = await Crypto.sign({ did, payload: this.digest(), detached: true }) } /** diff --git a/packages/protocol/src/resource.ts b/packages/protocol/src/resource.ts index 280b376c..adea113c 100644 --- a/packages/protocol/src/resource.ts +++ b/packages/protocol/src/resource.ts @@ -4,7 +4,7 @@ import type { Offering } from './resource-kinds/index.js' import { typeid } from 'typeid-js' import { Crypto } from './crypto.js' import { validate } from './validator.js' -import { PortableDid } from '@web5/dids' +import { BearerDid } from '@web5/dids' /** @@ -46,7 +46,7 @@ export abstract class Resource { * @param did - the signer's DID * @throws If the signature could not be produced */ - async sign(did: PortableDid): Promise { + async sign(did: BearerDid): Promise { this._signature = await Crypto.sign({ did, payload: this.digest(), detached: true }) } diff --git a/packages/protocol/tests/crypto.spec.ts b/packages/protocol/tests/crypto.spec.ts index 678a1f8c..a65145d9 100644 --- a/packages/protocol/tests/crypto.spec.ts +++ b/packages/protocol/tests/crypto.spec.ts @@ -6,7 +6,7 @@ import { Crypto, DevTools } from '../src/main.js' describe('Crypto', () => { describe('sign / verify', () => { it('works with did:ion', async () => { - const alice = await DevTools.createDid('ion') + const alice = await DevTools.createDid() const payload = { timestamp: new Date().toISOString() } const payloadBytes = Convert.object(payload).toUint8Array() @@ -15,7 +15,7 @@ describe('Crypto', () => { }).timeout(30_000) it('works with did:key', async () => { - const alice = await DevTools.createDid('key') + const alice = await DevTools.createDid() const payload = { timestamp: new Date().toISOString() } const payloadBytes = Convert.object(payload).toUint8Array() @@ -25,14 +25,14 @@ describe('Crypto', () => { }) it('works with detached content', async () => { - const alice = await DevTools.createDid('ion') + const alice = await DevTools.createDid() const payload = { timestamp: new Date().toISOString() } const payloadBytes = Convert.object(payload).toUint8Array() const token = await Crypto.sign({ did: alice, payload: payloadBytes, detached: true }) const did = await Crypto.verify({ signature: token, detachedPayload: payloadBytes }) - expect(alice.did).to.equal(did) + expect(alice.uri).to.equal(did) }).timeout(30_000) }) }) \ No newline at end of file diff --git a/packages/protocol/tests/exchange.spec.ts b/packages/protocol/tests/exchange.spec.ts index e07a3d5a..57a93c8e 100644 --- a/packages/protocol/tests/exchange.spec.ts +++ b/packages/protocol/tests/exchange.spec.ts @@ -1,10 +1,10 @@ -import { PortableDid } from '@web5/dids' +import { BearerDid } from '@web5/dids' import { expect } from 'chai' import { Close, DevTools, Exchange, Message, Order, OrderStatus, Quote, Rfq } from '../src/main.js' describe('Exchange', () => { - let aliceDid: PortableDid - let pfiDid: PortableDid + let aliceDid: BearerDid + let pfiDid: BearerDid let rfq: Rfq let quote: Quote let closeByAlice: Close @@ -14,12 +14,12 @@ describe('Exchange', () => { beforeEach(async () => { aliceDid = await DevTools.createDid() - pfiDid = await DevTools.createDid() + pfiDid = await DevTools.createDid('dht') rfq = Rfq.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, }, data: await DevTools.createRfqData() }) @@ -27,8 +27,8 @@ describe('Exchange', () => { closeByAlice = Close.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, exchangeId : rfq.metadata.exchangeId, }, data: { @@ -39,8 +39,8 @@ describe('Exchange', () => { quote = Quote.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId }, data: DevTools.createQuoteData() @@ -49,8 +49,8 @@ describe('Exchange', () => { closeByPfi = Close.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId, }, data: { @@ -61,8 +61,8 @@ describe('Exchange', () => { order = Order.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, exchangeId : rfq.metadata.exchangeId }, }) @@ -70,8 +70,8 @@ describe('Exchange', () => { orderStatus = OrderStatus.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId, }, data: { @@ -115,8 +115,8 @@ describe('Exchange', () => { it('throws if the messages listed do not have matching exchange_id', async () => { const quote = Quote.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : Message.generateId('rfq') }, data: DevTools.createQuoteData() @@ -133,13 +133,10 @@ describe('Exchange', () => { }) it('throws if the messages listed have timestamp after Close', async () => { - const aliceDid = await DevTools.createDid() - const pfiDid = await DevTools.createDid() - const close = Close.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, exchangeId : rfq.metadata.exchangeId, }, data: { @@ -150,8 +147,8 @@ describe('Exchange', () => { const quote = Quote.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId }, data: DevTools.createQuoteData() @@ -288,13 +285,11 @@ describe('Exchange', () => { describe('messages', () => { it('returns the list of messages in the exchange', async () => { - const aliceDid = await DevTools.createDid() - const pfiDid = await DevTools.createDid() const rfq = Rfq.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, }, data: await DevTools.createRfqData() }) @@ -302,8 +297,8 @@ describe('Exchange', () => { const quote = Quote.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId }, data: DevTools.createQuoteData() @@ -312,8 +307,8 @@ describe('Exchange', () => { const order = Order.create({ metadata: { - from : aliceDid.did, - to : pfiDid.did, + from : aliceDid.uri, + to : pfiDid.uri, exchangeId : rfq.metadata.exchangeId }, }) @@ -321,8 +316,8 @@ describe('Exchange', () => { const orderStatus = OrderStatus.create({ metadata: { - from : pfiDid.did, - to : aliceDid.did, + from : pfiDid.uri, + to : aliceDid.uri, exchangeId : rfq.metadata.exchangeId, }, data: { diff --git a/packages/protocol/tests/generate-test-vectors.ts b/packages/protocol/tests/generate-test-vectors.ts index 81b849bc..4871d8d2 100644 --- a/packages/protocol/tests/generate-test-vectors.ts +++ b/packages/protocol/tests/generate-test-vectors.ts @@ -1,4 +1,3 @@ -import { DidKeyMethod } from '@web5/dids' import { VerifiableCredential } from '@web5/credentials' import { Close, DevTools, Message, Order, OrderStatus, Quote, Rfq } from '../src/main.js' import fs from 'fs' @@ -14,10 +13,10 @@ type TestVector = { } const generateParseOfferingVector = async () => { - const did = await DidKeyMethod.create() - const offering = DevTools.createOffering({ from: did.did }) + const pfiDid = await await DevTools.createDid('dht') + const offering = DevTools.createOffering({ from: pfiDid.uri }) - await offering.sign(did) + await offering.sign(pfiDid) return { description : 'Offering parses from string', @@ -28,16 +27,16 @@ const generateParseOfferingVector = async () => { } const generateParseQuoteVector = async () => { - const did = await DidKeyMethod.create() + const pfiDid = await DevTools.createDid('dht') const quote = Quote.create({ metadata: { exchangeId : Message.generateId('rfq'), - from : did.did, + from : pfiDid.uri, to : 'did:ex:pfi' }, data: DevTools.createQuoteData() }) - await quote.sign(did) + await quote.sign(pfiDid) return { description : 'Quote parses from string', @@ -48,20 +47,20 @@ const generateParseQuoteVector = async () => { } const generateParseRfqVector = async () => { - const did = await DidKeyMethod.create() + const aliceDid = await DevTools.createDid() const vc = await VerifiableCredential.create({ type : 'PuupuuCredential', - issuer : did.did, - subject : did.did, + issuer : aliceDid.uri, + subject : aliceDid.uri, data : { 'beep': 'boop' } }) - const vcJwt = await vc.sign({ did }) + const vcJwt = await vc.sign({ did: aliceDid }) const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : { offeringId : 'abcd123', payinMethod : { @@ -84,7 +83,7 @@ const generateParseRfqVector = async () => { } }) - await rfq.sign(did) + await rfq.sign(aliceDid) return { description : 'RFQ parses from string', @@ -95,12 +94,12 @@ const generateParseRfqVector = async () => { } const generateParseOrderVector = async () => { - const did = await DidKeyMethod.create() + const aliceDid = await DevTools.createDid() const order = Order.create({ - metadata: { from: did.did, to: 'did:ex:pfi', exchangeId: 'abcd123' } + metadata: { from: aliceDid.uri, to: 'did:ex:pfi', exchangeId: 'abcd123' } }) - await order.sign(did) + await order.sign(aliceDid) return { description : 'Order parses from string', @@ -111,15 +110,15 @@ const generateParseOrderVector = async () => { } const generateParseCloseVector = async () => { - const did = await DidKeyMethod.create() + const pfiDid = await DevTools.createDid('dht') const close = Close.create({ - metadata : { from: did.did, to: 'did:ex:pfi', exchangeId: 'abcd123' }, + metadata : { from: pfiDid.uri, to: 'did:ex:alice', exchangeId: 'abcd123' }, data : { reason: 'The reason for closing the exchange' } }) - await close.sign(did) + await close.sign(pfiDid) return { description : 'Close parses from string', @@ -130,15 +129,15 @@ const generateParseCloseVector = async () => { } const generateParseOrderStatusVector = async () => { - const did = await DidKeyMethod.create() + const pfiDid = await DevTools.createDid() const orderStatus = OrderStatus.create({ - metadata : { from: did.did, to: 'did:ex:pfi', exchangeId: 'abcd123' }, + metadata : { from: pfiDid.uri, to: 'did:ex:alice', exchangeId: 'abcd123' }, data : { orderStatus: 'wee' } }) - await orderStatus.sign(did) + await orderStatus.sign(pfiDid) return { description : 'Order Status parses from string', diff --git a/packages/protocol/tests/offering.spec.ts b/packages/protocol/tests/offering.spec.ts index e8c30d9a..3527132d 100644 --- a/packages/protocol/tests/offering.spec.ts +++ b/packages/protocol/tests/offering.spec.ts @@ -36,9 +36,9 @@ describe('Offering', () => { describe('sign', () => { it('sets signature property', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offering = Offering.create({ - metadata : { from: pfi.did }, + metadata : { from: pfi.uri }, data : DevTools.createOfferingData() }) @@ -50,9 +50,9 @@ describe('Offering', () => { }) it('includes alg and kid in jws header', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offering = Offering.create({ - metadata : { from: pfi.did }, + metadata : { from: pfi.uri }, data : DevTools.createOfferingData() }) @@ -68,9 +68,9 @@ describe('Offering', () => { describe('verify', () => { it('does not throw an exception if resource integrity is intact', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offering = Offering.create({ - metadata : { from: pfi.did }, + metadata : { from: pfi.uri }, data : DevTools.createOfferingData() }) @@ -79,9 +79,9 @@ describe('Offering', () => { }) it('throws an error if no signature is present on the resource provided', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offering = Offering.create({ - metadata : { from: pfi.did }, + metadata : { from: pfi.uri }, data : DevTools.createOfferingData() }) @@ -113,9 +113,9 @@ describe('Offering', () => { }) it('returns a Resource instance if parsing is successful', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offering = Offering.create({ - metadata : { from: pfi.did }, + metadata : { from: pfi.uri }, data : DevTools.createOfferingData() }) diff --git a/packages/protocol/tests/parse.spec.ts b/packages/protocol/tests/parse.spec.ts index ed1f853b..37d768d8 100644 --- a/packages/protocol/tests/parse.spec.ts +++ b/packages/protocol/tests/parse.spec.ts @@ -4,9 +4,9 @@ import { DevTools, Parser } from '../src/main.js' describe('Parser', () => { describe('parseMessage', async () => { it('throws if an unrecognized message kind is passed', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const unrecognizedMessageKind = { - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : {}, signature : '1234', } @@ -24,9 +24,9 @@ describe('Parser', () => { describe('parseResource', async () => { it('throws if an unrecognized resource kind is passed', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const unrecognizedResourceKind = { - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : {}, signature : '1234', } diff --git a/packages/protocol/tests/rfq.spec.ts b/packages/protocol/tests/rfq.spec.ts index 82fcaee8..6c82ffcc 100644 --- a/packages/protocol/tests/rfq.spec.ts +++ b/packages/protocol/tests/rfq.spec.ts @@ -8,9 +8,9 @@ import { expect } from 'chai' describe('Rfq', () => { describe('create', () => { it('creates an rfq', async () => { - const alice = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const message = Rfq.create({ - metadata : { from: alice.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) @@ -23,51 +23,51 @@ describe('Rfq', () => { describe('sign', () => { it('sets signature property', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) - await rfq.sign(did) + await rfq.sign(aliceDid) expect(rfq.signature).to.not.be.undefined expect(typeof rfq.signature).to.equal('string') }) it('includes alg and kid in jws header', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) - await rfq.sign(did) + await rfq.sign(aliceDid) const [base64UrlEncodedJwsHeader] = rfq.signature!.split('.') const jwsHeader: { kid?: string, alg?: string} = Convert.base64Url(base64UrlEncodedJwsHeader).toObject() - expect(jwsHeader['kid']).to.equal(did.document.verificationMethod![0].id) + expect(jwsHeader['kid']).to.equal(aliceDid.document.verificationMethod![0].id) expect(jwsHeader['alg']).to.exist }) }) describe('verify', () => { it('does not throw an exception if message integrity is intact', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) - await rfq.sign(did) + await rfq.sign(aliceDid) await rfq.verify() }) it('throws an error if no signature is present on the message provided', async () => { - const alice = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const rfq = Rfq.create({ - metadata : { from: alice.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) @@ -98,13 +98,13 @@ describe('Rfq', () => { }) it('returns an instance of Message if parsing is successful', async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : await DevTools.createRfqData() }) - await rfq.sign(did) + await rfq.sign(aliceDid) const jsonMessage = JSON.stringify(rfq) const parsedMessage = await Rfq.parse(jsonMessage) @@ -134,18 +134,18 @@ describe('Rfq', () => { let rfqOptions: CreateRfqOptions beforeEach(async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const vc = await VerifiableCredential.create({ // this credential fulfills the offering's required claims type : 'SanctionsCredential', - issuer : did.did, - subject : did.did, + issuer : aliceDid.uri, + subject : aliceDid.uri, data : { 'beep': 'boop' } }) offering = DevTools.createOffering() - const vcJwt = await vc.sign({ did }) + const vcJwt = await vc.sign({ did: aliceDid }) rfqOptions = { metadata: { @@ -157,7 +157,7 @@ describe('Rfq', () => { offeringId: offering.id, } } - rfqOptions.metadata.from = did.did + rfqOptions.metadata.from = aliceDid.uri rfqOptions.data.claims = [vcJwt] }) @@ -167,13 +167,13 @@ describe('Rfq', () => { }) it('succeeds if Rfq satisfies required payin amount and Offering has no required claims', async () => { - const pfi = await DevTools.createDid() + const pfi = await DevTools.createDid('dht') const offeringData = DevTools.createOfferingData() offeringData.requiredClaims = undefined const offering = Offering.create({ metadata: { - from: pfi.did + from: pfi.uri }, data: offeringData }) @@ -345,24 +345,24 @@ describe('Rfq', () => { describe('verifyClaims', () => { it(`does not throw an exception if an rfq's claims fulfill the provided offering's requirements`, async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const offering = DevTools.createOffering() const vc = await VerifiableCredential.create({ // this credential fulfills the offering's required claims type : 'SanctionsCredential', - issuer : did.did, - subject : did.did, + issuer : aliceDid.uri, + subject : aliceDid.uri, data : { 'beep': 'boop' } }) - const vcJwt = await vc.sign({ did }) + const vcJwt = await vc.sign({ did: aliceDid }) const rfqData = await DevTools.createRfqData() rfqData.claims = [vcJwt] const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : rfqData }) @@ -370,24 +370,24 @@ describe('Rfq', () => { }) it(`throws an exception if an rfq's claims dont fulfill the provided offering's requirements`, async () => { - const did = await DevTools.createDid() + const aliceDid = await DevTools.createDid() const offering = DevTools.createOffering() const vc = await VerifiableCredential.create({ type : 'PuupuuCredential', - issuer : did.did, - subject : did.did, + issuer : aliceDid.uri, + subject : aliceDid.uri, data : { 'beep': 'boop' } }) - const vcJwt = await vc.sign({ did}) + const vcJwt = await vc.sign({ did: aliceDid }) const rfqData = await DevTools.createRfqData() rfqData.claims = [vcJwt] const rfq = Rfq.create({ - metadata : { from: did.did, to: 'did:ex:pfi' }, + metadata : { from: aliceDid.uri, to: 'did:ex:pfi' }, data : rfqData }) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6d1b3d43..e27a8da5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,17 +61,17 @@ importers: specifier: workspace:* version: link:../protocol '@web5/common': - specifier: 0.2.2 - version: 0.2.2 + specifier: 0.2.3 + version: 0.2.3 '@web5/credentials': - specifier: 0.4.1 - version: 0.4.1 + specifier: 0.4.2 + version: 0.4.2 '@web5/crypto': - specifier: 0.2.4 - version: 0.2.4 + specifier: 0.4.0 + version: 0.4.0 '@web5/dids': - specifier: 0.2.4 - version: 0.2.4 + specifier: 0.4.0 + version: 0.4.0 ms: specifier: 2.1.3 version: 2.1.3 @@ -158,8 +158,8 @@ importers: specifier: workspace:* version: link:../protocol '@web5/dids': - specifier: 0.2.2 - version: 0.2.2 + specifier: 0.4.0 + version: 0.4.0 cors: specifier: 2.8.5 version: 2.8.5 @@ -204,17 +204,17 @@ importers: specifier: ^7.0.5 version: 7.10.14 '@web5/common': - specifier: 0.2.2 - version: 0.2.2 + specifier: 0.2.3 + version: 0.2.3 '@web5/credentials': - specifier: 0.4.1 - version: 0.4.1 + specifier: 0.4.2 + version: 0.4.2 '@web5/crypto': - specifier: 0.2.4 - version: 0.2.4 + specifier: 0.4.0 + version: 0.4.0 '@web5/dids': - specifier: 0.2.4 - version: 0.2.4 + specifier: 0.4.0 + version: 0.4.0 ajv: specifier: 8.12.0 version: 8.12.0 @@ -512,16 +512,6 @@ packages: prettier: 2.8.8 dev: true - /@decentralized-identity/ion-pow-sdk@1.0.17: - resolution: {integrity: sha512-vk7DTDM8aKDbFyu1ad/qkoRrGL4q+KvNeL/FNZXhkWPaDhVExBN/qGEoRLf1YSfFe+myto3+4RYTPut+riiqnw==} - dependencies: - buffer: 6.0.3 - cross-fetch: 3.1.5 - hash-wasm: 4.9.0 - transitivePeerDependencies: - - encoding - dev: false - /@decentralized-identity/ion-sdk@1.0.1: resolution: {integrity: sha512-+P+DXcRSFjsEsI5KIqUmVjpzgUT28B2lWpTO+IxiBcfibAN/1Sg20NebGTO/+serz2CnSZf95N2a1OZ6eXypGQ==} dependencies: @@ -533,6 +523,14 @@ packages: uri-js: 4.4.1 dev: false + /@dnsquery/dns-packet@6.1.1: + resolution: {integrity: sha512-WXTuFvL3G+74SchFAtz3FgIYVOe196ycvGsMgvSH/8Goptb1qpIQtIuM4SOK9G9lhMWYpHxnXyy544ZhluFOew==} + engines: {node: '>=6'} + dependencies: + '@leichtgewicht/ip-codec': 2.0.4 + utf8-codec: 1.0.0 + dev: false + /@esbuild/android-arm64@0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -864,40 +862,20 @@ packages: resolution: {integrity: sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==} dev: false - /@noble/ciphers@0.1.4: - resolution: {integrity: sha512-d3ZR8vGSpy3v/nllS+bD/OMN5UZqusWiQqkyj7AwzTnhXFH72pF5oB4Ach6DQ50g5kXxC28LdaYBEpsyv9KOUQ==} - dev: false - - /@noble/ciphers@0.4.0: - resolution: {integrity: sha512-xaUaUUDWbHIFSxaQ/pIe+33VG2mfJp6N/KxKLmZr5biWdNznCAmfu24QRhX10BbVAuqOahAoyp0S4M9md6GPDw==} + /@noble/ciphers@0.4.1: + resolution: {integrity: sha512-QCOA9cgf3Rc33owG0AYBB9wszz+Ul2kramWN8tXG44Gyciud/tbkEqvxRF/IpqQaBpRBNi9f4jdNxqB2CQCIXg==} dev: false - /@noble/curves@1.1.0: - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} + /@noble/curves@1.3.0: + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} dependencies: - '@noble/hashes': 1.3.1 - dev: false - - /@noble/curves@1.2.0: - resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} - dependencies: - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.3.3 dev: false /@noble/ed25519@2.0.0: resolution: {integrity: sha512-/extjhkwFupyopDrt80OMWKdLgP429qLZj+z6sYJz90rF2Iz0gjZh2ArMKPImUl13Kx+0EXI2hN9T/KJV0/Zng==} dev: false - /@noble/hashes@1.3.1: - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} - engines: {node: '>= 16'} - dev: false - - /@noble/hashes@1.3.2: - resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} - engines: {node: '>= 16'} - dev: false - /@noble/hashes@1.3.3: resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} @@ -1931,16 +1909,8 @@ packages: - utf-8-validate dev: true - /@web5/common@0.2.1: - resolution: {integrity: sha512-Tt5P17HgQCx+Epw0IHnhRKqp5UU3E4xtsE8PkdghOBnvntBB0op5P6efvR1WqmJft5+VunDHt3yZAZstuqQkNg==} - engines: {node: '>=18.0.0'} - dependencies: - level: 8.0.0 - multiformats: 11.0.2 - dev: false - - /@web5/common@0.2.2: - resolution: {integrity: sha512-dRn6SmALExeTLMTK/W5ozGarfaddK+Lraf5OjuIGLAaLfcX1RWx3oDMoY5Hr9LjfxHJC8mGXB8DnKflbeYJRgA==} + /@web5/common@0.2.3: + resolution: {integrity: sha512-WTbIS6l5inrQTS5cwOoQP5KEuUHZqOWCKCDAA62qGUn4QyySolog9Gt2HCNUEClIzzk/d5DHcpBgLCadHoJ6rQ==} engines: {node: '>=18.0.0'} dependencies: level: 8.0.0 @@ -1948,75 +1918,37 @@ packages: readable-stream: 4.4.2 dev: false - /@web5/credentials@0.4.1: - resolution: {integrity: sha512-GMbS/N9AqAURjH6+Mvo49AJJxe9uli5mU+dzXtGgFJhiwD4FfqRPxdO1C3R0Tj2aCY3OAQVcCKQgmLRm2hHZlw==} + /@web5/credentials@0.4.2: + resolution: {integrity: sha512-/IMeKDAqrugGuv1hX9rNEEPlj3AiGFszWjoblGec0lw2+JMy0ZIXatCU5gujg8/ejdDFzO7wu9TsQa0SKzGWXw==} engines: {node: '>=18.0.0'} dependencies: '@sphereon/pex': 2.1.0 - '@web5/common': 0.2.2 - '@web5/crypto': 0.2.4 - '@web5/dids': 0.2.4 - transitivePeerDependencies: - - encoding - - supports-color - dev: false - - /@web5/crypto@0.2.2: - resolution: {integrity: sha512-vHFg0wXQSQXrwuBNQyDHnmSZchfTfO6/Sv+7rDsNkvofs+6lGTE8CZ02cwUYMeIwTRMLer12c+fMfzYrXokEUQ==} - engines: {node: '>=18.0.0'} - dependencies: - '@noble/ciphers': 0.1.4 - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 - '@web5/common': 0.2.1 - dev: false - - /@web5/crypto@0.2.4: - resolution: {integrity: sha512-heRUuV10mZ04dWp1C2mNF/EEPw8nnRe+yAXvmclJ+4XUHL6+mY7j+hjYOTKUAQzd4ouvbHrpJM0uYcUntA3AeA==} - engines: {node: '>=18.0.0'} - dependencies: - '@noble/ciphers': 0.4.0 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@web5/common': 0.2.2 + '@web5/common': 0.2.3 + '@web5/crypto': 0.4.0 + '@web5/dids': 0.4.0 dev: false - /@web5/dids@0.2.2: - resolution: {integrity: sha512-dARcpQIMzmayINWFemxP+shhfHLtYB+ZXoSZ1TKKnjF7qzraL30KwBSDwaNEPYaAzgo0x/1rvyv+zAgfa5MeNw==} + /@web5/crypto@0.4.0: + resolution: {integrity: sha512-GIKn2CizQKeATvHQqmC4ky26b3q2pJOd2GjIYsOSw/3Y3QIEm3holDGqu9FHs6kacmr6u0Pv5ELvccs58+cKEg==} engines: {node: '>=18.0.0'} dependencies: - '@decentralized-identity/ion-pow-sdk': 1.0.17 - '@decentralized-identity/ion-sdk': 1.0.1 - '@web5/common': 0.2.1 - '@web5/crypto': 0.2.2 - did-resolver: 4.1.0 - dns-packet: 5.6.1 - level: 8.0.0 - ms: 2.1.3 - pkarr: 1.1.1 - z32: 1.0.1 - transitivePeerDependencies: - - encoding - - supports-color + '@noble/ciphers': 0.4.1 + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@web5/common': 0.2.3 dev: false - /@web5/dids@0.2.4: - resolution: {integrity: sha512-e+m+xgpiM8ydTJgWcPdwmjILLMZYdl2kwahlO22mK0azSKVrg1klpGrUODzqkrWrQ5O0tnOyqEy39FcD5Sy11w==} + /@web5/dids@0.4.0: + resolution: {integrity: sha512-e+QcrKWlWPJVBbpz4QKrdcgPoj+uC8YUXt4tGKj1mC4kV0rCtIioMLw9Djg+54pp3VXl3eGKxju98UEddyZwqA==} engines: {node: '>=18.0.0'} dependencies: - '@decentralized-identity/ion-pow-sdk': 1.0.17 '@decentralized-identity/ion-sdk': 1.0.1 - '@web5/common': 0.2.2 - '@web5/crypto': 0.2.2 - did-resolver: 4.1.0 - dns-packet: 5.6.1 + '@dnsquery/dns-packet': 6.1.1 + '@web5/common': 0.2.3 + '@web5/crypto': 0.4.0 + bencode: 4.0.0 level: 8.0.0 ms: 2.1.3 - pkarr: 1.1.1 - z32: 1.0.1 - transitivePeerDependencies: - - encoding - - supports-color dev: false /abort-controller@3.0.0: @@ -2286,6 +2218,7 @@ packages: /b4a@1.6.4: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: true /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2304,17 +2237,6 @@ packages: engines: {node: '>=10.0.0'} dev: true - /bencode@2.0.3: - resolution: {integrity: sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==} - dev: false - - /bencode@3.1.1: - resolution: {integrity: sha512-btsxX9201yoWh45TdqYg6+OZ5O1xTYKTYSGvJndICDFtznE/9zXgow8yjMvvhOqKKuzuL7h+iiCMpfkG8+QuBA==} - engines: {node: '>=12.20.0'} - dependencies: - uint8-util: 2.2.4 - dev: false - /bencode@4.0.0: resolution: {integrity: sha512-AERXw18df0pF3ziGOCyUjqKZBVNH8HV3lBxnx5w0qtgMIk4a1wb9BkcCQbkp9Zstfrn/dzRwl7MmUHHocX3sRQ==} engines: {node: '>=12.20.0'} @@ -2338,36 +2260,6 @@ packages: engines: {node: '>=8'} dev: true - /bittorrent-dht@11.0.5: - resolution: {integrity: sha512-R09D6uNaziRqsc+B/j5QzkjceTak+wH9vcNLnkmt8A52EWF9lQwBP0vvCKgSA3AJOYYl+41n3osA2KYYn/z5uQ==} - engines: {node: '>=12.20.0'} - dependencies: - bencode: 4.0.0 - debug: 4.3.4(supports-color@8.1.1) - k-bucket: 5.1.0 - k-rpc: 5.1.0 - last-one-wins: 1.0.4 - lru: 3.1.0 - randombytes: 2.1.0 - record-cache: 1.2.0 - transitivePeerDependencies: - - supports-color - dev: false - - /blake2b-wasm@2.4.0: - resolution: {integrity: sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==} - dependencies: - b4a: 1.6.4 - nanoassert: 2.0.0 - dev: false - - /blake2b@2.1.4: - resolution: {integrity: sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==} - dependencies: - blake2b-wasm: 2.4.0 - nanoassert: 2.0.0 - dev: false - /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} dev: true @@ -2607,12 +2499,6 @@ packages: engines: {node: '>=6'} dev: false - /chacha20-universal@1.0.4: - resolution: {integrity: sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==} - dependencies: - nanoassert: 2.0.0 - dev: false - /chai@4.3.10: resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} engines: {node: '>=4'} @@ -2650,11 +2536,6 @@ packages: supports-color: 7.2.0 dev: true - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false - /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true @@ -2684,19 +2565,6 @@ packages: fsevents: 2.3.3 dev: true - /chrome-dgram@3.0.6: - resolution: {integrity: sha512-bqBsUuaOiXiqxXt/zA/jukNJJ4oaOtc7ciwqJpZVEaaXwwxqgI2/ZdG02vXYWUhHGziDlvGMQWk0qObgJwVYKA==} - dependencies: - inherits: 2.0.4 - run-series: 1.1.9 - dev: false - - /chrome-dns@1.0.1: - resolution: {integrity: sha512-HqsYJgIc8ljJJOqOzLphjAs79EUuWSX3nzZi2LNkzlw3GIzAeZbaSektC8iT/tKvLqZq8yl1GJu5o6doA4TRbg==} - dependencies: - chrome-net: 3.3.4 - dev: false - /chrome-launcher@0.15.2: resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} engines: {node: '>=12.13.0'} @@ -2710,12 +2578,6 @@ packages: - supports-color dev: true - /chrome-net@3.3.4: - resolution: {integrity: sha512-Jzy2EnzmE+ligqIZUsmWnck9RBXLuUy6CaKyuNMtowFG3ZvLt8d+WBJCTPEludV0DHpIKjAOlwjFmTaEdfdWCw==} - dependencies: - inherits: 2.0.4 - dev: false - /chromium-bidi@0.4.16(devtools-protocol@0.0.1147663): resolution: {integrity: sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==} peerDependencies: @@ -2949,14 +2811,6 @@ packages: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} dev: true - /cross-fetch@3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} - dependencies: - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - dev: false - /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: @@ -3065,6 +2919,7 @@ packages: dependencies: ms: 2.1.2 supports-color: 8.1.1 + dev: true /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -3194,10 +3049,6 @@ packages: wrappy: 1.0.2 dev: true - /did-resolver@4.1.0: - resolution: {integrity: sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA==} - dev: false - /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} @@ -3223,13 +3074,6 @@ packages: path-type: 4.0.0 dev: true - /dns-packet@5.6.1: - resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} - engines: {node: '>=6'} - dependencies: - '@leichtgewicht/ip-codec': 2.0.4 - dev: false - /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} @@ -4072,12 +3916,6 @@ packages: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} dev: true - /graceful-goodbye@1.3.0: - resolution: {integrity: sha512-hcZOs20emYlTM7MmUE0FpuZcjlk2GPsR+UYTHDeWxtGjXcbh2CawGi8vlzqsIvspqAbot7mRv3sC/uhgtKc4hQ==} - dependencies: - safety-catch: 1.0.2 - dev: false - /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true @@ -4115,6 +3953,7 @@ packages: /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + dev: true /has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} @@ -4144,10 +3983,6 @@ packages: safe-buffer: 5.2.1 dev: true - /hash-wasm@4.9.0: - resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==} - dev: false - /hash.js@1.1.7: resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} dependencies: @@ -4661,29 +4496,6 @@ packages: resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} dev: false - /k-bucket@5.1.0: - resolution: {integrity: sha512-Fac7iINEovXIWU20GPnOMLUbjctiS+cnmyjC4zAUgvs3XPf1vo9akfCHkigftSic/jiKqKl+KA3a/vFcJbHyCg==} - dependencies: - randombytes: 2.1.0 - dev: false - - /k-rpc-socket@1.11.1: - resolution: {integrity: sha512-8xtA8oqbZ6v1Niryp2/g4GxW16EQh5MvrUylQoOG+zcrDff5CKttON2XUXvMwlIHq4/2zfPVFiinAccJ+WhxoA==} - dependencies: - bencode: 2.0.3 - chrome-dgram: 3.0.6 - chrome-dns: 1.0.1 - chrome-net: 3.3.4 - dev: false - - /k-rpc@5.1.0: - resolution: {integrity: sha512-FGc+n70Hcjoa/X2JTwP+jMIOpBz+pkRffHnSl9yrYiwUxg3FIgD50+u1ePfJUOnRCnx6pbjmVk5aAeB1wIijuQ==} - dependencies: - k-bucket: 5.1.0 - k-rpc-socket: 1.11.1 - randombytes: 2.1.0 - dev: false - /keygrip@1.1.0: resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} engines: {node: '>= 0.6'} @@ -4777,10 +4589,6 @@ packages: - supports-color dev: true - /last-one-wins@1.0.4: - resolution: {integrity: sha512-t+KLJFkHPQk8lfN6WBOiGkiUXoub+gnb2XTYI2P3aiISL+94xgZ1vgz1SXN/N4hthuOoLXarXfBZPUruyjQtfA==} - dev: false - /level-supports@4.0.1: resolution: {integrity: sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==} engines: {node: '>=12'} @@ -4931,13 +4739,6 @@ packages: engines: {node: '>=16.14'} dev: true - /lru@3.1.0: - resolution: {integrity: sha512-5OUtoiVIGU4VXBOshidmtOsvBIvcQR6FD/RzWSvaeHyxCGB+PCUCu+52lqMfdc0h/2CLvHhZS4TwUmMQrrMbBQ==} - engines: {node: '>= 0.4.0'} - dependencies: - inherits: 2.0.4 - dev: false - /lunr@2.3.9: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} dev: true @@ -5210,6 +5011,7 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -5245,10 +5047,6 @@ packages: varint: 5.0.2 dev: false - /nanoassert@2.0.0: - resolution: {integrity: sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==} - dev: false - /nanocolors@0.2.13: resolution: {integrity: sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==} dev: true @@ -5305,18 +5103,6 @@ packages: lodash: 4.17.21 dev: true - /node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -5715,21 +5501,6 @@ packages: engines: {node: '>=6'} dev: true - /pkarr@1.1.1: - resolution: {integrity: sha512-X27LKqf83X3WuJd2Z9qdfVxkmfOu6HUbY0pm11LqeBbFmgmZRPgOxJG8bKiIsmmD6Vjc25j45KHYflF2lfodyQ==} - hasBin: true - dependencies: - bencode: 3.1.1 - bittorrent-dht: 11.0.5 - chalk: 5.3.0 - dns-packet: 5.6.1 - graceful-goodbye: 1.3.0 - sodium-universal: 4.0.0 - z32: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: false - /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -5953,6 +5724,7 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 + dev: true /randomfill@1.0.4: resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} @@ -6042,12 +5814,6 @@ packages: picomatch: 2.3.1 dev: true - /record-cache@1.2.0: - resolution: {integrity: sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==} - dependencies: - b4a: 1.6.4 - dev: false - /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -6192,10 +5958,6 @@ packages: queue-microtask: 1.2.3 dev: true - /run-series@1.1.9: - resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==} - dev: false - /rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} dependencies: @@ -6225,10 +5987,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /safety-catch@1.0.2: - resolution: {integrity: sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==} - dev: false - /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -6321,34 +6079,6 @@ packages: safe-buffer: 5.2.1 dev: true - /sha256-universal@1.2.1: - resolution: {integrity: sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==} - dependencies: - b4a: 1.6.4 - sha256-wasm: 2.2.2 - dev: false - - /sha256-wasm@2.2.2: - resolution: {integrity: sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==} - dependencies: - b4a: 1.6.4 - nanoassert: 2.0.0 - dev: false - - /sha512-universal@1.2.1: - resolution: {integrity: sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==} - dependencies: - b4a: 1.6.4 - sha512-wasm: 2.3.4 - dev: false - - /sha512-wasm@2.3.4: - resolution: {integrity: sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==} - dependencies: - b4a: 1.6.4 - nanoassert: 2.0.0 - dev: false - /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -6409,12 +6139,6 @@ packages: supports-color: 7.2.0 dev: true - /siphash24@1.3.1: - resolution: {integrity: sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==} - dependencies: - nanoassert: 2.0.0 - dev: false - /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -6466,39 +6190,6 @@ packages: smart-buffer: 4.2.0 dev: true - /sodium-javascript@0.8.0: - resolution: {integrity: sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==} - dependencies: - blake2b: 2.1.4 - chacha20-universal: 1.0.4 - nanoassert: 2.0.0 - sha256-universal: 1.2.1 - sha512-universal: 1.2.1 - siphash24: 1.3.1 - xsalsa20: 1.2.0 - dev: false - - /sodium-native@4.0.5: - resolution: {integrity: sha512-YGimGhy7Ho6pTAAvuNdn3Tv9C2MD7HP89X1omReHat0Fd1mMnapGqwzb5YoHTAbIEh8tQmKP6+uLlwYCkf+EOA==} - requiresBuild: true - dependencies: - node-gyp-build: 4.8.0 - dev: false - - /sodium-universal@4.0.0: - resolution: {integrity: sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==} - dependencies: - blake2b: 2.1.4 - chacha20-universal: 1.0.4 - nanoassert: 2.0.0 - sha256-universal: 1.2.1 - sha512-universal: 1.2.1 - siphash24: 1.3.1 - sodium-javascript: 0.8.0 - sodium-native: 4.0.5 - xsalsa20: 1.2.0 - dev: false - /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -6732,6 +6423,7 @@ packages: engines: {node: '>=10'} dependencies: has-flag: 4.0.0 + dev: true /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} @@ -6828,6 +6520,7 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true /tr46@3.0.0: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} @@ -7086,6 +6779,10 @@ packages: qs: 6.11.2 dev: true + /utf8-codec@1.0.0: + resolution: {integrity: sha512-S/QSLezp3qvG4ld5PUfXiH7mCFxLKjSVZRFkB3DOjgwHuJPFDkInAXc/anf7BAbHt/D38ozDzL+QMZ6/7gsI6w==} + dev: false + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true @@ -7161,6 +6858,7 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true /webidl-conversions@7.0.0: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} @@ -7180,6 +6878,7 @@ packages: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 + dev: true /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -7314,10 +7013,6 @@ packages: resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} dev: true - /xsalsa20@1.2.0: - resolution: {integrity: sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==} - dev: false - /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -7440,9 +7135,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - - /z32@1.0.1: - resolution: {integrity: sha512-Uytfqf6VEVchHKZDw0NRdCViOARHP84uzvOw0CXCMLOwhgHZUL9XibpEPLLQN10mCVLxOlGCQWbkV7km7yNYcw==} - dependencies: - b4a: 1.6.4 - dev: false diff --git a/tbdex b/tbdex index 7ec25f98..cb6d62ad 160000 --- a/tbdex +++ b/tbdex @@ -1 +1 @@ -Subproject commit 7ec25f981b8ae44c179b3206944ac604329561c5 +Subproject commit cb6d62ad6973d0deafcb5cdee6d28d546afb0c41