Skip to content

Commit

Permalink
fix: fix viem support, add ethers support (#929)
Browse files Browse the repository at this point in the history
Aman035 authored Dec 18, 2023
1 parent 1b492bf commit 636b64e
Showing 17 changed files with 317 additions and 327 deletions.
4 changes: 1 addition & 3 deletions packages/restapi/package.json
Original file line number Diff line number Diff line change
@@ -5,10 +5,8 @@
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"peerDependencies": {
"ethers": "^5.6.8"
},
"dependencies": {
"ethers": "^5.6.8",
"@ambire/signature-validator": "^1.3.1",
"@metamask/eth-sig-util": "^5.0.2",
"@pushprotocol/socket": "^0.5.2",
61 changes: 35 additions & 26 deletions packages/restapi/src/lib/channels/subscribe.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,23 @@
import axios from "axios";
import {
getCAIPAddress,
getConfig,
getCAIPDetails,
signTypedData
} from '../helpers';
import axios from 'axios';
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getTypeInformation,
getDomainInformation,
getSubscriptionMessage
getSubscriptionMessage,
} from './signature.helpers';
import Constants, {ENV} from '../constants';
import { SignerType } from "../types";
import Constants, { ENV } from '../constants';
import { SignerType } from '../types';
export type SubscribeOptionsType = {
signer: SignerType;
channelAddress: string;
userAddress: string;
verifyingContractAddress?: string;
env?: ENV;
onSuccess?: () => void
onError?: (err: Error) => void,
}
onSuccess?: () => void;
onError?: (err: Error) => void;
};

export const subscribe = async (
options: SubscribeOptionsType
) => {
export const subscribe = async (options: SubscribeOptionsType) => {
const {
signer,
channelAddress,
@@ -36,19 +29,26 @@ export const subscribe = async (
} = options || {};

try {
const _channelAddress = await getCAIPAddress(env, channelAddress, 'Channel');
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 { API_BASE_URL, EPNS_COMMUNICATOR_CONTRACT } = getConfig(
env,
channelCAIPDetails
);

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

@@ -59,17 +59,23 @@ export const subscribe = async (
);

// get type information
const typeInformation = getTypeInformation("Subscribe");
const typeInformation = getTypeInformation('Subscribe');

// get message
const messageInformation = getSubscriptionMessage(
channelCAIPDetails.address,
userCAIPDetails.address,
"Subscribe"
'Subscribe'
);

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

const verificationProof = signature; // might change

@@ -78,18 +84,21 @@ export const subscribe = async (
message: {
...messageInformation,
channel: _channelAddress,
subscriber: _userAddress
subscriber: _userAddress,
},
};

await axios.post(requestUrl, body);

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

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

return { status: "error", message: err instanceof Error ? err.message : JSON.stringify(err) };
return {
status: 'error',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
}
};
18 changes: 5 additions & 13 deletions packages/restapi/src/lib/channels/subscribeV2.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import axios from 'axios';
import {
getCAIPAddress,
getConfig,
getCAIPDetails,
signTypedData,
} from '../helpers';
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getDomainInformation,
getTypeInformationV2,
@@ -77,8 +72,8 @@ export const subscribeV2 = async (options: SubscribeOptionsV2Type) => {
),
};
// sign a message using EIP712
const signature = await signTypedData(
signer,
const pushSigner = new Signer(signer);
const signature = pushSigner.signTypedData(
domainInformation,
typeInformation,
messageInformation,
@@ -89,9 +84,7 @@ export const subscribeV2 = async (options: SubscribeOptionsV2Type) => {

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

message: messageInformation.data,
};

const res = await axios.post(requestUrl, body);
@@ -100,11 +93,10 @@ export const subscribeV2 = async (options: SubscribeOptionsV2Type) => {

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?? '' ,
status: err?.response?.status ?? '',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
63 changes: 36 additions & 27 deletions packages/restapi/src/lib/channels/unsubscribe.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
import axios from "axios";
import {
getCAIPAddress,
getConfig,
getCAIPDetails,
signTypedData
} from '../helpers';
import axios from 'axios';
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getTypeInformation,
getDomainInformation,
getSubscriptionMessage
getSubscriptionMessage,
} from './signature.helpers';
import Constants, {ENV} from '../constants';
import { SignerType } from "../types";
import Constants, { ENV } from '../constants';
import { SignerType } from '../types';

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

export const unsubscribe = async (
options: UnSubscribeOptionsType
) => {
export const unsubscribe = async (options: UnSubscribeOptionsType) => {
const {
signer,
channelAddress,
@@ -37,19 +30,26 @@ export const unsubscribe = async (
} = options || {};

try {
const _channelAddress = await getCAIPAddress(env, channelAddress, 'Channel');
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 { API_BASE_URL, EPNS_COMMUNICATOR_CONTRACT } = getConfig(
env,
channelCAIPDetails
);

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

@@ -60,17 +60,23 @@ export const unsubscribe = async (
);

// get type information
const typeInformation = getTypeInformation("Unsubscribe");
const typeInformation = getTypeInformation('Unsubscribe');

// get message
const messageInformation = getSubscriptionMessage(
channelCAIPDetails.address,
userCAIPDetails.address,
"Unsubscribe"
'Unsubscribe'
);

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

const verificationProof = signature; // might change

@@ -79,18 +85,21 @@ export const unsubscribe = async (
message: {
...messageInformation,
channel: _channelAddress,
unsubscriber: _userAddress
unsubscriber: _userAddress,
},
};

await axios.post(requestUrl, body);

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

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

return { status: "error", message: err instanceof Error ? err.message : JSON.stringify(err) };
return {
status: 'error',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
}
};
15 changes: 4 additions & 11 deletions packages/restapi/src/lib/channels/unsubscribeV2.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import axios from 'axios';
import { getCAIPAddress, getConfig, getCAIPDetails, Signer } from '../helpers';
import {
getCAIPAddress,
getConfig,
getCAIPDetails,
signTypedData,
} from '../helpers';
import {
getTypeInformation,
getDomainInformation,
getSubscriptionMessage,
getTypeInformationV2,
getSubscriptionMessageV2,
} from './signature.helpers';
@@ -79,8 +72,8 @@ export const unsubscribeV2 = async (options: UnSubscribeOptionsV2Type) => {
};

// sign a message using EIP712
const signature = await signTypedData(
signer,
const pushSigner = new Signer(signer);
const signature = await pushSigner.signTypedData(
domainInformation,
typeInformation,
messageInformation,
@@ -103,7 +96,7 @@ export const unsubscribeV2 = async (options: UnSubscribeOptionsV2Type) => {
if (typeof onError === 'function') onError(err as Error);

return {
status: err?.response?.status?? '' ,
status: err?.response?.status ?? '',
message: err instanceof Error ? err.message : JSON.stringify(err),
};
}
13 changes: 6 additions & 7 deletions packages/restapi/src/lib/chat/helpers/crypto.ts
Original file line number Diff line number Diff line change
@@ -13,12 +13,10 @@ import {
} from '../../types';
import { get } from '../../user';
import {
Signer,
decryptPGPKey,
decryptWithWalletRPCMethod,
isValidETHAddress,
walletToPCAIP10,
signTypedData,
signMessage,
} from '../../helpers';
import { get as getUser } from '../../user';
import { createUserService } from './service';
@@ -363,7 +361,8 @@ export const getEip191Signature = async (
const _signer = wallet?.signer;
// EIP191 signature

const signature = await signMessage(_signer, message);
const pushSigner = new Signer(_signer);
const signature = await pushSigner.signMessage(message);
const sigType = version === 'v1' ? 'eip191' : 'eip191v2';
return { verificationProof: `${sigType}:${signature}` };
};
@@ -381,17 +380,17 @@ export const getEip712Signature = async (

const typeInformation = getTypeInformation();
const _signer = wallet?.signer;
const pushSigner = new Signer(_signer);
let chainId: number;
try {
chainId = await _signer.getChainId();
chainId = await pushSigner.getChainId();
} catch (err) {
chainId = 1;
}
const domain = getDomainInformation(chainId);

// sign a message using EIP712
const signedMessage = await signTypedData(
_signer,
const signedMessage = await pushSigner.signTypedData(
isDomainEmpty ? {} : domain,
typeInformation,
{ data: hash },
35 changes: 17 additions & 18 deletions packages/restapi/src/lib/chat/helpers/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
import { pCAIP10ToWallet, getAddress } from "../../helpers";
import { SignerType, walletType } from "../../types";
import { Signer, pCAIP10ToWallet } from '../../helpers';
import { SignerType, walletType } from '../../types';

export const getWallet = (options: walletType): {
account: string | null,
signer: SignerType | null
export const getWallet = (
options: walletType
): {
account: string | null;
signer: SignerType | null;
} => {
const {
account,
signer
} = options || {};
const { account, signer } = options || {};

return {
account: account ? pCAIP10ToWallet(account) : account,
signer
signer,
};
}
};

export const getAccountAddress = async (options: walletType): Promise<string> => {
const {
account,
signer
} = options || {};
export const getAccountAddress = async (
options: walletType
): Promise<string> => {
const { account, signer } = options || {};

return account || (await getAddress(signer as SignerType)) || ''
}
const pushSigner = new Signer(signer as SignerType);
return account || (await pushSigner.getAddress()) || '';
};
6 changes: 3 additions & 3 deletions packages/restapi/src/lib/helpers/crypto.ts
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ import {
import { verifyProfileSignature } from '../chat/helpers/signature';
import { upgrade } from '../user/upgradeUser';
import PROGRESSHOOK from '../progressHook';
import { getAddress } from './signer';
import { Signer } from './signer';

const KDFSaltSize = 32; // bytes
const AESGCMNonceSize = 12; // property iv
@@ -52,8 +52,8 @@ if (typeof window !== 'undefined' && window.crypto) {
/** DEPRECATED */
export const getPublicKey = async (options: walletType): Promise<string> => {
const { account, signer } = options || {};
const address: string =
account || (await getAddress(signer as SignerType)) || '';
const pushSigner = signer ? new Signer(signer) : undefined;
const address: string = account || (await pushSigner?.getAddress()) || '';
const metamaskProvider = new ethers.providers.Web3Provider(
(window as any).ethereum
);
131 changes: 80 additions & 51 deletions packages/restapi/src/lib/helpers/signer.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,89 @@
import { SignerType } from '../types';
import { SignerType, viemSignerType } from '../types';
import { Bytes, TypedDataDomain, TypedDataField } from 'ethers';

export const signMessage = async (
signer: SignerType,
message: string
): Promise<string> => {
// Check the signer type using type guards
if ('signMessage' in signer) {
// If the signer has a signMessage function with the ethersV5SignerType signature
if ('_signTypedData' in signer) {
// It's ethersV5SignerType, use its signMessage function
const signature = await signer.signMessage(message);
return signature;
export class Signer {
private signer: SignerType;

constructor(signer: SignerType) {
this.signer = signer;
}

/**
* Determine if the signer is a Viem signer
*/
isViemSigner(signer: SignerType): signer is viemSignerType {
return (
typeof (signer as any).signTypedData === 'function' &&
typeof (signer as any).getChainId === 'function' &&
signer.signMessage.length === 1 && // Checking if the function takes one argument
(signer as any).signTypedData.length === 1 // Checking if the function takes one argument
);
}

async signMessage(message: string | Bytes): Promise<string> {
if (
'signMessage' in this.signer &&
typeof this.signer.signMessage === 'function'
) {
if (this.isViemSigner(this.signer)) {
// Viem signer requires additional arguments
return this.signer.signMessage({
message,
account: this.signer.account,
});
} else {
// EthersV5 and EthersV6
return this.signer.signMessage(message);
}
} else {
// It's viemSignerType, use its signMessage function
const signature = await signer.signMessage({
message,
account: signer.account,
throw new Error('Signer does not support signMessage');
}
}

async signTypedData(
domain: TypedDataDomain,
types: Record<string, TypedDataField[]>,
value: Record<string, any>,
primaryType?: string
): Promise<string> {
if (this.isViemSigner(this.signer)) {
// Call Viem's signTypedData with its specific structure
return this.signer.signTypedData({
domain: domain,
types: types,
primaryType: primaryType,
message: value,
account: this.signer.account,
});
return signature;
} else if ('_signTypedData' in this.signer) {
// ethersV5 signer uses _signTypedData
return this.signer._signTypedData(domain, types, value);
} else if ('signTypedData' in this.signer) {
// ethersV6 signer uses signTypedData
return this.signer.signTypedData(domain, types, value);
} else {
throw new Error('Signer does not support signTypedData');
}
} else {
throw new Error('Invalid signer type provided.');
}
};

export const signTypedData = async (
signer: SignerType,
domain: any,
types: any,
value: any,
primaryType: string
): Promise<string> => {
// Check the signer type using type guards
if ('_signTypedData' in signer) {
// It's ethersV5SignerType, use its functions
const signature = await signer._signTypedData(domain, types, value);
return signature;
} else if ('signTypedData' in signer) {
// It's viemSignerType, use its functions
const signature = await signer.signTypedData({
account: signer.account,
domain,
types,
primaryType: primaryType,
message: value,
});
return signature;
} else {
throw new Error('Invalid signer type provided.');
async getAddress(): Promise<string> {
if (this.isViemSigner(this.signer)) {
return this.signer.account['address'] ?? '';
} else {
return await this.signer.getAddress();
}
}
};

export const getAddress = async (signer: SignerType): Promise<string> => {
if ('getAddress' in signer) {
return await signer.getAddress();
} else {
return signer.account['address'] ?? '';
async getChainId(): Promise<number> {
if (this.isViemSigner(this.signer)) {
// Viem signer has a direct method for getChainId
return this.signer.getChainId();
} else if ('provider' in this.signer && this.signer.provider) {
// EthersV5 and EthersV6
const network = await this.signer.provider.getNetwork();
return network.chainId;
} else {
return 1; // Return default chainId
}
}
};
}
10 changes: 6 additions & 4 deletions packages/restapi/src/lib/payloads/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { v4 as uuidv4 } from 'uuid';
import { ENV } from '../constants';
import { getCAIPAddress, signTypedData } from '../helpers';
import { Signer, getCAIPAddress } from '../helpers';
import * as CryptoJS from 'crypto-js';

import {
@@ -255,8 +255,8 @@ export async function getVerificationProof({
chainId: chainId,
verifyingContract: verifyingContract,
};
const signature = await signTypedData(
signer,
const pushSigner = new Signer(signer);
const signature = await pushSigner.signTypedData(
domain,
type,
message,
@@ -325,7 +325,9 @@ export function getSource(
export function getCAIPFormat(chainId: number, address: string) {
// EVM based chains
if (
[1, 11155111, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161].includes(chainId)
[
1, 11155111, 42, 137, 80001, 56, 97, 10, 420, 1442, 1101, 421613, 42161,
].includes(chainId)
) {
return `eip155:${chainId}:${address}`;
}
45 changes: 0 additions & 45 deletions packages/restapi/src/lib/pushNotification/channel.ts
Original file line number Diff line number Diff line change
@@ -153,17 +153,6 @@ export class Channel extends PushNotificationBaseClass {
progressHook,
} = options || {};
try {
if ('_signTypedData' in this.signer!) {
if (!this.signer || !this.signer.provider) {
throw new Error('ethers provider/signer is not provided');
}
} else if ('signTypedData' in this.signer!) {
if (!this.coreContract.write) {
throw new Error('viem signer is not provided');
}
} else {
throw new Error('Unsupported Signer');
}
// create push token instance
let aliasInfo;
// validate all the parameters and length
@@ -256,17 +245,6 @@ export class Channel extends PushNotificationBaseClass {
try {
// create push token instance
let aliasInfo;
if ('_signTypedData' in this.signer!) {
if (!this.signer || !this.signer.provider) {
throw new Error('ethers provider/signer is not provided');
}
} else if ('signTypedData' in this.signer!) {
if (!this.coreContract.write) {
throw new Error('viem signer is not provided');
}
} else {
throw new Error('Unsupported Signer');
}
// validate all the parameters and length
this.validateChannelParameters(options);
// check for PUSH balance
@@ -357,17 +335,6 @@ export class Channel extends PushNotificationBaseClass {
verify = async (channelToBeVerified: string) => {
try {
this.checkSignerObjectExists();
if ('_signTypedData' in this.signer!) {
if (!this.signer || !this.signer.provider) {
throw new Error('ethers provider/signer is not provided');
}
} else if ('signTypedData' in this.signer!) {
if (!this.coreContract.write) {
throw new Error('viem signer is not provided');
}
} else {
throw new Error('Unsupported Signer');
}
if (validateCAIP(channelToBeVerified)) {
channelToBeVerified = channelToBeVerified.split(':')[2];
}
@@ -396,18 +363,6 @@ export class Channel extends PushNotificationBaseClass {
setting = async (configuration: NotificationSettings) => {
try {
this.checkSignerObjectExists();
//TODO: create a separate function later
if ('_signTypedData' in this.signer!) {
if (!this.signer || !this.signer.provider) {
throw new Error('ethers provider/signer is not provided');
}
} else if ('signTypedData' in this.signer!) {
if (!this.coreContract.write) {
throw new Error('viem signer is not provided');
}
} else {
throw new Error('Unsupported Signer');
}
// check for PUSH balance
const pushTokenContract = await this.createContractInstance(
config.TOKEN[this.env!],
4 changes: 2 additions & 2 deletions packages/restapi/src/lib/pushNotification/delegate.ts
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ export class Delegate extends PushNotificationBaseClass {
if (validateCAIP(delegate)) {
delegate = this.getAddressFromCaip(delegate);
}
const networkDetails = await this.getChianId(this.signer!);
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');
@@ -88,7 +88,7 @@ export class Delegate extends PushNotificationBaseClass {
if (validateCAIP(delegate)) {
delegate = this.getAddressFromCaip(delegate);
}
const networkDetails = await this.getChianId(this.signer!);
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');
210 changes: 99 additions & 111 deletions packages/restapi/src/lib/pushNotification/pushNotificationBase.ts

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion packages/restapi/src/lib/pushapi/PushAPI.ts
Original file line number Diff line number Diff line change
@@ -97,7 +97,8 @@ export class PushAPI {
if (
args.length === 1 &&
typeof args[0] === 'object' &&
'account' in args[0]
'account' in args[0] &&
typeof args[0].account === 'string'
) {
// Single options object provided
options = args[0];
20 changes: 17 additions & 3 deletions packages/restapi/src/lib/types/index.ts
Original file line number Diff line number Diff line change
@@ -328,7 +328,6 @@ export enum GROUP_RULES_SUB_CATEGORY {
GET = 'GET',
}


export enum GROUP_RULES_PERMISSION {
ENTRY = 'Entry',
CHAT = 'Chat',
@@ -649,12 +648,24 @@ export type ethersV5SignerType = {
types: Record<string, Array<TypedDataField>>,
value: Record<string, any>
) => Promise<string>;
getChainId: () => Promise<number>;
getAddress: () => Promise<string>;
signMessage: (message: Bytes | string) => Promise<string>;
privateKey?: string;
provider?: providers.Provider;
};

export type ethersV6SignerType = {
signTypedData: (
domain: TypedDataDomain,
types: Record<string, Array<TypedDataField>>,
value: Record<string, any>
) => Promise<string>;
getAddress: () => Promise<string>;
signMessage: (message: Bytes | string) => Promise<string>;
privateKey?: string;
provider?: providers.Provider;
};

export type viemSignerType = {
signTypedData: (args: {
account: any;
@@ -674,7 +685,10 @@ export type viemSignerType = {
provider?: providers.Provider;
};

export type SignerType = ethersV5SignerType | viemSignerType;
export type SignerType =
| ethersV5SignerType
| ethersV6SignerType
| viemSignerType;

export type EnvOptionsType = {
env?: ENV;
2 changes: 2 additions & 0 deletions packages/restapi/tests/lib/notification/channel.test.ts
Original file line number Diff line number Diff line change
@@ -411,6 +411,8 @@ describe('PushAPI.channel functionality', () => {

describe('channel :: create', () => {
it('Should create channel', async () => {
const channelInfo = await userKate.channel.info();
if (channelInfo) return; // skip if already exists
const res = await userKate.channel.create({
name: 'SDK Test',
description: 'Testing new description',
4 changes: 2 additions & 2 deletions packages/restapi/yarn.lock
Original file line number Diff line number Diff line change
@@ -1213,9 +1213,9 @@ ethereum-cryptography@^1.1.2:
"@scure/bip32" "1.1.5"
"@scure/bip39" "1.1.1"

ethers@^5.6.5:
ethers@^5.6.5, ethers@^5.6.8:
version "5.7.2"
resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==
dependencies:
"@ethersproject/abi" "5.7.0"

0 comments on commit 636b64e

Please sign in to comment.