Skip to content

Commit

Permalink
fix: add apis for initiate and verify alias. (#1239)
Browse files Browse the repository at this point in the history
* fix: add apis for initiate and verify alias.

* fix: address code review feedback
  • Loading branch information
Razaso authored Apr 28, 2024
1 parent 8874df0 commit 34859e4
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export type UserSetting = {

export type AliasOptions = Omit<GetAliasInfoOptionsType, 'env'>;

export type AliasInfoOptions = {
raw?: boolean;
version?: number;
}

export enum FeedType {
INBOX = 'INBOX',
SPAM = 'SPAM',
Expand Down
91 changes: 85 additions & 6 deletions packages/restapi/src/lib/pushNotification/alias.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { ENV } from '../constants';
import { AliasOptions } from './PushNotificationTypes';

import { AliasInfoOptions, AliasOptions } from './PushNotificationTypes';
import { SignerType } from '../types';
import { validateCAIP } from '../helpers';
import CONFIG, * as config from '../config';
import * as PUSH_ALIAS from '../alias';
import { PushNotificationBaseClass } from './pushNotificationBase';


export class Alias {
private env: ENV
constructor(env: ENV) {
this.env = env
export class Alias extends PushNotificationBaseClass {
constructor(signer?: SignerType, env?: ENV, account?: string) {
super(signer, env, account);
}

/**
Expand All @@ -22,4 +24,81 @@ export class Alias {
throw new Error(`Push SDK Error: API : alias::info : ${error}`);
}
};

/**
* @description adds an alias to the channel
* @param {string} alias - alias address in caip to be added
* @param {AliasInfoOptions} options - options related to alias
* @returns the transaction hash if the transaction is successfull
*/
initiate = async (alias: string, options?: AliasInfoOptions): Promise<any> => {
try {
this.checkSignerObjectExists();
const networkDetails = await this.getChainId(this.signer!);
const caip = `eip155:${networkDetails}`;
if (!CONFIG[this.env!][caip] || !config.VIEM_CONFIG[this.env!][caip]) {
throw new Error('Unsupported Chainid');
}
const commAddress = CONFIG[this.env!][caip].EPNS_COMMUNICATOR_CONTRACT;

const commContract = this.createContractInstance(
commAddress,
config.ABIS.COMM,
config.VIEM_CONFIG[this.env!][caip].NETWORK
);

const addAliasRes = await this.initiateAddAlias(commContract, alias);
let resp: { [key: string]: any } = { tx: addAliasRes }
if (options?.raw) {
resp = {
...resp,
"raw": {
"initiateVerificationProof": addAliasRes
}
}
}
return resp;
} catch (error) {
throw new Error(`Push SDK Error: Contract : alias::add : ${error}`);
}
};

/**
* @description verifies an alias address of a channel
* @param {string} channelAddress - channelAddress to be verified
* @param {AliasInfoOptions} options - options related to alias
* @returns the transaction hash if the transaction is successfull
*/
verify = async (channelAddress: string, options?: AliasInfoOptions) => {
try {
this.checkSignerObjectExists();
const networkDetails = await this.getChainId(this.signer!);
const caip = `eip155:${networkDetails}`;

if (!CONFIG[this.env!][caip] || !config.VIEM_CONFIG[this.env!][caip]) {
throw new Error('Unsupported Chainid');
}
const commAddress = CONFIG[this.env!][caip].EPNS_COMMUNICATOR_CONTRACT;

const commContract = this.createContractInstance(
commAddress,
config.ABIS.COMM,
config.VIEM_CONFIG[this.env!][caip].NETWORK
);
const { verifyAliasRes, channelInfo } = await this.verifyAlias(commContract, channelAddress);
let resp: { [key: string]: any } = { tx: verifyAliasRes }
if (options?.raw) {
resp = {
...resp,
"raw": {
"initiateVerificationProof": channelInfo.initiate_verification_proof,
"verifyVerificationProof": verifyAliasRes
}
}
}
return resp;
} catch (error) {
throw new Error(`Push SDK Error: Contract : alias::verify : ${error}`);
}
};
}
2 changes: 1 addition & 1 deletion packages/restapi/src/lib/pushNotification/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Channel extends PushNotificationBaseClass {
constructor(signer?: SignerType, env?: ENV, account?: string) {
super(signer, env, account);
this.delegate = new Delegate(signer, env, account);
this.alias = new Alias(env!);
this.alias = new Alias(signer, env, account);
}

/**
Expand Down
71 changes: 71 additions & 0 deletions packages/restapi/src/lib/pushNotification/pushNotificationBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
CreateChannelOptions,
NotificationSettings,
UserSetting,
AliasInfoOptions,
} from './PushNotificationTypes';
import * as config from '../config';
import { getAccountAddress } from '../chat/helpers';
Expand All @@ -31,6 +32,7 @@ import {
} from '../helpers';
import { axiosGet, axiosPost } from '../utils/axiosUtil';
import { PushAPI } from '../pushapi/PushAPI';
import { channel } from 'diagnostics_channel';

// ERROR CONSTANTS
const ERROR_ACCOUNT_NEEDED = 'Account is required';
Expand Down Expand Up @@ -835,6 +837,75 @@ export class PushNotificationBaseClass {
}
}

protected async initiateAddAlias(contract: any, alias: string) {
try {
if (!this.signer) {
throw new Error('Signer is not provided');
}
const pushSigner = new Signer(this.signer);
let addAliasRes
if (!pushSigner.isViemSigner(this.signer)) {
if (!this.signer.provider) {
throw new Error('ethers provider is not provided');
}

const addAliasTrxPromise = contract!['verifyChannelAlias'](alias);
const addAliasTrx = await addAliasTrxPromise;
await this.signer?.provider?.waitForTransaction(addAliasTrx.hash);
addAliasRes = addAliasTrx.hash;
} else {
if (!contract.write) {
throw new Error('viem signer is not provided');
}

const addAliasTrxPromise = contract.write.verifyChannelAlias({
args: [alias],
});
addAliasRes = await addAliasTrxPromise;
}
return addAliasRes;
} catch (error: any) {
throw new Error(error.message);
}
}

protected async verifyAlias(contract: any, channelAddress: string) {
try {
if (!this.signer) {
throw new Error('Signer is not provided');
}
const pushSigner = new Signer(this.signer);
let verifyAliasRes
if (!pushSigner.isViemSigner(this.signer)) {
if (!this.signer.provider) {
throw new Error('ethers provider is not provided');
}
const addAliasTrxPromise = contract!['verifyChannelAlias'](channelAddress);
const addAliasTrx = await addAliasTrxPromise;
await this.signer?.provider?.waitForTransaction(addAliasTrx.hash);
verifyAliasRes = addAliasTrx.hash;
} else {
if (!contract.write) {
throw new Error('viem signer is not provided');
}
const addAliasTrxPromise = contract.write.verifyChannelAlias({
args: [channelAddress],
});
verifyAliasRes = await addAliasTrxPromise;
}

const networkDetails = await pushSigner.getChainId();
const aliasAddress = await pushSigner.getAddress();

const aliasIncaip = `eip155:${networkDetails}:${aliasAddress}`;
const channelInfo = await this.getChannelOrAliasInfo(aliasIncaip);

return { verifyAliasRes, channelInfo };
} catch (error: any) {
throw new Error(error.message);
}
}

/**
* @param aliasInCaip Alias address in CAIP format
* @returns Channel info for the alias
Expand Down
125 changes: 119 additions & 6 deletions packages/restapi/tests/lib/notification/alias.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { PushAPI } from '../../../src/lib/pushapi/PushAPI';
import { expect } from 'chai';
import { ethers } from 'ethers';
import { bsc, bscTestnet, sepolia } from 'viem/chains';
import { ENV } from '../../../src/lib/constants';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

describe('PushAPI.alias functionality', () => {
let userAlice: PushAPI;
let userBob: PushAPI;
let userKate: PushAPI;
let userSam: PushAPI
let signer1: any;
let account1: string;
let signer2: any;
let viemUser: any;
let viemUser1: any;
let account2: string;

// accessing env dynamically using process.env
Expand All @@ -20,34 +26,141 @@ describe('PushAPI.alias functionality', () => {
beforeEach(async () => {
signer1 = new ethers.Wallet(`0x${process.env['WALLET_PRIVATE_KEY']}`);
account1 = await signer1.getAddress();

const provider = (ethers as any).providers
? new (ethers as any).providers.JsonRpcProvider('https://rpc.sepolia.org')
: new (ethers as any).JsonRpcProvider('https://rpc.sepolia.org');

const provider1 = (ethers as any).providers
? new (ethers as any).providers.JsonRpcProvider('https://bsc-testnet-rpc.publicnode.com')
: new (ethers as any).JsonRpcProvider('https://bsc-testnet-rpc.publicnode.com');


signer2 = new ethers.Wallet(
`0x${process.env['WALLET_PRIVATE_KEY']}`,
provider
);

const signer3 = createWalletClient({
account: privateKeyToAccount(`0x${process.env['WALLET_PRIVATE_KEY']}`),
chain: sepolia,
transport: http(),
});


const signer4 = new ethers.Wallet(
`0x${process.env['NFT_HOLDER_WALLET_PRIVATE_KEY_1']}`,
provider1
);

const signer5 = createWalletClient({
account: privateKeyToAccount(`0x${process.env['NFT_HOLDER_WALLET_PRIVATE_KEY_1']}`),
chain: bscTestnet,
transport: http(),
});

account2 = await signer2.getAddress();

// initialisation with signer and provider
// initialization with signer
userAlice = await PushAPI.initialize(signer1, { env: _env });

// initialization with signer and provider
userKate = await PushAPI.initialize(signer2, { env: _env });
// initialisation with signer
userAlice = await PushAPI.initialize(signer2, { env: _env });
// TODO: remove signer1 after chat makes signer as optional

//initialisation without signer
userBob = await PushAPI.initialize(signer1, { env: _env });

// initalisation with viem
viemUser = await PushAPI.initialize(signer3, { env: _env });

// initalisation the verification account
userSam = await PushAPI.initialize(signer4, { env: _env });
viemUser1 = await PushAPI.initialize(signer5, { env: _env });

});

describe('alias :: info', () => {
// TODO: remove skip after signer becomes optional
it('Should return response', async () => {
const res = await userBob.channel.alias.info({
alias: '0x93A829d16DE51745Db0530A0F8E8A9B8CA5370E5',
aliasChain: 'POLYGON',
});
// console.log(res)
expect(res).not.null;
});
});

describe('alias :: add', () => {
// TODO: remove skip after signer becomes optional
it('Without signer and account :: should throw error', async () => {
await expect(() =>
userBob.channel.alias.initiate(
'eip155:11155111:0x74415Bc4C4Bf4Baecc2DD372426F0a1D016Fa924'
)
).to.Throw;
});

it('With signer and without provider :: should throw error', async () => {
await expect(() =>
userAlice.channel.alias.initiate(
'eip155:11155111:0x74415Bc4C4Bf4Baecc2DD372426F0a1D016Fa924'
)
).to.Throw;
});

it('With signer and provider :: should add alias', async () => {
const res = await userKate.channel.alias.initiate(
'eip155:97:0x2dFc6E90B9Cd0Fc1E0A2da82e3b094e9369caCdB'
);
expect(res).not.null;
}, 100000000);

it('With signer and provider :: should add alias', async () => {
const res = await userKate.channel.alias.initiate(
'eip155:97:0x2dFc6E90B9Cd0Fc1E0A2da82e3b094e9369caCdB',
{ raw: true }
);
expect(res).not.null;
}, 100000000);

it('With viem signer and provider :: should add alias', async () => {
const res = await viemUser.channel.alias.initiate(
'eip155:97:0x2dFc6E90B9Cd0Fc1E0A2da82e3b094e9369caCdB'
);
expect(res).not.null;
}, 100000000);

it('With signer and provider :: should throw error and provider doesnt match', async () => {
await expect(() =>
userAlice.channel.alias.initiate(
'eip155:97:0x2dFc6E90B9Cd0Fc1E0A2da82e3b094e9369caCdB'
)
).to.Throw;
});
});

describe('alias :: verify', () => {
it('Without signer and account :: should throw error', async () => {
await expect(() =>
userBob.channel.alias.verify(
'eip155:11155111:0x74415Bc4C4Bf4Baecc2DD372426F0a1D016Fa924'
)
).to.Throw;
});

it('With signer and without provider :: should throw error', async () => {
await expect(() =>
userAlice.channel.alias.verify(
'eip155:11155111:0x74415Bc4C4Bf4Baecc2DD372426F0a1D016Fa924'
)
).to.Throw;
});

it('With signer and provider :: should verify alias', async () => {
const res = await userSam.channel.alias.verify(
'0x6eF394b8dcc840d3d65a835E371066244187B1C6',
{ raw: true }
);
expect(res).not.null;
}, 100000000);
});
});

0 comments on commit 34859e4

Please sign in to comment.