Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Adding SDK support for channel tags APIs #1347

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions packages/restapi/src/lib/channels/getTags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
getCAIPAddress,
getAPIBaseUrls
} from '../helpers';
import Constants, { ENV } from '../constants';
import { axiosGet } from '../utils/axiosUtil';

/**
* GET v1/channels/${channelAddressInCAIP}/tags
*/
export type GetTagsOptionsType = {
/** address of the channel */
channel: string;
env?: ENV;
}

/**
* Returns the list of tags associated with the channel
*/
export const getTags = async (
options : GetTagsOptionsType
) => {
const {
channel,
env = Constants.ENV.PROD,
} = options || {};

const _channel = await getCAIPAddress(env, channel, 'Channel');
const API_BASE_URL = getAPIBaseUrls(env);
const apiEndpoint = `${API_BASE_URL}/v1/channels`;
const requestUrl = `${apiEndpoint}/${_channel}/tags`;

return await axiosGet(requestUrl)
.then((response) => response.data?.tags)
.catch((err) => {
console.error(`[EPNS-SDK] - API ${requestUrl}: `, err);
});
}
3 changes: 2 additions & 1 deletion packages/restapi/src/lib/channels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ export * from './getChannels';
export * from './getDelegates';
export * from './getSubscribers';
export * from './search';
export * from './getTags';
export * from './searchTags';
export * from './subscribe';
export * from './subscribeV2';
export * from './unsubscribe';
export * from './unsubscribeV2';

41 changes: 41 additions & 0 deletions packages/restapi/src/lib/channels/searchTags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { getAPIBaseUrls, getQueryParams, getLimit } from '../helpers';
import Constants, {ENV} from '../constants';
import { axiosGet } from '../utils/axiosUtil';

/**
* GET /v1/channels/search/
* optional params: page=(1)&limit=(20{min:1}{max:30})&query=(searchquery)
*/

export type SearchChannelTagsOptionsType = {
query: string;
env?: ENV;
page?: number;
limit?: number;
}

export const searchTags = async (
options: SearchChannelTagsOptionsType
) => {
const {
query,
env = Constants.ENV.LOCAL,
page = Constants.PAGINATION.INITIAL_PAGE,
limit = Constants.PAGINATION.LIMIT,
} = options || {};

if (!query) throw Error('"query" not provided!');
const API_BASE_URL = getAPIBaseUrls(env);
const apiEndpoint = `${API_BASE_URL}/v1/channels/search/tags`;
const queryObj = {
page,
limit: getLimit(limit),
query: query
};
const requestUrl = `${apiEndpoint}?${getQueryParams(queryObj)}`;
return axiosGet(requestUrl)
.then((response) => response.data.channels)
.catch((err) => {
console.error(`[Push SDK] - API ${requestUrl}: `, err);
});
}
2 changes: 1 addition & 1 deletion packages/restapi/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export const CORE_CONFIG = {
EPNS_CORE_CONTRACT: '0x5ab1520e2bd519bdab2e1347eee81c00a77f4946',
},
[ENV.LOCAL]: {
API_BASE_URL: API_BASE_URL[ENV.DEV],
API_BASE_URL: API_BASE_URL[ENV.LOCAL],
EPNS_CORE_CONTRACT: '0x5ab1520e2bd519bdab2e1347eee81c00a77f4946',
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export type CreateChannelOptions = {
icon: string;
url: string;
alias?: string;
tags?: string[];
progressHook?: (progress: ProgressHookType) => void;
};

Expand Down
28 changes: 28 additions & 0 deletions packages/restapi/src/lib/pushNotification/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,19 @@ import {

import { Alias } from './alias';
import { Delegate } from './delegate';
import { Tags } from './tags';
import { PushNotificationBaseClass } from './pushNotificationBase';

export class Channel extends PushNotificationBaseClass {
public delegate!: Delegate;
public alias!: Alias;
public tags!: Tags;

constructor(signer?: SignerType, env?: ENV, account?: string) {
super(signer, env, account);
this.delegate = new Delegate(signer, env, account);
this.alias = new Alias(signer, env, account);
this.tags = new Tags(this, signer, env, account);
}

/**
Expand Down Expand Up @@ -158,6 +162,8 @@ export class Channel extends PushNotificationBaseClass {
alias = null,
progressHook,
} = options || {};

let tags = options.tags;
try {
// create push token instance
let aliasInfo;
Expand Down Expand Up @@ -188,6 +194,17 @@ export class Channel extends PushNotificationBaseClass {
aliasDetails?.address,
};
}
// check for tags length
if (tags && tags.length > 5) {
tags = tags.slice(0, 5);
}

const tagsStr = tags && tags.length > 0 ? tags.join('') : '';

if (tagsStr.length > 512) {
throw new Error('Tags length should not exceed 512 characters');
}

// construct channel identity
progressHook?.(PROGRESSHOOK['PUSH-CREATE-01'] as ProgressHookType);
const input = {
Expand All @@ -196,6 +213,7 @@ export class Channel extends PushNotificationBaseClass {
url: url,
icon: icon,
aliasDetails: aliasInfo ?? {},
tags
};
const cid = await this.uploadToIPFSViaPushNode(JSON.stringify(input));
const allowanceAmount = await this.fetchAllownace(
Expand Down Expand Up @@ -248,6 +266,7 @@ export class Channel extends PushNotificationBaseClass {
alias = null,
progressHook,
} = options || {};
let tags = options.tags;
try {
// create push token instance
let aliasInfo;
Expand Down Expand Up @@ -284,6 +303,14 @@ export class Channel extends PushNotificationBaseClass {
aliasDetails?.address,
};
}

// check for tags length
if (tags && tags.length > 5) {
tags = tags.slice(0, 5);
}

const tagsStr = tags && tags.length > 0 ? tags.join('') : '';

// construct channel identity
progressHook?.(PROGRESSHOOK['PUSH-UPDATE-01'] as ProgressHookType);
const input = {
Expand All @@ -292,6 +319,7 @@ export class Channel extends PushNotificationBaseClass {
url: url,
icon: icon,
aliasDetails: aliasInfo ?? {},
tags
};
const cid = await this.uploadToIPFSViaPushNode(JSON.stringify(input));
// approve the tokens to core contract
Expand Down
129 changes: 129 additions & 0 deletions packages/restapi/src/lib/pushNotification/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import Constants, { ENV } from '../constants';
import { SignerType } from '../types';
import { ChannelInfoOptions, ChannelSearchOptions } from './PushNotificationTypes';
import * as PUSH_CHANNEL from '../channels';
import { PushNotificationBaseClass } from './pushNotificationBase';
import { Channel } from './channel';

export class Tags extends PushNotificationBaseClass {
private channel: Channel;

constructor(channel: Channel, signer?: SignerType, env?: ENV, account?: string) {
super(signer, env, account);
this.channel = channel;
}

/**
* @description - Get delegates of a channell
* @param {string} [options.channel] - channel in caip. defaults to account from signer with eth caip
* @returns array of delegates
*/
get = async (options?: ChannelInfoOptions) => {
try {
this.checkSignerObjectExists();
const channel = await this.channel.info()
return await PUSH_CHANNEL.getTags({
channel: channel,
env: this.env,
});
} catch (error) {
throw new Error(`Push SDK Error: API : tags::get : ${error}`);
}
};

/**
* @description adds tags for a channel
* @param {Array<string>} tags - tags to be added
* @returns the tags if the transaction is successfull
*/
add = async (tags: Array<string>) => {
try {
this.checkSignerObjectExists();
const channel = await this.channel.info()

const resp = await this.channel.update({
name: channel.name,
description: channel.info,
url: channel.url,
icon: channel.icon,
tags: tags
});

return { tags }

} catch (error) {
throw new Error(`Push SDK Error: Contract : tags::add : ${error}`);
}
};

/**
* @description update tags for a channel
* @param {Array<string>} tags - tags to be added
* @returns the tags if the transaction is successfull
*/
update = async (tags: Array<string>) => {
try {
this.checkSignerObjectExists();
const channel = await this.channel.info()
await this.channel.update({
name: channel.name,
description: channel.info,
url: channel.url,
icon: channel.icon,
tags: tags
});

return { tags }
} catch (error) {
throw new Error(`Push SDK Error: Contract : tags::update : ${error}`);
}
};

/**
* @description removes tags from a channel
* @returns status of the request
*/
remove = async () => {
try {
this.checkSignerObjectExists();
const channel = await this.channel.info()
await this.channel.update({
name: channel.name,
description: channel.info,
url: channel.url,
icon: channel.icon,
tags: []
});

return { status: "success" }

} catch (error) {
throw new Error(`Push SDK Error: Contract : tags::remove : ${error}`);
}
};

/**
* @description - returns relevant information as per the query that was passed
* @param {string} query - search query
* @param {number} [options.page] - page number. default is set to Constants.PAGINATION.INITIAL_PAGE
* @param {number} [options.limit] - number of feeds per page. default is set to Constants.PAGINATION.LIMIT
* @returns Array of results relevant to the serach query
*/
search = async (query: string, options?: ChannelSearchOptions) => {
try {
const {
page = Constants.PAGINATION.INITIAL_PAGE,
limit = Constants.PAGINATION.LIMIT,
} = options || {};

return await PUSH_CHANNEL.searchTags({
query: query,
page: page,
limit: limit,
env: this.env,
});
} catch (error) {
throw new Error(`Push SDK Error: API : channel::tags::search : ${error}`);
}
}
}
Loading
Loading