@xmtp/agent-sdk 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,29 @@
1
+ import EventEmitter from "node:events";
2
+ import type { ContentCodec } from "@xmtp/content-type-primitives";
3
+ import { Client, type ClientOptions } from "@xmtp/node-sdk";
4
+ import { AgentContext } from "./AgentContext";
5
+ interface EventHandlerMap<ContentTypes> {
6
+ error: [error: Error];
7
+ message: [ctx: AgentContext<ContentTypes>];
8
+ start: [];
9
+ stop: [];
10
+ }
11
+ export interface AgentOptions<ContentTypes> {
12
+ client: Client<ContentTypes>;
13
+ }
14
+ export type AgentMiddleware<ContentTypes> = (ctx: AgentContext<ContentTypes>, next: () => Promise<void>) => Promise<void>;
15
+ export declare class Agent<ContentTypes> extends EventEmitter<EventHandlerMap<ContentTypes>> {
16
+ #private;
17
+ constructor({ client }: AgentOptions<ContentTypes>);
18
+ static create<ContentCodecs extends ContentCodec[] = []>(signer: Parameters<typeof Client.create>[0], options?: Omit<ClientOptions, "codecs"> & {
19
+ codecs?: ContentCodecs;
20
+ }): Promise<Agent<import("@xmtp/node-sdk").ExtractCodecContentTypes<ContentCodecs>>>;
21
+ static build<ContentCodecs extends ContentCodec[] = []>(identifier: Parameters<typeof Client.build>[0], options?: Omit<ClientOptions, "codecs"> & {
22
+ codecs?: ContentCodecs;
23
+ }): Promise<Agent<import("@xmtp/node-sdk").ExtractCodecContentTypes<ContentCodecs>>>;
24
+ use(middleware: AgentMiddleware<ContentTypes>): this;
25
+ start(): Promise<void>;
26
+ get client(): Client<ContentTypes>;
27
+ stop(): void;
28
+ }
29
+ export {};
@@ -0,0 +1,88 @@
1
+ import EventEmitter from "node:events";
2
+ import { Client, } from "@xmtp/node-sdk";
3
+ import { filter } from "@/utils/filter";
4
+ import { AgentContext } from "./AgentContext";
5
+ export class Agent extends EventEmitter {
6
+ #client;
7
+ #middleware = [];
8
+ #isListening = false;
9
+ constructor({ client }) {
10
+ super();
11
+ this.#client = client;
12
+ }
13
+ static async create(signer,
14
+ // Note: we need to omit this so that "Client.create" can correctly infer the codecs.
15
+ options) {
16
+ const client = await Client.create(signer, options);
17
+ return new Agent({ client });
18
+ }
19
+ static async build(identifier,
20
+ // Note: we need to omit this so that "Client.build" can correctly infer the codecs.
21
+ options) {
22
+ const client = await Client.build(identifier, options);
23
+ return new Agent({ client });
24
+ }
25
+ use(middleware) {
26
+ this.#middleware.push(middleware);
27
+ return this;
28
+ }
29
+ async start() {
30
+ if (this.#isListening) {
31
+ return;
32
+ }
33
+ try {
34
+ this.#isListening = true;
35
+ void this.emit("start");
36
+ const stream = await this.#client.conversations.streamAllMessages();
37
+ for await (const message of stream) {
38
+ // The "stop()" method sets "isListening"
39
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
40
+ if (!this.#isListening)
41
+ break;
42
+ try {
43
+ await this.#processMessage(message);
44
+ }
45
+ catch (error) {
46
+ this.#throwError(error);
47
+ }
48
+ }
49
+ }
50
+ catch (error) {
51
+ this.#isListening = false;
52
+ this.#throwError(error);
53
+ }
54
+ }
55
+ async #processMessage(message) {
56
+ const conversation = await this.#client.conversations.getConversationById(message.conversationId);
57
+ if (!conversation) {
58
+ this.#throwError(new Error(`Failed to process message ID "${message.id}" for conversation ID "${message.conversationId}" because the conversation could not be found.`));
59
+ return;
60
+ }
61
+ const context = new AgentContext(message, conversation, this.#client);
62
+ let middlewareIndex = 0;
63
+ const next = async () => {
64
+ if (middlewareIndex < this.#middleware.length) {
65
+ const currentMiddleware = this.#middleware[middlewareIndex++];
66
+ await currentMiddleware(context, next);
67
+ }
68
+ else if (filter.notFromSelf(message, this.#client)) {
69
+ // Note: we are filtering the agent's own message to avoid
70
+ // infinite message loops when a "message" listener replies
71
+ void this.emit("message", context);
72
+ }
73
+ };
74
+ await next();
75
+ }
76
+ get client() {
77
+ return this.#client;
78
+ }
79
+ stop() {
80
+ this.#isListening = false;
81
+ void this.emit("stop");
82
+ }
83
+ #throwError(error) {
84
+ const newError = error instanceof Error ? error : new Error(String(error));
85
+ void this.emit("error", newError);
86
+ }
87
+ }
88
+ //# sourceMappingURL=Agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Agent.js","sourceRoot":"","sources":["../../src/core/Agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Client, Conversation, DecodedMessage } from "@xmtp/node-sdk";
2
+ export declare class AgentContext<ContentTypes = unknown> {
3
+ #private;
4
+ constructor(message: DecodedMessage<ContentTypes>, conversation: Conversation, client: Client<ContentTypes>);
5
+ sendText(text: string): Promise<void>;
6
+ sendTextReply(text: string): Promise<void>;
7
+ getSenderAddress(): Promise<string>;
8
+ get message(): DecodedMessage<ContentTypes>;
9
+ get conversation(): Conversation<unknown>;
10
+ get client(): Client<ContentTypes>;
11
+ }
@@ -0,0 +1,40 @@
1
+ import { ContentTypeReply } from "@xmtp/content-type-reply";
2
+ import { ContentTypeText } from "@xmtp/content-type-text";
3
+ export class AgentContext {
4
+ #client;
5
+ #message;
6
+ #conversation;
7
+ constructor(message, conversation, client) {
8
+ this.#message = message;
9
+ this.#conversation = conversation;
10
+ this.#client = client;
11
+ }
12
+ async sendText(text) {
13
+ await this.#conversation.send(text, ContentTypeText);
14
+ }
15
+ async sendTextReply(text) {
16
+ const reply = {
17
+ reference: this.#message.id,
18
+ referenceInboxId: this.#message.senderInboxId,
19
+ contentType: ContentTypeText,
20
+ content: text,
21
+ };
22
+ await this.#conversation.send(reply, ContentTypeReply);
23
+ }
24
+ async getSenderAddress() {
25
+ const inboxState = await this.#client.preferences.inboxStateFromInboxIds([
26
+ this.#message.senderInboxId,
27
+ ]);
28
+ return inboxState[0].identifiers[0].identifier;
29
+ }
30
+ get message() {
31
+ return this.#message;
32
+ }
33
+ get conversation() {
34
+ return this.#conversation;
35
+ }
36
+ get client() {
37
+ return this.#client;
38
+ }
39
+ }
40
+ //# sourceMappingURL=AgentContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentContext.js","sourceRoot":"","sources":["../../src/core/AgentContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAc,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,MAAM,OAAO,YAAY;IACvB,OAAO,CAAuB;IAC9B,QAAQ,CAA+B;IACvC,aAAa,CAAe;IAE5B,YACE,OAAqC,EACrC,YAA0B,EAC1B,MAA4B;QAE5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,KAAK,GAAU;YACnB,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC3B,gBAAgB,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa;YAC7C,WAAW,EAAE,eAAe;YAC5B,OAAO,EAAE,IAAI;SACd,CAAC;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,sBAAsB,CAAC;YACvE,IAAI,CAAC,QAAQ,CAAC,aAAa;SAC5B,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACjD,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export * from "./Agent";
@@ -0,0 +1,2 @@
1
+ export * from "./Agent";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
package/dist/demo.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/demo.js ADDED
@@ -0,0 +1,33 @@
1
+ import { ReplyCodec } from "@xmtp/content-type-reply";
2
+ import { Agent } from "./core";
3
+ import { createSigner, createUser, filter as f, withFilter } from "./utils";
4
+ const user = createUser();
5
+ const signer = createSigner(user);
6
+ const agent = await Agent.create(signer, {
7
+ codecs: [new ReplyCodec()],
8
+ dbPath: null,
9
+ env: "dev",
10
+ });
11
+ agent.on("message", (ctx) => {
12
+ void ctx.conversation.send("First message!");
13
+ });
14
+ agent.on("message", withFilter(f.and(f.notFromSelf, f.textOnly), (ctx) => {
15
+ void ctx.conversation.send("Goodbye!");
16
+ agent.stop();
17
+ }));
18
+ agent.on("message", (ctx) => {
19
+ console.log("Got message:", ctx.message.content);
20
+ });
21
+ const errorHandler = (error) => {
22
+ console.log("Caught error", error);
23
+ };
24
+ agent.on("error", errorHandler);
25
+ agent.off("error", errorHandler);
26
+ agent.on("start", () => {
27
+ const address = agent.client.accountIdentifier?.identifier;
28
+ const env = agent.client.options?.env;
29
+ const url = `http://xmtp.chat/dm/${address}?env=${env}`;
30
+ console.log(`We are online: ${url}`);
31
+ });
32
+ void agent.start();
33
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE5E,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;AAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE;IACvC,MAAM,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;IAC1B,MAAM,EAAE,IAAI;IACZ,GAAG,EAAE,KAAK;CACX,CAAC,CAAC;AAEH,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;IAC1B,KAAK,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,EAAE,CACN,SAAS,EACT,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;IACnD,KAAK,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,EAAE,CAAC;AACf,CAAC,CAAC,CACH,CAAC;AAEF,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;IAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,EAAE;IACtC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAEhC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AAEjC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;IACrB,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,UAAU,CAAC;IAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;IACtC,MAAM,GAAG,GAAG,uBAAuB,OAAO,QAAQ,GAAG,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./core";
2
+ export * from "./utils";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
@@ -0,0 +1,48 @@
1
+ import type { Client, DecodedMessage } from "@xmtp/node-sdk";
2
+ import type { AgentContext } from "@/core/AgentContext";
3
+ /**
4
+ * Function type for filtering messages based on content and client state.
5
+ */
6
+ export type MessageFilter<ContentTypes> = (message: DecodedMessage, client: Client<ContentTypes>) => boolean;
7
+ /**
8
+ * Creates a filter for messages from specific senders
9
+ *
10
+ * @param senderInboxId - Single sender ID or array of sender IDs to match
11
+ * @returns Filter function
12
+ */
13
+ declare function fromSender<ContentTypes>(senderInboxId: string | string[]): MessageFilter<ContentTypes>;
14
+ /**
15
+ * Creates a filter that requires all provided filters to pass
16
+ *
17
+ * @param filters - Array of filters that must all return true
18
+ * @returns Filter function
19
+ */
20
+ declare function and<ContentTypes>(...filters: MessageFilter<ContentTypes>[]): MessageFilter<ContentTypes>;
21
+ /**
22
+ * Creates a filter that requires at least one provided filter to pass.
23
+ *
24
+ * @param filters - Array of filters where at least one must return true
25
+ * @returns Filter function
26
+ */
27
+ declare function or<ContentTypes>(...filters: MessageFilter<ContentTypes>[]): MessageFilter<ContentTypes>;
28
+ /**
29
+ * Creates a filter that inverts the result of another filter.
30
+ *
31
+ * @param filter - The filter to negate
32
+ * @returns Filter function
33
+ */
34
+ declare function not<ContentTypes>(filter: MessageFilter<ContentTypes>): MessageFilter<ContentTypes>;
35
+ /**
36
+ * Pre-configured filter instances and factory functions for common filtering scenarios
37
+ */
38
+ export declare const filter: {
39
+ notFromSelf: MessageFilter<unknown>;
40
+ fromSelf: MessageFilter<unknown>;
41
+ textOnly: MessageFilter<unknown>;
42
+ fromSender: typeof fromSender;
43
+ and: typeof and;
44
+ or: typeof or;
45
+ not: typeof not;
46
+ };
47
+ export declare const withFilter: <ContentTypes>(filter: MessageFilter<ContentTypes>, listener: (ctx: AgentContext<ContentTypes>) => void) => (ctx: AgentContext<ContentTypes>) => void;
48
+ export {};
@@ -0,0 +1,109 @@
1
+ import { ContentTypeText } from "@xmtp/content-type-text";
2
+ /**
3
+ * Creates a filter that excludes messages from the agent itself.
4
+ *
5
+ * @returns Filter function
6
+ */
7
+ function notFromSelf() {
8
+ return (message, client) => {
9
+ return message.senderInboxId !== client.inboxId;
10
+ };
11
+ }
12
+ /**
13
+ * Creates a filter that includes only messages from the agent itself.
14
+ *
15
+ * @returns Filter function
16
+ */
17
+ function fromSelf() {
18
+ return (message, client) => {
19
+ return message.senderInboxId === client.inboxId;
20
+ };
21
+ }
22
+ /**
23
+ * Creates a filter that includes only text messages.
24
+ *
25
+ * @returns Filter function
26
+ */
27
+ function textOnly() {
28
+ return (message) => {
29
+ return !!message.contentType?.sameAs(ContentTypeText);
30
+ };
31
+ }
32
+ /**
33
+ * Creates a filter for messages from specific senders
34
+ *
35
+ * @param senderInboxId - Single sender ID or array of sender IDs to match
36
+ * @returns Filter function
37
+ */
38
+ function fromSender(senderInboxId) {
39
+ const senderIds = Array.isArray(senderInboxId)
40
+ ? senderInboxId
41
+ : [senderInboxId];
42
+ return (message) => {
43
+ return senderIds.includes(message.senderInboxId);
44
+ };
45
+ }
46
+ /**
47
+ * Creates a filter that requires all provided filters to pass
48
+ *
49
+ * @param filters - Array of filters that must all return true
50
+ * @returns Filter function
51
+ */
52
+ function and(...filters) {
53
+ return (message, client) => {
54
+ for (const filter of filters) {
55
+ const result = filter(message, client);
56
+ if (!result)
57
+ return false;
58
+ }
59
+ return true;
60
+ };
61
+ }
62
+ /**
63
+ * Creates a filter that requires at least one provided filter to pass.
64
+ *
65
+ * @param filters - Array of filters where at least one must return true
66
+ * @returns Filter function
67
+ */
68
+ function or(...filters) {
69
+ return (message, client) => {
70
+ for (const filter of filters) {
71
+ const result = filter(message, client);
72
+ if (result)
73
+ return true;
74
+ }
75
+ return false;
76
+ };
77
+ }
78
+ /**
79
+ * Creates a filter that inverts the result of another filter.
80
+ *
81
+ * @param filter - The filter to negate
82
+ * @returns Filter function
83
+ */
84
+ function not(filter) {
85
+ return (message, client) => {
86
+ return !filter(message, client);
87
+ };
88
+ }
89
+ /**
90
+ * Pre-configured filter instances and factory functions for common filtering scenarios
91
+ */
92
+ export const filter = {
93
+ // basic filters
94
+ notFromSelf: notFromSelf(),
95
+ fromSelf: fromSelf(),
96
+ textOnly: textOnly(),
97
+ // factory functions
98
+ fromSender,
99
+ // combinators
100
+ and,
101
+ or,
102
+ not,
103
+ };
104
+ export const withFilter = (filter, listener) => (ctx) => {
105
+ if (filter(ctx.message, ctx.client)) {
106
+ listener(ctx);
107
+ }
108
+ };
109
+ //# sourceMappingURL=filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/utils/filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAY1D;;;;GAIG;AACH,SAAS,WAAW;IAClB,OAAO,CAAC,OAAuB,EAAE,MAA4B,EAAE,EAAE;QAC/D,OAAO,OAAO,CAAC,aAAa,KAAK,MAAM,CAAC,OAAO,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ;IACf,OAAO,CAAC,OAAuB,EAAE,MAA4B,EAAE,EAAE;QAC/D,OAAO,OAAO,CAAC,aAAa,KAAK,MAAM,CAAC,OAAO,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ;IACf,OAAO,CAAC,OAAuB,EAAE,EAAE;QACjC,OAAO,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CACjB,aAAgC;IAEhC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;QAC5C,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAEpB,OAAO,CAAC,OAAuB,EAAE,EAAE;QACjC,OAAO,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,GAAG,CACV,GAAG,OAAsC;IAEzC,OAAO,CAAC,OAAuB,EAAE,MAA4B,EAAE,EAAE;QAC/D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvC,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,EAAE,CACT,GAAG,OAAsC;IAEzC,OAAO,CAAC,OAAuB,EAAE,MAA4B,EAAE,EAAE;QAC/D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvC,IAAI,MAAM;gBAAE,OAAO,IAAI,CAAC;QAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,GAAG,CACV,MAAmC;IAEnC,OAAO,CAAC,OAAuB,EAAE,MAA4B,EAAE,EAAE;QAC/D,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gBAAgB;IAChB,WAAW,EAAE,WAAW,EAAE;IAC1B,QAAQ,EAAE,QAAQ,EAAE;IACpB,QAAQ,EAAE,QAAQ,EAAE;IACpB,oBAAoB;IACpB,UAAU;IACV,cAAc;IACd,GAAG;IACH,EAAE;IACF,GAAG;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GACrB,CACE,MAAmC,EACnC,QAAmD,EACnD,EAAE,CACJ,CAAC,GAA+B,EAAE,EAAE;IAClC,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./filter";
2
+ export * from "./user";
@@ -0,0 +1,3 @@
1
+ export * from "./filter";
2
+ export * from "./user";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type Identifier, type Signer } from "@xmtp/node-sdk";
2
+ import { type Chain, type Hex, type PrivateKeyAccount, type WalletClient } from "viem";
3
+ export type User = {
4
+ key: Hex;
5
+ account: PrivateKeyAccount;
6
+ wallet: WalletClient;
7
+ };
8
+ export declare const createUser: (key?: `0x${string}`, chain?: Chain) => User;
9
+ export declare const createIdentifier: (user: User) => Identifier;
10
+ export declare const createSigner: (user: User) => Signer;
@@ -0,0 +1,35 @@
1
+ import { createWalletClient, http, toBytes, } from "viem";
2
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
3
+ import { sepolia } from "viem/chains";
4
+ export const createUser = (key, chain = sepolia) => {
5
+ const accountKey = key ?? generatePrivateKey();
6
+ const account = privateKeyToAccount(accountKey);
7
+ return {
8
+ key: accountKey,
9
+ account,
10
+ wallet: createWalletClient({
11
+ account,
12
+ chain,
13
+ transport: http(),
14
+ }),
15
+ };
16
+ };
17
+ export const createIdentifier = (user) => ({
18
+ identifier: user.account.address.toLowerCase(),
19
+ identifierKind: 0 /* IdentifierKind.Ethereum */,
20
+ });
21
+ export const createSigner = (user) => {
22
+ const identifier = createIdentifier(user);
23
+ return {
24
+ type: "EOA",
25
+ getIdentifier: () => identifier,
26
+ signMessage: async (message) => {
27
+ const signature = await user.wallet.signMessage({
28
+ account: user.account,
29
+ message,
30
+ });
31
+ return toBytes(signature);
32
+ },
33
+ };
34
+ };
35
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/utils/user.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,IAAI,EACJ,OAAO,GAKR,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAQtC,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,GAAmB,EACnB,QAAe,OAAO,EAChB,EAAE;IACR,MAAM,UAAU,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAChD,OAAO;QACL,GAAG,EAAE,UAAU;QACf,OAAO;QACP,MAAM,EAAE,kBAAkB,CAAC;YACzB,OAAO;YACP,KAAK;YACL,SAAS,EAAE,IAAI,EAAE;SAClB,CAAC;KACH,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAc,EAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;IAC9C,cAAc,iCAAyB;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAU,EAAU,EAAE;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,aAAa,EAAE,GAAG,EAAE,CAAC,UAAU;QAC/B,WAAW,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;YACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;gBAC9C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO;aACR,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "node": ">=20"
23
23
  },
24
24
  "files": [
25
- "dist/src",
25
+ "dist",
26
26
  "!dist/**/*.test.*"
27
27
  ],
28
28
  "homepage": "https://github.com/xmtp/xmtp-js",
@@ -62,5 +62,5 @@
62
62
  "typecheck": "tsc --noEmit"
63
63
  },
64
64
  "type": "module",
65
- "version": "0.0.1"
65
+ "version": "0.0.2"
66
66
  }