diff --git a/docs/getting-started.md b/docs/getting-started.md index 11b379545..e01efab71 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -243,7 +243,7 @@ Creating a CType requires specifying its structure as a [JSON schema](https://js ```typescript const ctype = Kilt.CType.fromSchema({ - $schema: 'http://kilt-protocol.org/draft-01/ctype#', + $schema: 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', title: 'Drivers License', properties: { name: { diff --git a/docs/getting-started.ts b/docs/getting-started.ts index 1c7852c68..37ea6e41d 100644 --- a/docs/getting-started.ts +++ b/docs/getting-started.ts @@ -95,7 +95,7 @@ async function main(): Promise { /* 2.2 Build a CType */ const ctype = Kilt.CType.fromSchema({ - $schema: 'http://kilt-protocol.org/draft-01/ctype#', + $schema: 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', title: 'Drivers License', properties: { name: { diff --git a/packages/core/src/__integrationtests__/Ctypes.spec.ts b/packages/core/src/__integrationtests__/Ctypes.spec.ts index e27055ae4..ebab866ad 100644 --- a/packages/core/src/__integrationtests__/Ctypes.spec.ts +++ b/packages/core/src/__integrationtests__/Ctypes.spec.ts @@ -27,7 +27,10 @@ beforeAll(async () => { await initializeApi() }) -describe('When there is an CtypeCreator and a verifier', () => { +describe.each([ + 'http://kilt-protocol.org/draft-01/ctype#', + 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', +])('schema id %s', (schemaId) => { let ctypeCreator: FullDidDetails let paymentAccount: KeyringPair let ctypeCounter = 0 @@ -37,7 +40,7 @@ describe('When there is an CtypeCreator and a verifier', () => { ctypeCounter += 1 return CType.fromSchema({ $id: `kilt:ctype:0x${ctypeCounter}`, - $schema: 'http://kilt-protocol.org/draft-01/ctype#', + $schema: schemaId, title: `ctype${ctypeCounter}`, properties: { name: { type: 'string' }, @@ -104,7 +107,7 @@ describe('When there is an CtypeCreator and a verifier', () => { it('should tell when a ctype is not on chain', async () => { const iAmNotThere = CType.fromSchema({ $id: 'kilt:ctype:0x2', - $schema: 'http://kilt-protocol.org/draft-01/ctype#', + $schema: schemaId, title: 'ctype2', properties: { game: { type: 'string' }, @@ -115,7 +118,7 @@ describe('When there is an CtypeCreator and a verifier', () => { const iAmNotThereWithOwner = CType.fromSchema( { $id: 'kilt:ctype:0x3', - $schema: 'http://kilt-protocol.org/draft-01/ctype#', + $schema: schemaId, title: 'ctype2', properties: { game: { type: 'string' }, diff --git a/packages/core/src/ctype/CType.utils.spec.ts b/packages/core/src/ctype/CType.utils.spec.ts index decf282dd..351c56a2d 100644 --- a/packages/core/src/ctype/CType.utils.spec.ts +++ b/packages/core/src/ctype/CType.utils.spec.ts @@ -22,37 +22,6 @@ import { getOwner, isStored } from './CType.chain' jest.mock('./CType.chain') -const ctypeInput = { - $id: 'kilt:ctype:0x1', - $schema: 'http://kilt-protocol.org/draft-01/ctype-input#', - title: 'Ctype Title', - properties: [ - { - $id: 'kilt:ctype:0xfirst-property', - $ref: 'First Property', - type: 'integer', - }, - { - $id: 'kilt:ctype:0xsecond-property', - $ref: 'Second Property', - type: 'string', - }, - ], - type: 'object', - required: ['first-property', 'second-property'], -} as any as ICType['schema'] - -const ctypeWrapperModel: ICType['schema'] = { - $id: 'kilt:ctype:0x2', - $schema: 'http://kilt-protocol.org/draft-01/ctype#', - title: 'name', - properties: { - 'first-property': { type: 'integer' }, - 'second-property': { type: 'string' }, - }, - type: 'object', -} - const goodClaim = { 'first-property': 10, 'second-property': '12', @@ -64,80 +33,118 @@ const badClaim = { 'third-property': true, } -describe('CTypeUtils', () => { - it('verifies claims', () => { - expect(verifyClaimStructure(goodClaim, ctypeWrapperModel)).toBeTruthy() - expect(verifyClaimStructure(badClaim, ctypeWrapperModel)).toBeFalsy() - expect(verifySchemaWithErrors(badClaim, CTypeWrapperModel, [])).toBeFalsy() - expect(() => { - verifyClaimStructure(badClaim, ctypeInput) - }).toThrow(SDKErrors.ERROR_OBJECT_MALFORMED()) - }) - it('verifies ctypes', () => { - expect(verifySchema(ctypeWrapperModel, CTypeModel)).toBeTruthy() - }) -}) - -describe('CType registration verification', () => { - const didAlice = 'did:kilt:4p6K4tpdZtY3rNqM2uorQmsS6d3woxtnWMHjtzGftHmDb41N' - const didBob = 'did:kilt:4rDeMGr3Hi4NfxRUp8qVyhvgW3BSUBLneQisGa9ASkhh2sXB' +describe.each([ + 'http://kilt-protocol.org/draft-01/ctype#', + 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', +])('schema id %s', (schemaId) => { + const ctypeInput = { + $id: 'kilt:ctype:0x1', + $schema: schemaId, + title: 'Ctype Title', + properties: [ + { + $id: 'kilt:ctype:0xfirst-property', + $ref: 'First Property', + type: 'integer', + }, + { + $id: 'kilt:ctype:0xsecond-property', + $ref: 'Second Property', + type: 'string', + }, + ], + type: 'object', + required: ['first-property', 'second-property'], + } as any as ICType['schema'] - const rawCType = { + const ctypeWrapperModel: ICType['schema'] = { $id: 'kilt:ctype:0x2', - $schema: 'http://kilt-protocol.org/draft-01/ctype#', - title: 'CtypeModel 2', + $schema: schemaId, + title: 'name', properties: { - name: { type: 'string' }, + 'first-property': { type: 'integer' }, + 'second-property': { type: 'string' }, }, type: 'object', - } as ICType['schema'] - - describe('when CType is not registered', () => { - beforeAll(() => { - ;(getOwner as jest.Mock).mockReturnValue(null) - ;(isStored as jest.Mock).mockReturnValue(false) + } + + describe('CTypeUtils', () => { + it('verifies claims', () => { + expect(verifyClaimStructure(goodClaim, ctypeWrapperModel)).toBeTruthy() + expect(verifyClaimStructure(badClaim, ctypeWrapperModel)).toBeFalsy() + expect( + verifySchemaWithErrors(badClaim, CTypeWrapperModel, []) + ).toBeFalsy() + expect(() => { + verifyClaimStructure(badClaim, ctypeInput) + }).toThrow(SDKErrors.ERROR_OBJECT_MALFORMED()) }) - - it('does not verify registration when not registered', async () => { - const ctype = CType.fromSchema(rawCType, didAlice) - await expect(ctype.verifyStored()).resolves.toBeFalsy() - }) - - it('does not verify owner when not registered', async () => { - const ctype = CType.fromSchema(rawCType, didAlice) - await expect(ctype.verifyOwner()).resolves.toBeFalsy() + it('verifies ctypes', () => { + expect(verifySchema(ctypeWrapperModel, CTypeModel)).toBeTruthy() }) }) - describe('when CType is registered', () => { - beforeAll(() => { - ;(getOwner as jest.Mock).mockReturnValue(didAlice) - ;(isStored as jest.Mock).mockReturnValue(true) - }) - - it('verifies registration when owner not set', async () => { - const ctype = CType.fromSchema(rawCType) - await expect(ctype.verifyStored()).resolves.toBeTruthy() - }) - - it('verifies registration when owner matches', async () => { - const ctype = CType.fromSchema(rawCType, didAlice) - await expect(ctype.verifyStored()).resolves.toBeTruthy() - }) - - it('verifies registration when owner does not match', async () => { - const ctype = CType.fromSchema(rawCType, didBob) - await expect(ctype.verifyStored()).resolves.toBeTruthy() - }) - - it('verifies owner when owner matches', async () => { - const ctype = CType.fromSchema(rawCType, didAlice) - await expect(ctype.verifyOwner()).resolves.toBeTruthy() + describe('CType registration verification', () => { + const didAlice = 'did:kilt:4p6K4tpdZtY3rNqM2uorQmsS6d3woxtnWMHjtzGftHmDb41N' + const didBob = 'did:kilt:4rDeMGr3Hi4NfxRUp8qVyhvgW3BSUBLneQisGa9ASkhh2sXB' + + const rawCType = { + $id: 'kilt:ctype:0x2', + $schema: schemaId, + title: 'CtypeModel 2', + properties: { + name: { type: 'string' }, + }, + type: 'object', + } as ICType['schema'] + + describe('when CType is not registered', () => { + beforeAll(() => { + ;(getOwner as jest.Mock).mockReturnValue(null) + ;(isStored as jest.Mock).mockReturnValue(false) + }) + + it('does not verify registration when not registered', async () => { + const ctype = CType.fromSchema(rawCType, didAlice) + await expect(ctype.verifyStored()).resolves.toBeFalsy() + }) + + it('does not verify owner when not registered', async () => { + const ctype = CType.fromSchema(rawCType, didAlice) + await expect(ctype.verifyOwner()).resolves.toBeFalsy() + }) }) - it('does not verify owner when owner does not match', async () => { - const ctype = CType.fromSchema(rawCType, didBob) - await expect(ctype.verifyOwner()).resolves.toBeFalsy() + describe('when CType is registered', () => { + beforeAll(() => { + ;(getOwner as jest.Mock).mockReturnValue(didAlice) + ;(isStored as jest.Mock).mockReturnValue(true) + }) + + it('verifies registration when owner not set', async () => { + const ctype = CType.fromSchema(rawCType) + await expect(ctype.verifyStored()).resolves.toBeTruthy() + }) + + it('verifies registration when owner matches', async () => { + const ctype = CType.fromSchema(rawCType, didAlice) + await expect(ctype.verifyStored()).resolves.toBeTruthy() + }) + + it('verifies registration when owner does not match', async () => { + const ctype = CType.fromSchema(rawCType, didBob) + await expect(ctype.verifyStored()).resolves.toBeTruthy() + }) + + it('verifies owner when owner matches', async () => { + const ctype = CType.fromSchema(rawCType, didAlice) + await expect(ctype.verifyOwner()).resolves.toBeTruthy() + }) + + it('does not verify owner when owner does not match', async () => { + const ctype = CType.fromSchema(rawCType, didBob) + await expect(ctype.verifyOwner()).resolves.toBeFalsy() + }) }) }) }) diff --git a/packages/core/src/ctype/CTypeSchema.ts b/packages/core/src/ctype/CTypeSchema.ts index 63342a9a6..20c78f12f 100644 --- a/packages/core/src/ctype/CTypeSchema.ts +++ b/packages/core/src/ctype/CTypeSchema.ts @@ -12,7 +12,7 @@ import { JsonSchema } from '@kiltprotocol/utils' export const CTypeModel: JsonSchema.Schema = { - $id: 'http://kilt-protocol.org/draft-01/ctype#', + $id: 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', properties: { @@ -24,7 +24,10 @@ export const CTypeModel: JsonSchema.Schema = { $schema: { type: 'string', format: 'uri', - const: 'http://kilt-protocol.org/draft-01/ctype#', + enum: [ + 'http://kilt-protocol.org/draft-01/ctype#', + 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype.json', + ], }, title: { type: 'string', @@ -70,7 +73,7 @@ export const CTypeModel: JsonSchema.Schema = { } export const CTypeWrapperModel = { - $id: 'http://kilt-protocol.org/draft-01/ctype-wrapper#', + $id: 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype-wrapper.json', $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', properties: { @@ -89,7 +92,7 @@ export const CTypeWrapperModel = { } export const MetadataModel = { - $id: 'http://kilt-protocol.org/draft-01/ctype-metadata', + $id: 'ipns://k51qzi5uqu5dkglos1mtdukd4axyhwav7e98bga8g2nptrkgcbj9506ruoadiz/v1/ctype-metadata.json', $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', properties: {