Skip to content

Commit

Permalink
Merge pull request #697 from xmtp/rygine/dms
Browse files Browse the repository at this point in the history
Add 1:1 messages, consent state, and more identity updates
  • Loading branch information
rygine authored Oct 30, 2024
2 parents 78f2141 + 981bcf4 commit 50d2684
Show file tree
Hide file tree
Showing 17 changed files with 785 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/small-singers-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@xmtp/node-sdk": patch
---

Add 1:1 messages, consent state, and more identity updates
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: MLS Client
name: Node SDK

on:
push:
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ To learn more about the contents of this repository, see this README and the REA
### SDKs

- [`js-sdk`](https://github.com/xmtp/xmtp-js/blob/main/sdks/js-sdk): XMTP JS client SDK for Node and the browser
- [`node-sdk`](https://github.com/xmtp/xmtp-js/blob/main/sdks/node-sdk): XMTP client SDK for Node (V3 only)
- [`browser-sdk`](https://github.com/xmtp/xmtp-js/blob/main/sdks/browser-sdk): XMTP client SDK for browsers (V3 only)

### Content types

Expand All @@ -22,8 +24,9 @@ To learn more about the contents of this repository, see this README and the REA

### Packages

- [`frames-client`](https://github.com/xmtp/xmtp-js/blob/main/packages/frames-client): XMTP Open Frames client
- [`consent-proof-signature`](https://github.com/xmtp/xmtp-js/blob/main/packages/consent-proof-signature): Lightweight package for creating consent proofs
- [`frames-client`](https://github.com/xmtp/xmtp-js/blob/main/packages/frames-client): XMTP Open Frames client
- [`frames-validator`](https://github.com/xmtp/xmtp-js/blob/main/packages/frames-validator): Tools for validating POST payloads from XMTP Open Frames

## Contributing

Expand Down
51 changes: 48 additions & 3 deletions sdks/node-sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,49 @@
# XMTP MLS Client
# XMTP client SDK for Node

> **Important**
> This package is currently in **Alpha** status. Do not use in production as the API is not final and certain functionality may not work as intended. This package only works in Node.
This package provides the XMTP client SDK for Node.

To keep up with the latest SDK developments, see the [Issues tab](https://github.com/xmtp/xmtp-js/issues) in this repo.

To learn more about XMTP and get answers to frequently asked questions, see the [XMTP documentation](https://xmtp.org/docs).

> [!CAUTION]
> This SDK is currently in alpha. The API is subject to change and it is not yet recommended for production use.
## Requirements

- Node.js 20+

## Install

**NPM**

```bash
npm install @xmtp/node-sdk
```

**PNPM**

```bash
pnpm install @xmtp/node-sdk
```

**Yarn**

```bash
yarn add @xmtp/node-sdk
```

## XMTP network environments

XMTP provides `production`, `dev`, and `local` network environments to support the development phases of your project. To learn more about these environments, see our [official documentation](https://xmtp.org/docs/build/authentication#environments).

## Developing

Run `yarn dev` to build the SDK and watch for changes, which will trigger a rebuild.

### Useful commands

- `yarn build`: Builds the SDK
- `yarn clean`: Removes `node_modules``dist`, and `.turbo` folders
- `yarn test`: Runs all tests
- `yarn typecheck`: Runs `tsc`
4 changes: 3 additions & 1 deletion sdks/node-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"clean:deps": "rimraf node_modules",
"clean:dist": "rimraf dist",
"clean:tests": "rimraf test/*.db3* ||:",
"dev": "yarn build --watch",
"test": "vitest run",
"test:cov": "vitest run --coverage",
"typecheck": "tsc"
Expand All @@ -51,7 +52,7 @@
"@xmtp/content-type-group-updated": "^1.0.0",
"@xmtp/content-type-primitives": "^1.0.2",
"@xmtp/content-type-text": "^1.0.0",
"@xmtp/node-bindings": "^0.0.14",
"@xmtp/node-bindings": "^0.0.16",
"@xmtp/proto": "^3.62.1"
},
"devDependencies": {
Expand All @@ -67,6 +68,7 @@
"rollup-plugin-filesize": "^10.0.0",
"rollup-plugin-tsconfig-paths": "^1.5.2",
"typescript": "^5.6.3",
"uuid": "^11.0.2",
"viem": "^2.13.6",
"vite": "^5.4.9",
"vite-tsconfig-paths": "^5.0.1",
Expand Down
35 changes: 26 additions & 9 deletions sdks/node-sdk/src/AsyncStream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type ResolveValue<T> = {
value: T | undefined;
done: boolean;
error: Error | null;
};

type ResolveNext<T> = (resolveValue: ResolveValue<T>) => void;
Expand All @@ -24,10 +25,10 @@ export class AsyncStream<T> {
return this.#done;
}

callback: StreamCallback<T> = (err, value) => {
if (err) {
console.error("stream error", err);
this.stop();
callback: StreamCallback<T> = (error, value) => {
if (error) {
console.error("stream error", error);
this.stop(error);
return;
}

Expand All @@ -36,26 +37,42 @@ export class AsyncStream<T> {
}

if (this.#resolveNext) {
this.#resolveNext({ value, done: false });
this.#resolveNext({
done: false,
error: null,
value,
});
this.#resolveNext = null;
} else {
this.#queue.push(value);
}
};

stop = () => {
stop = (error?: Error) => {
this.#done = true;
if (this.#resolveNext) {
this.#resolveNext({ value: undefined, done: true });
this.#resolveNext({
done: true,
error: error ?? null,
value: undefined,
});
}
this.stopCallback?.();
};

next = (): Promise<ResolveValue<T>> => {
if (this.#queue.length > 0) {
return Promise.resolve({ value: this.#queue.shift(), done: false });
return Promise.resolve({
done: false,
error: null,
value: this.#queue.shift(),
});
} else if (this.#done) {
return Promise.resolve({ value: undefined, done: true });
return Promise.resolve({
done: true,
error: null,
value: undefined,
});
} else {
return new Promise((resolve) => {
this.#resolveNext = resolve;
Expand Down
67 changes: 60 additions & 7 deletions sdks/node-sdk/src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import {
generateInboxId,
getInboxIdForAddress,
NapiGroupMessageKind,
NapiSignatureRequestType,
type NapiClient,
type NapiConsent,
type NapiConsentEntityType,
type NapiMessage,
type NapiSignatureRequestType,
} from "@xmtp/node-bindings";
import { Conversations } from "@/Conversations";

Expand Down Expand Up @@ -135,7 +137,7 @@ export class Client {
return this.#innerClient.isRegistered();
}

async signatureText() {
async createInboxSignatureText() {
try {
const signatureText = await this.#innerClient.createInboxSignatureText();
return signatureText;
Expand All @@ -144,15 +146,54 @@ export class Client {
}
}

async addWalletSignatureText(
existingAccountAddress: string,
newAccountAddress: string,
) {
try {
const signatureText = await this.#innerClient.addWalletSignatureText(
existingAccountAddress,
newAccountAddress,
);
return signatureText;
} catch {
return null;
}
}

async revokeWalletSignatureText(accountAddress: string) {
try {
const signatureText =
await this.#innerClient.revokeWalletSignatureText(accountAddress);
return signatureText;
} catch {
return null;
}
}

async revokeInstallationsSignatureText() {
try {
const signatureText =
await this.#innerClient.revokeInstallationsSignatureText();
return signatureText;
} catch {
return null;
}
}

async canMessage(accountAddresses: string[]) {
return this.#innerClient.canMessage(accountAddresses);
}

addSignature(signatureBytes: Uint8Array) {
void this.#innerClient.addSignature(
NapiSignatureRequestType.CreateInbox,
signatureBytes,
);
addSignature(
signatureType: NapiSignatureRequestType,
signatureBytes: Uint8Array,
) {
void this.#innerClient.addSignature(signatureType, signatureBytes);
}

async applySignatures() {
return this.#innerClient.applySignatureRequests();
}

async registerIdentity() {
Expand Down Expand Up @@ -210,6 +251,10 @@ export class Client {
return this.#innerClient.inboxState(refreshFromNetwork);
}

async getLatestInboxState(inboxId: string) {
return this.#innerClient.getLatestInboxState(inboxId);
}

async inboxStateFromInboxIds(
inboxIds: string[],
refreshFromNetwork?: boolean,
Expand All @@ -219,4 +264,12 @@ export class Client {
inboxIds,
);
}

async setConsentStates(consentStates: NapiConsent[]) {
return this.#innerClient.setConsentStates(consentStates);
}

async getConsentState(entityType: NapiConsentEntityType, entity: string) {
return this.#innerClient.getConsentState(entityType, entity);
}
}
18 changes: 17 additions & 1 deletion sdks/node-sdk/src/Conversation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { ContentTypeId } from "@xmtp/content-type-primitives";
import { ContentTypeText } from "@xmtp/content-type-text";
import type { NapiGroup, NapiListMessagesOptions } from "@xmtp/node-bindings";
import type {
NapiConsentState,
NapiGroup,
NapiListMessagesOptions,
} from "@xmtp/node-bindings";
import { AsyncStream, type StreamCallback } from "@/AsyncStream";
import type { Client } from "@/Client";
import { DecodedMessage } from "@/DecodedMessage";
Expand Down Expand Up @@ -197,4 +201,16 @@ export class Conversation {
.filter((message) => message.content !== undefined)
);
}

get consentState() {
return this.#group.consentState();
}

updateConsentState(consentState: NapiConsentState) {
this.#group.updateConsentState(consentState);
}

get dmPeerInboxId() {
return this.#group.dmPeerInboxId();
}
}
Loading

0 comments on commit 50d2684

Please sign in to comment.