diff --git a/README.md b/README.md
index 6cc5ea396..fe14fdc1b 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@
-
+
@@ -177,7 +177,7 @@ node main
- **[Website](https://push.org)** To checkout our Product.
- **[Docs](https://docs.push.org/developers/)** For comprehensive documentation.
- **[Blog](https://medium.com/push-protocol)** To learn more about our partners, new launches, etc.
-- **[Discord](discord.gg/pushprotocol)** for support and discussions with the community and the team.
+- **[Discord](https://discord.com/invite/pushprotocol)** for support and discussions with the community and the team.
- **[GitHub](https://github.com/ethereum-push-notification-service)** for source code, project board, issues, and pull requests.
- **[Twitter](https://twitter.com/pushprotocol)** for the latest updates on the product and published blogs.
@@ -196,7 +196,7 @@ Read how you can contribute
+
## License
Check out our License HERE
diff --git a/packages/examples/sdk-backend-node/.env.sample b/packages/examples/sdk-backend-node/.env.sample
index 550450212..a444eee26 100644
--- a/packages/examples/sdk-backend-node/.env.sample
+++ b/packages/examples/sdk-backend-node/.env.sample
@@ -43,8 +43,8 @@ VIDEO_CHAIN_ID=your_video_chain_id
# VIDEO SENDER ADDRESS
VIDEO_SENDER_ADDRESS=your_video_sender_address
-# VIDEO RECIPEINT ADDRESS
-VIDEO_RECIPEINT_ADDRESS=your_video_recipeint_address
+# VIDEO RECIPIENT ADDRESS
+VIDEO_RECIPIENT_ADDRESS=your_video_recipient_address
# VIDEO CHAT ID
VIDEO_CHAT_ID=your_video_chat_id
\ No newline at end of file
diff --git a/packages/examples/sdk-backend-node/chat/chat.lowlevel.ts b/packages/examples/sdk-backend-node/chat/chat.lowlevel.ts
new file mode 100644
index 000000000..852b62153
--- /dev/null
+++ b/packages/examples/sdk-backend-node/chat/chat.lowlevel.ts
@@ -0,0 +1,667 @@
+import * as PushAPI from '@pushprotocol/restapi';
+import { createSocketConnection, EVENTS } from '@pushprotocol/socket';
+import { ethers } from 'ethers';
+import {
+ adjectives,
+ animals,
+ colors,
+ uniqueNamesGenerator,
+} from 'unique-names-generator';
+import { ENV } from '../types';
+import { config } from '../config';
+import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
+import { createWalletClient, http } from 'viem';
+import { goerli } from 'viem/chains';
+
+// CONFIGS
+const { env, showAPIResponse } = config;
+
+/***************** SAMPLE SIGNER GENERATION *********************/
+/**
+ * USING VIEM
+ */
+// Random Wallet Signers
+const signer = createWalletClient({
+ account: privateKeyToAccount(generatePrivateKey()),
+ chain: goerli,
+ transport: http(),
+});
+const signerAddress = signer.account.address;
+const secondSigner = createWalletClient({
+ account: privateKeyToAccount(generatePrivateKey()),
+ chain: goerli,
+ transport: http(),
+});
+const secondSignerAddress = secondSigner.account.address;
+// Dummy Wallet Addresses
+const randomWallet1 = privateKeyToAccount(generatePrivateKey()).address;
+const randomWallet2 = privateKeyToAccount(generatePrivateKey()).address;
+const randomWallet3 = privateKeyToAccount(generatePrivateKey()).address;
+
+/**
+ * USING ETHERS
+ */
+// // Random Wallet Signers
+// const signer = ethers.Wallet.createRandom();
+// const signerAddress = signer.address;
+// const secondSigner = ethers.Wallet.createRandom();
+// const secondSignerAddress = secondSigner.address;
+// // Dummy Wallet Addresses
+// const randomWallet1 = ethers.Wallet.createRandom().address;
+// const randomWallet2 = ethers.Wallet.createRandom().address;
+// const randomWallet3 = ethers.Wallet.createRandom().address;
+
+/************************************************************* */
+
+// Group Chat Data
+const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+});
+const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+});
+const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+// Push Chat - Run Chat Use cases
+export const runChatLowlevelUseCases = async (): Promise => {
+ console.log('PushAPI.user.create');
+ await PushAPI_user_create();
+
+ console.log('PushAPI.user.get');
+ await PushAPI_user_get();
+
+ console.log('PushAPI_chat_decryptPGPKey');
+ await PushAPI_chat_decryptPGPKey();
+
+ console.log('PushAPI.chat.chats');
+ await PushAPI_chat_chats();
+
+ console.log('PushAPI.chat.requests');
+ await PushAPI_chat_requests();
+
+ console.log('PushAPI.chat.send');
+ const TargetChatId = await PushAPI_chat_send();
+
+ console.log('PushAPI.chat.approve');
+ await PushAPI_chat_approve();
+
+ console.log('PushAPI chat Video call Notification');
+ await PushAPI_chat_video_call_notification(TargetChatId);
+
+ console.log('PushAPI.chat.createGroup');
+ const { chatId, name } = await PushAPI_chat_createGroup();
+
+ console.log('PushAPI.chat.conversationHash');
+ await PushAPI_chat_conversationHash();
+
+ console.log('PushAPI_chat_history');
+ await PushAPI_chat_history();
+
+ console.log('PushAPI.chat.latest');
+ await PushAPI_chat_latest();
+
+ console.log('PushAPI.chat.updateGroup');
+ await PushAPI_chat_updateGroup(chatId);
+
+ console.log('PushAPI.chat.getGroupByName');
+ await PushAPI_chat_getGroupByName(name);
+
+ console.log('PushAPI.chat.getGroup');
+ await PushAPI_chat_getGroup(chatId);
+
+ console.log('PushAPI.chat.decryptConversation');
+ await PushAPI_chat_decryptConversation();
+
+ console.log('Push Chat - PushSDKSocket()');
+ await PushChatSDKSocket();
+};
+
+// Push Chat - PushAPI.user.create
+async function PushAPI_user_create(silent = !showAPIResponse) {
+ const user = await PushAPI.user.create({
+ signer: signer,
+ env: env as ENV,
+ });
+
+ const user_2 = await PushAPI.user.create({
+ signer: secondSigner,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_user_create | Response - 200 OK');
+ if (!silent) {
+ console.log(user);
+ console.log(user_2);
+ }
+
+ return user;
+}
+
+// Push Chat - PushAPI.user.get
+async function PushAPI_user_get(silent = !showAPIResponse) {
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_user_get | Response - 200 OK');
+
+ if (!silent) {
+ console.log(user);
+ }
+}
+
+// Push Chat - PushAPI.chat.decryptPGPKey
+async function PushAPI_chat_decryptPGPKey(silent = !showAPIResponse) {
+ // get user and derive encrypted PGP key
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // decrypt the PGP Key
+ const pgpKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ console.log('PushAPI_chat_decryptPGPKey | Response - 200 OK');
+ if (!silent) {
+ console.log(pgpKey);
+ }
+}
+
+// Push Chat - PushAPI.chat.chats
+async function PushAPI_chat_chats(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Actual api
+ const response = await PushAPI.chat.chats({
+ account: `eip155:${signerAddress}`,
+ toDecrypt: true,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_chats | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.requests
+async function PushAPI_chat_requests(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Actual api
+ const response = await PushAPI.chat.requests({
+ account: `eip155:${signerAddress}`,
+ toDecrypt: true,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_requests | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.conversationHash
+async function PushAPI_chat_conversationHash(silent = !showAPIResponse) {
+ // conversation hash are also called link inside chat messages
+ const conversationHash = await PushAPI.chat.conversationHash({
+ account: `eip155:${signerAddress}`,
+ conversationId: `eip155:${secondSignerAddress}`, // 2nd address
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_conversationHash | Response - 200 OK');
+ if (!silent) {
+ console.log(conversationHash);
+ }
+}
+
+// Push Chat - PushAPI.chat.latest
+async function PushAPI_chat_latest(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Fetch conversation hash
+ // conversation hash are also called link inside chat messages
+ const conversationHash = await PushAPI.chat.conversationHash({
+ account: `eip155:${signerAddress}`,
+ conversationId: `eip155:${secondSignerAddress}`, // 2nd address
+ env: env as ENV,
+ });
+
+ // Actual API
+ const response = await PushAPI.chat.latest({
+ threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
+ account: `eip155:${signerAddress}`,
+ toDecrypt: true,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_latest | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.history
+async function PushAPI_chat_history(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Fetch conversation hash
+ // conversation hash are also called link inside chat messages
+ const conversationHash = await PushAPI.chat.conversationHash({
+ account: `eip155:${signerAddress}`,
+ conversationId: `eip155:${secondSignerAddress}`, // 2nd address
+ env: env as ENV,
+ });
+
+ // Actual API
+ const response = await PushAPI.chat.history({
+ threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
+ account: `eip155:${signerAddress}`,
+ limit: 5,
+ toDecrypt: true,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_history | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.send
+// // Will send a message to the user or chat request in case user hasn't approved them
+async function PushAPI_chat_send(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Actual api
+ const response = await PushAPI.chat.send({
+ messageObj: {
+ content: "Gm gm! It's me... Mario",
+ },
+ messageType: 'Text', // can be "Text" | "Image" | "File" | "GIF"
+ receiverAddress: secondSignerAddress,
+
+ signer: signer,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_send | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+ return response.chatId;
+}
+
+// Push Chat - Approve
+async function PushAPI_chat_approve(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${secondSignerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: secondSigner,
+ });
+
+ // Actual api
+ const approve = await PushAPI.chat.approve({
+ status: 'Approved',
+ senderAddress: signerAddress, // receiver's address or chatId of a group
+
+ signer: secondSigner,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_approve | Response - 200 OK');
+ if (!silent) {
+ console.log(approve);
+ }
+}
+
+// Push Chat - PushAPI.chat.createGroup
+async function PushAPI_chat_createGroup(
+ silent = !showAPIResponse
+): Promise<{ chatId: string; name: string }> {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Actual API
+ // Convert image to base 64 and pass
+ const response = await PushAPI.chat.createGroup({
+ groupName,
+ groupDescription,
+ members: [`eip155:${randomWallet1}`, `eip155:${randomWallet2}`],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+
+ signer: signer,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_createGroup | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+ return { chatId: response.chatId, name: response.groupName };
+}
+
+// Push Chat - PushAPI.chat.updateGroup
+async function PushAPI_chat_updateGroup(
+ chatId: string,
+ silent = !showAPIResponse
+) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Actual API
+ // Convert image to base 64 and pass
+ // This is an idempotent operation, meaning it requires all group info to be passed no matter if only few things change
+ // Why so? To ensure that verificationProof always is able to replicate the current group info (trustless since signature is stored with the info)
+ const response = await PushAPI.chat.updateGroup({
+ chatId,
+ groupName,
+ groupDescription,
+ members: [
+ `eip155:${randomWallet1}`,
+ `eip155:${randomWallet2}`,
+ `eip155:${randomWallet3}`,
+ `eip155:${signerAddress}`,
+ ],
+ groupImage,
+ admins: [`eip155:${signerAddress}`], // takes signer as admin automatically, add more if you want to
+
+ signer: signer,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_updateGroup | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.getGroupByName
+async function PushAPI_chat_getGroupByName(
+ name: string,
+ silent = !showAPIResponse
+) {
+ const response = await PushAPI.chat.getGroupByName({
+ groupName: name,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_getGroupByName | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.getGroup
+async function PushAPI_chat_getGroup(
+ chatId: string,
+ silent = !showAPIResponse
+) {
+ const response = await PushAPI.chat.getGroup({
+ chatId: chatId,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_getGroup | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Chat - PushAPI.chat.decryptConversation
+async function PushAPI_chat_decryptConversation(silent = !showAPIResponse) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${signerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: signer,
+ });
+
+ // Fetch conversation hash
+ // conversation hash are also called link inside chat messages
+ const conversationHash = await PushAPI.chat.conversationHash({
+ account: `eip155:${signerAddress}`,
+ conversationId: `eip155:${secondSignerAddress}`, // 2nd address
+ env: env as ENV,
+ });
+
+ // Chat History
+ const encryptedChats = await PushAPI.chat.history({
+ threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
+ account: `eip155:${signerAddress}`,
+ limit: 5,
+ toDecrypt: false,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+
+ // Decrypted Chat
+ const decryptedChat = await PushAPI.chat.decryptConversation({
+ messages: encryptedChats, // array of message object fetched from chat.history method
+ connectedUser: user, // user meta data object fetched from chat.get method
+ pgpPrivateKey: pgpDecrpyptedPvtKey, //decrypted private key
+ env: env as ENV,
+ });
+
+ console.log('PushAPI_chat_decryptConversation | Response - 200 OK');
+ if (!silent) {
+ console.log(decryptedChat);
+ }
+}
+
+// Push Chat - Socket Connection
+async function PushChatSDKSocket(silent = !showAPIResponse) {
+ const pushSDKSocket = createSocketConnection({
+ user: `eip155:${signerAddress}`,
+ socketType: 'chat',
+ socketOptions: { autoConnect: true, reconnectionAttempts: 3 },
+ env: env as ENV,
+ });
+
+ if (!pushSDKSocket) {
+ throw new Error('Socket not connected');
+ }
+
+ pushSDKSocket.on(EVENTS.CONNECT, async () => {
+ console.log('Socket Connected - will disconnect after 4 seconds');
+
+ // send a chat from other wallet to this one to see the result
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: `eip155:${secondSignerAddress}`,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+
+ signer: secondSigner,
+ });
+
+ // Actual api
+ const response = await PushAPI.chat.send({
+ messageContent: "Gm gm! It's me... Mario",
+ messageType: 'Text',
+ receiverAddress: `eip155:${signerAddress}`,
+
+ signer: secondSigner,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ env: env as ENV,
+ });
+ console.log('PushAPI_chat_send | Response - 200 OK');
+ });
+
+ pushSDKSocket.on(EVENTS.DISCONNECT, () => {
+ console.log('Socket Disconnected');
+ });
+
+ pushSDKSocket.on(EVENTS.CHAT_RECEIVED_MESSAGE, (message) => {
+ // feedItem is the notification data when that notification was received
+ console.log('Incoming Push Chat message from Socket');
+ if (!silent) {
+ console.log(message);
+ }
+
+ // disconnect socket after this, not to be done in real implementations
+ pushSDKSocket.disconnect();
+ });
+
+ const delay = (ms: number) =>
+ new Promise((resolve) => setTimeout(resolve, ms));
+ await delay(4000);
+}
+
+async function PushAPI_chat_video_call_notification(
+ chatId: string,
+ silent = !showAPIResponse
+) {
+ // Fetch user
+ const user = await PushAPI.user.get({
+ account: signerAddress,
+ env: env as ENV,
+ });
+
+ // Decrypt PGP Key
+ const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
+ encryptedPGPPrivateKey: user.encryptedPrivateKey,
+ signer: signer,
+ });
+ // get PGP KEy
+ const apiResponse = await PushAPI.payloads.sendNotification({
+ senderType: 1,
+ signer: signer,
+ pgpPrivateKey: pgpDecrpyptedPvtKey,
+ chatId: chatId,
+ type: 3, // target
+ identityType: 2, // direct payload
+ notification: {
+ title: `VC TITLE:`,
+ body: `VC BODY`,
+ },
+ payload: {
+ title: `payload title`,
+ body: `sample msg body`,
+ cta: '',
+ img: '',
+ additionalMeta: {
+ type: '1+1',
+ data: 'Random DATA',
+ domain: 'push.org',
+ },
+ },
+ recipients: secondSignerAddress, // recipient address
+ channel: signerAddress, // your channel address
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
+ if (!silent) {
+ console.log(apiResponse);
+ }
+}
diff --git a/packages/examples/sdk-backend-node/chat/chat.ts b/packages/examples/sdk-backend-node/chat/chat.ts
index 3b594ec1c..fba19a0be 100644
--- a/packages/examples/sdk-backend-node/chat/chat.ts
+++ b/packages/examples/sdk-backend-node/chat/chat.ts
@@ -1,25 +1,21 @@
-import * as PushAPI from '@pushprotocol/restapi';
-import { createSocketConnection, EVENTS } from '@pushprotocol/socket';
-import { ethers } from 'ethers';
+import { PushAPI } from '@pushprotocol/restapi';
import {
adjectives,
animals,
colors,
uniqueNamesGenerator,
} from 'unique-names-generator';
-import { ENV } from '../types';
import { config } from '../config';
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
import { createWalletClient, http } from 'viem';
import { goerli } from 'viem/chains';
+import { STREAM } from '@pushprotocol/restapi/src/lib/pushstream/pushStreamTypes';
// CONFIGS
const { env, showAPIResponse } = config;
/***************** SAMPLE SIGNER GENERATION *********************/
-/**
- * USING VIEM
- */
+// Uing VIEM
// Random Wallet Signers
const signer = createWalletClient({
account: privateKeyToAccount(generatePrivateKey()),
@@ -33,27 +29,20 @@ const secondSigner = createWalletClient({
transport: http(),
});
const secondSignerAddress = secondSigner.account.address;
+const thirdSigner = createWalletClient({
+ account: privateKeyToAccount(generatePrivateKey()),
+ chain: goerli,
+ transport: http(),
+});
+const thirdSignerAddress = thirdSigner.account.address;
+
// Dummy Wallet Addresses
const randomWallet1 = privateKeyToAccount(generatePrivateKey()).address;
const randomWallet2 = privateKeyToAccount(generatePrivateKey()).address;
const randomWallet3 = privateKeyToAccount(generatePrivateKey()).address;
+/****************************************************************/
-/**
- * USING ETHERS
- */
-// // Random Wallet Signers
-// const signer = ethers.Wallet.createRandom();
-// const signerAddress = signer.address;
-// const secondSigner = ethers.Wallet.createRandom();
-// const secondSignerAddress = secondSigner.address;
-// // Dummy Wallet Addresses
-// const randomWallet1 = ethers.Wallet.createRandom().address;
-// const randomWallet2 = ethers.Wallet.createRandom().address;
-// const randomWallet3 = ethers.Wallet.createRandom().address;
-
-/************************************************************* */
-
-// Group Chat Data
+/***************** SAMPLE GROUP DATA ****************************/
const groupName = uniqueNamesGenerator({
dictionaries: [adjectives, colors, animals],
});
@@ -62,613 +51,211 @@ const groupDescription = uniqueNamesGenerator({
});
const groupImage =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
-
-// Push Chat - Run Chat Use cases
-export const runChatUseCases = async (): Promise => {
- console.log(`
- ██████ ██ ██ █████ ████████
- ██ ██ ██ ██ ██ ██
- ██ ███████ ███████ ██
- ██ ██ ██ ██ ██ ██
- ██████ ██ ██ ██ ██ ██
- `);
- console.log('PushAPI.user.create');
- await PushAPI_user_create();
-
- console.log('PushAPI.user.get');
- await PushAPI_user_get();
-
- console.log('PushAPI_chat_decryptPGPKey');
- await PushAPI_chat_decryptPGPKey();
-
- console.log('PushAPI.chat.chats');
- await PushAPI_chat_chats();
-
- console.log('PushAPI.chat.requests');
- await PushAPI_chat_requests();
-
- console.log('PushAPI.chat.send');
- const TargetChatId = await PushAPI_chat_send();
-
- console.log('PushAPI.chat.approve');
- await PushAPI_chat_approve();
-
- console.log('PushAPI chat Video call Notification');
- await PushAPI_chat_video_call_notification(TargetChatId);
-
- console.log('PushAPI.chat.createGroup');
- const { chatId, name } = await PushAPI_chat_createGroup();
-
- console.log('PushAPI.chat.conversationHash');
- await PushAPI_chat_conversationHash();
-
- console.log('PushAPI_chat_history');
- await PushAPI_chat_history();
-
- console.log('PushAPI.chat.latest');
- await PushAPI_chat_latest();
-
- console.log('PushAPI.chat.updateGroup');
- await PushAPI_chat_updateGroup(chatId);
-
- console.log('PushAPI.chat.getGroupByName');
- await PushAPI_chat_getGroupByName(name);
-
- console.log('PushAPI.chat.getGroup');
- await PushAPI_chat_getGroup(chatId);
-
- console.log('PushAPI.chat.decryptConversation');
- await PushAPI_chat_decryptConversation();
-
- console.log('Push Chat - PushSDKSocket()');
- await PushChatSDKSocket();
-};
-
-// Push Chat - PushAPI.user.create
-async function PushAPI_user_create(silent = !showAPIResponse) {
- const user = await PushAPI.user.create({
- signer: signer,
- env: env as ENV,
- });
-
- const user_2 = await PushAPI.user.create({
- signer: secondSigner,
- env: env as ENV,
- });
-
- console.log('PushAPI_user_create | Response - 200 OK');
- if (!silent) {
- console.log(user);
- console.log(user_2);
- }
-
- return user;
-}
-
-// Push Chat - PushAPI.user.get
-async function PushAPI_user_get(silent = !showAPIResponse) {
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
+/***************** SAMPLE GROUP DATA ****************************/
+
+const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
+
+const eventlistener = async (
+ pushAPI: PushAPI,
+ eventName: string
+): Promise => {
+ pushAPI.stream.on(eventName, (data: any) => {
+ if (showAPIResponse) {
+ console.log('Stream Event Received');
+ console.log(data);
+ console.log('\n');
+ }
});
+};
- console.log('PushAPI_user_get | Response - 200 OK');
-
- if (!silent) {
- console.log(user);
+export const runChatClassUseCases = async (): Promise => {
+ const userAlice = await PushAPI.initialize(signer, { env });
+ const userBob = await PushAPI.initialize(secondSigner, { env });
+ const userKate = await PushAPI.initialize(thirdSigner, { env });
+
+ // Listen stream events to receive websocket events
+ console.log(`Listening ${STREAM.CHAT} Events`);
+ eventlistener(userAlice, STREAM.CHAT);
+ console.log(`Listening ${STREAM.CHAT_OPS} Events`);
+ eventlistener(userAlice, STREAM.CHAT_OPS);
+ console.log('\n\n');
+
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.list');
+ const aliceChats = await userAlice.chat.list('CHATS');
+ const aliceRequests = await userAlice.chat.list('REQUESTS');
+ if (showAPIResponse) {
+ console.log(aliceChats);
+ console.log(aliceRequests);
}
-}
-
-// Push Chat - PushAPI.chat.decryptPGPKey
-async function PushAPI_chat_decryptPGPKey(silent = !showAPIResponse) {
- // get user and derive encrypted PGP key
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // decrypt the PGP Key
- const pgpKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- console.log('PushAPI_chat_decryptPGPKey | Response - 200 OK');
- if (!silent) {
- console.log(pgpKey);
+ console.log('PushAPI.chat.list | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.latest');
+ const aliceLatestChatWithBob = await userAlice.chat.latest(
+ secondSignerAddress
+ );
+ if (showAPIResponse) {
+ console.log(aliceLatestChatWithBob);
}
-}
-
-// Push Chat - PushAPI.chat.chats
-async function PushAPI_chat_chats(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Actual api
- const response = await PushAPI.chat.chats({
- account: `eip155:${signerAddress}`,
- toDecrypt: true,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_chats | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ console.log('PushAPI.chat.latest | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.history');
+ const aliceChatHistoryWithBob = await userAlice.chat.history(
+ secondSignerAddress
+ );
+ if (showAPIResponse) {
+ console.log(aliceChatHistoryWithBob);
}
-}
-
-// Push Chat - PushAPI.chat.requests
-async function PushAPI_chat_requests(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Actual api
- const response = await PushAPI.chat.requests({
- account: `eip155:${signerAddress}`,
- toDecrypt: true,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
+ console.log('PushAPI.chat.history | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.send');
+ const aliceMessagesBob = await userAlice.chat.send(secondSignerAddress, {
+ content: 'Hello Bob!',
+ type: 'Text',
});
-
- console.log('PushAPI_chat_requests | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ if (showAPIResponse) {
+ console.log(aliceMessagesBob);
}
-}
-
-// Push Chat - PushAPI.chat.conversationHash
-async function PushAPI_chat_conversationHash(silent = !showAPIResponse) {
- // conversation hash are also called link inside chat messages
- const conversationHash = await PushAPI.chat.conversationHash({
- account: `eip155:${signerAddress}`,
- conversationId: `eip155:${secondSignerAddress}`, // 2nd address
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_conversationHash | Response - 200 OK');
- if (!silent) {
- console.log(conversationHash);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.chat.send | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.accept');
+ const bobAcceptsRequest = await userBob.chat.accept(signerAddress);
+ if (showAPIResponse) {
+ console.log(bobAcceptsRequest);
}
-}
-
-// Push Chat - PushAPI.chat.latest
-async function PushAPI_chat_latest(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Fetch conversation hash
- // conversation hash are also called link inside chat messages
- const conversationHash = await PushAPI.chat.conversationHash({
- account: `eip155:${signerAddress}`,
- conversationId: `eip155:${secondSignerAddress}`, // 2nd address
- env: env as ENV,
- });
-
- // Actual API
- const response = await PushAPI.chat.latest({
- threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
- account: `eip155:${signerAddress}`,
- toDecrypt: true,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_latest | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.chat.accept | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.reject');
+ await userKate.chat.send(signerAddress, {
+ content: 'Sending malicious message',
+ type: 'Text',
+ });
+ const AliceRejectsRequest = await userAlice.chat.reject(thirdSignerAddress);
+ if (showAPIResponse) {
+ console.log(AliceRejectsRequest);
}
-}
-
-// Push Chat - PushAPI.chat.history
-async function PushAPI_chat_history(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Fetch conversation hash
- // conversation hash are also called link inside chat messages
- const conversationHash = await PushAPI.chat.conversationHash({
- account: `eip155:${signerAddress}`,
- conversationId: `eip155:${secondSignerAddress}`, // 2nd address
- env: env as ENV,
- });
-
- // Actual API
- const response = await PushAPI.chat.history({
- threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
- account: `eip155:${signerAddress}`,
- limit: 5,
- toDecrypt: true,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_history | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.chat.reject | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.block');
+ const AliceBlocksBob = await userAlice.chat.block([secondSignerAddress]);
+ if (showAPIResponse) {
+ console.log(AliceBlocksBob);
}
-}
-
-// Push Chat - PushAPI.chat.send
-// // Will send a message to the user or chat request in case user hasn't approved them
-async function PushAPI_chat_send(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Actual api
- const response = await PushAPI.chat.send({
- messageObj: {
- content: "Gm gm! It's me... Mario",
- },
- messageType: 'Text', // can be "Text" | "Image" | "File" | "GIF"
- receiverAddress: secondSignerAddress,
-
- signer: signer,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_send | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ console.log('PushAPI.chat.block | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.chat.unblock');
+ const AliceUnblocksBob = await userAlice.chat.unblock([secondSignerAddress]);
+ if (showAPIResponse) {
+ console.log(AliceUnblocksBob);
}
- return response.chatId;
-}
-
-// Push Chat - Approve
-async function PushAPI_chat_approve(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${secondSignerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: secondSigner,
- });
-
- // Actual api
- const approve = await PushAPI.chat.approve({
- status: 'Approved',
- senderAddress: signerAddress, // receiver's address or chatId of a group
-
- signer: secondSigner,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_approve | Response - 200 OK');
- if (!silent) {
- console.log(approve);
+ console.log('PushAPI.chat.unblock | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.create');
+ const createdGroup = await userAlice.chat.group.create(groupName, {
+ description: groupDescription,
+ image: groupImage,
+ members: [randomWallet1, randomWallet2],
+ admins: [],
+ private: false,
+ });
+ const groupChatId = createdGroup.chatId; // to be used in other examples
+ if (showAPIResponse) {
+ console.log(createdGroup);
}
-}
-
-// Push Chat - PushAPI.chat.createGroup
-async function PushAPI_chat_createGroup(
- silent = !showAPIResponse
-): Promise<{ chatId: string; name: string }> {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Actual API
- // Convert image to base 64 and pass
- const response = await PushAPI.chat.createGroup({
- groupName,
- groupDescription,
- members: [`eip155:${randomWallet1}`, `eip155:${randomWallet2}`],
- groupImage,
- admins: [], // takes signer as admin automatically, add more if you want to
- isPublic: true,
-
- signer: signer,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_createGroup | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.create | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.permissions');
+ const grouppermissions = await userAlice.chat.group.permissions(groupChatId);
+ if (showAPIResponse) {
+ console.log(grouppermissions);
}
- return { chatId: response.chatId, name: response.groupName };
-}
-
-// Push Chat - PushAPI.chat.updateGroup
-async function PushAPI_chat_updateGroup(
- chatId: string,
- silent = !showAPIResponse
-) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Actual API
- // Convert image to base 64 and pass
- // This is an idempotent operation, meaning it requires all group info to be passed no matter if only few things change
- // Why so? To ensure that verificationProof always is able to replicate the current group info (trustless since signature is stored with the info)
- const response = await PushAPI.chat.updateGroup({
- chatId,
- groupName,
- groupDescription,
- members: [
- `eip155:${randomWallet1}`,
- `eip155:${randomWallet2}`,
- `eip155:${randomWallet3}`,
- `eip155:${signerAddress}`,
- ],
- groupImage,
- admins: [`eip155:${signerAddress}`], // takes signer as admin automatically, add more if you want to
-
- signer: signer,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_updateGroup | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ console.log('PushAPI.group.permissions | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.info');
+ const groupInfo = await userAlice.chat.group.info(groupChatId);
+ if (showAPIResponse) {
+ console.log(groupInfo);
}
-}
-
-// Push Chat - PushAPI.chat.getGroupByName
-async function PushAPI_chat_getGroupByName(
- name: string,
- silent = !showAPIResponse
-) {
- const response = await PushAPI.chat.getGroupByName({
- groupName: name,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_getGroupByName | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ console.log('PushAPI.group.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.update');
+ const updatedGroup = await userAlice.chat.group.update(groupChatId, {
+ description: 'Updated Description',
+ });
+ if (showAPIResponse) {
+ console.log(updatedGroup);
}
-}
-
-// Push Chat - PushAPI.chat.getGroup
-async function PushAPI_chat_getGroup(
- chatId: string,
- silent = !showAPIResponse
-) {
- const response = await PushAPI.chat.getGroup({
- chatId: chatId,
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_getGroup | Response - 200 OK');
- if (!silent) {
- console.log(response);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.update | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.add');
+ const addMember = await userAlice.chat.group.add(groupChatId, {
+ role: 'MEMBER',
+ accounts: [randomWallet3],
+ });
+ if (showAPIResponse) {
+ console.log(addMember);
}
-}
-
-// Push Chat - PushAPI.chat.decryptConversation
-async function PushAPI_chat_decryptConversation(silent = !showAPIResponse) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${signerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: signer,
- });
-
- // Fetch conversation hash
- // conversation hash are also called link inside chat messages
- const conversationHash = await PushAPI.chat.conversationHash({
- account: `eip155:${signerAddress}`,
- conversationId: `eip155:${secondSignerAddress}`, // 2nd address
- env: env as ENV,
- });
-
- // Chat History
- const encryptedChats = await PushAPI.chat.history({
- threadhash: conversationHash.threadHash, // get conversation hash from conversationHash function and send the response threadhash here
- account: `eip155:${signerAddress}`,
- limit: 5,
- toDecrypt: false,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
-
- // Decrypted Chat
- const decryptedChat = await PushAPI.chat.decryptConversation({
- messages: encryptedChats, // array of message object fetched from chat.history method
- connectedUser: user, // user meta data object fetched from chat.get method
- pgpPrivateKey: pgpDecrpyptedPvtKey, //decrypted private key
- env: env as ENV,
- });
-
- console.log('PushAPI_chat_decryptConversation | Response - 200 OK');
- if (!silent) {
- console.log(decryptedChat);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.add | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.remove');
+ const removeMember = await userAlice.chat.group.remove(groupChatId, {
+ role: 'MEMBER',
+ accounts: [randomWallet3],
+ });
+ if (showAPIResponse) {
+ console.log(removeMember);
}
-}
-
-// Push Chat - Socket Connection
-async function PushChatSDKSocket(silent = !showAPIResponse) {
- const pushSDKSocket = createSocketConnection({
- user: `eip155:${signerAddress}`,
- socketType: 'chat',
- socketOptions: { autoConnect: true, reconnectionAttempts: 3 },
- env: env as ENV,
- });
-
- if (!pushSDKSocket) {
- throw new Error('Socket not connected');
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.remove | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.join');
+ const joinGrp = await userBob.chat.group.join(groupChatId);
+ if (showAPIResponse) {
+ console.log(joinGrp);
}
-
- pushSDKSocket.on(EVENTS.CONNECT, async () => {
- console.log('Socket Connected - will disconnect after 4 seconds');
-
- // send a chat from other wallet to this one to see the result
- // Fetch user
- const user = await PushAPI.user.get({
- account: `eip155:${secondSignerAddress}`,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
-
- signer: secondSigner,
- });
-
- // Actual api
- const response = await PushAPI.chat.send({
- messageContent: "Gm gm! It's me... Mario",
- messageType: 'Text',
- receiverAddress: `eip155:${signerAddress}`,
-
- signer: secondSigner,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- env: env as ENV,
- });
- console.log('PushAPI_chat_send | Response - 200 OK');
- });
-
- pushSDKSocket.on(EVENTS.DISCONNECT, () => {
- console.log('Socket Disconnected');
- });
-
- pushSDKSocket.on(EVENTS.CHAT_RECEIVED_MESSAGE, (message) => {
- // feedItem is the notification data when that notification was received
- console.log('Incoming Push Chat message from Socket');
- if (!silent) {
- console.log(message);
- }
-
- // disconnect socket after this, not to be done in real implementations
- pushSDKSocket.disconnect();
- });
-
- const delay = (ms: number) =>
- new Promise((resolve) => setTimeout(resolve, ms));
- await delay(4000);
-}
-
-async function PushAPI_chat_video_call_notification(
- chatId: string,
- silent = !showAPIResponse
-) {
- // Fetch user
- const user = await PushAPI.user.get({
- account: signerAddress,
- env: env as ENV,
- });
-
- // Decrypt PGP Key
- const pgpDecrpyptedPvtKey = await PushAPI.chat.decryptPGPKey({
- encryptedPGPPrivateKey: user.encryptedPrivateKey,
- signer: signer,
- });
- // get PGP KEy
- const apiResponse = await PushAPI.payloads.sendNotification({
- senderType: 1,
- signer: signer,
- pgpPrivateKey: pgpDecrpyptedPvtKey,
- chatId: chatId,
- type: 3, // target
- identityType: 2, // direct payload
- notification: {
- title: `VC TITLE:`,
- body: `VC BODY`,
- },
- payload: {
- title: `payload title`,
- body: `sample msg body`,
- cta: '',
- img: '',
- additionalMeta: {
- type: '1+1',
- data: 'Random DATA',
- domain: 'push.org',
- },
- },
- recipients: secondSignerAddress, // recipient address
- channel: signerAddress, // your channel address
- env: env as ENV,
- });
-
- console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
- if (!silent) {
- console.log(apiResponse);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.join | Response - 200 OK\n\n');
+ //-------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.leave');
+ const leaveGrp = await userBob.chat.group.leave(groupChatId);
+ if (showAPIResponse) {
+ console.log(leaveGrp);
}
-}
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.leave | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.group.reject');
+ const sampleGrp = await userAlice.chat.group.create('Sample Grp', {
+ description: groupDescription,
+ image: groupImage,
+ members: [secondSignerAddress], // invite bob
+ admins: [],
+ private: true,
+ });
+ await userBob.chat.group.reject(sampleGrp.chatId);
+ await delay(2000); // Delay added to log the events in order
+ console.log('PushAPI.group.reject | Response - 200 OK\n\n');
+};
diff --git a/packages/examples/sdk-backend-node/chat/index.ts b/packages/examples/sdk-backend-node/chat/index.ts
index 40bccd361..85621540f 100644
--- a/packages/examples/sdk-backend-node/chat/index.ts
+++ b/packages/examples/sdk-backend-node/chat/index.ts
@@ -1,2 +1,28 @@
-export { runChatUseCases } from './chat';
-export { runNFTChatUseCases } from './nftChat';
+import { runChatLowlevelUseCases } from './chat.lowlevel';
+import { runNFTChatLowLevelUseCases } from './nftChat.lowlevel';
+import { runChatClassUseCases } from './chat';
+
+export const runChatUseCases = async (): Promise => {
+ console.log(`
+░█████╗░██╗░░██╗░█████╗░████████╗
+██╔══██╗██║░░██║██╔══██╗╚══██╔══╝
+██║░░╚═╝███████║███████║░░░██║░░░
+██║░░██╗██╔══██║██╔══██║░░░██║░░░
+╚█████╔╝██║░░██║██║░░██║░░░██║░░░
+░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝░░░╚═╝░░░
+ `);
+
+ await runChatClassUseCases();
+ console.log(`
+▒█▀▀█ ▒█░▒█ ░█▀▀█ ▀▀█▀▀ ░ ▒█░░░ ▒█▀▀▀█ ▒█░░▒█ ▒█░░░ ▒█▀▀▀ ▒█░░▒█ ▒█▀▀▀ ▒█░░░
+▒█░░░ ▒█▀▀█ ▒█▄▄█ ░▒█░░ ▄ ▒█░░░ ▒█░░▒█ ▒█▒█▒█ ▒█░░░ ▒█▀▀▀ ░▒█▒█░ ▒█▀▀▀ ▒█░░░
+▒█▄▄█ ▒█░▒█ ▒█░▒█ ░▒█░░ █ ▒█▄▄█ ▒█▄▄▄█ ▒█▄▀▄█ ▒█▄▄█ ▒█▄▄▄ ░░▀▄▀░ ▒█▄▄▄ ▒█▄▄█
+ `);
+ await runChatLowlevelUseCases();
+ console.log(`
+▒█▄░▒█ ▒█▀▀▀ ▀▀█▀▀ ▒█▀▀█ ▒█░▒█ ░█▀▀█ ▀▀█▀▀ ░ ▒█░░░ ▒█▀▀▀█ ▒█░░▒█ ▒█░░░ ▒█▀▀▀ ▒█░░▒█ ▒█▀▀▀ ▒█░░░
+▒█▒█▒█ ▒█▀▀▀ ░▒█░░ ▒█░░░ ▒█▀▀█ ▒█▄▄█ ░▒█░░ ▄ ▒█░░░ ▒█░░▒█ ▒█▒█▒█ ▒█░░░ ▒█▀▀▀ ░▒█▒█░ ▒█▀▀▀ ▒█░░░
+▒█░░▀█ ▒█░░░ ░▒█░░ ▒█▄▄█ ▒█░▒█ ▒█░▒█ ░▒█░░ █ ▒█▄▄█ ▒█▄▄▄█ ▒█▄▀▄█ ▒█▄▄█ ▒█▄▄▄ ░░▀▄▀░ ▒█▄▄▄ ▒█▄▄█
+ `);
+ await runNFTChatLowLevelUseCases();
+};
diff --git a/packages/examples/sdk-backend-node/chat/nftChat.ts b/packages/examples/sdk-backend-node/chat/nftChat.lowlevel.ts
similarity index 96%
rename from packages/examples/sdk-backend-node/chat/nftChat.ts
rename to packages/examples/sdk-backend-node/chat/nftChat.lowlevel.ts
index b238022be..2f5142d5c 100644
--- a/packages/examples/sdk-backend-node/chat/nftChat.ts
+++ b/packages/examples/sdk-backend-node/chat/nftChat.lowlevel.ts
@@ -74,15 +74,7 @@ const skipExample = () => {
};
// Push Chat - Run Chat Use cases
-export const runNFTChatUseCases = async (): Promise => {
- console.log(`
- ███ ██ ███████ ████████ ██████ ██ ██ █████ ████████
- ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ██ ██ ██ █████ ██ ██ ███████ ███████ ██
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ██ ████ ██ ██ ██████ ██ ██ ██ ██ ██
- `);
-
+export const runNFTChatLowLevelUseCases = async (): Promise => {
if (skipExample()) {
console.log('Skipping examples as required env vars are missing');
return;
@@ -526,9 +518,9 @@ async function PushAPI_nft_chat_updateGroup(
chatId,
groupName: updatedNftGroupName,
groupDescription,
- members: [nftAccount2, nftAccount3],
+ members: [nftAccount2, nftAccount3, nftAccount1],
groupImage,
- admins: [nftAccount2],
+ admins: [nftAccount1],
account: nftAccount1,
signer: nftSigner1,
pgpPrivateKey: pgpDecrpyptedPvtKey,
diff --git a/packages/examples/sdk-backend-node/main.ts b/packages/examples/sdk-backend-node/main.ts
index dbb09f210..e8a538268 100644
--- a/packages/examples/sdk-backend-node/main.ts
+++ b/packages/examples/sdk-backend-node/main.ts
@@ -1,11 +1,12 @@
-import { runNotificaitonsUseCases } from './notification';
-import { runChatUseCases, runNFTChatUseCases } from './chat';
+import { runUserCases } from './user';
+import { runNotificationUseCases } from './notification';
+import { runChatUseCases } from './chat';
import { runVideoUseCases } from './video';
-import { runSpacesUseCases } from './spaces';
-import { runPushAPICases } from './pushAPI';
+import { runSpaceUseCases } from './space';
import { config } from './config';
import { ENV } from './types';
+import { exit } from 'process';
// CONFIGS
const { env } = config;
@@ -15,12 +16,12 @@ const start = async (): Promise => {
console.log(`${returnHeadingLog()}`);
console.log(`${returnENVLog()}`);
- await runPushAPICases();
- await runNotificaitonsUseCases();
+ await runUserCases();
+ await runNotificationUseCases();
await runChatUseCases();
- await runNFTChatUseCases();
await runVideoUseCases();
- await runSpacesUseCases();
+ await runSpaceUseCases();
+ exit(0);
};
start();
@@ -32,39 +33,54 @@ start();
// -----------
function returnHeadingLog() {
const headingLog = `
- ███████ ██████ ██ ██ ███████ ██ ██ ███ ██ ██████ ████████ ██ ██████ ███ ██ █████ ██ ██ ████████ ██ ██
- ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██
- ███████ ██ ██ █████ █████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███████ ██ ██ ██ ████
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ███████ ██████ ██ ██ ██ ██████ ██ ████ ██████ ██ ██ ██████ ██ ████ ██ ██ ███████ ██ ██ ██
+
+░██████╗██████╗░██╗░░██╗ ███████╗██╗░░░██╗███╗░░██╗░█████╗░████████╗██╗░█████╗░███╗░░██╗░█████╗░██╗░░░░░██╗████████╗██╗░░░██╗
+██╔════╝██╔══██╗██║░██╔╝ ██╔════╝██║░░░██║████╗░██║██╔══██╗╚══██╔══╝██║██╔══██╗████╗░██║██╔══██╗██║░░░░░██║╚══██╔══╝╚██╗░██╔╝
+╚█████╗░██║░░██║█████═╝░ █████╗░░██║░░░██║██╔██╗██║██║░░╚═╝░░░██║░░░██║██║░░██║██╔██╗██║███████║██║░░░░░██║░░░██║░░░░╚████╔╝░
+░╚═══██╗██║░░██║██╔═██╗░ ██╔══╝░░██║░░░██║██║╚████║██║░░██╗░░░██║░░░██║██║░░██║██║╚████║██╔══██║██║░░░░░██║░░░██║░░░░░╚██╔╝░░
+██████╔╝██████╔╝██║░╚██╗ ██║░░░░░╚██████╔╝██║░╚███║╚█████╔╝░░░██║░░░██║╚█████╔╝██║░╚███║██║░░██║███████╗██║░░░██║░░░░░░██║░░░
+╚═════╝░╚═════╝░╚═╝░░╚═╝ ╚═╝░░░░░░╚═════╝░╚═╝░░╚══╝░╚════╝░░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═╝░░╚═╝╚══════╝╚═╝░░░╚═╝░░░░░░╚═╝░░░
`;
return headingLog;
}
function returnENVLog() {
let environmentLog = `
- ███████ ████████ █████ ██████ ██ ███ ██ ██████
- ██ ██ ██ ██ ██ ██ ████ ██ ██
- ███████ ██ ███████ ██ ███ ██ ██ ██ ██ ██ ███
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ███████ ██ ██ ██ ██████ ██ ██ ████ ██████
+
+███████╗███╗░░██╗██╗░░░██╗ ░░░░░░ ░██████╗████████╗░█████╗░░██████╗░██╗███╗░░██╗░██████╗░
+██╔════╝████╗░██║██║░░░██║ ░░░░░░ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝░██║████╗░██║██╔════╝░
+█████╗░░██╔██╗██║╚██╗░██╔╝ █████╗ ╚█████╗░░░░██║░░░███████║██║░░██╗░██║██╔██╗██║██║░░██╗░
+██╔══╝░░██║╚████║░╚████╔╝░ ╚════╝ ░╚═══██╗░░░██║░░░██╔══██║██║░░╚██╗██║██║╚████║██║░░╚██╗
+███████╗██║░╚███║░░╚██╔╝░░ ░░░░░░ ██████╔╝░░░██║░░░██║░░██║╚██████╔╝██║██║░╚███║╚██████╔╝
+╚══════╝╚═╝░░╚══╝░░░╚═╝░░░ ░░░░░░ ╚═════╝░░░░╚═╝░░░╚═╝░░╚═╝░╚═════╝░╚═╝╚═╝░░╚══╝░╚═════╝░
`;
if (env === ENV.PROD) {
environmentLog = `
- ██████ ██████ ██████ ██████ ██ ██ ██████ ████████ ██ ██████ ███ ██
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
- ██████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ██ ██ ██ ██████ ██████ ██████ ██████ ██ ██ ██████ ██ ████
+███████╗███╗░░██╗██╗░░░██╗ ░░░░░░ ██████╗░██████╗░░█████╗░██████╗░
+██╔════╝████╗░██║██║░░░██║ ░░░░░░ ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
+█████╗░░██╔██╗██║╚██╗░██╔╝ █████╗ ██████╔╝██████╔╝██║░░██║██║░░██║
+██╔══╝░░██║╚████║░╚████╔╝░ ╚════╝ ██╔═══╝░██╔══██╗██║░░██║██║░░██║
+███████╗██║░╚███║░░╚██╔╝░░ ░░░░░░ ██║░░░░░██║░░██║╚█████╔╝██████╔╝
+╚══════╝╚═╝░░╚══╝░░░╚═╝░░░ ░░░░░░ ╚═╝░░░░░╚═╝░░╚═╝░╚════╝░╚═════╝░
`;
} else if (env === ENV.DEV) {
environmentLog = `
- ██████ ███████ ██ ██
- ██ ██ ██ ██ ██
- ██ ██ █████ ██ ██
- ██ ██ ██ ██ ██
- ██████ ███████ ████
+███████╗███╗░░██╗██╗░░░██╗ ░░░░░░ ██████╗░███████╗██╗░░░██╗
+██╔════╝████╗░██║██║░░░██║ ░░░░░░ ██╔══██╗██╔════╝██║░░░██║
+█████╗░░██╔██╗██║╚██╗░██╔╝ █████╗ ██║░░██║█████╗░░╚██╗░██╔╝
+██╔══╝░░██║╚████║░╚████╔╝░ ╚════╝ ██║░░██║██╔══╝░░░╚████╔╝░
+███████╗██║░╚███║░░╚██╔╝░░ ░░░░░░ ██████╔╝███████╗░░╚██╔╝░░
+╚══════╝╚═╝░░╚══╝░░░╚═╝░░░ ░░░░░░ ╚═════╝░╚══════╝░░░╚═╝░░░
+ `;
+ } else if (env === ENV.LOCAL) {
+ environmentLog = `
+███████╗███╗░░██╗██╗░░░██╗ ░░░░░░ ██╗░░░░░░█████╗░░█████╗░░█████╗░██╗░░░░░
+██╔════╝████╗░██║██║░░░██║ ░░░░░░ ██║░░░░░██╔══██╗██╔══██╗██╔══██╗██║░░░░░
+█████╗░░██╔██╗██║╚██╗░██╔╝ █████╗ ██║░░░░░██║░░██║██║░░╚═╝███████║██║░░░░░
+██╔══╝░░██║╚████║░╚████╔╝░ ╚════╝ ██║░░░░░██║░░██║██║░░██╗██╔══██║██║░░░░░
+███████╗██║░╚███║░░╚██╔╝░░ ░░░░░░ ███████╗╚█████╔╝╚█████╔╝██║░░██║███████╗
+╚══════╝╚═╝░░╚══╝░░░╚═╝░░░ ░░░░░░ ╚══════╝░╚════╝░░╚════╝░╚═╝░░╚═╝╚══════╝
`;
}
diff --git a/packages/examples/sdk-backend-node/notification/index.ts b/packages/examples/sdk-backend-node/notification/index.ts
index 605a60a23..f2251c1c7 100644
--- a/packages/examples/sdk-backend-node/notification/index.ts
+++ b/packages/examples/sdk-backend-node/notification/index.ts
@@ -1,384 +1,20 @@
-import * as PushAPI from '@pushprotocol/restapi';
-import { createSocketConnection, EVENTS } from '@pushprotocol/socket';
-import { ethers } from 'ethers';
-import { config } from '../config';
+import { runNotificaitonsLowLevelUseCases } from './notification.lowlevel';
+import { runNotificationClassUseCases } from './notification';
-import { createWalletClient, http } from 'viem';
-import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
-import { goerli } from 'viem/chains';
-
-enum ENV {
- PROD = 'prod',
- STAGING = 'staging',
- DEV = 'dev',
- /**
- * **This is for local development only**
- */
- LOCAL = 'local',
-}
-
-// CONFIGS
-const { env, showAPIResponse } = config;
-
-// If you own a channel, you can use your channel address as well
-const channelPrivateKey = process.env.WALLET_PRIVATE_KEY;
-
-/***************** SAMPLE SIGNER GENERATION *********************/
-/**
- * USING VIEM
- */
-const signerChannel = channelPrivateKey
- ? createWalletClient({
- account: privateKeyToAccount(`0x${channelPrivateKey}`),
- chain: goerli,
- transport: http(),
- })
- : undefined;
-const channelAddress = signerChannel
- ? signerChannel.account.address
- : undefined;
-// Random Wallet Signers
-const signer = createWalletClient({
- account: privateKeyToAccount(generatePrivateKey()),
- chain: goerli,
- transport: http(),
-});
-const signerAddress = signer.account.address;
-// Dummy Wallet Addresses
-const randomWallet1 = privateKeyToAccount(generatePrivateKey()).address;
-
-/**
- * USING ETHERS
- */
-// const signerChannel = new ethers.Wallet(`0x${channelPrivateKey}`);
-// const channelAddress = signerChannel.address;
-// // Random Wallet Signers
-// const signer = ethers.Wallet.createRandom();
-// const signerAddress = signer.address;
-// // Dummy Wallet Addresses
-// const randomWallet1 = ethers.Wallet.createRandom().address;
-/************************************************************* */
-
-const skipExample = () => {
- const requiredEnvVars = ['WALLET_PRIVATE_KEY'];
-
- for (const envVar of requiredEnvVars) {
- if (!process.env[envVar]) {
- return true; // Skip the example if any of the required env vars is missing
- }
- }
-
- return false; // All required env vars are present, don't skip the example
-};
-
-// Push Notification - Run Notifications Use cases
-export const runNotificaitonsUseCases = async (): Promise => {
+export const runNotificationUseCases = async (): Promise => {
+ console.log(`
+███╗░░██╗░█████╗░████████╗██╗███████╗██╗░█████╗░░█████╗░████████╗██╗░█████╗░███╗░░██╗
+████╗░██║██╔══██╗╚══██╔══╝██║██╔════╝██║██╔══██╗██╔══██╗╚══██╔══╝██║██╔══██╗████╗░██║
+██╔██╗██║██║░░██║░░░██║░░░██║█████╗░░██║██║░░╚═╝███████║░░░██║░░░██║██║░░██║██╔██╗██║
+██║╚████║██║░░██║░░░██║░░░██║██╔══╝░░██║██║░░██╗██╔══██║░░░██║░░░██║██║░░██║██║╚████║
+██║░╚███║╚█████╔╝░░░██║░░░██║██║░░░░░██║╚█████╔╝██║░░██║░░░██║░░░██║╚█████╔╝██║░╚███║
+╚═╝░░╚══╝░╚════╝░░░░╚═╝░░░╚═╝╚═╝░░░░░╚═╝░╚════╝░╚═╝░░╚═╝░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝
+ `);
+ await runNotificationClassUseCases();
console.log(`
- ███ ██ ██████ ████████ ██ ███████ ██ ██████ █████ ████████ ██ ██████ ███ ██ ███████
- ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██
- ██ ██ ██ ██ ██ ██ ██ █████ ██ ██ ███████ ██ ██ ██ ██ ██ ██ ██ ███████
- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
- ██ ████ ██████ ██ ██ ██ ██ ██████ ██ ██ ██ ██ ██████ ██ ████ ███████
+▒█▄░▒█ ▒█▀▀▀█ ▀▀█▀▀ ▀█▀ ▒█▀▀▀ ▀█▀ ▒█▀▀█ ░█▀▀█ ▀▀█▀▀ ▀█▀ ▒█▀▀▀█ ▒█▄░▒█ ░ ▒█░░░ ▒█▀▀▀█ ▒█░░▒█ ▒█░░░ ▒█▀▀▀ ▒█░░▒█ ▒█▀▀▀ ▒█░░░
+▒█▒█▒█ ▒█░░▒█ ░▒█░░ ▒█░ ▒█▀▀▀ ▒█░ ▒█░░░ ▒█▄▄█ ░▒█░░ ▒█░ ▒█░░▒█ ▒█▒█▒█ ▄ ▒█░░░ ▒█░░▒█ ▒█▒█▒█ ▒█░░░ ▒█▀▀▀ ░▒█▒█░ ▒█▀▀▀ ▒█░░░
+▒█░░▀█ ▒█▄▄▄█ ░▒█░░ ▄█▄ ▒█░░░ ▄█▄ ▒█▄▄█ ▒█░▒█ ░▒█░░ ▄█▄ ▒█▄▄▄█ ▒█░░▀█ █ ▒█▄▄█ ▒█▄▄▄█ ▒█▄▀▄█ ▒█▄▄█ ▒█▄▄▄ ░░▀▄▀░ ▒█▄▄▄ ▒█▄▄█
`);
- console.log('PushAPI.user.getFeeds');
- await PushAPI_user_getFeeds();
-
- console.log('PushAPI.user.getFeeds [Spam]');
- await PushAPI_user_getFeeds__spam();
-
- console.log('PushAPI.user.getSubscriptions');
- await PushAPI_user_getSubscriptions();
-
- if (!skipExample()) {
- console.log('PushAPI.channels.getChannel()');
- await PushAPI_channels_getChannel();
-
- console.log('PushAPI.channels.search()');
- await PushAPI_channels_search();
-
- console.log('PushAPI.channels.subscribe()');
- await PushAPI_channels_subscribe();
-
- console.log('PushAPI.channels.unsubscribe()');
- await PushAPI_channels_unsubscribe();
-
- // IMPORTANT: VARIOUS OTHER NOTIFICATIONS FORMAT SUPPORTED
- // EXAMPLES HERE: https://github.com/ethereum-push-notification-service/push-sdk/blob/main/packages/restapi/README.md
- console.log(
- 'PushAPI.payloads.sendNotification() [Direct Payload, Single Recipient]'
- );
- await PushAPI_payloads_sendNotification__direct_payload_single_recipient();
-
- console.log(
- 'PushAPI.payloads.sendNotification() [Direct Payload, Batch of Recipients (Subset)]'
- );
- await PushAPI_payloads_sendNotification__direct_payload_group_of_recipient_subset();
-
- console.log(
- 'PushAPI.payloads.sendNotification() [Direct Payload, All Recipients (Broadcast)]'
- );
- await PushAPI_payloads_sendNotification__direct_payload_all_recipients_brodcast();
-
- console.log('PushAPI.channels._getSubscribers()');
- await PushAPI_channels_getSubscribers();
-
- console.log('Push Notification - PushSDKSocket()');
- await PushSDKSocket();
- }
+ await runNotificaitonsLowLevelUseCases();
};
-
-// Push Notification - PushAPI.user.getFeeds
-async function PushAPI_user_getFeeds(silent = !showAPIResponse) {
- const notifications = await PushAPI.user.getFeeds({
- user: `eip155:5:${signerAddress}`, // user address in CAIP
- env: env as ENV,
- });
-
- console.log('PushAPI.user.getFeeds | Response - 200 OK');
- if (!silent) {
- console.log(notifications);
- }
-}
-
-// Push Notification - PushAPI.user.getFeeds - Spam
-async function PushAPI_user_getFeeds__spam(silent = !showAPIResponse) {
- const notifications = await PushAPI.user.getFeeds({
- user: `eip155:5:${signerAddress}`, // user address in CAIP
- spam: true,
- env: env as ENV,
- });
-
- console.log('PushAPI.user.getFeeds [Spam] | Response - 200 OK');
- if (!silent) {
- console.log(notifications);
- }
-}
-
-// Push Notification - PushAPI.user.getSubscriptions
-async function PushAPI_user_getSubscriptions(silent = !showAPIResponse) {
- const subscriptions = await PushAPI.user.getSubscriptions({
- user: `eip155:5:${signerAddress}`, // user address in CAIP
- env: env as ENV,
- });
-
- console.log('PushAPI.user.getSubscriptions | Response - 200 OK');
- if (!silent) {
- console.log(subscriptions);
- }
-}
-
-// Push Notification - PushAPI.channels.getChannel
-async function PushAPI_channels_getChannel(silent = !showAPIResponse) {
- const channelData = await PushAPI.channels.getChannel({
- channel: channelAddress as string,
- env: env as ENV,
- });
-
- console.log('PushAPI.channels.getChannel | Response - 200 OK');
- if (!silent) {
- console.log(channelData);
- }
-}
-
-// Push Notification - PushAPI.channels.search
-async function PushAPI_channels_search(silent = !showAPIResponse) {
- const channelsData = await PushAPI.channels.search({
- query: 'push', // a search query
- page: 1, // page index
- limit: 20, // no of items per page
- env: env as ENV,
- });
-
- console.log('PushAPI.channels.search | Response - 200 OK');
- if (!silent) {
- console.log(channelsData);
- }
-}
-
-// Push Notification - PushAPI.channels.subscribe
-async function PushAPI_channels_subscribe(silent = !showAPIResponse) {
- const response = await PushAPI.channels.subscribe({
- signer: signer,
- channelAddress: `eip155:5:${channelAddress}`, // channel address in CAIP
- userAddress: `eip155:5:${signerAddress}`, // user address in CAIP
- onSuccess: () => {
- console.log('opt in success');
- },
- onError: () => {
- console.error('opt in error');
- },
- env: env as ENV,
- });
-
- console.log('PushAPI.channels.subscribe | Response - 200 OK');
- if (!silent) {
- console.log(response);
- }
-}
-
-// Push Notification - PushAPI.channels.unsubscribe
-async function PushAPI_channels_unsubscribe(silent = !showAPIResponse) {
- const response = await PushAPI.channels.unsubscribe({
- signer: signer,
- channelAddress: `eip155:5:${channelAddress}`, // channel address in CAIP
- userAddress: `eip155:5:${signerAddress}`, // user address in CAIP
- onSuccess: () => {
- console.log('opt out success');
- },
- onError: () => {
- console.error('opt out error');
- },
- env: env as ENV,
- });
-
- console.log('PushAPI.channels.unsubscribe | Response - 200 OK');
- if (!silent) {
- console.log(response);
- }
-}
-
-// Push Notification - Send Notifications
-// Direct payload for single recipient(target)
-// PushAPI.payloads.sendNotification
-async function PushAPI_payloads_sendNotification__direct_payload_single_recipient(
- silent = !showAPIResponse
-) {
- const apiResponse = await PushAPI.payloads.sendNotification({
- signer: signerChannel, // Need to resolve to channel address
- type: 3, // target
- identityType: 2, // direct payload
- notification: {
- title: `notification TITLE:`,
- body: `notification BODY`,
- },
- payload: {
- title: `payload title`,
- body: `sample msg body`,
- cta: '',
- img: '',
- },
- recipients: `eip155:5:${signerAddress}`, // recipient address
- channel: `eip155:5:${channelAddress}`, // your channel address
- env: env as ENV,
- });
-
- console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
- if (!silent) {
- console.log(apiResponse);
- }
-}
-
-// Push Notification - Direct payload for group of recipients(subset)
-// PushAPI.payloads.sendNotification
-async function PushAPI_payloads_sendNotification__direct_payload_group_of_recipient_subset(
- silent = !showAPIResponse
-) {
- const apiResponse = await PushAPI.payloads.sendNotification({
- signer: signerChannel, // Need to resolve to channel address
- type: 4, // subset
- identityType: 2, // direct payload
- notification: {
- title: `notification TITLE:`,
- body: `notification BODY`,
- },
- payload: {
- title: `payload title`,
- body: `sample msg body`,
- cta: '',
- img: '',
- },
- recipients: [`eip155:5:${signerAddress}`, `eip155:5:${randomWallet1}`], // recipient addresses
- channel: `eip155:5:${channelAddress}`, // your channel address
- env: env as ENV,
- });
-
- console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
- if (!silent) {
- console.log(apiResponse);
- }
-}
-
-// Push Notification - Direct payload for all recipients(broadcast)
-// PushAPI.payloads.sendNotification
-async function PushAPI_payloads_sendNotification__direct_payload_all_recipients_brodcast(
- silent = !showAPIResponse
-) {
- const apiResponse = await PushAPI.payloads.sendNotification({
- signer: signerChannel, // Needs to resolve to channel address
- type: 1, // broadcast
- identityType: 2, // direct payload
- notification: {
- title: `notification TITLE:`,
- body: `notification BODY`,
- },
- payload: {
- title: `payload title`,
- body: `sample msg body`,
- cta: '',
- img: '',
- },
- channel: `eip155:5:${channelAddress}`, // your channel address
- env: env as ENV,
- });
-
- console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
- if (!silent) {
- console.log(apiResponse);
- }
-}
-
-// Push Notification - Get Subscribers list from channels (DEPRECATED)
-async function PushAPI_channels_getSubscribers(silent = !showAPIResponse) {
- const subscribers = await PushAPI.channels._getSubscribers({
- channel: `eip155:5:${channelAddress}`, // channel address in CAIP
- env: env as ENV,
- });
-
- console.log('PushAPI.channels._getSubscribers | Response - 200 OK');
- if (!silent) {
- console.log(subscribers);
- }
-}
-
-// Push Notification - Socket Connection
-async function PushSDKSocket(silent = !showAPIResponse) {
- const pushSDKSocket = createSocketConnection({
- user: `eip155:5:${signerAddress}`, // CAIP, see below
- socketOptions: { autoConnect: false },
- env: env as ENV,
- });
-
- if (!pushSDKSocket) {
- throw new Error('PushSDKSocket | Socket Connection Failed');
- }
-
- pushSDKSocket.connect();
-
- pushSDKSocket.on(EVENTS.CONNECT, async () => {
- console.log('Socket Connected - will disconnect after 4 seconds');
-
- // send a notification to see the result
- await PushAPI_payloads_sendNotification__direct_payload_single_recipient(
- true
- );
- });
-
- pushSDKSocket.on(EVENTS.DISCONNECT, () => {
- console.log('Socket Disconnected');
- });
-
- pushSDKSocket.on(EVENTS.USER_FEEDS, (feedItem) => {
- // feedItem is the notification data when that notification was received
- console.log('Incoming Feed from Socket');
- if (!silent) {
- console.log(feedItem);
- }
-
- // disconnect socket after this, not to be done in real implementations
- pushSDKSocket.disconnect();
- });
-
- const delay = (ms: number) =>
- new Promise((resolve) => setTimeout(resolve, ms));
- await delay(4000);
-}
diff --git a/packages/examples/sdk-backend-node/notification/notification.lowlevel.ts b/packages/examples/sdk-backend-node/notification/notification.lowlevel.ts
new file mode 100644
index 000000000..e2f04f99a
--- /dev/null
+++ b/packages/examples/sdk-backend-node/notification/notification.lowlevel.ts
@@ -0,0 +1,377 @@
+import * as PushAPI from '@pushprotocol/restapi';
+import { createSocketConnection, EVENTS } from '@pushprotocol/socket';
+import { ethers } from 'ethers';
+import { config } from '../config';
+
+import { createWalletClient, http } from 'viem';
+import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
+import { goerli } from 'viem/chains';
+
+enum ENV {
+ PROD = 'prod',
+ STAGING = 'staging',
+ DEV = 'dev',
+ /**
+ * **This is for local development only**
+ */
+ LOCAL = 'local',
+}
+
+// CONFIGS
+const { env, showAPIResponse } = config;
+
+// If you own a channel, you can use your channel address as well
+const channelPrivateKey = process.env.WALLET_PRIVATE_KEY;
+
+/***************** SAMPLE SIGNER GENERATION *********************/
+/**
+ * USING VIEM
+ */
+const signerChannel = channelPrivateKey
+ ? createWalletClient({
+ account: privateKeyToAccount(`0x${channelPrivateKey}`),
+ chain: goerli,
+ transport: http(),
+ })
+ : undefined;
+const channelAddress = signerChannel
+ ? signerChannel.account.address
+ : undefined;
+// Random Wallet Signers
+const signer = createWalletClient({
+ account: privateKeyToAccount(generatePrivateKey()),
+ chain: goerli,
+ transport: http(),
+});
+const signerAddress = signer.account.address;
+// Dummy Wallet Addresses
+const randomWallet1 = privateKeyToAccount(generatePrivateKey()).address;
+
+/**
+ * USING ETHERS
+ */
+// const signerChannel = new ethers.Wallet(`0x${channelPrivateKey}`);
+// const channelAddress = signerChannel.address;
+// // Random Wallet Signers
+// const signer = ethers.Wallet.createRandom();
+// const signerAddress = signer.address;
+// // Dummy Wallet Addresses
+// const randomWallet1 = ethers.Wallet.createRandom().address;
+/************************************************************* */
+
+const skipExample = () => {
+ const requiredEnvVars = ['WALLET_PRIVATE_KEY'];
+
+ for (const envVar of requiredEnvVars) {
+ if (!process.env[envVar]) {
+ return true; // Skip the example if any of the required env vars is missing
+ }
+ }
+
+ return false; // All required env vars are present, don't skip the example
+};
+
+// Push Notification - Run Notifications Use cases
+export const runNotificaitonsLowLevelUseCases = async (): Promise => {
+ console.log('PushAPI.user.getFeeds');
+ await PushAPI_user_getFeeds();
+
+ console.log('PushAPI.user.getFeeds [Spam]');
+ await PushAPI_user_getFeeds__spam();
+
+ console.log('PushAPI.user.getSubscriptions');
+ await PushAPI_user_getSubscriptions();
+
+ if (!skipExample()) {
+ console.log('PushAPI.channels.getChannel()');
+ await PushAPI_channels_getChannel();
+
+ console.log('PushAPI.channels.search()');
+ await PushAPI_channels_search();
+
+ console.log('PushAPI.channels.subscribe()');
+ await PushAPI_channels_subscribe();
+
+ console.log('PushAPI.channels.unsubscribe()');
+ await PushAPI_channels_unsubscribe();
+
+ // IMPORTANT: VARIOUS OTHER NOTIFICATIONS FORMAT SUPPORTED
+ // EXAMPLES HERE: https://github.com/ethereum-push-notification-service/push-sdk/blob/main/packages/restapi/README.md
+ console.log(
+ 'PushAPI.payloads.sendNotification() [Direct Payload, Single Recipient]'
+ );
+ await PushAPI_payloads_sendNotification__direct_payload_single_recipient();
+
+ console.log(
+ 'PushAPI.payloads.sendNotification() [Direct Payload, Batch of Recipients (Subset)]'
+ );
+ await PushAPI_payloads_sendNotification__direct_payload_group_of_recipient_subset();
+
+ console.log(
+ 'PushAPI.payloads.sendNotification() [Direct Payload, All Recipients (Broadcast)]'
+ );
+ await PushAPI_payloads_sendNotification__direct_payload_all_recipients_brodcast();
+
+ console.log('PushAPI.channels._getSubscribers()');
+ await PushAPI_channels_getSubscribers();
+
+ console.log('Push Notification - PushSDKSocket()');
+ await PushSDKSocket();
+ }
+};
+
+// Push Notification - PushAPI.user.getFeeds
+async function PushAPI_user_getFeeds(silent = !showAPIResponse) {
+ const notifications = await PushAPI.user.getFeeds({
+ user: `eip155:5:${signerAddress}`, // user address in CAIP
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.user.getFeeds | Response - 200 OK');
+ if (!silent) {
+ console.log(notifications);
+ }
+}
+
+// Push Notification - PushAPI.user.getFeeds - Spam
+async function PushAPI_user_getFeeds__spam(silent = !showAPIResponse) {
+ const notifications = await PushAPI.user.getFeeds({
+ user: `eip155:5:${signerAddress}`, // user address in CAIP
+ spam: true,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.user.getFeeds [Spam] | Response - 200 OK');
+ if (!silent) {
+ console.log(notifications);
+ }
+}
+
+// Push Notification - PushAPI.user.getSubscriptions
+async function PushAPI_user_getSubscriptions(silent = !showAPIResponse) {
+ const subscriptions = await PushAPI.user.getSubscriptions({
+ user: `eip155:5:${signerAddress}`, // user address in CAIP
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.user.getSubscriptions | Response - 200 OK');
+ if (!silent) {
+ console.log(subscriptions);
+ }
+}
+
+// Push Notification - PushAPI.channels.getChannel
+async function PushAPI_channels_getChannel(silent = !showAPIResponse) {
+ const channelData = await PushAPI.channels.getChannel({
+ channel: channelAddress as string,
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.channels.getChannel | Response - 200 OK');
+ if (!silent) {
+ console.log(channelData);
+ }
+}
+
+// Push Notification - PushAPI.channels.search
+async function PushAPI_channels_search(silent = !showAPIResponse) {
+ const channelsData = await PushAPI.channels.search({
+ query: 'push', // a search query
+ page: 1, // page index
+ limit: 20, // no of items per page
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.channels.search | Response - 200 OK');
+ if (!silent) {
+ console.log(channelsData);
+ }
+}
+
+// Push Notification - PushAPI.channels.subscribe
+async function PushAPI_channels_subscribe(silent = !showAPIResponse) {
+ const response = await PushAPI.channels.subscribe({
+ signer: signer,
+ channelAddress: `eip155:5:${channelAddress}`, // channel address in CAIP
+ userAddress: `eip155:5:${signerAddress}`, // user address in CAIP
+ onSuccess: () => {
+ console.log('opt in success');
+ },
+ onError: () => {
+ console.error('opt in error');
+ },
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.channels.subscribe | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Notification - PushAPI.channels.unsubscribe
+async function PushAPI_channels_unsubscribe(silent = !showAPIResponse) {
+ const response = await PushAPI.channels.unsubscribe({
+ signer: signer,
+ channelAddress: `eip155:5:${channelAddress}`, // channel address in CAIP
+ userAddress: `eip155:5:${signerAddress}`, // user address in CAIP
+ onSuccess: () => {
+ console.log('opt out success');
+ },
+ onError: () => {
+ console.error('opt out error');
+ },
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.channels.unsubscribe | Response - 200 OK');
+ if (!silent) {
+ console.log(response);
+ }
+}
+
+// Push Notification - Send Notifications
+// Direct payload for single recipient(target)
+// PushAPI.payloads.sendNotification
+async function PushAPI_payloads_sendNotification__direct_payload_single_recipient(
+ silent = !showAPIResponse
+) {
+ const apiResponse = await PushAPI.payloads.sendNotification({
+ signer: signerChannel, // Need to resolve to channel address
+ type: 3, // target
+ identityType: 2, // direct payload
+ notification: {
+ title: `notification TITLE:`,
+ body: `notification BODY`,
+ },
+ payload: {
+ title: `payload title`,
+ body: `sample msg body`,
+ cta: '',
+ img: '',
+ },
+ recipients: `eip155:5:${signerAddress}`, // recipient address
+ channel: `eip155:5:${channelAddress}`, // your channel address
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
+ if (!silent) {
+ console.log(apiResponse);
+ }
+}
+
+// Push Notification - Direct payload for group of recipients(subset)
+// PushAPI.payloads.sendNotification
+async function PushAPI_payloads_sendNotification__direct_payload_group_of_recipient_subset(
+ silent = !showAPIResponse
+) {
+ const apiResponse = await PushAPI.payloads.sendNotification({
+ signer: signerChannel, // Need to resolve to channel address
+ type: 4, // subset
+ identityType: 2, // direct payload
+ notification: {
+ title: `notification TITLE:`,
+ body: `notification BODY`,
+ },
+ payload: {
+ title: `payload title`,
+ body: `sample msg body`,
+ cta: '',
+ img: '',
+ },
+ recipients: [`eip155:5:${signerAddress}`, `eip155:5:${randomWallet1}`], // recipient addresses
+ channel: `eip155:5:${channelAddress}`, // your channel address
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
+ if (!silent) {
+ console.log(apiResponse);
+ }
+}
+
+// Push Notification - Direct payload for all recipients(broadcast)
+// PushAPI.payloads.sendNotification
+async function PushAPI_payloads_sendNotification__direct_payload_all_recipients_brodcast(
+ silent = !showAPIResponse
+) {
+ const apiResponse = await PushAPI.payloads.sendNotification({
+ signer: signerChannel, // Needs to resolve to channel address
+ type: 1, // broadcast
+ identityType: 2, // direct payload
+ notification: {
+ title: `notification TITLE:`,
+ body: `notification BODY`,
+ },
+ payload: {
+ title: `payload title`,
+ body: `sample msg body`,
+ cta: '',
+ img: '',
+ },
+ channel: `eip155:5:${channelAddress}`, // your channel address
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.payloads.sendNotification | Response - 204 OK');
+ if (!silent) {
+ console.log(apiResponse);
+ }
+}
+
+// Push Notification - Get Subscribers list from channels (DEPRECATED)
+async function PushAPI_channels_getSubscribers(silent = !showAPIResponse) {
+ const subscribers = await PushAPI.channels._getSubscribers({
+ channel: `eip155:5:${channelAddress}`, // channel address in CAIP
+ env: env as ENV,
+ });
+
+ console.log('PushAPI.channels._getSubscribers | Response - 200 OK');
+ if (!silent) {
+ console.log(subscribers);
+ }
+}
+
+// Push Notification - Socket Connection
+async function PushSDKSocket(silent = !showAPIResponse) {
+ const pushSDKSocket = createSocketConnection({
+ user: `eip155:5:${signerAddress}`, // CAIP, see below
+ socketOptions: { autoConnect: false },
+ env: env as ENV,
+ });
+
+ if (!pushSDKSocket) {
+ throw new Error('PushSDKSocket | Socket Connection Failed');
+ }
+
+ pushSDKSocket.connect();
+
+ pushSDKSocket.on(EVENTS.CONNECT, async () => {
+ console.log('Socket Connected - will disconnect after 4 seconds');
+
+ // send a notification to see the result
+ await PushAPI_payloads_sendNotification__direct_payload_single_recipient(
+ true
+ );
+ });
+
+ pushSDKSocket.on(EVENTS.DISCONNECT, () => {
+ console.log('Socket Disconnected');
+ });
+
+ pushSDKSocket.on(EVENTS.USER_FEEDS, (feedItem) => {
+ // feedItem is the notification data when that notification was received
+ console.log('Incoming Feed from Socket');
+ if (!silent) {
+ console.log(feedItem);
+ }
+
+ // disconnect socket after this, not to be done in real implementations
+ pushSDKSocket.disconnect();
+ });
+
+ const delay = (ms: number) =>
+ new Promise((resolve) => setTimeout(resolve, ms));
+ await delay(4000);
+}
diff --git a/packages/examples/sdk-backend-node/notification/notification.ts b/packages/examples/sdk-backend-node/notification/notification.ts
new file mode 100644
index 000000000..2865fee94
--- /dev/null
+++ b/packages/examples/sdk-backend-node/notification/notification.ts
@@ -0,0 +1,257 @@
+import { PushAPI } from '@pushprotocol/restapi';
+import { config } from '../config';
+import { ethers } from 'ethers';
+import { STREAM } from '@pushprotocol/restapi/src/lib/pushstream/pushStreamTypes';
+
+// CONFIGS
+const { env, showAPIResponse } = config;
+
+const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
+
+const eventlistener = async (
+ pushAPI: PushAPI,
+ eventName: string
+): Promise => {
+ pushAPI.stream.on(eventName, (data: any) => {
+ if (showAPIResponse) {
+ console.log('Stream Event Received');
+ console.log(data);
+ console.log('\n');
+ }
+ });
+};
+
+export const runNotificationClassUseCases = async (): Promise => {
+ if (!process.env.WALLET_PRIVATE_KEY) {
+ console.log(
+ 'skipping PushAPI.channel examples, no private key passed in .env'
+ );
+ return;
+ }
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ // Signer Generation
+ const provider = new ethers.providers.JsonRpcProvider(
+ 'https://goerli.blockpi.network/v1/rpc/public' // Goerli Provider
+ );
+ const signer = new ethers.Wallet(
+ `0x${process.env.WALLET_PRIVATE_KEY}`,
+ provider
+ );
+ const randomWallet1 = ethers.Wallet.createRandom().address;
+ const randomWallet2 = ethers.Wallet.createRandom().address;
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ const userAlice = await PushAPI.initialize(signer, { env });
+
+ // Listen Stream Events for getting websocket events
+ console.log(`Listening ${STREAM.NOTIF} Events`);
+ eventlistener(userAlice, STREAM.NOTIF);
+ console.log(`Listening ${STREAM.NOTIF_OPS} Events`);
+ eventlistener(userAlice, STREAM.NOTIF_OPS);
+ console.log('\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.info');
+ const channelInfo = await userAlice.channel.info();
+ if (showAPIResponse) {
+ console.log(channelInfo);
+ }
+ console.log('PushAPI.channel.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.search');
+ const searchedChannels = await userAlice.channel.search(
+ 'push' // search by name or address
+ );
+ if (showAPIResponse) {
+ console.log(searchedChannels);
+ }
+ console.log('PushAPI.channel.search | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.subscribers');
+ const channelSubscribers = await userAlice.channel.subscribers();
+ if (showAPIResponse) {
+ console.log(channelSubscribers);
+ }
+ console.log('PushAPI.channel.subscribers | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.send');
+ if (channelInfo) {
+ const broadcastNotif = await userAlice.channel.send(['*'], {
+ notification: {
+ title: 'test',
+ body: 'test',
+ },
+ });
+ await delay(3000); // Delay added to log the events in order
+ const targetedNotif = await userAlice.channel.send([signer.address], {
+ notification: {
+ title: 'test',
+ body: 'test',
+ },
+ });
+ await delay(3000); // Delay added to log the events in order
+ const subsetNotif = await userAlice.channel.send(
+ [randomWallet1, randomWallet2, signer.address],
+ {
+ notification: {
+ title: 'test',
+ body: 'test',
+ },
+ }
+ );
+ await delay(3000); // Delay added to log the events in order
+ if (showAPIResponse) {
+ console.log(broadcastNotif, targetedNotif, subsetNotif);
+ }
+ console.log('PushAPI.channel.send | Response - 200 OK\n\n');
+ } else {
+ console.log(
+ 'skipping PushAPI.channel.send as no channel exists with the signer\n\n'
+ );
+ }
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ // These Examples requires wallet to hold some ETH & PUSH
+ const balance = await provider.getBalance(signer.address);
+ if (parseFloat(ethers.utils.formatEther(balance)) < 0.001) {
+ console.log(
+ 'skipping PushAPI.channel examples, wallet does not have enough balance to pay fee'
+ );
+ }
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.create');
+ if (channelInfo) {
+ console.log('skipping PushAPI.channel.create as it already exists\n\n');
+ } else {
+ const createdChannel = await userAlice.channel.create({
+ name: 'Test Channel',
+ description: 'Test Description',
+ icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAz0lEQVR4AcXBsU0EQQyG0e+saWJ7oACiKYDMEZVs6GgSpC2BIhzRwAS0sgk9HKn3gpFOAv3v3V4/3+4U4Z1q5KTy42Ql940qvFONnFSGmCFmiN2+fj7uCBlihpgh1ngwcvKfwjuVIWaIGWKNB+GdauSk8uNkJfeNKryzYogZYoZY40m5b/wlQ8wQM8TayMlKeKcaOVkJ71QjJyuGmCFmiDUe+HFy4VyEd57hx0mV+0ZliBlihlgL71w4FyMnVXhnZeSkiu93qheuDDFDzBD7BcCyMAOfy204AAAAAElFTkSuQmCC',
+ url: 'https://push.org',
+ });
+ if (showAPIResponse) {
+ console.log(createdChannel);
+ }
+ console.log('PushAPI.channel.create | Response - 200 OK\n\n');
+ }
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.update');
+ const updatedChannel = await userAlice.channel.update({
+ name: 'Updated Name',
+ description: 'Testing new description',
+ url: 'https://google.com',
+ icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAz0lEQVR4AcXBsU0EQQyG0e+saWJ7oACiKYDMEZVs6GgSpC2BIhzRwAS0sgk9HKn3gpFOAv3v3V4/3+4U4Z1q5KTy42Ql940qvFONnFSGmCFmiN2+fj7uCBlihpgh1ngwcvKfwjuVIWaIGWKNB+GdauSk8uNkJfeNKryzYogZYoZY40m5b/wlQ8wQM8TayMlKeKcaOVkJ71QjJyuGmCFmiDUe+HFy4VyEd57hx0mV+0ZliBlihlgL71w4FyMnVXhnZeSkiu93qheuDDFDzBD7BcCyMAOfy204AAAAAElFTkSuQmCC',
+ });
+ if (showAPIResponse) {
+ console.log(updatedChannel);
+ }
+ console.log('PushAPI.channel.update | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.verify');
+ // only verified channels can verify other channels (otherwise this action is skipped by sdk)
+ if (channelInfo.verified_status) {
+ const verifiedTrx = await userAlice.channel.verify(
+ '0x35B84d6848D16415177c64D64504663b998A6ab4'
+ );
+ if (showAPIResponse) {
+ console.log(verifiedTrx);
+ }
+ }
+ console.log('PushAPI.channel.verify | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.setting');
+ const channelSettingTrx = await userAlice.channel.setting([
+ { type: 0, default: 1, description: 'My Notif Settings' },
+ ]);
+ if (showAPIResponse) {
+ console.log(channelSettingTrx);
+ }
+ console.log('PushAPI.channel.setting | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.delegate.add');
+ const addedDelegate = await userAlice.channel.delegate.add(
+ `eip155:5:${randomWallet1}`
+ );
+
+ if (showAPIResponse) {
+ console.log(addedDelegate);
+ }
+ console.log('PushAPI.channel.delegate.add | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.delegate.get');
+ const delegates = await userAlice.channel.delegate.get();
+ if (showAPIResponse) {
+ console.log(delegates);
+ }
+ console.log('PushAPI.channel.delegate.get | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.delegate.remove');
+ const removedDelegate = await userAlice.channel.delegate.remove(
+ `eip155:5:${randomWallet1}`
+ );
+ if (showAPIResponse) {
+ console.log(removedDelegate);
+ }
+ console.log('PushAPI.channel.delegate.remove | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.channel.alias.info');
+ const aliasInfo = await userAlice.channel.alias.info({
+ alias: '0x35B84d6848D16415177c64D64504663b998A6ab4',
+ aliasChain: 'POLYGON',
+ });
+ if (showAPIResponse) {
+ console.log(aliasInfo);
+ }
+ console.log('PushAPI.channel.alias.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.notification.list');
+ const inboxNotifications = await userAlice.notification.list('INBOX');
+ const spamNotifications = await userAlice.notification.list('SPAM');
+ if (showAPIResponse) {
+ console.log(inboxNotifications, spamNotifications);
+ }
+ console.log('PushAPI.notification.list | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.notification.subscribe');
+ const subscribeResponse = await userAlice.notification.subscribe(
+ 'eip155:5:0xD8634C39BBFd4033c0d3289C4515275102423681' // channel to subscribe
+ );
+ if (showAPIResponse) {
+ console.log(subscribeResponse);
+ }
+ console.log('PushAPI.notification.subscribe | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.notification.subscriptions');
+ const aliceSubscriptions = await userAlice.notification.subscriptions();
+ if (showAPIResponse) {
+ console.log(aliceSubscriptions);
+ }
+ console.log('PushAPI.notification.subscriptions | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.notification.unsubscribe');
+ const unsubscribeResponse = await userAlice.notification.unsubscribe(
+ 'eip155:5:0xD8634C39BBFd4033c0d3289C4515275102423681' // channel to unsubscribe
+ );
+ if (showAPIResponse) {
+ console.log(unsubscribeResponse);
+ }
+ console.log('PushAPI.notification.unsubscribe | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+};
diff --git a/packages/examples/sdk-backend-node/package.json b/packages/examples/sdk-backend-node/package.json
index 64da4f88a..a75fdb60c 100644
--- a/packages/examples/sdk-backend-node/package.json
+++ b/packages/examples/sdk-backend-node/package.json
@@ -11,7 +11,7 @@
"author": "",
"license": "ISC",
"dependencies": {
- "@pushprotocol/restapi": "0.0.1-alpha.39",
+ "@pushprotocol/restapi": "0.0.1-alpha.44",
"@pushprotocol/socket": "^0.5.2"
}
}
diff --git a/packages/examples/sdk-backend-node/pushAPI/index.ts b/packages/examples/sdk-backend-node/pushAPI/index.ts
deleted file mode 100644
index 2b02dca10..000000000
--- a/packages/examples/sdk-backend-node/pushAPI/index.ts
+++ /dev/null
@@ -1,305 +0,0 @@
-import { PushAPI } from '@pushprotocol/restapi';
-import {
- adjectives,
- animals,
- colors,
- uniqueNamesGenerator,
-} from 'unique-names-generator';
-import { config } from '../config';
-import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
-import { createWalletClient, http } from 'viem';
-import { goerli } from 'viem/chains';
-import { createSocketConnection, EVENTS } from '@pushprotocol/socket';
-
-// CONFIGS
-const { env, showAPIResponse } = config;
-
-/***************** SAMPLE SIGNER GENERATION *********************/
-// Uing VIEM
-// Random Wallet Signers
-const signer = createWalletClient({
- account: privateKeyToAccount(generatePrivateKey()),
- chain: goerli,
- transport: http(),
-});
-const signerAddress = signer.account.address;
-const secondSigner = createWalletClient({
- account: privateKeyToAccount(generatePrivateKey()),
- chain: goerli,
- transport: http(),
-});
-const secondSignerAddress = secondSigner.account.address;
-const thirdSigner = createWalletClient({
- account: privateKeyToAccount(generatePrivateKey()),
- chain: goerli,
- transport: http(),
-});
-const thirdSignerAddress = thirdSigner.account.address;
-// Dummy Wallet Addresses
-const randomWallet1 = privateKeyToAccount(generatePrivateKey()).address;
-const randomWallet2 = privateKeyToAccount(generatePrivateKey()).address;
-const randomWallet3 = privateKeyToAccount(generatePrivateKey()).address;
-/****************************************************************/
-
-/***************** SAMPLE GROUP DATA ****************************/
-const groupName = uniqueNamesGenerator({
- dictionaries: [adjectives, colors, animals],
-});
-const groupDescription = uniqueNamesGenerator({
- dictionaries: [adjectives, colors, animals],
-});
-const groupImage =
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
-/***************** SAMPLE GROUP DATA ****************************/
-
-export const runPushAPICases = async (): Promise => {
- console.log(`
-
-██████╗░██╗░░░██╗░██████╗██╗░░██╗░█████╗░██████╗░██╗ ░█████╗░██╗░░░░░░█████╗░░██████╗░██████╗
-██╔══██╗██║░░░██║██╔════╝██║░░██║██╔══██╗██╔══██╗██║ ██╔══██╗██║░░░░░██╔══██╗██╔════╝██╔════╝
-██████╔╝██║░░░██║╚█████╗░███████║███████║██████╔╝██║ ██║░░╚═╝██║░░░░░███████║╚█████╗░╚█████╗░
-██╔═══╝░██║░░░██║░╚═══██╗██╔══██║██╔══██║██╔═══╝░██║ ██║░░██╗██║░░░░░██╔══██║░╚═══██╗░╚═══██╗
-██║░░░░░╚██████╔╝██████╔╝██║░░██║██║░░██║██║░░░░░██║ ╚█████╔╝███████╗██║░░██║██████╔╝██████╔╝
-╚═╝░░░░░░╚═════╝░╚═════╝░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░░░░╚═╝ ░╚════╝░╚══════╝╚═╝░░╚═╝╚═════╝░╚═════╝░
- `);
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.initialize');
- const userAlice = await PushAPI.initialize(signer, { env });
- const userBob = await PushAPI.initialize(secondSigner, { env });
- console.log('PushAPI.initialize | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.info');
- const userAliceInfo = await userAlice.user.info();
- if (showAPIResponse) {
- console.log(userAliceInfo);
- }
- console.log('PushAPI.info | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.profile.info');
- const userAliceProfileInfo = await userAlice.profile.info();
- if (showAPIResponse) {
- console.log(userAliceProfileInfo);
- }
- console.log('PushAPI.profile.info | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.profile.update');
- const updatedName = 'Bob The Builder';
- const response = await userAlice.profile.update({ name: updatedName });
- if (showAPIResponse) {
- console.log(response);
- }
- console.log('PushAPI.profile.update | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.list');
- const aliceChats = await userAlice.chat.list('CHATS');
- const aliceRequests = await userAlice.chat.list('REQUESTS');
- if (showAPIResponse) {
- console.log(aliceChats);
- console.log(aliceRequests);
- }
- console.log('PushAPI.chat.list | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.latest');
- const aliceLatestChatWithBob = await userAlice.chat.latest(
- secondSignerAddress
- );
- if (showAPIResponse) {
- console.log(aliceLatestChatWithBob);
- }
- console.log('PushAPI.chat.latest | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.history');
- const aliceChatHistoryWithBob = await userAlice.chat.history(
- secondSignerAddress
- );
- if (showAPIResponse) {
- console.log(aliceChatHistoryWithBob);
- }
- console.log('PushAPI.chat.history | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.send');
- const aliceMessagesBob = await userAlice.chat.send(secondSignerAddress, {
- content: 'Hello Bob!',
- type: 'Text',
- });
- if (showAPIResponse) {
- console.log(aliceMessagesBob);
- }
- console.log('PushAPI.chat.send | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.decrypt');
- const pushSDKSocket = createSocketConnection({
- user: signerAddress,
- socketType: 'chat',
- socketOptions: { autoConnect: true, reconnectionAttempts: 3 },
- env: env,
- });
- if (pushSDKSocket) {
- await userAlice.chat.send(secondSignerAddress, {
- content: 'Hello Bob!',
- type: 'Text',
- });
- pushSDKSocket.on(EVENTS.CHAT_RECEIVED_MESSAGE, async (message) => {
- // uncomment after latest sdk deployment
- // await userAlice.chat.decrypt([message]);
- // pushSDKSocket.disconnect();
- });
- }
- console.log('PushAPI.chat.decrypt | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.accept');
- const bobAcceptsRequest = await userBob.chat.accept(signerAddress);
- if (showAPIResponse) {
- console.log(bobAcceptsRequest);
- }
- console.log('PushAPI.chat.accept | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.reject');
- const tempUser = await PushAPI.initialize(thirdSigner, { env });
- await tempUser.chat.send(secondSignerAddress, {
- content: 'Sending Malicious message to bob',
- });
- const bobRejectsRequest = await userBob.chat.reject(thirdSignerAddress);
- if (showAPIResponse) {
- console.log(bobRejectsRequest);
- }
- console.log('PushAPI.chat.reject | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.block');
- const AliceBlocksBob = await userAlice.chat.block([secondSignerAddress]);
- if (showAPIResponse) {
- console.log(AliceBlocksBob);
- }
- console.log('PushAPI.chat.block | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.chat.unblock');
- const AliceUnblocksBob = await userAlice.chat.unblock([secondSignerAddress]);
- if (showAPIResponse) {
- console.log(AliceUnblocksBob);
- }
- console.log('PushAPI.chat.unblock | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.create');
- const createdGroup = await userAlice.chat.group.create(groupName, {
- description: groupDescription,
- image: groupImage,
- members: [randomWallet1, randomWallet2],
- admins: [],
- private: false,
- });
- const groupChatId = createdGroup.chatId; // to be used in other examples
- if (showAPIResponse) {
- console.log(createdGroup);
- }
- console.log('PushAPI.group.create | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.permissions');
- const grouppermissions = await userAlice.chat.group.permissions(groupChatId);
- if (showAPIResponse) {
- console.log(grouppermissions);
- }
- console.log('PushAPI.group.permissions | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.info');
- const groupInfo = await userAlice.chat.group.info(groupChatId);
- if (showAPIResponse) {
- console.log(groupInfo);
- }
- console.log('PushAPI.group.info | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.update');
- const updatedGroup = await userAlice.chat.group.update(groupChatId, {
- description: 'Updated Description',
- });
- if (showAPIResponse) {
- console.log(updatedGroup);
- }
- console.log('PushAPI.group.update | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.add');
- const addMember = await userAlice.chat.group.add(groupChatId, {
- role: 'MEMBER',
- accounts: [randomWallet3],
- });
- if (showAPIResponse) {
- console.log(addMember);
- }
- console.log('PushAPI.group.add | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.remove');
- const removeMember = await userAlice.chat.group.remove(groupChatId, {
- role: 'MEMBER',
- accounts: [randomWallet3],
- });
- if (showAPIResponse) {
- console.log(removeMember);
- }
- console.log('PushAPI.group.remove | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.join');
- const joinGrp = await userBob.chat.group.join(groupChatId);
- if (showAPIResponse) {
- console.log(joinGrp);
- }
- console.log('PushAPI.group.join | Response - 200 OK\n\n');
- //-------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.leave');
- const leaveGrp = await userBob.chat.group.leave(groupChatId);
- if (showAPIResponse) {
- console.log(leaveGrp);
- }
- console.log('PushAPI.group.leave | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.group.reject');
- const sampleGrp = await userAlice.chat.group.create('Sample Grp', {
- description: groupDescription,
- image: groupImage,
- members: [secondSignerAddress], // invite bob
- admins: [],
- private: true,
- });
- const rejectGrpJoiningReq = await userBob.chat.group.reject(sampleGrp.chatId);
- if (showAPIResponse) {
- console.log(rejectGrpJoiningReq);
- }
- console.log('PushAPI.group.reject | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.encryption.info');
- const encryptionInfo = await userAlice.encryption.info();
- if (showAPIResponse) {
- console.log(encryptionInfo);
- }
- console.log('PushAPI.encryption.info | Response - 200 OK\n\n');
- // -------------------------------------------------------------------
- // -------------------------------------------------------------------
- console.log('PushAPI.encryption.update');
- const PGP_V3 = 'eip191-aes256-gcm-hkdf-sha256';
- const encryptionUpdate = await userAlice.encryption.update(PGP_V3 as any);
- if (showAPIResponse) {
- console.log(encryptionUpdate);
- }
- console.log('PushAPI.encryption.update | Response - 200 OK\n\n');
-};
diff --git a/packages/examples/sdk-backend-node/spaces/index.ts b/packages/examples/sdk-backend-node/space/index.ts
similarity index 94%
rename from packages/examples/sdk-backend-node/spaces/index.ts
rename to packages/examples/sdk-backend-node/space/index.ts
index 64e04891d..43c7afb32 100644
--- a/packages/examples/sdk-backend-node/spaces/index.ts
+++ b/packages/examples/sdk-backend-node/space/index.ts
@@ -43,15 +43,14 @@ const spaceDescription = uniqueNamesGenerator({
const spaceImage =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
-export const runSpacesUseCases = async (): Promise => {
+export const runSpaceUseCases = async (): Promise => {
console.log(`
- ███████╗██████╗ █████╗ ██████╗███████╗███████╗
- ██╔════╝██╔══██╗██╔══██╗██╔════╝██╔════╝██╔════╝
- ███████╗██████╔╝███████║██║ █████╗ ███████╗
- ╚════██║██╔═══╝ ██╔══██║██║ ██╔══╝ ╚════██║
- ███████║██║ ██║ ██║╚██████╗███████╗███████║
- ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚══════╝
-
+░██████╗██████╗░░█████╗░░█████╗░███████╗
+██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝
+╚█████╗░██████╔╝███████║██║░░╚═╝█████╗░░
+░╚═══██╗██╔═══╝░██╔══██║██║░░██╗██╔══╝░░
+██████╔╝██║░░░░░██║░░██║╚█████╔╝███████╗
+╚═════╝░╚═╝░░░░░╚═╝░░╚═╝░╚════╝░╚══════╝
`);
console.log('PushAPI.user.create');
diff --git a/packages/examples/sdk-backend-node/user/index.ts b/packages/examples/sdk-backend-node/user/index.ts
new file mode 100644
index 000000000..6a9dd6d30
--- /dev/null
+++ b/packages/examples/sdk-backend-node/user/index.ts
@@ -0,0 +1,75 @@
+import { PushAPI } from '@pushprotocol/restapi';
+import { config } from '../config';
+import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
+import { createWalletClient, http } from 'viem';
+import { goerli } from 'viem/chains';
+
+// CONFIGS
+const { env, showAPIResponse } = config;
+
+/***************** SAMPLE SIGNER GENERATION *********************/
+// Uing VIEM
+// Random Wallet Signers
+const signer = createWalletClient({
+ account: privateKeyToAccount(generatePrivateKey()),
+ chain: goerli,
+ transport: http(),
+});
+
+export const runUserCases = async (): Promise => {
+ console.log(`
+██╗░░░██╗░██████╗███████╗██████╗░
+██║░░░██║██╔════╝██╔════╝██╔══██╗
+██║░░░██║╚█████╗░█████╗░░██████╔╝
+██║░░░██║░╚═══██╗██╔══╝░░██╔══██╗
+╚██████╔╝██████╔╝███████╗██║░░██║
+░╚═════╝░╚═════╝░╚══════╝╚═╝░░╚═╝
+`);
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.initialize');
+ const userAlice = await PushAPI.initialize(signer, { env });
+ console.log('PushAPI.initialize | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.info');
+ const userAliceInfo = await userAlice.info();
+ if (showAPIResponse) {
+ console.log(userAliceInfo);
+ }
+ console.log('PushAPI.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.profile.info');
+ const userAliceProfileInfo = await userAlice.profile.info();
+ if (showAPIResponse) {
+ console.log(userAliceProfileInfo);
+ }
+ console.log('PushAPI.profile.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.profile.update');
+ const updatedName = 'Bob The Builder';
+ const response = await userAlice.profile.update({ name: updatedName });
+ if (showAPIResponse) {
+ console.log(response);
+ }
+ console.log('PushAPI.profile.update | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.encryption.info');
+ const encryptionInfo = await userAlice.encryption.info();
+ if (showAPIResponse) {
+ console.log(encryptionInfo);
+ }
+ console.log('PushAPI.encryption.info | Response - 200 OK\n\n');
+ // -------------------------------------------------------------------
+ // -------------------------------------------------------------------
+ console.log('PushAPI.encryption.update');
+ const PGP_V3 = 'eip191-aes256-gcm-hkdf-sha256';
+ const encryptionUpdate = await userAlice.encryption.update(PGP_V3 as any);
+ if (showAPIResponse) {
+ console.log(encryptionUpdate);
+ }
+ console.log('PushAPI.encryption.update | Response - 200 OK\n\n');
+};
diff --git a/packages/examples/sdk-backend-node/video/index.ts b/packages/examples/sdk-backend-node/video/index.ts
index 209522514..afc8e636e 100644
--- a/packages/examples/sdk-backend-node/video/index.ts
+++ b/packages/examples/sdk-backend-node/video/index.ts
@@ -21,14 +21,14 @@ const videoSetData: (
let videoObject: any = null;
const videoLocalStream = null; // get the local stream
const videoSenderAddress = process.env.VIDEO_SENDER_ADDRESS;
-const videoRecipientAddress = process.env.VIDEO_RECIPEINT_ADDRESS;
+const videoRecipientAddress = process.env.VIDEO_RECIPIENT_ADDRESS;
const videoChatId = process.env.VIDEO_CHAT_ID;
let videoSignalData_1: any = null;
const skipExample = () => {
const requiredEnvVars = [
'VIDEO_SENDER_ADDRESS',
- 'VIDEO_RECIPEINT_ADDRESS',
+ 'VIDEO_RECIPIENT_ADDRESS',
'VIDEO_CHAT_ID',
'VIDEO_CHAIN_ID',
];
@@ -45,12 +45,12 @@ const skipExample = () => {
// Push Video - Run Video Use cases
export const runVideoUseCases = async (): Promise => {
console.log(`
- ██╗ ██╗██╗██████╗ ███████╗ ██████╗
- ██║ ██║██║██╔══██╗██╔════╝██╔═══██╗
- ██║ ██║██║██║ ██║█████╗ ██║ ██║
- ╚██╗ ██╔╝██║██║ ██║██╔══╝ ██║ ██║
- ╚████╔╝ ██║██████╔╝███████╗╚██████╔╝
- ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝
+██╗░░░██╗██╗██████╗░███████╗░█████╗░
+██║░░░██║██║██╔══██╗██╔════╝██╔══██╗
+╚██╗░██╔╝██║██║░░██║█████╗░░██║░░██║
+░╚████╔╝░██║██║░░██║██╔══╝░░██║░░██║
+░░╚██╔╝░░██║██████╔╝███████╗╚█████╔╝
+░░░╚═╝░░░╚═╝╚═════╝░╚══════╝░╚════╝░
`);
if (videoLocalStream === null) {
diff --git a/packages/examples/sdk-frontend-react/src/app/components/Connect.tsx b/packages/examples/sdk-frontend-react/src/app/components/Connect.tsx
index 1041ea25b..cc5b89378 100644
--- a/packages/examples/sdk-frontend-react/src/app/components/Connect.tsx
+++ b/packages/examples/sdk-frontend-react/src/app/components/Connect.tsx
@@ -19,10 +19,12 @@ const NETWORK_MAPPING: NwMappingType = {
10: 'OPTIMISM_MAINNET',
1442: 'POLYGON_ZK_EVM_TESTNET',
1101: 'POLYGON_ZK_EVM_MAINNET',
+ 421613: "ARBITRUM_TESTNET",
+ 42161: "ARBITRUMONE_MAINNET"
};
const injected = new InjectedConnector({
- supportedChainIds: [1, 3, 4, 5, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101],
+ supportedChainIds: [1, 3, 4, 5, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161],
});
const ConnectWrapper = styled.div`
diff --git a/packages/examples/sdk-frontend-react/src/app/helpers.ts b/packages/examples/sdk-frontend-react/src/app/helpers.ts
index d5af6bc15..bad12f49d 100644
--- a/packages/examples/sdk-frontend-react/src/app/helpers.ts
+++ b/packages/examples/sdk-frontend-react/src/app/helpers.ts
@@ -18,7 +18,7 @@ const Constants = {
},
DEFAULT_CHAIN_ID: 5,
DEV_CHAIN_ID: 99999,
- NON_ETH_CHAINS: [137, 80001, 56, 97, 10, 420, 1442, 1101],
+ NON_ETH_CHAINS: [137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161],
ETH_CHAINS: [1, 5],
};
diff --git a/packages/reactnative/README.md b/packages/reactnative/README.md
index 4eae3bfa0..d3e665c64 100644
--- a/packages/reactnative/README.md
+++ b/packages/reactnative/README.md
@@ -208,5 +208,5 @@ where
| cta | string | Call To Action Link (given during notification creation) |
| image | string | Any media link (given during notification creation) |
| appbot | string | is the notification is from EPNS bot the value is "1" else "0" |
-| chainName | string | Can be anyone of the following blockchain networks on which the notification was sent - "ETH_MAINNET", "ETH_TEST_GOERLI", "POLYGON_MAINNET", "POLYGON_TEST_MUMBAI", "BSC_MAINNET, "BSC_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "POLYGON_ZK_EVM_TESTNET", "POLYGON_ZK_EVM_MAINNET", "THE_GRAPH" |
+| chainName | string | Can be anyone of the following blockchain networks on which the notification was sent - "ETH_MAINNET", "ETH_TEST_GOERLI", "POLYGON_MAINNET", "POLYGON_TEST_MUMBAI", "BSC_MAINNET, "BSC_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "POLYGON_ZK_EVM_TESTNET", "POLYGON_ZK_EVM_MAINNET", "ARBITRUM_TESTNET", "ARBITRUMONE_MAINNET", "THE_GRAPH" |
| youTubeAPIKey | string | Your generated Youtube API key |
\ No newline at end of file
diff --git a/packages/reactnative/src/lib/components/chainDetails/arbitrumSVG.tsx b/packages/reactnative/src/lib/components/chainDetails/arbitrumSVG.tsx
new file mode 100644
index 000000000..7106c3552
--- /dev/null
+++ b/packages/reactnative/src/lib/components/chainDetails/arbitrumSVG.tsx
@@ -0,0 +1,29 @@
+import * as React from 'react';
+import { SVGProps } from 'react';
+
+const ArbitrumSvgComponent = (props: SVGProps) => (
+
+);
+
+export default ArbitrumSvgComponent;
diff --git a/packages/reactnative/src/lib/components/chainDetails/index.tsx b/packages/reactnative/src/lib/components/chainDetails/index.tsx
index 08c8cb55b..dbd6c8e19 100644
--- a/packages/reactnative/src/lib/components/chainDetails/index.tsx
+++ b/packages/reactnative/src/lib/components/chainDetails/index.tsx
@@ -3,9 +3,15 @@ import PolygonSvg from "./polygonSVG";
import GraphSvg from "./thegraphSVG";
import BscSvg from "./bscSVG";
import OptimismSvg from "./optimismSVG"
-import PolygonZKEVMSvg from "./polygonZKEVMSVG";
+import PolygonZKEVMSvg from "./polygonZkEVMSVG";
+import ArbitrumSvgComponent from "./arbitrumSVG";
-export default {
+type Network = {
+ label: string;
+ Icon: any;
+};
+
+const networks: Record = {
ETH_TEST_GOERLI: { label: "ETHEREUM GOERLI", Icon: EthereumSvg },
ETH_MAINNET: { label: "ETHEREUM MAINNET", Icon: EthereumSvg },
POLYGON_TEST_MUMBAI: { label: "POLYGON MUMBAI", Icon: PolygonSvg },
@@ -16,5 +22,9 @@ export default {
OPTIMISM_MAINNET: { label: "OPTIMISM MAINNET", Icon: OptimismSvg },
POLYGON_ZK_EVM_TESTNET: {label:"POLYGON_ZK_EVM_TESTNET",Icon: PolygonZKEVMSvg},
POLYGON_ZK_EVM_MAINNET: {label:"POLYGON_ZK_EVM_MAINNET",Icon: PolygonZKEVMSvg},
+ ARBITRUM_TESTNET: {label:"ARBITRUM_TESTNET",Icon: ArbitrumSvgComponent},
+ ARBITRUMONE_MAINNET: {label: "ARBITRUMONE_MAINNET", Icon: ArbitrumSvgComponent},
THE_GRAPH: { label: "THE GRAPH", Icon: GraphSvg },
-};
\ No newline at end of file
+};
+
+export default networks
\ No newline at end of file
diff --git a/packages/reactnative/src/lib/components/notifications/notification.tsx b/packages/reactnative/src/lib/components/notifications/notification.tsx
index 30869655e..bbc064056 100644
--- a/packages/reactnative/src/lib/components/notifications/notification.tsx
+++ b/packages/reactnative/src/lib/components/notifications/notification.tsx
@@ -18,7 +18,7 @@ import { ImageDownloadWithIndicator, VideoDownloadWithIndicator } from '../load
// ================= Define types
-export type chainNameType = "ETH_TEST_GOERLI" | "POLYGON_TEST_MUMBAI" | "ETH_MAINNET" | "POLYGON_MAINNET" | "BSC_MAINNET" | "BSC_TESTNET" | "OPTIMISM_MAINNET" | "OPTIMISM_TESTNET" | "POLYGON_ZK_EVM_TESTNET" | "POLYGON_ZK_EVM_MAINNET" | "THE_GRAPH" | undefined;
+export type chainNameType = "ETH_TEST_GOERLI" | "POLYGON_TEST_MUMBAI" | "ETH_MAINNET" | "POLYGON_MAINNET" | "BSC_MAINNET" | "BSC_TESTNET" | "OPTIMISM_MAINNET" | "OPTIMISM_TESTNET" | "POLYGON_ZK_EVM_TESTNET" | "POLYGON_ZK_EVM_MAINNET" | "ARBITRUMONE_MAINNET" | "ARBITRUM_TESTNET" | "THE_GRAPH" | undefined;
const botImageLocalPath = '../../assets/epnsbot.png';
diff --git a/packages/restapi/README.md b/packages/restapi/README.md
index 1aa9dffde..1c51666e1 100644
--- a/packages/restapi/README.md
+++ b/packages/restapi/README.md
@@ -181,6 +181,8 @@ Binance Mainnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
Binance Testnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
Optimism Mainnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
Optimism Testnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
+Arbitrum Mainnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
+Arbitrum One Testnet - 0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa
```
# SDK Features
@@ -4567,15 +4569,14 @@ const aliceMessagesBob = await userAlice.chat.send(bobAddress, {
});
```
-| Param | Type | Default | Remarks |
-| ---------------------- | ---------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------- |
-| `recipient` | `string` | - | Recipient ( For Group Chats target is chatId, for 1 To 1 chat target is Push DID ) |
-| `options` | `object` | - | Configuration for message to be sent |
-| `options.type` \* | `Text` or `Image` or `File` or `MediaEmbed` or `GIF` or `Meta` or `Reaction` | - | Type of message Content |
-| `options.content` | `string` | - | Message Content |
-| `options.action` \* | `string` | - | Message action ( Only available for Meta & Reaction Messages ) |
-| `options.reference` \* | `string` or `null` | - | Message reference hash ( Only available for Reaction Messages ) |
-| `options.info` \* | `{ affected : string[]: arbitrary?: { [key: string]: any } }` | - | Message reference hash ( Only available for Meta Messages ) |
+| Param | Type | Default | Remarks |
+| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------- |
+| `recipient` | `string` | - | Recipient ( For Group Chats target is chatId, for 1 To 1 chat target is Push DID ) |
+| `options` | `object` | - | Configuration for message to be sent |
+| `options.type` \* | `Text` or `Image` or `Audio` or `Video` or `File` or `MediaEmbed` or `GIF` or `Meta` or `Reaction` or `Receipt` or `Intent` or `Reply` or `Composite` | - | Type of message Content |
+| `options.content` | `string` or `{type: `Text`or`Image`or`Audio`or`Video`or`File`or`MediaEmbed`or`GIF` ; content: string}` [For Reply] or `{type: `Text`or`Image`or`Audio`or`Video`or`File`or`MediaEmbed`or`GIF` ; content: string}[]` [For Composite] | - | Message Content |
+| `options.reference` \* | `string` | - | Message reference hash ( Only available for Reaction & Reply Messages ) |
+| `options.info` \* | `{ affected : string[]: arbitrary?: { [key: string]: any } }` | - | Message reference hash ( Only available for Meta & UserActivity Messages ) |
\* - Optional
diff --git a/packages/restapi/src/lib/chat/send.ts b/packages/restapi/src/lib/chat/send.ts
index 30a396495..095f0fa73 100644
--- a/packages/restapi/src/lib/chat/send.ts
+++ b/packages/restapi/src/lib/chat/send.ts
@@ -11,16 +11,8 @@ import {
import { conversationHash } from './conversationHash';
import { ISendMessagePayload, sendMessagePayload } from './helpers';
import { getGroup } from './getGroup';
-import {
- MessageObj,
- REACTION_SYMBOL,
- ReactionMessage,
-} from '../types/messageTypes';
-import {
- messageObjSchema,
- metaMessageObjSchema,
- reationMessageObjSchema,
-} from '../validations/messageObject';
+import { MessageObj } from '../types/messageTypes';
+import { validateMessageObj } from '../validations/messageObject';
/**
* SENDS A PUSH CHAT MESSAGE
@@ -54,14 +46,18 @@ export const send = async (
})
: null;
- // OVERRIDE CONTENT FOR REACTION MESSAGE
- if (messageType === MessageType.REACTION) {
- messageObj.content =
- REACTION_SYMBOL[(messageObj as Omit).action];
+ // Not supported by legacy sdk versions, need to override messageContent to avoid parsing errors on legacy sdk versions
+ let messageContent: string;
+ if (
+ messageType === MessageType.REPLY ||
+ messageType === MessageType.COMPOSITE
+ ) {
+ messageContent =
+ 'MessageType Not Supported by this sdk version. Plz upgrade !!!';
+ } else {
+ messageContent = messageObj.content as string;
}
- const messageContent = messageObj.content; // provide backward compatibility & override deprecated field
-
const conversationResponse = await conversationHash({
conversationId: receiver,
account: sender.did,
@@ -138,36 +134,7 @@ const validateOptions = async (options: ComputedOptionsType) => {
}
}
- if (
- messageType === MessageType.TEXT ||
- messageType === MessageType.IMAGE ||
- messageType === MessageType.FILE ||
- messageType === MessageType.MEDIA_EMBED ||
- messageType === MessageType.GIF
- ) {
- const { error } = messageObjSchema.validate(messageObj);
- if (error) {
- throw new Error(
- `Unable to parse this messageType. Please ensure 'messageObj' is properly defined.`
- );
- }
- }
-
- if (messageType === MessageType.META) {
- const { error } = metaMessageObjSchema.validate(messageObj);
- if (error) {
- throw new Error(
- `Unable to parse this messageType. Please ensure 'messageObj' is properly defined.`
- );
- }
- } else if (messageType === MessageType.REACTION) {
- const { error } = reationMessageObjSchema.validate(messageObj);
- if (error) {
- throw new Error(
- `Unable to parse this messageType. Please ensure 'messageObj' is properly defined.`
- );
- }
- }
+ validateMessageObj(messageObj, messageType);
};
const computeOptions = (options: ChatSendOptionsType): ComputedOptionsType => {
@@ -203,6 +170,36 @@ const computeOptions = (options: ChatSendOptionsType): ComputedOptionsType => {
messageObj = rest;
}
+ // Parse Reply Message
+ if (messageType === MessageType.REPLY) {
+ if (typeof messageObj.content === 'object') {
+ const { type, ...rest } = messageObj.content;
+ messageObj.content = {
+ messageType: type,
+ messageObj: rest,
+ };
+ } else {
+ throw new Error('Options.message is not properly defined for Reply');
+ }
+ }
+
+ // Parse Composite Message
+ if (messageType === MessageType.COMPOSITE) {
+ if (messageObj.content instanceof Array) {
+ messageObj.content = messageObj.content.map(
+ (obj: { type: string; content: string }) => {
+ const { type, ...rest } = obj;
+ return {
+ messageType: type,
+ messageObj: rest,
+ };
+ }
+ );
+ } else {
+ throw new Error('Options.message is not properly defined for Composite');
+ }
+ }
+
const account = options.account !== undefined ? options.account : null;
const to = options.to !== undefined ? options.to : options.receiverAddress;
diff --git a/packages/restapi/src/lib/config.ts b/packages/restapi/src/lib/config.ts
index e597c22bc..36f9e6ddc 100644
--- a/packages/restapi/src/lib/config.ts
+++ b/packages/restapi/src/lib/config.ts
@@ -39,9 +39,11 @@ const BLOCKCHAIN_NETWORK = {
OPTIMISM_MAINNET: 'eip155:10',
POLYGON_ZK_EVM_TESTNET: 'eip155:1442',
POLYGON_ZK_EVM_MAINNET: 'eip155:1101',
+ ARBITRUM_TESTNET: 'eip155:421613',
+ ARBITRUMONE_MAINNET: "eip155:42161"
};
-export type ALIAS_CHAIN = 'POLYGON' | 'BSC' | 'OPTIMISM' | 'POLYGONZKEVM';
+export type ALIAS_CHAIN = 'POLYGON' | 'BSC' | 'OPTIMISM' | 'POLYGONZKEVM' | "ARBITRUMONE";
export const ETH_CHAIN_ID = {
[ENV.PROD]: 1,
@@ -74,6 +76,12 @@ export const ALIAS_CHAIN_ID = {
[ENV.DEV]: 1442,
[ENV.LOCAL]: 1442,
},
+ ARBITRUMONE: {
+ [ENV.PROD]: 42161,
+ [ENV.STAGING]: 421613,
+ [ENV.DEV]: 421613,
+ [ENV.LOCAL]: 421613,
+ }
};
export const CHAIN_ID = {
@@ -168,6 +176,10 @@ const CONFIG = {
API_BASE_URL: API_BASE_URL[ENV.PROD],
EPNS_COMMUNICATOR_CONTRACT: '0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa',
},
+ [BLOCKCHAIN_NETWORK.ARBITRUMONE_MAINNET]: {
+ API_BASE_URL: API_BASE_URL[ENV.PROD],
+ EPNS_COMMUNICATOR_CONTRACT: '0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa',
+ },
},
[ENV.STAGING]: {
[BLOCKCHAIN_NETWORK.ETH_GOERLI]: {
@@ -190,6 +202,10 @@ const CONFIG = {
API_BASE_URL: API_BASE_URL[ENV.STAGING],
EPNS_COMMUNICATOR_CONTRACT: '0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa',
},
+ [BLOCKCHAIN_NETWORK.ARBITRUM_TESTNET]: {
+ API_BASE_URL: API_BASE_URL[ENV.STAGING],
+ EPNS_COMMUNICATOR_CONTRACT: '0xb3971BCef2D791bc4027BbfedFb47319A4AAaaAa',
+ },
},
[ENV.DEV]: {
[BLOCKCHAIN_NETWORK.ETH_GOERLI]: {
@@ -212,6 +228,10 @@ const CONFIG = {
API_BASE_URL: API_BASE_URL[ENV.DEV],
EPNS_COMMUNICATOR_CONTRACT: '0x630b152e4185c63D7177c656b56b26f878C61572',
},
+ [BLOCKCHAIN_NETWORK.ARBITRUM_TESTNET]: {
+ API_BASE_URL: API_BASE_URL[ENV.STAGING],
+ EPNS_COMMUNICATOR_CONTRACT: '0x2f6aE0907116A2c50D712e78b48D874fadeB6850',
+ },
},
[ENV.LOCAL]: {
[BLOCKCHAIN_NETWORK.ETH_GOERLI]: {
@@ -234,6 +254,10 @@ const CONFIG = {
API_BASE_URL: API_BASE_URL[ENV.DEV],
EPNS_COMMUNICATOR_CONTRACT: '0x630b152e4185c63D7177c656b56b26f878C61572',
},
+ [BLOCKCHAIN_NETWORK.ARBITRUM_TESTNET]: {
+ API_BASE_URL: API_BASE_URL[ENV.STAGING],
+ EPNS_COMMUNICATOR_CONTRACT: '0x2f6aE0907116A2c50D712e78b48D874fadeB6850',
+ },
},
};
diff --git a/packages/restapi/src/lib/constants.ts b/packages/restapi/src/lib/constants.ts
index 4735b547a..94d46f3d4 100644
--- a/packages/restapi/src/lib/constants.ts
+++ b/packages/restapi/src/lib/constants.ts
@@ -27,21 +27,20 @@ export enum ENCRYPTION_TYPE {
export enum MessageType {
TEXT = 'Text',
IMAGE = 'Image',
+ VIDEO = 'Video',
+ AUDIO = 'Audio',
FILE = 'File',
+ /** @deprecated - Use `MediaEmbed` Instead */
+ GIF = 'GIF',
MEDIA_EMBED = 'MediaEmbed',
META = 'Meta',
REACTION = 'Reaction',
- /**
- * @deprecated - Use MediaEmbed Instead
- */
- GIF = 'GIF',
-
- // TODO
- // AUDIO = 'Audio',
- // VIDEO = 'Video',
- // PAYMENT = 'Payment',
- // REPLY = 'Reply',
- // COMPOSITE = 'Composite',
+ RECEIPT = 'Receipt',
+ USER_ACTIVITY = 'UserActivity',
+ INTENT = 'Intent',
+ REPLY = 'Reply',
+ COMPOSITE = 'Composite',
+ PAYMENT = 'Payment',
}
const Constants = {
@@ -55,7 +54,7 @@ const Constants = {
},
DEFAULT_CHAIN_ID: 5,
DEV_CHAIN_ID: 99999,
- NON_ETH_CHAINS: [137, 80001, 56, 97, 10, 420, 1442, 1101],
+ NON_ETH_CHAINS: [137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161],
ETH_CHAINS: [1, 5],
ENC_TYPE_V1: 'x25519-xsalsa20-poly1305',
ENC_TYPE_V2: 'aes256GcmHkdfSha256',
diff --git a/packages/restapi/src/lib/payloads/constants.ts b/packages/restapi/src/lib/payloads/constants.ts
index a3c5d9a41..da01fafc7 100644
--- a/packages/restapi/src/lib/payloads/constants.ts
+++ b/packages/restapi/src/lib/payloads/constants.ts
@@ -13,6 +13,8 @@ export const CHAIN_ID_TO_SOURCE: ChainIdToSourceType = {
420: 'OPTIMISM_TESTNET',
1442: 'POLYGON_ZK_EVM_TESTNET',
1101: 'POLYGON_ZK_EVM_MAINNET',
+ 421613: "ARBITRUM_TESTNET",
+ 42161: "ARBITRUMONE_MAINNET"
};
export const SOURCE_TYPES = {
@@ -26,6 +28,8 @@ export const SOURCE_TYPES = {
OPTIMISM_TESTNET: 'OPTIMISM_TESTNET',
POLYGON_ZK_EVM_TESTNET: 'POLYGON_ZK_EVM_TESTNET',
POLYGON_ZK_EVM_MAINNET: 'POLYGON_ZK_EVM_MAINNET',
+ ARBITRUM_TESTNET: "ARBITRUM_TESTNET",
+ ARBITRUMONE_MAINNET: "ARBITRUMONE_MAINNET",
THE_GRAPH: 'THE_GRAPH',
PUSH_VIDEO: 'PUSH_VIDEO',
};
diff --git a/packages/restapi/src/lib/payloads/helpers.ts b/packages/restapi/src/lib/payloads/helpers.ts
index 6b7016feb..1863ed1ca 100644
--- a/packages/restapi/src/lib/payloads/helpers.ts
+++ b/packages/restapi/src/lib/payloads/helpers.ts
@@ -321,7 +321,7 @@ export function getSource(
export function getCAIPFormat(chainId: number, address: string) {
// EVM based chains
- if ([1, 5, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101].includes(chainId)) {
+ if ([1, 5, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161].includes(chainId)) {
return `eip155:${chainId}:${address}`;
}
diff --git a/packages/restapi/src/lib/space/Space.ts b/packages/restapi/src/lib/space/Space.ts
index 7ddd78b27..a466da5fb 100644
--- a/packages/restapi/src/lib/space/Space.ts
+++ b/packages/restapi/src/lib/space/Space.ts
@@ -29,7 +29,7 @@ import {
} from '../types';
import { VIDEO_CALL_TYPE } from '../payloads/constants';
import sendLiveSpaceData from './helpers/sendLiveSpaceData';
-import { META_ACTION } from '../types/messageTypes';
+import { CHAT } from '../types/messageTypes';
import { broadcastRaisedHand } from './broadcastRaisedHand';
import { onReceiveMetaMessage } from './onReceiveMetaMessage';
import { onJoinListener } from './onJoinListener';
@@ -157,7 +157,7 @@ export class Space extends Video {
env: this.env,
spaceId: this.spaceSpecificData.spaceId,
signer: this.signer,
- action: META_ACTION.PROMOTE_TO_ADMIN, // TODO: Add a meta action for SPEAKER_JOINED
+ action: CHAT.META.GROUP.ADMIN.PRVILEGE, // TODO: Add a meta action for SPEAKER_JOINED
});
}
},
diff --git a/packages/restapi/src/lib/space/broadcastRaisedHand.ts b/packages/restapi/src/lib/space/broadcastRaisedHand.ts
index db2c0b1c9..d90b706e8 100644
--- a/packages/restapi/src/lib/space/broadcastRaisedHand.ts
+++ b/packages/restapi/src/lib/space/broadcastRaisedHand.ts
@@ -1,6 +1,6 @@
import { produce } from 'immer';
import sendLiveSpaceData from './helpers/sendLiveSpaceData';
-import { META_ACTION } from '../types/messageTypes';
+import { CHAT } from '../types/messageTypes';
import { pCAIP10ToWallet } from '../helpers';
import type Space from './Space';
@@ -41,6 +41,6 @@ export async function broadcastRaisedHand(
env: this.env,
spaceId: this.spaceSpecificData.spaceId,
signer: this.signer,
- action: META_ACTION.USER_INTERACTION,
+ action: CHAT.META.GROUP.USER.INTERACTION,
});
}
diff --git a/packages/restapi/src/lib/space/helpers/getLiveSpaceData.ts b/packages/restapi/src/lib/space/helpers/getLiveSpaceData.ts
index 4d3f952a4..7f8896b00 100644
--- a/packages/restapi/src/lib/space/helpers/getLiveSpaceData.ts
+++ b/packages/restapi/src/lib/space/helpers/getLiveSpaceData.ts
@@ -1,7 +1,7 @@
import { conversationHash, history } from '../../chat';
import { MessageType } from '../../constants';
import { EnvOptionsType, LiveSpaceData } from '../../types';
-import { MetaMessage } from '../../types/messageTypes';
+import { InfoMessage } from '../../types/messageTypes';
import { initLiveSpaceData } from '../Space';
interface GetLatestMessageType extends EnvOptionsType {
@@ -54,7 +54,7 @@ const getLiveSpaceData = async ({
latestMetaMessage.messageObj !== null
) {
// found the latest meta message
- liveSpaceData = (latestMetaMessage.messageObj as Omit)
+ liveSpaceData = (latestMetaMessage.messageObj as Omit)
?.info?.arbitrary as LiveSpaceData;
}
diff --git a/packages/restapi/src/lib/space/helpers/sendLiveSpaceData.ts b/packages/restapi/src/lib/space/helpers/sendLiveSpaceData.ts
index 78cb59fb1..099eed844 100644
--- a/packages/restapi/src/lib/space/helpers/sendLiveSpaceData.ts
+++ b/packages/restapi/src/lib/space/helpers/sendLiveSpaceData.ts
@@ -1,11 +1,10 @@
import { send } from '../../chat';
import { MessageType } from '../../constants';
import { EnvOptionsType, LiveSpaceData, SignerType } from '../../types';
-import { META_ACTION } from '../../types/messageTypes';
interface SendLiveSpaceData extends EnvOptionsType {
liveSpaceData?: LiveSpaceData;
- action: META_ACTION;
+ action: string;
spaceId: string;
pgpPrivateKey: string;
signer: SignerType;
@@ -26,8 +25,7 @@ const sendLiveSpaceData = async ({
signer,
messageType: MessageType.META,
messageObj: {
- content: 'PUSH SPACE META MESSAGE',
- action,
+ content: action,
info: {
affected: [],
arbitrary: liveSpaceData,
diff --git a/packages/restapi/src/lib/space/onJoinListener.ts b/packages/restapi/src/lib/space/onJoinListener.ts
index 30db1c4dd..72aa30c68 100644
--- a/packages/restapi/src/lib/space/onJoinListener.ts
+++ b/packages/restapi/src/lib/space/onJoinListener.ts
@@ -3,7 +3,7 @@ import { get } from './get';
import { pCAIP10ToWallet } from '../helpers';
import { produce } from 'immer';
-import { META_ACTION } from '../types/messageTypes';
+import { CHAT } from '../types/messageTypes';
import type Space from './Space';
export interface OnJoinListenerType {
@@ -43,11 +43,12 @@ export async function onJoinListener(this: Space, options: OnJoinListenerType) {
const modifiedLiveSpaceData = produce(
this.spaceSpecificData.liveSpaceData,
(draft) => {
- const isListenerAlreadyAdded = this.spaceSpecificData.liveSpaceData.listeners.find(
- (currentListener) =>
- pCAIP10ToWallet(currentListener.address) ===
- pCAIP10ToWallet(receivedAddress)
- );
+ const isListenerAlreadyAdded =
+ this.spaceSpecificData.liveSpaceData.listeners.find(
+ (currentListener) =>
+ pCAIP10ToWallet(currentListener.address) ===
+ pCAIP10ToWallet(receivedAddress)
+ );
if (isListenerAlreadyAdded) {
// listener is already added in the meta message
@@ -75,6 +76,6 @@ export async function onJoinListener(this: Space, options: OnJoinListenerType) {
env: this.env,
signer: this.signer,
liveSpaceData: modifiedLiveSpaceData,
- action: META_ACTION.ADD_LISTENER,
+ action: CHAT.META.SPACE.LISTENER.ADD,
});
}
diff --git a/packages/restapi/src/lib/space/onReceiveMetaMessage.ts b/packages/restapi/src/lib/space/onReceiveMetaMessage.ts
index f6b6ae24c..800511e31 100644
--- a/packages/restapi/src/lib/space/onReceiveMetaMessage.ts
+++ b/packages/restapi/src/lib/space/onReceiveMetaMessage.ts
@@ -1,6 +1,6 @@
import { MessageType } from '../constants';
import { IMessageIPFS, LiveSpaceData } from '../types';
-import { MetaMessage } from '../types/messageTypes';
+import { InfoMessage } from '../types/messageTypes';
import type Space from './Space';
export interface OnReceiveMetaMessageType {
@@ -18,14 +18,14 @@ export function onReceiveMetaMessage(
if (
receivedMetaMessage.messageType !== MessageType.META ||
typeof receivedMetaMessage.messageObj !== 'object' ||
- !(receivedMetaMessage?.messageObj as Omit)?.info
+ !(receivedMetaMessage?.messageObj as Omit)?.info
?.arbitrary
) {
return;
}
const receivedLiveSpaceData = (
- receivedMetaMessage.messageObj as Omit
+ receivedMetaMessage.messageObj as Omit
).info.arbitrary as LiveSpaceData;
console.log('RECEIVED LIVE SPACE DATA', receivedLiveSpaceData);
diff --git a/packages/restapi/src/lib/space/rejectPromotionRequest.ts b/packages/restapi/src/lib/space/rejectPromotionRequest.ts
index 3fb45154b..f2be499e9 100644
--- a/packages/restapi/src/lib/space/rejectPromotionRequest.ts
+++ b/packages/restapi/src/lib/space/rejectPromotionRequest.ts
@@ -1,6 +1,6 @@
import { produce } from 'immer';
import sendLiveSpaceData from './helpers/sendLiveSpaceData';
-import { META_ACTION } from '../types/messageTypes';
+import { CHAT } from '../types/messageTypes';
import { pCAIP10ToWallet } from '../helpers';
import type Space from './Space';
@@ -41,6 +41,6 @@ export async function rejectPromotionRequest(
env: this.env,
spaceId: this.spaceSpecificData.spaceId,
signer: this.signer,
- action: META_ACTION.USER_INTERACTION, // TODO: Add a reject request type
+ action: CHAT.META.GROUP.USER.INTERACTION, // TODO: Add a reject request type
});
}
diff --git a/packages/restapi/src/lib/space/start.ts b/packages/restapi/src/lib/space/start.ts
index 23ac20bc9..5fd42f966 100644
--- a/packages/restapi/src/lib/space/start.ts
+++ b/packages/restapi/src/lib/space/start.ts
@@ -24,7 +24,7 @@ export interface StartSpaceType extends EnvOptionsType {
import type Space from './Space';
import { produce } from 'immer';
import { pCAIP10ToWallet } from '../helpers';
-import { META_ACTION } from '../types/messageTypes';
+import { CHAT } from '../types/messageTypes';
import sendLiveSpaceData from './helpers/sendLiveSpaceData';
type StartType = {
@@ -94,7 +94,7 @@ export async function start(this: Space): Promise {
await sendLiveSpaceData({
liveSpaceData,
- action: META_ACTION.CREATE_SPACE,
+ action: CHAT.META.SPACE.CREATE,
spaceId: this.spaceSpecificData.spaceId,
signer: this.signer,
pgpPrivateKey: this.pgpPrivateKey,
diff --git a/packages/restapi/src/lib/types/messageTypes.ts b/packages/restapi/src/lib/types/messageTypes.ts
index 49f4d986a..634121784 100644
--- a/packages/restapi/src/lib/types/messageTypes.ts
+++ b/packages/restapi/src/lib/types/messageTypes.ts
@@ -3,67 +3,92 @@
*/
import { MessageType } from '../constants';
-export enum META_ACTION {
- /**
- * DEFAULT GROUP ACTIONS
- */
- CREATE_GROUP = 1,
- ADD_MEMBER = 2,
- REMOVE_MEMBER = 3,
- PROMOTE_TO_ADMIN = 4,
- DEMOTE_FROM_ADMIN = 5,
- /**
- * SHARED ACTIONS
- */
- CHANGE_IMAGE_OR_DESC = 6,
- CHANGE_META = 7,
- /**
- * SPACES ACTIONS
- */
- CREATE_SPACE = 8,
- ADD_LISTENER = 9,
- REMOVE_LISTENER = 10,
- PROMOTE_TO_SPEAKER = 11,
- DEMOTE_FROM_SPEARKER = 12,
- PROMOTE_TO_COHOST = 13,
- DEMOTE_FROM_COHOST = 14,
- USER_INTERACTION = 15, // For MIC_ON | MIC_OFF | RAISE_HAND | EMOJI REACTION | or any other user activity
-}
+export const CHAT = {
+ META: {
+ GROUP: {
+ CREATE: 'CREATE_GROUP',
+ MEMBER: {
+ ADD: 'ADD_MEMBER',
+ REMOVE: 'REMOVE_MEMBER',
+ PRIVILEGE: 'ASSIGN_MEMBER_PRIVILEGE',
+ },
+ ADMIN: {
+ PRVILEGE: 'ASSIGN_ADMIN_PRIVILEGE',
+ },
+ // todo: Why do we need update group when we already have profile and meta update
+ UPDATE: 'UPDATE_GROUP',
+ PROFILE: {
+ UPDATE: 'UPDATE_GROUP_PROFILE',
+ },
+ // todo : this seems to be a wierd name CHAT.META.GROUP.META.UPDATE
+ META: {
+ UPDATE: 'UPDATE_GROUP_META',
+ },
+ // todo : Remove this as it comes under UserActivity now ( remove after space changes )
+ USER: {
+ INTERACTION: 'USER_INTERACTION',
+ },
+ },
+ SPACE: {
+ CREATE: 'CREATE_SPACE',
+ LISTENER: {
+ ADD: 'ADD_LISTENER',
+ REMOVE: 'REMOVE_LISTENER',
+ PRVILEGE: 'ASSIGN_LISTENER_PRIVILEGE',
+ },
+ SPEAKER: {
+ PRVILEGE: 'ASSIGN_SPEAKER_PRIVILEGE',
+ },
+ COHOST: {
+ PRVILEGE: 'ASSIGN_COHOST_PRIVILEGE',
+ },
+ },
+ },
-export enum REACTION_TYPE {
- THUMBS_UP,
- THUMBS_DOWN,
- HEART,
- CLAP,
- LAUGHING_FACE,
- SAD_FACE,
- ANGRY_FACE,
- SURPRISED_FACE,
- CLAPPING_HANDS,
- FIRE,
-}
+ REACTION: {
+ THUMBSUP: '\u{1F44D}',
+ THUMBSDOWN: '\u{1F44E}',
+ HEART: '\u{2764}\u{FE0F}',
+ CLAP: '\u{1F44F}',
+ LAUGH: '\u{1F602}',
+ SAD: '\u{1F622}',
+ ANGRY: '\u{1F621}',
+ SUPRISE: '\u{1F632}',
+ FIRE: '\u{1F525}',
+ },
+
+ RECEIPT: {
+ READ: 'READ_RECEIPT',
+ },
-// Create a mapping object that associates reaction types with their Unicode escape sequences
-export const REACTION_SYMBOL: Record = {
- [REACTION_TYPE.THUMBS_UP]: '\u{1F44D}',
- [REACTION_TYPE.THUMBS_DOWN]: '\u{1F44E}',
- [REACTION_TYPE.HEART]: '\u{2764}\u{FE0F}',
- [REACTION_TYPE.CLAP]: '\u{1F44F}',
- [REACTION_TYPE.LAUGHING_FACE]: '\u{1F602}',
- [REACTION_TYPE.SAD_FACE]: '\u{1F622}',
- [REACTION_TYPE.ANGRY_FACE]: '\u{1F621}',
- [REACTION_TYPE.SURPRISED_FACE]: '\u{1F632}',
- [REACTION_TYPE.CLAPPING_HANDS]: '\u{1F44F}\u{1F44F}',
- [REACTION_TYPE.FIRE]: '\u{1F525}',
+ UA: {
+ LISTENER: {
+ JOIN: 'LISTENER_JOIN',
+ LEAVE: 'LISTENER_LEAVE',
+ MICREQUEST: 'LISTENER_REQUEST_MIC',
+ },
+ SPEAKER: {
+ MIC_ON: 'SPEAKER_MIC_ON',
+ MIC_OFF: 'SPEAKER_MIC_OFF',
+ },
+ },
+
+ INTENT: {
+ ACCEPT: 'ACCEPT_INTENT',
+ REJECT: 'REJECT_INTENT',
+ JOIN: 'JOIN_GROUP',
+ LEAVE: 'LEAVE_GROUP',
+ },
};
-export interface BaseMessage {
+interface BaseMessage {
type?: T;
content: string;
}
-export interface MetaMessage extends BaseMessage<`${MessageType.META}`> {
- action: META_ACTION;
+// Used by MessageType.Meta & MessageType.USER_ACTIVITY
+export interface InfoMessage
+ extends BaseMessage<`${MessageType.META}` | `${MessageType.USER_ACTIVITY}`> {
info: {
affected: string[];
arbitrary?: {
@@ -72,28 +97,53 @@ export interface MetaMessage extends BaseMessage<`${MessageType.META}`> {
};
}
-export interface ReactionMessage
- extends BaseMessage<`${MessageType.REACTION}`> {
- action: REACTION_TYPE;
- reference?: string | null;
+interface ReferenceMessage
+ extends BaseMessage<`${MessageType.REACTION}` | `${MessageType.RECEIPT}`> {
+ reference: string;
+}
+
+interface ReplyMessage {
+ type: `${MessageType.REPLY}`;
+ /** Only Few BaseMessageTypes are allowed, this can be changed in the future */
+ content: {
+ type: string;
+ content: string;
+ };
+ reference: string;
+}
+
+interface CompositeMessage {
+ type: `${MessageType.COMPOSITE}`;
+ /** Only Few BaseMessageTypes are allowed, this can be changed in the future */
+ content: {
+ type: string;
+ content: string;
+ }[];
}
-export type BaseMessageTypes =
+type BaseMessageTypes =
| `${MessageType.TEXT}`
| `${MessageType.IMAGE}`
+ | `${MessageType.VIDEO}`
+ | `${MessageType.AUDIO}`
| `${MessageType.FILE}`
+ | `${MessageType.GIF}`
| `${MessageType.MEDIA_EMBED}`
- | `${MessageType.GIF}`;
+ | `${MessageType.INTENT}`;
export type Message =
| BaseMessage
- | MetaMessage
- | ReactionMessage;
+ | InfoMessage
+ | ReferenceMessage
+ | ReplyMessage
+ | CompositeMessage;
/**
* @deprecated
*/
export type MessageObj =
| Omit, 'type'>
- | Omit
- | Omit;
+ | Omit
+ | Omit
+ | Omit
+ | Omit;
diff --git a/packages/restapi/src/lib/validations/messageObject.ts b/packages/restapi/src/lib/validations/messageObject.ts
index 6057d12d5..d40382126 100644
--- a/packages/restapi/src/lib/validations/messageObject.ts
+++ b/packages/restapi/src/lib/validations/messageObject.ts
@@ -1,14 +1,26 @@
import * as Joi from 'joi';
-import { META_ACTION, REACTION_TYPE } from '../types/messageTypes';
+import { CHAT, MessageObj } from '../types/messageTypes';
+import { MessageType } from '../constants';
-export const messageObjSchema = Joi.object({
+const extractValidValues = (obj: any): string[] => {
+ const validValues: string[] = [];
+ for (const key in obj) {
+ if (typeof obj[key] === 'string') {
+ validValues.push(obj[key]);
+ } else if (typeof obj[key] === 'object') {
+ validValues.push(...extractValidValues(obj[key]));
+ }
+ }
+ return validValues;
+};
+
+const messageObjSchema = Joi.object({
content: Joi.string().required().allow(''),
});
-export const metaMessageObjSchema = Joi.object({
- content: Joi.string().required().allow(''),
- action: Joi.number()
- .valid(...Object.values(META_ACTION))
+const metaMessageObjSchema = Joi.object({
+ content: Joi.string()
+ .valid(...Object.values(extractValidValues(CHAT.META)))
.required(),
info: Joi.object({
affected: Joi.array().items(Joi.string()).required(),
@@ -16,10 +28,133 @@ export const metaMessageObjSchema = Joi.object({
}).required(),
});
-export const reationMessageObjSchema = Joi.object({
- content: Joi.string().required().allow(''),
- action: Joi.number()
- .valid(...Object.values(REACTION_TYPE))
+const reationMessageObjSchema = Joi.object({
+ content: Joi.string()
+ .valid(...Object.values(extractValidValues(CHAT.REACTION)))
+ .required(),
+ reference: Joi.string().required(),
+});
+
+const receiptMessageObjSchema = Joi.object({
+ content: Joi.string()
+ .valid(...Object.values(extractValidValues(CHAT.RECEIPT)))
.required(),
- reference: Joi.string().allow(null),
+ reference: Joi.string().required(),
});
+
+const userActivityMessageObjSchema = Joi.object({
+ content: Joi.string()
+ .valid(...Object.values(extractValidValues(CHAT.UA)))
+ .required(),
+ info: Joi.object({
+ affected: Joi.array().items(Joi.string()).required(),
+ arbitrary: Joi.object().pattern(Joi.string(), Joi.any()),
+ }).required(),
+});
+
+const intentMessageObjSchema = Joi.object({
+ content: Joi.string().valid(
+ ...Object.values(extractValidValues(CHAT.INTENT))
+ ),
+});
+
+const replyMessageObjSchema = Joi.object({
+ content: Joi.object({
+ messageType: Joi.string()
+ .valid(
+ ...Object.values([
+ MessageType.TEXT,
+ MessageType.IMAGE,
+ MessageType.AUDIO,
+ MessageType.VIDEO,
+ MessageType.FILE,
+ MessageType.MEDIA_EMBED,
+ ])
+ )
+ .required(),
+ messageObj: Joi.object({
+ content: Joi.string().required(), // Change the validation as needed
+ }).required(),
+ }).required(),
+ reference: Joi.string().required(),
+});
+
+const compositeMessageObjSchema = Joi.object({
+ content: Joi.array()
+ .items(
+ Joi.object({
+ messageType: Joi.string()
+ .valid(
+ ...Object.values([
+ MessageType.TEXT,
+ MessageType.IMAGE,
+ MessageType.AUDIO,
+ MessageType.VIDEO,
+ MessageType.FILE,
+ MessageType.MEDIA_EMBED,
+ ])
+ )
+ .required(),
+ messageObj: Joi.object({
+ content: Joi.string().required(),
+ }).required(),
+ })
+ )
+ .required(),
+});
+
+export const validateMessageObj = (
+ messageObj: MessageObj,
+ messageType: MessageType
+) => {
+ let error: Joi.ValidationError | undefined = undefined;
+ switch (messageType) {
+ case MessageType.TEXT:
+ case MessageType.IMAGE:
+ case MessageType.VIDEO:
+ case MessageType.AUDIO:
+ case MessageType.FILE:
+ case MessageType.MEDIA_EMBED:
+ case MessageType.GIF: {
+ error = messageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.META: {
+ error = metaMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.REACTION: {
+ error = reationMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.RECEIPT: {
+ error = receiptMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.USER_ACTIVITY: {
+ error = userActivityMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.INTENT: {
+ error = intentMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.REPLY: {
+ error = replyMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ case MessageType.COMPOSITE: {
+ error = compositeMessageObjSchema.validate(messageObj).error;
+ break;
+ }
+ default: {
+ throw new Error('Invalid MessageType');
+ }
+ }
+
+ if (error) {
+ throw new Error(
+ `Unable to parse this messageType. Please ensure 'messageObj' is properly defined.`
+ );
+ }
+};
diff --git a/packages/restapi/tests/lib/chat/createGroup.test.ts b/packages/restapi/tests/lib/chat/createGroup.test.ts
index 5c8db3987..d9ea55a2e 100644
--- a/packages/restapi/tests/lib/chat/createGroup.test.ts
+++ b/packages/restapi/tests/lib/chat/createGroup.test.ts
@@ -127,8 +127,8 @@ const expectGroup = async (
expect(group.members[0].image).to.be.a('string');
expect(group.pendingMembers).to.be.an('array');
expect(group.pendingMembers.length).to.equal(pendingMembers.length);
- expect(group.pendingMembers[0].wallet).to.equal(pendingMembers[0]);
- expect(group.pendingMembers[1].wallet).to.equal(pendingMembers[1]);
+ expect(pendingMembers.includes(group.pendingMembers[0].wallet)).to.be.true;
+ expect(pendingMembers.includes(group.pendingMembers[1].wallet)).to.be.true;
expect(group.groupImage).to.equal(groupImage);
expect(group.groupName).to.equal(groupName);
expect(group.groupDescription).to.equal(groupDescription);
diff --git a/packages/restapi/tests/lib/chat/send.test.ts b/packages/restapi/tests/lib/chat/send.test.ts
index fc3e8d0dd..5aeb21512 100644
--- a/packages/restapi/tests/lib/chat/send.test.ts
+++ b/packages/restapi/tests/lib/chat/send.test.ts
@@ -6,7 +6,7 @@ import { ethers } from 'ethers';
import Constants, { MessageType } from '../../../src/lib/constants';
import { upgrade } from '../../../src/lib/user/upgradeUser';
import { decryptPGPKey } from '../../../src/lib/helpers';
-import { createGroup, send } from '../../../src/lib/chat';
+import { approve, createGroup, send } from '../../../src/lib/chat';
import { MessageWithCID, SignerType } from '../../../src/lib/types';
import { decryptAndVerifyMessage } from '../../../src/lib/chat/helpers';
import {
@@ -15,14 +15,11 @@ import {
colors,
uniqueNamesGenerator,
} from 'unique-names-generator';
-import {
- REACTION_SYMBOL,
- REACTION_TYPE,
-} from '../../../src/lib/types/messageTypes';
+import { CHAT } from '../../../src/lib/types/messageTypes';
chai.use(chaiAsPromised);
const _env = Constants.ENV.DEV;
-describe('PushAPI.chat.send', () => {
+describe.only('PushAPI.chat.send', () => {
const provider = ethers.getDefaultProvider(5);
let _signer1: any;
let walletAddress1: string;
@@ -630,6 +627,232 @@ describe('PushAPI.chat.send', () => {
);
});
});
+ describe('Video Message', () => {
+ const MESSAGE_TYPE = MessageType.VIDEO;
+ const MESSAGE = '{"content":"data:application/mp4;base64,JVBERi0xLjQKJ}';
+ it('should throw error using wrong messageObj', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ action: 1,
+ info: { affected: [] },
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ // Video message was not supported in v1 & v2
+ it('should throw error for deprecated V1', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V2 | EncType - Plaintext', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V3 | EncType - Plaintext', async () => {
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V3 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
+ describe('Audio Message', () => {
+ const MESSAGE_TYPE = MessageType.AUDIO;
+ const MESSAGE = '{"content":"data:application/mp3;base64,JVBERi0xLjQKJ}';
+ it('should throw error using wrong messageObj', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ action: 1,
+ info: { affected: [] },
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ // Audio message was not supported in v1 & v2
+ it('should throw error for deprecated V1', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V2 | EncType - Plaintext', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V3 | EncType - Plaintext', async () => {
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V3 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
describe('File Message', () => {
const MESSAGE_TYPE = MessageType.FILE;
const MESSAGE = '{"content":"data:application/pdf;base64,JVBERi0xLjQKJ}';
@@ -773,8 +996,8 @@ describe('PushAPI.chat.send', () => {
);
});
});
- describe('MediaEmbed Message', () => {
- const MESSAGE_TYPE = MessageType.MEDIA_EMBED;
+ describe('GIF Message', () => {
+ const MESSAGE_TYPE = MessageType.GIF;
const MESSAGE =
'ttps://media1.giphy.com/media/FtlUfrq3pVZXVNjoxf/giphy360p.mp4?cid=ecf05e47jk317254v9hbdjrknemduocie4pf54wtsir98xsx&ep=v1_videos_search&rid=giphy360p.mp4&ct=v';
it('should throw error using wrong messageObj', async () => {
@@ -917,8 +1140,8 @@ describe('PushAPI.chat.send', () => {
);
});
});
- describe('GIF Message', () => {
- const MESSAGE_TYPE = MessageType.GIF;
+ describe('MediaEmbed Message', () => {
+ const MESSAGE_TYPE = MessageType.MEDIA_EMBED;
const MESSAGE =
'ttps://media1.giphy.com/media/FtlUfrq3pVZXVNjoxf/giphy360p.mp4?cid=ecf05e47jk317254v9hbdjrknemduocie4pf54wtsir98xsx&ep=v1_videos_search&rid=giphy360p.mp4&ct=v';
it('should throw error using wrong messageObj', async () => {
@@ -1063,7 +1286,7 @@ describe('PushAPI.chat.send', () => {
});
describe('Meta Message', () => {
const MESSAGE_TYPE = MessageType.META;
- const MESSAGE = 'xyz created group PUSH';
+ const MESSAGE = CHAT.META.GROUP.CREATE;
it('should throw error using messageContent or wrong MessageObject', async () => {
await expect(
send({
@@ -1087,7 +1310,7 @@ describe('PushAPI.chat.send', () => {
await expect(
send({
messageType: MESSAGE_TYPE,
- messageObj: { content: MESSAGE, reference: '' },
+ messageObj: { content: MESSAGE },
messageContent: MESSAGE,
receiverAddress: account2,
signer: _signer1,
@@ -1097,30 +1320,25 @@ describe('PushAPI.chat.send', () => {
await expect(
send({
messageType: MESSAGE_TYPE,
- messageObj: { content: MESSAGE, action: 1 }, // no info provided
+ messageObj: { content: MESSAGE, action: 1 }, // no info
messageContent: MESSAGE,
receiverAddress: account2,
signer: _signer1,
env: _env,
})
).to.be.rejected;
- });
- it('should throw error for non-group', async () => {
await expect(
send({
messageType: MESSAGE_TYPE,
- messageObj: {
- content: MESSAGE,
- action: 1,
- info: { affected: [] },
- },
+ messageObj: { content: MESSAGE, action: 1, info: { affected: [] } }, // action is not allowed
+ messageContent: MESSAGE,
receiverAddress: account2,
signer: _signer1,
env: _env,
})
).to.be.rejected;
});
- it('should throw error for non member of group', async () => {
+ it('should throw error for invalid content', async () => {
const groupName = uniqueNamesGenerator({
dictionaries: [adjectives, colors, animals],
});
@@ -1133,28 +1351,76 @@ describe('PushAPI.chat.send', () => {
const group = await createGroup({
groupName,
groupDescription,
- members: [_nftAccount1, _nftAccount2],
+ members: [_nftAccount1, _nftAccount2, account2],
groupImage,
admins: [], // takes signer as admin automatically, add more if you want to
isPublic: true,
signer: _signer1,
env: _env,
});
+
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ message: {
+ type: MESSAGE_TYPE,
+ content: 'INVALID CONTENT',
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for non-group', async () => {
await expect(
send({
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
- receiverAddress: group.chatId,
- signer: _signer2,
+ receiverAddress: account2,
+ signer: _signer1,
env: _env,
})
).to.be.rejected;
});
- it('should throw error for Non-Admin member of group', async () => {
+ it('should throw error for non member of group', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+ signer: _signer1,
+ env: _env,
+ });
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer2,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for Non-Admin member of group', async () => {
const groupName = uniqueNamesGenerator({
dictionaries: [adjectives, colors, animals],
});
@@ -1179,7 +1445,6 @@ describe('PushAPI.chat.send', () => {
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
receiverAddress: group.chatId,
@@ -1212,7 +1477,6 @@ describe('PushAPI.chat.send', () => {
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
receiverAddress: group.chatId,
@@ -1222,7 +1486,7 @@ describe('PushAPI.chat.send', () => {
await expectMsg(
msg,
MESSAGE_TYPE,
- { content: MESSAGE, action: 1, info: { affected: [] } },
+ { content: MESSAGE, info: { affected: [] } },
account1,
_signer1,
group.chatId,
@@ -1253,7 +1517,6 @@ describe('PushAPI.chat.send', () => {
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
receiverAddress: group.chatId,
@@ -1263,7 +1526,7 @@ describe('PushAPI.chat.send', () => {
await expectMsg(
msg,
MESSAGE_TYPE,
- { content: MESSAGE, action: 1, info: { affected: [] } },
+ { content: MESSAGE, info: { affected: [] } },
account1,
_signer1,
group.chatId,
@@ -1294,7 +1557,6 @@ describe('PushAPI.chat.send', () => {
message: {
type: MESSAGE_TYPE,
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
to: group.chatId,
@@ -1304,7 +1566,7 @@ describe('PushAPI.chat.send', () => {
await expectMsg(
msg,
MESSAGE_TYPE,
- { content: MESSAGE, action: 1, info: { affected: [] } },
+ { content: MESSAGE, info: { affected: [] } },
account1,
_signer1,
group.chatId,
@@ -1335,7 +1597,6 @@ describe('PushAPI.chat.send', () => {
message: {
type: MESSAGE_TYPE,
content: MESSAGE,
- action: 1,
info: { affected: [] },
},
to: group.chatId,
@@ -1345,7 +1606,7 @@ describe('PushAPI.chat.send', () => {
await expectMsg(
msg,
MESSAGE_TYPE,
- { content: MESSAGE, action: 1, info: { affected: [] } },
+ { content: MESSAGE, info: { affected: [] } },
account1,
_signer1,
group.chatId,
@@ -1355,8 +1616,8 @@ describe('PushAPI.chat.send', () => {
});
describe('Reaction Message', () => {
const MESSAGE_TYPE = MessageType.REACTION;
- const MESSAGE = '';
- it('should throw error using messageContent or wrong MessageObject', async () => {
+ const MESSAGE = CHAT.REACTION.CLAP;
+ it('should throw error using messageContent on wrong MessageObject', async () => {
await expect(
send({
messageType: MESSAGE_TYPE,
@@ -1370,12 +1631,175 @@ describe('PushAPI.chat.send', () => {
send({
messageType: MESSAGE_TYPE,
messageObj: { content: MESSAGE },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE, info: { affected: [] } },
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error on wrong content', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: 'Invalid Symbol',
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V1 | EncType - PlainText', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V1 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V2 | EncType - PlainText', async () => {
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ });
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
+ describe('Receipt Message', () => {
+ const MESSAGE_TYPE = MessageType.RECEIPT;
+ const MESSAGE = CHAT.RECEIPT.READ;
+ it('should throw error using messageContent on wrong MessageObject', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
messageContent: MESSAGE,
receiverAddress: account2,
signer: _signer1,
env: _env,
})
).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
await expect(
send({
messageType: MESSAGE_TYPE,
@@ -1387,12 +1811,29 @@ describe('PushAPI.chat.send', () => {
})
).to.be.rejected;
});
+ it('should throw error on wrong content', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: 'Invalid Message Content',
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
it('Deprecated V1 | EncType - PlainText', async () => {
const msg = await send({
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: REACTION_TYPE.THUMBS_UP,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
receiverAddress: walletAddress2,
signer: _signer1,
@@ -1402,8 +1843,9 @@ describe('PushAPI.chat.send', () => {
msg,
MESSAGE_TYPE,
{
- content: REACTION_SYMBOL[REACTION_TYPE.THUMBS_UP], // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL,
- action: REACTION_TYPE.THUMBS_UP,
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
account1,
_signer1,
@@ -1421,7 +1863,8 @@ describe('PushAPI.chat.send', () => {
messageType: MESSAGE_TYPE,
messageObj: {
content: MESSAGE,
- action: REACTION_TYPE.THUMBS_UP,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
receiverAddress: walletAddress2,
signer: _signer1,
@@ -1431,8 +1874,9 @@ describe('PushAPI.chat.send', () => {
msg,
MESSAGE_TYPE,
{
- content: REACTION_SYMBOL[REACTION_TYPE.THUMBS_UP], // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
- action: REACTION_TYPE.THUMBS_UP,
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
account1,
_signer1,
@@ -1445,7 +1889,8 @@ describe('PushAPI.chat.send', () => {
message: {
type: MESSAGE_TYPE,
content: MESSAGE,
- action: REACTION_TYPE.THUMBS_UP,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
to: walletAddress2,
signer: _signer1,
@@ -1455,8 +1900,9 @@ describe('PushAPI.chat.send', () => {
msg,
MESSAGE_TYPE,
{
- content: REACTION_SYMBOL[REACTION_TYPE.THUMBS_UP], // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL,
- action: REACTION_TYPE.THUMBS_UP,
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
account1,
_signer1,
@@ -1474,7 +1920,8 @@ describe('PushAPI.chat.send', () => {
message: {
type: MESSAGE_TYPE,
content: MESSAGE,
- action: REACTION_TYPE.THUMBS_UP,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
to: walletAddress2,
signer: _signer1,
@@ -1484,8 +1931,9 @@ describe('PushAPI.chat.send', () => {
msg,
MESSAGE_TYPE,
{
- content: REACTION_SYMBOL[REACTION_TYPE.THUMBS_UP], // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
- action: REACTION_TYPE.THUMBS_UP,
+ content: MESSAGE, // REACTION OVERRIDES THE MESSAGE CONTENT TO THE SYMBOL
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
},
account1,
_signer1,
@@ -1494,21 +1942,817 @@ describe('PushAPI.chat.send', () => {
);
});
});
-});
+ describe('User Activity Message', () => {
+ const MESSAGE_TYPE = MessageType.USER_ACTIVITY;
+ const MESSAGE = CHAT.UA.LISTENER.JOIN;
+ it('should throw error using messageContent or wrong MessageObject', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE, action: 1 }, // no info
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE, action: 1, info: { affected: [] } }, // action is not allowed
+ messageContent: MESSAGE,
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for invalid content', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
-/**
- * HELPER FUNCTION
- */
-const expectMsg = async (
- msg: MessageWithCID,
- messageType: string,
- content: string | { [key: string]: any },
- sender: string,
- senderSigner: SignerType, // or receiverSigner
- receiver: string,
- encType?: 'PlainText' | 'pgp'
-): Promise => {
- expect(msg.fromDID).to.include(sender);
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2, account2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+ signer: _signer1,
+ env: _env,
+ });
+
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ message: {
+ type: MESSAGE_TYPE,
+ content: 'INVALID CONTENT',
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for non-group', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for non member of group', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+ signer: _signer1,
+ env: _env,
+ });
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer2,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V1 | EncType - PlainText ( Public Grp )', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [account2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+ signer: _signer1,
+ env: _env,
+ });
+ // approve intent
+ await approve({
+ senderAddress: group.chatId,
+ status: 'Approved',
+ account: account2,
+ signer: _signer2,
+ env: _env,
+ });
+ // send message
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer2,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE, info: { affected: [] } },
+ account2,
+ _signer2,
+ group.chatId,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V1 | EncType - pgp ( Private Grp )', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2, account2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: false,
+ signer: _signer1,
+ env: _env,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ receiverAddress: group.chatId,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE, info: { affected: [] } },
+ account1,
+ _signer1,
+ group.chatId,
+ 'pgp'
+ );
+ });
+ it('V2 | EncType - PlainText ( Public Grp )', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2, account2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: true,
+ signer: _signer1,
+ env: _env,
+ });
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ to: group.chatId,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE, info: { affected: [] } },
+ account1,
+ _signer1,
+ group.chatId,
+ 'PlainText'
+ );
+ });
+ it('V2 | EncType - pgp ( Private Grp )', async () => {
+ const groupName = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupDescription = uniqueNamesGenerator({
+ dictionaries: [adjectives, colors, animals],
+ });
+ const groupImage =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAvklEQVR4AcXBsW2FMBiF0Y8r3GQb6jeBxRauYRpo4yGQkMd4A7kg7Z/GUfSKe8703fKDkTATZsJsrr0RlZSJ9r4RLayMvLmJjnQS1d6IhJkwE2bT13U/DBzp5BN73xgRZsJMmM1HOolqb/yWiWpvjJSUiRZWopIykTATZsJs5g+1N6KSMiO1N/5DmAkzYTa9Lh6MhJkwE2ZzSZlo7xvRwson3txERzqJhJkwE2bT6+JhoKTMJ2pvjAgzYSbMfgDlXixqjH6gRgAAAABJRU5ErkJggg==';
+
+ const group = await createGroup({
+ groupName,
+ groupDescription,
+ members: [_nftAccount1, _nftAccount2, account2],
+ groupImage,
+ admins: [], // takes signer as admin automatically, add more if you want to
+ isPublic: false,
+ signer: _signer1,
+ env: _env,
+ });
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ info: { affected: [] },
+ },
+ to: group.chatId,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE, info: { affected: [] } },
+ account1,
+ _signer1,
+ group.chatId,
+ 'pgp'
+ );
+ });
+ });
+ describe('Intent Message', () => {
+ const MESSAGE_TYPE = MessageType.INTENT;
+ const MESSAGE = CHAT.INTENT.ACCEPT;
+ it('should throw error using wrong messageObj', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] }, // not supported for intent
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error using wrong content', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: 'Invalid Message',
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V1 | EncType - Plaintext', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V1 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: { content: MESSAGE },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ MESSAGE,
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V2 | EncType - Plaintext', async () => {
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ message: { type: MESSAGE_TYPE, content: MESSAGE },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ { content: MESSAGE },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
+ describe('Reply Message', () => {
+ const MESSAGE_TYPE = MessageType.REPLY;
+ const MESSAGE = {
+ type: MessageType.TEXT,
+ content: 'Replying to prev message',
+ };
+ it('should throw error using wrong messageObj', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ // Adding content is legacy format is not allowed for reply
+ content: {
+ messageType: MessageType.TEXT,
+ messageObj: {
+ content: 'Hey',
+ },
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error using wrong content', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: 'Invalid Message',
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for unsupported messageType reply', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: {
+ type: MessageType.RECEIPT,
+ content: CHAT.RECEIPT.READ,
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V1 | EncType - Plaintext', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: {
+ messageType: MESSAGE.type,
+ messageObj: { content: MESSAGE.content },
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V1 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: {
+ messageType: MESSAGE.type,
+ messageObj: { content: MESSAGE.content },
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V2 | EncType - Plaintext', async () => {
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: {
+ messageType: MESSAGE.type,
+ messageObj: { content: MESSAGE.content },
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: {
+ messageType: MESSAGE.type,
+ messageObj: { content: MESSAGE.content },
+ },
+ reference:
+ 'bafyreia22girudospfbs3q7t6eelb453rmwsi7shkejwxtwpp57xww6vae',
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
+ describe('Composite Message', () => {
+ const MESSAGE_TYPE = MessageType.COMPOSITE;
+ const MESSAGE = [
+ {
+ type: MessageType.TEXT as string,
+ content: 'Replying to prev message',
+ },
+ ];
+ it('should throw error using wrong messageObj', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ info: { affected: [] }, // not supported for composite
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error using wrong content', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: 'Invalid Message',
+ },
+ receiverAddress: account2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('should throw error for unsupported messageType composite', async () => {
+ await expect(
+ send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: [
+ {
+ type: MessageType.READ_RECEIPT,
+ content: CHAT.READ_RECEIPT,
+ },
+ ],
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ })
+ ).to.be.rejected;
+ });
+ it('Deprecated V1 | EncType - Plaintext', async () => {
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: [
+ {
+ messageType: MESSAGE[0].type,
+ messageObj: { content: MESSAGE[0].content },
+ },
+ ],
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('Deprecated V1 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ messageType: MESSAGE_TYPE,
+ messageObj: {
+ content: MESSAGE,
+ },
+ receiverAddress: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: [
+ {
+ messageType: MESSAGE[0].type,
+ messageObj: { content: MESSAGE[0].content },
+ },
+ ],
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ it('V2 | EncType - Plaintext', async () => {
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: [
+ {
+ messageType: MESSAGE[0].type,
+ messageObj: { content: MESSAGE[0].content },
+ },
+ ],
+ },
+ account1,
+ _signer1,
+ account2,
+ 'PlainText'
+ );
+ });
+ it('V2 | EncType - pgp', async () => {
+ await create({
+ account: account2,
+ env: _env,
+ signer: _signer2,
+ version: Constants.ENC_TYPE_V1,
+ });
+ const msg = await send({
+ message: {
+ type: MESSAGE_TYPE,
+ content: MESSAGE,
+ },
+ to: walletAddress2,
+ signer: _signer1,
+ env: _env,
+ });
+ await expectMsg(
+ msg,
+ MESSAGE_TYPE,
+ {
+ content: [
+ {
+ messageType: MESSAGE[0].type,
+ messageObj: { content: MESSAGE[0].content },
+ },
+ ],
+ },
+ account1,
+ _signer1,
+ account2,
+ 'pgp'
+ );
+ });
+ });
+});
+
+/**
+ * HELPER FUNCTION
+ */
+const expectMsg = async (
+ msg: MessageWithCID,
+ messageType: string,
+ content: string | { [key: string]: any },
+ sender: string,
+ senderSigner: SignerType, // or receiverSigner
+ receiver: string,
+ encType?: 'PlainText' | 'pgp'
+): Promise => {
+ expect(msg.fromDID).to.include(sender);
expect(msg.fromCAIP10).to.include(sender);
expect(msg.toDID).to.include(receiver);
expect(msg.toCAIP10).to.include(receiver);
@@ -1518,6 +2762,9 @@ const expectMsg = async (
expect(msg.sigType).to.equal(msg.verificationProof?.split(':')[0]);
//Backward Compatibility check ( signature signs messageContent and will be diff from vProof )
expect(msg.signature).not.to.equal(msg.verificationProof?.split(':')[1]);
+
+ const unsupportedContent =
+ 'MessageType Not Supported by this sdk version. Plz upgrade !!!';
try {
if (encType && encType === 'pgp') {
throw new Error('Should be encrypted');
@@ -1527,11 +2774,14 @@ const expectMsg = async (
if (typeof content === 'string') {
expect((msg.messageObj as { content: string }).content).to.equal(content);
//Backward Compatibility check
- expect(msg.messageContent).to.equal(content);
+ expect(msg.messageContent).to.be.oneOf([content, unsupportedContent]);
} else {
expect(msg.messageObj).to.eql(content);
//Backward Compatibility check
- expect(msg.messageContent).to.equal((content as any).content);
+ expect(msg.messageContent).to.be.oneOf([
+ (content as any).content,
+ unsupportedContent,
+ ]);
}
} catch (err) {
if (encType && encType === 'PlainText') {
@@ -1557,11 +2807,17 @@ const expectMsg = async (
content
);
//Backward Compatibility check
- expect(decryptedMsg.messageContent).to.equal(content);
+ expect(decryptedMsg.messageContent).to.be.oneOf([
+ content,
+ unsupportedContent,
+ ]);
} else {
expect(decryptedMsg.messageObj).to.eql(content);
//Backward Compatibility check
- expect(decryptedMsg.messageContent).to.equal((content as any).content);
+ expect(decryptedMsg.messageContent).to.be.oneOf([
+ (content as any).content,
+ unsupportedContent,
+ ]);
}
}
};
diff --git a/packages/restapi/tests/lib/chat/updateGroup.test.ts b/packages/restapi/tests/lib/chat/updateGroup.test.ts
index 436c10bd6..5f10b2db5 100644
--- a/packages/restapi/tests/lib/chat/updateGroup.test.ts
+++ b/packages/restapi/tests/lib/chat/updateGroup.test.ts
@@ -179,7 +179,7 @@ const expectGroup = async (
expect(group.pendingMembers).to.be.an('array');
expect(group.pendingMembers.length).to.equal(pendingMembers.length);
for (let i = 0; i < pendingMembers.length; i++) {
- expect(group.pendingMembers[i].wallet).to.equal(pendingMembers[i]);
+ expect(pendingMembers.includes(group.pendingMembers[i].wallet)).to.be.true;
}
expect(group.groupImage).to.equal(groupImage);
expect(group.groupName).to.equal(groupName);
diff --git a/packages/restapi/tests/lib/progressHook/progressHook.test.ts b/packages/restapi/tests/lib/progressHook/progressHook.test.ts
index 3d177985b..4ea5a4155 100644
--- a/packages/restapi/tests/lib/progressHook/progressHook.test.ts
+++ b/packages/restapi/tests/lib/progressHook/progressHook.test.ts
@@ -86,14 +86,7 @@ describe('ProgressHook Tests', () => {
for (let i = 0; i < progressInfo.length - 1; i++) {
expect(progressInfo[i]).to.deep.equal(expectedHooks[i]);
}
- const expectedErrorHook = {
- progressId: 'PUSH-ERROR-00',
- progressTitle: 'Non Specific Error',
- progressInfo:
- '[Push SDK] - API - Error - API create() -: Error: [Push SDK] - API https://backend-dev.epns.io/apis/v2/users/: AxiosError: Request failed with status code 400',
- level: 'ERROR',
- };
- expect(progressInfo[4]).to.deep.equal(expectedErrorHook);
+ expect(progressInfo[4].progressId).to.be.equal('PUSH-ERROR-00');
}
});
it('Decrypt Push Profile Success ProgressHooks', async () => {
diff --git a/packages/uiweb/README.md b/packages/uiweb/README.md
index fe84d77d5..d5f2e96f0 100644
--- a/packages/uiweb/README.md
+++ b/packages/uiweb/README.md
@@ -149,7 +149,7 @@ where
| cta | string | Call To Action Link (given during notification creation) |
| image | string | Any media link (given during notification creation) |
| url | string | Channel Link (given during channel setup) |
-| chainName | string | Can be anyone of the following blockchain networks on which the notification was sent - "ETH_MAINNET", "ETH_TEST_GOERLI", "POLYGON_MAINNET", "POLYGON_TEST_MUMBAI", "BSC_MAINNET, "BSC_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "POLYGON_ZK_EVM_TESTNET", "POLYGON_ZK_EVM_MAINNET", "THE_GRAPH" |
+| chainName | string | Can be anyone of the following blockchain networks on which the notification was sent - "ETH_MAINNET", "ETH_TEST_GOERLI", "POLYGON_MAINNET", "POLYGON_TEST_MUMBAI", "BSC_MAINNET, "BSC_TESTNET", "OPTIMISM_MAINNET", "OPTIMISM_TESTNET", "POLYGON_ZK_EVM_TESTNET", "POLYGON_ZK_EVM_MAINNET", "ARBITRUM_TESTNET", "ARBITRUMONE_MAINNET", "THE_GRAPH" |
| theme | string | 'light' or 'dark' (customization to be given by the dApp) |
| customTheme | INotificationItemTheme | custom theme object for the component |
| isSpam | boolean | whether a spam notification or not |
diff --git a/packages/uiweb/src/lib/components/notification/chainDetails.tsx b/packages/uiweb/src/lib/components/notification/chainDetails.tsx
index ad783c516..403f12c39 100644
--- a/packages/uiweb/src/lib/components/notification/chainDetails.tsx
+++ b/packages/uiweb/src/lib/components/notification/chainDetails.tsx
@@ -7,7 +7,7 @@ import { BSCSvg } from "../../icons/BSCSvg";
import { OptimismSvg } from "../../icons/OptimismSvg";
import { PolygonzkevmSvg } from "../../icons/PolygonzkevmSvg";
import { TheGraphSvg } from "../../icons/TheGraphSvg";
-import { ReactElement } from "react";
+import { ArbitrumSvg } from "../../icons/ArbitrumSvg"
const createSVGIcon = (element:any, chainName: string) => {
return (
@@ -58,5 +58,14 @@ export default {
label: 'POLYGON ZK EVM MAINNET',
icon: createSVGIcon(, 'Polygon ZK EVM Mainnet'),
},
+
+ ARBITRUMONE_MAINNET: {
+ label: 'ARBITRUMONE MAINNET',
+ icon: createSVGIcon(, 'Arbitrum Mainnet'),
+ },
+ ARBITRUM_TESTNET: {
+ label: 'ARBITRUM TESTNET',
+ icon: createSVGIcon(, 'Arbitrum Testnet'),
+ },
THE_GRAPH: { label: 'THE GRAPH', icon: createSVGIcon(, 'The Graph') },
};
diff --git a/packages/uiweb/src/lib/components/notification/index.tsx b/packages/uiweb/src/lib/components/notification/index.tsx
index bcec3907b..8ce4dd911 100644
--- a/packages/uiweb/src/lib/components/notification/index.tsx
+++ b/packages/uiweb/src/lib/components/notification/index.tsx
@@ -34,6 +34,8 @@ export type chainNameType =
| 'OPTIMISM_TESTNET'
| 'POLYGON_ZK_EVM_TESTNET'
| 'POLYGON_ZK_EVM_MAINNET'
+ | 'ARBITRUMONE_MAINNET'
+ | 'ARBITRUM_TESTNET'
| 'THE_GRAPH'
| undefined;
diff --git a/packages/uiweb/src/lib/config/constants.ts b/packages/uiweb/src/lib/config/constants.ts
index b91a48dad..edd9b7cf7 100644
--- a/packages/uiweb/src/lib/config/constants.ts
+++ b/packages/uiweb/src/lib/config/constants.ts
@@ -51,25 +51,30 @@ export const allowedNetworks = {
1, //for ethereum mainnet
137, //for polygon mainnet
56, // for bnb mainnet
- // 10 // for optimism mainnet
+ 10, // for optimism mainnet
+ 42161 // for arbitrum mainnet
],
'dev' : [
5, // for eth goerli
80001, //for mumbai polygon
97, // bnb testnet
- 420 // optimism goerli testnet
+ 420, // optimism goerli testnet
+ 421613 // for arbitrum testnet
],
'staging' : [
// 42, //for kovan
5, // for goerli
80001, //for mumbai polygon
- 97 // bnb testnet
+ 97, // bnb testnet
+ 420, // optimism goerli testnet
+ 421613 // for arbitrum testnet
],
'local' :[
5, // for eth goerli
80001, //for mumbai polygon
97, // bnb testnet
- 420 // optimism goerli testnet
+ 420, // optimism goerli testnet
+ 421613 // for arbitrum testnet
]
}
diff --git a/packages/uiweb/src/lib/icons/ArbitrumSvg.tsx b/packages/uiweb/src/lib/icons/ArbitrumSvg.tsx
new file mode 100644
index 000000000..5703e7717
--- /dev/null
+++ b/packages/uiweb/src/lib/icons/ArbitrumSvg.tsx
@@ -0,0 +1,23 @@
+import * as React from 'react';
+
+export const ArbitrumSvg = () => (
+
+);
+