Skip to content

Commit e9d832f

Browse files
authored
fix(sdk): use correct controller during stream creation (#724)
* fix(sdk): use correct controller during stream creation * fix: lint * fix: tests * feat: add did session test * chore: test to update stream with different session did
1 parent b547dc6 commit e9d832f

11 files changed

Lines changed: 231 additions & 69 deletions

File tree

CODEOWNERS

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,2 @@
11
# Default all files to the eng reviewers team
22
* @ceramicnetwork/eng-reviewers
3-
4-
# Pick two reviewers for each top level directory:
5-
# the owner and someone from the eng-reviewers team.
6-
/.github/ @smrz2001 @ceramicnetwork/eng-reviewers
7-
/anchor-service/ @nathanielc @ceramicnetwork/eng-reviewers
8-
/anchor-remote/ @nathanielc @ceramicnetwork/eng-reviewers
9-
/api-server/ @dav1do @ceramicnetwork/eng-reviewers
10-
/api/ @dav1do @ceramicnetwork/eng-reviewers
11-
/beetle/ @nathanielc @ceramicnetwork/eng-reviewers
12-
/ci-scripts/ @smrz2001 @ceramicnetwork/eng-reviewers
13-
/core/ @nathanielc @ceramicnetwork/eng-reviewers
14-
/event/ @nathanielc @ceramicnetwork/eng-reviewers
15-
/flight/ @nathanielc @ceramicnetwork/eng-reviewers
16-
/fpm/ @smrz2001 @ceramicnetwork/eng-reviewers
17-
/kubo-rpc-server/ @nathanielc @ceramicnetwork/eng-reviewers
18-
/kubo-rpc/ @nathanielc @ceramicnetwork/eng-reviewers
19-
/metrics/ @dav1do @ceramicnetwork/eng-reviewers
20-
/migrations/ @dav1do @ceramicnetwork/eng-reviewers
21-
/olap/ @nathanielc @ceramicnetwork/eng-reviewers
22-
/one/ @stbrody @ceramicnetwork/eng-reviewers
23-
/p2p/ @nathanielc @ceramicnetwork/eng-reviewers
24-
/recon/ @nathanielc @ceramicnetwork/eng-reviewers
25-
/service/ @dav1do @ceramicnetwork/eng-reviewers
26-
/store/ @dav1do @ceramicnetwork/eng-reviewers
27-
/validation/ @dav1do @ceramicnetwork/eng-reviewers

sdk/packages/model-instance-client/src/client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import type { DocumentState, UnknownContent } from './types.js'
2828
export type CreateSingletonParams = {
2929
/** The model's stream ID */
3030
model: StreamID
31-
/** The controller of the stream (DID string or literal string) */
32-
controller: DIDString | string
31+
/** The controller of the stream */
32+
controller: DID
3333
/** A unique value to ensure determinism of the event */
3434
uniqueValue?: Uint8Array
3535
}

sdk/packages/model-instance-client/src/events.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
type EncodedDeterministicInitEventPayload,
1313
type JSONPatchOperation,
1414
} from '@ceramic-sdk/model-instance-protocol'
15-
import type { DIDString } from '@didtools/codecs'
1615
import type { DID } from 'dids'
1716
import type { CID } from 'multiformats/cid'
1817

@@ -57,7 +56,7 @@ export async function createInitEvent<
5756
const { content, controller, ...headerParams } = params
5857
const header = createInitHeader({
5958
...headerParams,
60-
controller: controller.id,
59+
controller,
6160
unique: false, // non-deterministic event
6261
})
6362
return await createSignedInitEvent(controller, content, header)
@@ -77,7 +76,7 @@ export async function createInitEvent<
7776
*/
7877
export function getDeterministicInitEventPayload(
7978
model: StreamID,
80-
controller: DIDString | string,
79+
controller: DID,
8180
uniqueValue?: Uint8Array,
8281
): DeterministicInitEventPayload {
8382
return {
@@ -100,7 +99,7 @@ export function getDeterministicInitEventPayload(
10099
*/
101100
export function getDeterministicInitEvent(
102101
model: StreamID,
103-
controller: DIDString | string,
102+
controller: DID,
104103
uniqueValue?: Uint8Array,
105104
): EncodedDeterministicInitEventPayload {
106105
const { header } = getDeterministicInitEventPayload(

sdk/packages/model-instance-client/src/utils.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
DocumentInitEventHeader,
44
type JSONPatchOperation,
55
} from '@ceramic-sdk/model-instance-protocol'
6-
import { type DIDString, asDIDString } from '@didtools/codecs'
6+
import { asDIDString } from '@didtools/codecs'
7+
import type { DID } from 'dids'
78
import jsonpatch from 'fast-json-patch'
89
import type { CID } from 'multiformats/cid'
910

@@ -38,8 +39,8 @@ export type CreateInitHeaderParams = {
3839
/** CID of specific model version to use when validating this instance.
3940
* When empty the the init commit of the model is used */
4041
modelVersion?: CID
41-
/** The DID string or literal string representing the controller of the document. */
42-
controller: DIDString | string
42+
/** The controller of the document. */
43+
controller: DID
4344
/** A unique value to ensure determinism, or a boolean to indicate uniqueness type. */
4445
unique?: Uint8Array | boolean
4546
/** Optional context for the document. */
@@ -68,8 +69,11 @@ export type CreateInitHeaderParams = {
6869
export function createInitHeader(
6970
params: CreateInitHeaderParams,
7071
): DocumentInitEventHeader {
72+
const did = params.controller.hasParent
73+
? params.controller.parent
74+
: params.controller.id
7175
const header: DocumentInitEventHeader = {
72-
controllers: [asDIDString(params.controller)],
76+
controllers: [asDIDString(did)],
7377
model: params.model,
7478
sep: 'model',
7579
}

sdk/packages/model-instance-client/test/lib.test.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,27 @@ const authenticatedDID = await getAuthenticatedDID(new Uint8Array(32))
2929
describe('getDeterministicInitEventPayload()', () => {
3030
test('returns the deterministic event payload without unique value by default', () => {
3131
const model = randomStreamID()
32-
const event = getDeterministicInitEventPayload(model, 'did:key:123')
32+
const event = getDeterministicInitEventPayload(model, authenticatedDID)
3333
expect(event.data).toBeNull()
34-
expect(event.header.controllers).toEqual(['did:key:123'])
34+
expect(event.header.controllers).toEqual([
35+
'did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp',
36+
])
3537
expect(event.header.model).toBe(model)
3638
expect(event.header.unique).toBeUndefined()
3739
})
3840

3941
test('returns the deterministic event payload with the provided unique value', () => {
4042
const model = randomStreamID()
4143
const unique = new Uint8Array([0, 1, 2])
42-
const event = getDeterministicInitEventPayload(model, 'did:key:123', unique)
44+
const event = getDeterministicInitEventPayload(
45+
model,
46+
authenticatedDID,
47+
unique,
48+
)
4349
expect(event.data).toBeNull()
44-
expect(event.header.controllers).toEqual(['did:key:123'])
50+
expect(event.header.controllers).toEqual([
51+
'did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp',
52+
])
4553
expect(event.header.model).toBe(model)
4654
expect(event.header.unique).toBe(unique)
4755
})
@@ -50,19 +58,23 @@ describe('getDeterministicInitEventPayload()', () => {
5058
describe('getDeterministicInitEvent()', () => {
5159
test('returns the deterministic event without unique value by default', () => {
5260
const model = randomStreamID()
53-
const event = getDeterministicInitEvent(model, 'did:key:123')
61+
const event = getDeterministicInitEvent(model, authenticatedDID)
5462
expect(event.data).toBeNull()
55-
expect(event.header.controllers).toEqual(['did:key:123'])
63+
expect(event.header.controllers).toEqual([
64+
'did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp',
65+
])
5666
expect(equals(event.header.model, model.bytes)).toBe(true)
5767
expect(event.header.unique).toBeUndefined()
5868
})
5969

6070
test('returns the deterministic event with the provided unique value', () => {
6171
const model = randomStreamID()
6272
const unique = new Uint8Array([0, 1, 2])
63-
const event = getDeterministicInitEvent(model, 'did:key:123', unique)
73+
const event = getDeterministicInitEvent(model, authenticatedDID, unique)
6474
expect(event.data).toBeNull()
65-
expect(event.header.controllers).toEqual(['did:key:123'])
75+
expect(event.header.controllers).toEqual([
76+
'did:key:z6MkiTBz1ymuepAQ4HEHYSF1H8quG5GLVVQR3djdX3mDooWp',
77+
])
6678
expect(equals(event.header.model, model.bytes)).toBe(true)
6779
expect(event.header.unique).toBe(unique)
6880
})
@@ -145,7 +157,7 @@ describe('ModelInstanceClient', () => {
145157
describe('getEvent() method', () => {
146158
test('gets a MID event by commit ID', async () => {
147159
const streamID = randomStreamID()
148-
const docEvent = getDeterministicInitEvent(streamID, 'did:key:123')
160+
const docEvent = getDeterministicInitEvent(streamID, authenticatedDID)
149161
const getEventType = jest.fn(() => docEvent)
150162
const ceramic = { getEventType } as unknown as CeramicClient
151163
const client = new ModelInstanceClient({ ceramic, did: authenticatedDID })
@@ -167,7 +179,7 @@ describe('ModelInstanceClient', () => {
167179
const client = new ModelInstanceClient({ ceramic, did: authenticatedDID })
168180

169181
const id = await client.createSingleton({
170-
controller: 'did:key:123',
182+
controller: authenticatedDID,
171183
model: randomStreamID(),
172184
})
173185
expect(postEventType).toHaveBeenCalled()

sdk/packages/model-instance-client/test/utils.test.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,49 @@
11
import { randomStreamID } from '@ceramic-sdk/identifiers'
2+
import { getAuthenticatedDID } from '@didtools/key-did'
23
import { equals } from 'uint8arrays'
34

45
import { createInitHeader } from '../src/utils.js'
56

7+
const authenticatedDID = await getAuthenticatedDID(new Uint8Array(32))
8+
69
describe('createInitHeader()', () => {
710
test('adds random unique bytes by default or when explcitly set to false', () => {
8-
const controller = 'did:key:123'
911
const model = randomStreamID()
1012

11-
const header1 = createInitHeader({ controller, model })
13+
const header1 = createInitHeader({ controller: authenticatedDID, model })
1214
expect(header1.unique).toBeInstanceOf(Uint8Array)
13-
const header2 = createInitHeader({ controller, model })
15+
const header2 = createInitHeader({ controller: authenticatedDID, model })
1416
expect(header2.unique).toBeInstanceOf(Uint8Array)
1517
expect(
1618
equals(header1.unique as Uint8Array, header2.unique as Uint8Array),
1719
).toBe(false)
1820

19-
const header3 = createInitHeader({ controller, model, unique: false })
21+
const header3 = createInitHeader({
22+
controller: authenticatedDID,
23+
model,
24+
unique: false,
25+
})
2026
expect(header3.unique).toBeInstanceOf(Uint8Array)
2127
expect(
2228
equals(header1.unique as Uint8Array, header3.unique as Uint8Array),
2329
).toBe(false)
2430
})
2531

2632
test('adds the specified unique bytes', () => {
27-
const controller = 'did:key:123'
2833
const model = randomStreamID()
2934
const unique = new Uint8Array([0, 1, 2])
3035

31-
const header1 = createInitHeader({ controller, model, unique })
36+
const header1 = createInitHeader({
37+
controller: authenticatedDID,
38+
model,
39+
unique,
40+
})
3241
expect(header1.unique).toBeInstanceOf(Uint8Array)
33-
const header2 = createInitHeader({ controller, model, unique })
42+
const header2 = createInitHeader({
43+
controller: authenticatedDID,
44+
model,
45+
unique,
46+
})
3447
expect(header2.unique).toBeInstanceOf(Uint8Array)
3548

3649
expect(
@@ -39,26 +52,27 @@ describe('createInitHeader()', () => {
3952
})
4053

4154
test('does not add unique bytes if set to true', () => {
42-
const controller = 'did:key:123'
4355
const model = randomStreamID()
44-
const header = createInitHeader({ controller, model, unique: true })
56+
const header = createInitHeader({
57+
controller: authenticatedDID,
58+
model,
59+
unique: true,
60+
})
4561
expect(header.unique).toBeUndefined()
4662
})
4763

4864
test('does not add context and shouldIndex by default', () => {
49-
const controller = 'did:key:123'
5065
const model = randomStreamID()
51-
const header = createInitHeader({ controller, model })
66+
const header = createInitHeader({ controller: authenticatedDID, model })
5267
expect(header.context).toBeUndefined()
5368
expect(header.shouldIndex).toBeUndefined()
5469
})
5570

5671
test('adds context and shouldIndex if specified', () => {
57-
const controller = 'did:key:123'
5872
const model = randomStreamID()
5973
const context = randomStreamID()
6074
const header = createInitHeader({
61-
controller,
75+
controller: authenticatedDID,
6276
model,
6377
context,
6478
shouldIndex: true,

sdk/packages/test-vectors/scripts/create-test-vectors.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,13 @@ for (const [controllerType, createController] of Object.entries(
135135
const controller = await createController()
136136

137137
// Deterministic (init) event
138-
const validDeterministicEvent = getDeterministicInitEvent(
139-
model,
140-
controller.id,
141-
)
138+
const validDeterministicEvent = getDeterministicInitEvent(model, controller)
142139

143140
// Signed init event
144141
const validInitPayload = InitEventPayload.encode({
145142
data: { test: true },
146143
header: createInitHeader({
147-
controller: controller.id,
144+
controller,
148145
model,
149146
unique: new Uint8Array([0, 1, 2, 3]),
150147
}),

tests/suite/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@ceramicnetwork/streamid": "^5.6.0",
4242
"@composedb/client": "^0.8.0",
4343
"@composedb/devtools": "^0.8.0",
44+
"@didtools/cacao": "^3.0.1",
4445
"@didtools/codecs": "^3.0.0",
4546
"@didtools/key-did": "^1.0.0",
4647
"@didtools/pkh-ethereum": "^0.5.0",

tests/suite/pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)