Skip to content

Commit 222c78f

Browse files
authored
Updated BaseMessage in preparation for external Store interface implementations (#418)
* Removed Record specific properties from `BaseMessage` * Renamed `BaseMessage` to `GenericMessage` - Makes more sense from the perspective of the store implementor, as they don't care about inheritance/extension * Opportunistic rename of `Reply" types
1 parent c58de77 commit 222c78f

29 files changed

+127
-122
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ For advanced users wishing to use this repo directly:
2323
npm install @tbd54566975/dwn-sdk-js
2424
```
2525

26-
Additional steps needed for some environments.
26+
## Additional Steps
2727

28-
Node.js <= 18
28+
This package has dependency on [`@noble/ed25519`](https://github.com/paulmillr/noble-ed25519#usage) and [`@noble/secp256k1`](https://github.com/paulmillr/noble-secp256k1#usage) v2, additional steps are needed for some environments:
29+
30+
- Node.js <= 18
2931

3032
```js
3133
// node.js 18 and earlier, needs globalThis.crypto polyfill
@@ -34,7 +36,7 @@ import { webcrypto } from "node:crypto";
3436
if (!globalThis.crypto) globalThis.crypto = webcrypto;
3537
```
3638

37-
React Native:
39+
- React Native:
3840

3941
```js
4042
// If you're on react native. React Native needs crypto.getRandomValues polyfill and sha512

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tbd54566975/dwn-sdk-js",
3-
"version": "0.0.36",
3+
"version": "0.0.37",
44
"description": "A reference implementation of https://identity.foundation/decentralized-web-node/spec/",
55
"repository": {
66
"type": "git",

src/core/auth.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { BaseMessage } from '../types/message-types.js';
21
import type { CID } from 'multiformats';
32
import type { DidResolver } from '../did/did-resolver.js';
43
import type { GeneralJws } from '../types/jws-types.js';
4+
import type { GenericMessage } from '../types/message-types.js';
55
import type { Message } from './message.js';
66

77
import { Cid } from '../utils/cid.js';
@@ -22,7 +22,7 @@ type AuthorizationPayloadConstraints = {
2222
*/
2323
export async function canonicalAuth(
2424
tenant: string,
25-
incomingMessage: Message<BaseMessage>,
25+
incomingMessage: Message<GenericMessage>,
2626
didResolver: DidResolver
2727
): Promise<void> {
2828
await authenticate(incomingMessage.message.authorization, didResolver);
@@ -36,7 +36,7 @@ export async function canonicalAuth(
3636
* @returns the parsed JSON payload object if validation succeeds.
3737
*/
3838
export async function validateAuthorizationIntegrity(
39-
message: BaseMessage,
39+
message: GenericMessage,
4040
authorizationPayloadConstraints?: AuthorizationPayloadConstraints
4141
): Promise<{ descriptorCid: CID, [key: string]: any }> {
4242
if (message.authorization === undefined) {
@@ -94,7 +94,7 @@ export async function authenticate(jws: GeneralJws | undefined, didResolver: Did
9494
* Authorizes the incoming message.
9595
* @throws {Error} if fails authentication
9696
*/
97-
export async function authorize(tenant: string, incomingMessage: Message<BaseMessage>): Promise<void> {
97+
export async function authorize(tenant: string, incomingMessage: Message<GenericMessage>): Promise<void> {
9898
// if author is the same as the target tenant, we can directly grant access
9999
if (incomingMessage.author === tenant) {
100100
return;

src/core/message-reply.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ type Status = {
66
detail: string
77
};
88

9-
export type BaseMessageReply = {
9+
export type GenericMessageReply = {
1010
status: Status;
1111
};
1212

13-
export function messageReplyFromError(e: unknown, code: number): BaseMessageReply {
13+
export function messageReplyFromError(e: unknown, code: number): GenericMessageReply {
1414

1515
const detail = e instanceof Error ? e.message : 'Error';
1616

1717
return { status: { code, detail } };
1818
}
1919

2020
/**
21-
* Catch-all message reply type. It is recommended to use BaseMessageReply or a message-specific reply type whereever possible.
21+
* Catch-all message reply type. It is recommended to use GenericMessageReply or a message-specific reply type whereever possible.
2222
*/
23-
export type GenericMessageReply = BaseMessageReply & {
23+
export type UnionMessageReply = GenericMessageReply & {
2424
/**
2525
* Resulting message entries or events returned from the invocation of the corresponding message.
2626
* e.g. the resulting messages from a RecordsQuery

src/core/message.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { GeneralJws } from '../types/jws-types.js';
22
import type { SignatureInput } from '../types/jws-types.js';
3-
import type { BaseDecodedAuthorizationPayload, BaseMessage, Descriptor, TimestampedMessage } from '../types/message-types.js';
3+
import type { BaseDecodedAuthorizationPayload, Descriptor, GenericMessage, TimestampedMessage } from '../types/message-types.js';
44

55
import { Cid } from '../utils/cid.js';
66
import { GeneralJwsSigner } from '../jose/jws/general/signer.js';
@@ -30,7 +30,7 @@ export enum DwnMethodName {
3030
Delete = 'Delete'
3131
}
3232

33-
export abstract class Message<M extends BaseMessage> {
33+
export abstract class Message<M extends GenericMessage> {
3434
readonly message: M;
3535
readonly authorizationPayload: any;
3636

@@ -42,14 +42,14 @@ export abstract class Message<M extends BaseMessage> {
4242

4343
if (message.authorization !== undefined) {
4444
this.authorizationPayload = Jws.decodePlainObjectPayload(message.authorization);
45-
this.author = Message.getAuthor(message as BaseMessage);
45+
this.author = Message.getAuthor(message as GenericMessage);
4646
}
4747
}
4848

4949
/**
5050
* Called by `JSON.stringify(...)` automatically.
5151
*/
52-
toJSON(): BaseMessage {
52+
toJSON(): GenericMessage {
5353
return this.message;
5454
}
5555

@@ -69,7 +69,7 @@ export abstract class Message<M extends BaseMessage> {
6969
/**
7070
* Gets the DID of the author of the given message, returned `undefined` if message is not signed.
7171
*/
72-
public static getAuthor(message: BaseMessage): string | undefined {
72+
public static getAuthor(message: GenericMessage): string | undefined {
7373
if (message.authorization === undefined) {
7474
return undefined;
7575
}
@@ -81,7 +81,7 @@ export abstract class Message<M extends BaseMessage> {
8181
/**
8282
* Gets the CID of the given message.
8383
*/
84-
public static async getCid(message: BaseMessage): Promise<string> {
84+
public static async getCid(message: GenericMessage): Promise<string> {
8585
// NOTE: we wrap the `computeCid()` here in case that
8686
// the message will contain properties that should not be part of the CID computation
8787
// and we need to strip them out (like `encodedData` that we historically had for a long time),
@@ -94,7 +94,7 @@ export abstract class Message<M extends BaseMessage> {
9494
* Compares message CID in lexicographical order according to the spec.
9595
* @returns 1 if `a` is larger than `b`; -1 if `a` is smaller/older than `b`; 0 otherwise (same message)
9696
*/
97-
public static async compareCid(a: BaseMessage, b: BaseMessage): Promise<number> {
97+
public static async compareCid(a: GenericMessage, b: GenericMessage): Promise<number> {
9898
// the < and > operators compare strings in lexicographical order
9999
const cidA = await Message.getCid(a);
100100
const cidB = await Message.getCid(b);
@@ -105,16 +105,16 @@ export abstract class Message<M extends BaseMessage> {
105105
* Compares the CID of two messages.
106106
* @returns `true` if `a` is newer than `b`; `false` otherwise
107107
*/
108-
public static async isCidLarger(a: BaseMessage, b: BaseMessage): Promise<boolean> {
108+
public static async isCidLarger(a: GenericMessage, b: GenericMessage): Promise<boolean> {
109109
const aIsLarger = (await Message.compareCid(a, b) > 0);
110110
return aIsLarger;
111111
}
112112

113113
/**
114114
* @returns message with the largest CID in the array using lexicographical compare. `undefined` if given array is empty.
115115
*/
116-
public static async getMessageWithLargestCid(messages: BaseMessage[]): Promise<BaseMessage | undefined> {
117-
let currentNewestMessage: BaseMessage | undefined = undefined;
116+
public static async getMessageWithLargestCid(messages: GenericMessage[]): Promise<GenericMessage | undefined> {
117+
let currentNewestMessage: GenericMessage | undefined = undefined;
118118
for (const message of messages) {
119119
if (currentNewestMessage === undefined || await Message.isCidLarger(message, currentNewestMessage)) {
120120
currentNewestMessage = message;

src/dwn.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { BaseMessage } from './types/message-types.js';
21
import type { DataStore } from './types/data-store.js';
32
import type { EventLog } from './types/event-log.js';
3+
import type { GenericMessage } from './types/message-types.js';
44
import type { MessageStore } from './types/message-store.js';
55
import type { MethodHandler } from './types/method-handler.js';
66
import type { Readable } from 'readable-stream';
77
import type { RecordsWriteHandlerOptions } from './handlers/records-write.js';
88
import type { TenantGate } from './core/tenant-gate.js';
9-
import type { BaseMessageReply , GenericMessageReply } from './core/message-reply.js';
9+
import type { GenericMessageReply, UnionMessageReply } from './core/message-reply.js';
1010
import type { MessagesGetMessage, MessagesGetReply } from './types/messages-types.js';
1111
import type { RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsWriteMessage } from './types/records-types.js';
1212

@@ -94,7 +94,7 @@ export class Dwn {
9494
* Processes the given DWN message and returns with a reply.
9595
* @param tenant The tenant DID to route the given message to.
9696
*/
97-
public async processMessage(tenant: string, rawMessage: any, dataStream?: Readable): Promise<GenericMessageReply> {
97+
public async processMessage(tenant: string, rawMessage: any, dataStream?: Readable): Promise<UnionMessageReply> {
9898
const errorMessageReply = await this.validateTenant(tenant) ?? await this.validateMessageIntegrity(rawMessage);
9999
if (errorMessageReply !== undefined) {
100100
return errorMessageReply;
@@ -103,7 +103,7 @@ export class Dwn {
103103
const handlerKey = rawMessage.descriptor.interface + rawMessage.descriptor.method;
104104
const methodHandlerReply = await this.methodHandlers[handlerKey].handle({
105105
tenant,
106-
message: rawMessage as BaseMessage,
106+
message: rawMessage as GenericMessage,
107107
dataStream
108108
});
109109

@@ -158,7 +158,7 @@ export class Dwn {
158158
/**
159159
* Privileged method for writing a pruned initial `RecordsWrite` to a DWN without needing to supply associated data.
160160
*/
161-
public async synchronizePrunedInitialRecordsWrite(tenant: string, message: RecordsWriteMessage): Promise<BaseMessageReply> {
161+
public async synchronizePrunedInitialRecordsWrite(tenant: string, message: RecordsWriteMessage): Promise<GenericMessageReply> {
162162
const errorMessageReply =
163163
await this.validateTenant(tenant) ??
164164
await this.validateMessageIntegrity(message, DwnInterfaceName.Records, DwnMethodName.Write);
@@ -178,9 +178,9 @@ export class Dwn {
178178
/**
179179
* Checks tenant gate to see if tenant is allowed.
180180
* @param tenant The tenant DID to route the given message to.
181-
* @returns BaseMessageReply if the message has an integrity error, otherwise undefined.
181+
* @returns GenericMessageReply if the message has an integrity error, otherwise undefined.
182182
*/
183-
public async validateTenant(tenant: string): Promise<BaseMessageReply | undefined> {
183+
public async validateTenant(tenant: string): Promise<GenericMessageReply | undefined> {
184184
const isTenant = await this.tenantGate.isTenant(tenant);
185185
if (!isTenant) {
186186
return {
@@ -195,13 +195,13 @@ export class Dwn {
195195
* @param dwnMessageInterface The interface of DWN message.
196196
* @param dwnMessageMethod The interface of DWN message.
197197
198-
* @returns BaseMessageReply if the message has an integrity error, otherwise undefined.
198+
* @returns GenericMessageReply if the message has an integrity error, otherwise undefined.
199199
*/
200200
public async validateMessageIntegrity(
201201
rawMessage: any,
202202
expectedInterface?: DwnInterfaceName,
203203
expectedMethod?: DwnMethodName,
204-
): Promise<BaseMessageReply | undefined> {
204+
): Promise<GenericMessageReply | undefined> {
205205
// Verify interface and method
206206
const dwnInterface = rawMessage?.descriptor?.interface;
207207
const dwnMethod = rawMessage?.descriptor?.method;

src/handlers/messages-get.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { DataStore } from '../types/data-store.js';
22
import type { DidResolver } from '../did/did-resolver.js';
33
import type { MessageStore } from '../types/message-store.js';
44
import type { MethodHandler } from '../types/method-handler.js';
5+
import type { RecordsWriteMessage } from '../types/records-types.js';
56
import type { MessagesGetMessage, MessagesGetReply, MessagesGetReplyEntry } from '../types/messages-types.js';
67

78
import { DataStream } from '../utils/data-stream.js';
@@ -66,8 +67,10 @@ export class MessagesGetHandler implements MethodHandler {
6667
continue;
6768
}
6869

69-
const dataCid = message.descriptor.dataCid;
70-
const dataSize = message.descriptor.dataSize;
70+
// RecordsWrite specific handling
71+
const recordsWrite = message as RecordsWriteMessage;
72+
const dataCid = recordsWrite.descriptor.dataCid;
73+
const dataSize = recordsWrite.descriptor.dataSize;
7174

7275
if (dataCid !== undefined && dataSize! <= DwnConstant.maxDataSizeAllowedToBeEncoded) {
7376
const messageCid = await Message.getCid(message);

src/handlers/permissions-grant.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { BaseMessageReply } from '../core/message-reply.js';
1+
import type { GenericMessageReply } from '../core/message-reply.js';
22
import type { MethodHandler } from '../types/method-handler.js';
33
import type { PermissionsGrantMessage } from '../types/permissions-types.js';
44
import type { DidResolver, EventLog, MessageStore } from '../index.js';
@@ -14,7 +14,7 @@ export class PermissionsGrantHandler implements MethodHandler {
1414
public async handle({
1515
tenant,
1616
message
17-
}: { tenant: string, message: PermissionsGrantMessage }): Promise<BaseMessageReply> {
17+
}: { tenant: string, message: PermissionsGrantMessage }): Promise<GenericMessageReply> {
1818
let permissionsGrant: PermissionsGrant;
1919
try {
2020
permissionsGrant = await PermissionsGrant.parse(message);
@@ -29,7 +29,7 @@ export class PermissionsGrantHandler implements MethodHandler {
2929
return messageReplyFromError(e, 401);
3030
}
3131

32-
const { dataSize, scope, conditions, ...propertiesToIndex } = message.descriptor;
32+
const { scope, conditions, ...propertiesToIndex } = message.descriptor;
3333
const indexes: { [key: string]: string } = {
3434
author: permissionsGrant.author!,
3535
...propertiesToIndex,

src/handlers/permissions-request.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { BaseMessageReply } from '../core/message-reply.js';
1+
import type { GenericMessageReply } from '../core/message-reply.js';
22
import type { MethodHandler } from '../types/method-handler.js';
33
import type { PermissionsRequestMessage } from '../types/permissions-types.js';
44
import type { DidResolver, EventLog, MessageStore } from '../index.js';
@@ -15,7 +15,7 @@ export class PermissionsRequestHandler implements MethodHandler {
1515
public async handle({
1616
tenant,
1717
message
18-
}: { tenant: string, message: PermissionsRequestMessage }): Promise<BaseMessageReply> {
18+
}: { tenant: string, message: PermissionsRequestMessage }): Promise<GenericMessageReply> {
1919
let permissionsRequest: PermissionsRequest;
2020
try {
2121
permissionsRequest = await PermissionsRequest.parse(message);
@@ -31,7 +31,7 @@ export class PermissionsRequestHandler implements MethodHandler {
3131
}
3232

3333
// store message
34-
const { dataSize, scope, conditions, ...propertiesToIndex } = message.descriptor;
34+
const { scope, conditions, ...propertiesToIndex } = message.descriptor;
3535
const indexes: { [key: string]: string } = {
3636
...propertiesToIndex,
3737
author: permissionsRequest.author!,

0 commit comments

Comments
 (0)