Skip to content

Commit

Permalink
fix: added sub/unsub v3
Browse files Browse the repository at this point in the history
akp111 committed Jun 5, 2024
1 parent 49cc34c commit 2254062
Showing 3 changed files with 235 additions and 0 deletions.
26 changes: 26 additions & 0 deletions packages/restapi/src/lib/channels/signature.helpers.ts
Original file line number Diff line number Diff line change
@@ -50,6 +50,32 @@ export const getSubscriptionMessageV2 = (
}
};

export const getSubscriptionMessageV3 = (
channel: string,
userAddress: string,
action: channelActionType,
userSetting?: string | null
) => {
const actionTypeKey =
action === 'Unsubscribe' ? 'unsubscriber' : 'subscriber';
if (action == 'Subscribe') {
return JSON.stringify({
channel,
[actionTypeKey]: userAddress,
action: action,
userSetting: userSetting?? '',
timestamp: Math.floor(Date.now() / 1000),
}, null, 4);
} else {
return JSON.stringify({
channel,
[actionTypeKey]: userAddress,
action: action,
timestamp: Math.floor(Date.now() / 1000),
}, null, 4);
}
};

export const getTypeInformation = (action: string) => {
if (action === 'Subscribe') {
return {
106 changes: 106 additions & 0 deletions packages/restapi/src/lib/channels/subscribeV3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getDomainInformation,
getTypeInformationV2,
getSubscriptionMessageV3,
} from './signature.helpers';
import Constants, { ENV } from '../constants';
import { SignerType } from '../types';
import { axiosPost } from '../utils/axiosUtil';

export type SubscribeOptionsV2Type = {
signer: SignerType;
channelAddress: string;
userAddress: string;
settings?: string | null;
verifyingContractAddress?: string;
env?: ENV;
origin?: string;
onSuccess?: () => void;
onError?: (err: Error) => void;
};

export const subscribeV2 = async (options: SubscribeOptionsV2Type) => {
const {
signer,
channelAddress,
userAddress,
settings = undefined,
verifyingContractAddress,
env = Constants.ENV.PROD,
origin,
onSuccess,
onError,
} = options || {};
try {
const _channelAddress = await getCAIPAddress(
env,
channelAddress,
'Channel'
);

const channelCAIPDetails = getCAIPDetails(_channelAddress);
if (!channelCAIPDetails) throw Error('Invalid Channel CAIP!');

const chainId = parseInt(channelCAIPDetails.networkId, 10);

const _userAddress = await getCAIPAddress(env, userAddress, 'User');

const userCAIPDetails = getCAIPDetails(_userAddress);
if (!userCAIPDetails) throw Error('Invalid User CAIP!');

const { API_BASE_URL, EPNS_COMMUNICATOR_CONTRACT } = getConfig(
env,
channelCAIPDetails
);

const requestUrl = `${API_BASE_URL}/v1/channels/${_channelAddress}/subscribe`;
// get domain information
const domainInformation = getDomainInformation(
chainId,
verifyingContractAddress || EPNS_COMMUNICATOR_CONTRACT
);

// get type information
const typeInformation = getTypeInformationV2();

// get message
const messageInformation = {
data: getSubscriptionMessageV3(
channelCAIPDetails.address,
userCAIPDetails.address,
'Subscribe',
settings
),
};
// sign a message using EIP712
const pushSigner = new Signer(signer);
const signature = await pushSigner.signTypedData(
domainInformation,
typeInformation,
messageInformation,
'Data'
);

const verificationProof = signature; // might change

const body = {
verificationProof: `eip712v3:${verificationProof}`,
message: messageInformation.data,
origin: origin
};

const res = await axiosPost(requestUrl, body);

if (typeof onSuccess === 'function') onSuccess();

return { status: res.status, message: 'successfully opted into channel' };
} catch (err: any) {
if (typeof onError === 'function') onError(err as Error);

return {
status: err?.response?.status ?? '',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
};
103 changes: 103 additions & 0 deletions packages/restapi/src/lib/channels/unsubscribeV3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getDomainInformation,
getTypeInformationV2,
getSubscriptionMessageV3,
} from './signature.helpers';
import Constants, { ENV } from '../constants';
import { SignerType } from '../types';
import { axiosPost } from '../utils/axiosUtil';

export type UnSubscribeOptionsV2Type = {
signer: SignerType;
channelAddress: string;
userAddress: string;
verifyingContractAddress?: string;
env?: ENV;
onSuccess?: () => void;
onError?: (err: Error) => void;
};

export const unsubscribeV2 = async (options: UnSubscribeOptionsV2Type) => {
const {
signer,
channelAddress,
userAddress,
verifyingContractAddress,
env = Constants.ENV.PROD,
onSuccess,
onError,
} = options || {};

try {
const _channelAddress = await getCAIPAddress(
env,
channelAddress,
'Channel'
);

const channelCAIPDetails = getCAIPDetails(_channelAddress);
if (!channelCAIPDetails) throw Error('Invalid Channel CAIP!');

const chainId = parseInt(channelCAIPDetails.networkId, 10);

const _userAddress = await getCAIPAddress(env, userAddress, 'User');

const userCAIPDetails = getCAIPDetails(_userAddress);
if (!userCAIPDetails) throw Error('Invalid User CAIP!');

const { API_BASE_URL, EPNS_COMMUNICATOR_CONTRACT } = getConfig(
env,
channelCAIPDetails
);

const requestUrl = `${API_BASE_URL}/v1/channels/${_channelAddress}/unsubscribe`;

// get domain information
const domainInformation = getDomainInformation(
chainId,
verifyingContractAddress || EPNS_COMMUNICATOR_CONTRACT
);

// get type information
const typeInformation = getTypeInformationV2();

// get message
const messageInformation = {
data: getSubscriptionMessageV3(
channelCAIPDetails.address,
userCAIPDetails.address,
'Unsubscribe'
),
};

// sign a message using EIP712
const pushSigner = new Signer(signer);
const signature = await pushSigner.signTypedData(
domainInformation,
typeInformation,
messageInformation,
'Data'
);

const verificationProof = signature; // might change

const body = {
verificationProof: `eip712v3:${verificationProof}`,
message: messageInformation.data,
};

const res = await axiosPost(requestUrl, body);

if (typeof onSuccess === 'function') onSuccess();

return { status: res.status, message: 'successfully opted out channel' };
} catch (err: any) {
if (typeof onError === 'function') onError(err as Error);

return {
status: err?.response?.status ?? '',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
};

0 comments on commit 2254062

Please sign in to comment.