Skip to content

Commit 3640282

Browse files
committed
feat: add did session test
1 parent 0bf5522 commit 3640282

4 files changed

Lines changed: 147 additions & 25 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

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.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { beforeAll, describe, expect, test } from '@jest/globals'
2+
import { AuthMethod, AuthMethodOpts, Cacao, SiweMessage } from '@didtools/cacao'
3+
import { AccountId } from 'caip'
4+
import { DIDSession } from 'did-session'
5+
import { randomString } from '@stablelib/random'
6+
import { normalizeAccountId } from '@ceramicnetwork/common'
7+
import { Wallet as Signer } from 'ethers'
8+
import { type ClientOptions, createFlightSqlClient, FlightSqlClient } from '@ceramic-sdk/flight-sql-client'
9+
import { CeramicClient } from '@ceramic-sdk/http-client'
10+
import { ModelClient } from '@ceramic-sdk/model-client'
11+
import type { ModelDefinition } from '@ceramic-sdk/model-protocol'
12+
import { StreamID } from '@ceramic-sdk/identifiers'
13+
import { ModelInstanceClient } from '@ceramic-sdk/model-instance-client'
14+
import { DID } from 'dids'
15+
16+
import { randomDID } from '../../../utils/didHelper'
17+
import { urlsToEndpoint } from '../../../utils/common'
18+
import { waitForEventState } from '../../../utils/rustCeramicHelpers'
19+
20+
const CeramicUrls = String(process.env.CERAMIC_URLS).split(',')
21+
const CeramicFlightUrls = String(process.env.CERAMIC_FLIGHT_URLS).split(',')
22+
const CeramicFlightEndpoints = urlsToEndpoint(CeramicFlightUrls)
23+
24+
const FLIGHT_OPTIONS: ClientOptions = {
25+
headers: new Array(),
26+
username: undefined,
27+
password: undefined,
28+
token: undefined,
29+
tls: false,
30+
host: CeramicFlightEndpoints[0].host,
31+
port: CeramicFlightEndpoints[0].port,
32+
}
33+
34+
const getCacao = (
35+
accountId: AccountId,
36+
signer: Signer
37+
): AuthMethod => async (opts: AuthMethodOpts) => {
38+
const now = new Date()
39+
const oneWeekLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000)
40+
const normalizedAccount = normalizeAccountId(accountId)
41+
42+
const siweMessage = new SiweMessage({
43+
domain: new URL(CeramicUrls[0]).hostname,
44+
address: normalizedAccount.address,
45+
statement: opts.statement ?? 'Give this application access to some of your data on Ceramic',
46+
uri: opts.uri,
47+
version: '1',
48+
nonce: opts.nonce ?? randomString(10),
49+
issuedAt: now.toISOString(),
50+
expirationTime: opts.expirationTime ?? oneWeekLater.toISOString(),
51+
chainId: normalizedAccount.chainId.reference,
52+
resources: opts.resources,
53+
})
54+
siweMessage.signature = await signer.signMessage(siweMessage.signMessage())
55+
56+
return Cacao.fromSiweMessage(siweMessage)
57+
}
58+
59+
export const authorizedSessionDid = async (
60+
signer: Signer,
61+
resources: string[],
62+
) => {
63+
const address = await signer.getAddress()
64+
const chainId = 'eip155:11155111'
65+
const caipAccountId = new AccountId({ address, chainId })
66+
const authMethod: AuthMethod = getCacao(caipAccountId, signer)
67+
const session = await DIDSession.authorize(
68+
authMethod,
69+
{ resources }
70+
)
71+
return session.did
72+
}
73+
74+
describe('create stream using session did', () => {
75+
let flightClient: FlightSqlClient
76+
let client: CeramicClient
77+
let modelInstanceClient: ModelInstanceClient
78+
let modelStream: StreamID
79+
80+
const testSigner = new Signer('0x4c0883a69102937d6231471b5dbb6204eaa7f9b0c8f2d6f8e1c5f3a2b6c7d8e9')
81+
let authenticatedDID: DID
82+
83+
beforeAll(async () => {
84+
flightClient = await createFlightSqlClient(FLIGHT_OPTIONS)
85+
86+
client = new CeramicClient({
87+
url: CeramicUrls[0]
88+
})
89+
90+
modelInstanceClient = new ModelInstanceClient({
91+
ceramic: client,
92+
did: await randomDID()
93+
})
94+
95+
const modelClient = new ModelClient({
96+
ceramic: client,
97+
did: await randomDID()
98+
})
99+
100+
const testModel: ModelDefinition = {
101+
version: '2.0',
102+
name: 'TestModel',
103+
description: 'List Test model',
104+
accountRelation: { type: 'list' },
105+
interface: false,
106+
implements: [],
107+
schema: {
108+
type: 'object',
109+
properties: {
110+
test: { type: 'string', maxLength: 10 },
111+
},
112+
additionalProperties: false,
113+
},
114+
}
115+
116+
modelStream = await modelClient.createDefinition(testModel)
117+
// Use the flightsql stream behavior to ensure the events states have been process before querying their states.
118+
await waitForEventState(flightClient, modelStream.cid)
119+
120+
authenticatedDID = await authorizedSessionDid(
121+
testSigner,
122+
[`ceramic://*?model=${modelStream.toString()}`],
123+
)
124+
}, 10000)
125+
126+
test('create stream', async () => {
127+
const commitID = await modelInstanceClient.createInstance({
128+
controller: authenticatedDID,
129+
model: modelStream,
130+
content: { test: 'hello' },
131+
shouldIndex: true,
132+
})
133+
134+
await waitForEventState(flightClient, commitID.cid)
135+
136+
const streamState = await modelInstanceClient.getDocumentState(commitID.baseID)
137+
const controller = streamState.metadata.controller
138+
const signerAddress = (await testSigner.getAddress()).toLowerCase()
139+
140+
expect(controller).toEqual(authenticatedDID.parent)
141+
expect(controller!.replace(/did:pkh.*:/, '').toLowerCase()).toEqual(signerAddress)
142+
})
143+
})

0 commit comments

Comments
 (0)