From 3c398901e76335a9f417009b3cf54295d204951c Mon Sep 17 00:00:00 2001 From: aman035 <guptaaman200115@gmail.com> Date: Fri, 14 Jun 2024 13:48:03 +0530 Subject: [PATCH] fix: added validator class and fix api route --- packages/d-node-notif/project.json | 2 +- .../d-node-notif/src/lib/abis/validator.ts | 1134 +++++++++++++++++ .../src/lib/alias/getAliasInfo.ts | 2 +- .../src/lib/channels/_getSubscribers.ts | 2 +- .../src/lib/channels/getChannel.ts | 2 +- .../lib/channels/getChannelNotifications.ts | 2 +- .../src/lib/channels/getChannels.ts | 2 +- .../src/lib/channels/getDelegates.ts | 22 +- .../src/lib/channels/getSubscribers.ts | 90 +- .../d-node-notif/src/lib/channels/search.ts | 18 +- .../src/lib/chat/helpers/service.ts | 4 +- packages/d-node-notif/src/lib/config.ts | 43 +- .../d-node-notif/src/lib/helpers/config.ts | 22 +- .../d-node-notif/src/lib/helpers/crypto.ts | 8 + .../src/lib/payloads/sendNotifications.ts | 2 +- .../pushNotification/pushNotificationBase.ts | 2 +- .../src/lib/pushValidator/pushValidator.ts | 144 +++ .../lib/pushValidator/pushValidatorTypes.ts | 44 + .../src/lib/user/getDelegations.ts | 20 +- .../d-node-notif/src/lib/user/getFeeds.ts | 14 +- .../src/lib/user/getFeedsPerChannel.ts | 2 +- .../src/lib/user/getSubscriptions.ts | 11 +- packages/d-node-notif/src/lib/user/getUser.ts | 2 +- .../src/lib/user/getUsersBatch.ts | 2 +- .../src/lib/user/profile.updateUser.ts | 2 +- packages/d-node-notif/tests/.env.sample | 2 +- .../tests/lib/initialize/initialize.test.ts | 22 + .../lib/pushValidator/pushValidator.test.ts | 57 + 28 files changed, 1545 insertions(+), 134 deletions(-) create mode 100644 packages/d-node-notif/src/lib/abis/validator.ts create mode 100644 packages/d-node-notif/src/lib/pushValidator/pushValidator.ts create mode 100644 packages/d-node-notif/src/lib/pushValidator/pushValidatorTypes.ts create mode 100644 packages/d-node-notif/tests/lib/initialize/initialize.test.ts create mode 100644 packages/d-node-notif/tests/lib/pushValidator/pushValidator.test.ts diff --git a/packages/d-node-notif/project.json b/packages/d-node-notif/project.json index 8d645914c..ce5577eb5 100644 --- a/packages/d-node-notif/project.json +++ b/packages/d-node-notif/project.json @@ -23,7 +23,7 @@ }, "test": { "executor": "@nrwl/workspace:run-commands", - "outputs": ["coverage/packages/restapi"], + "outputs": ["coverage/packages/d-node-notif"], "options": { "commands": ["yarn run test:d-node-notif"], "passWithNoTests": true diff --git a/packages/d-node-notif/src/lib/abis/validator.ts b/packages/d-node-notif/src/lib/abis/validator.ts new file mode 100644 index 000000000..7cb6d21ca --- /dev/null +++ b/packages/d-node-notif/src/lib/abis/validator.ts @@ -0,0 +1,1134 @@ +export const validatorABI = [ + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'previousAdmin', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'newAdmin', + type: 'address', + }, + ], + name: 'AdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'beacon', + type: 'address', + }, + ], + name: 'BeaconUpgraded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'valPerBlock', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'valPerBlockTarget', + type: 'uint16', + }, + ], + name: 'BlockParamsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint8', + name: 'version', + type: 'uint8', + }, + ], + name: 'Initialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'ownerWallet', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + indexed: false, + internalType: 'enum ValidatorV1.NodeType', + name: 'nodeType', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nodeTokens', + type: 'uint256', + }, + { + indexed: false, + internalType: 'string', + name: 'nodeApiBaseUrl', + type: 'string', + }, + ], + name: 'NodeAdded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'reporterWallet', + type: 'address', + }, + { + indexed: false, + internalType: 'address[]', + name: 'voters', + type: 'address[]', + }, + { + indexed: false, + internalType: 'enum ValidatorV1.VoteAction', + name: 'voteAction', + type: 'uint8', + }, + ], + name: 'NodeReported', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + indexed: false, + internalType: 'enum ValidatorV1.NodeStatus', + name: 'nodeStatus', + type: 'uint8', + }, + { + indexed: false, + internalType: 'uint256', + name: 'nodeTokens', + type: 'uint256', + }, + ], + name: 'NodeStatusChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferStarted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint16', + name: 'nodeRandomMinCount', + type: 'uint16', + }, + { + indexed: false, + internalType: 'uint16', + name: 'nodeRandomPingCount', + type: 'uint16', + }, + ], + name: 'RandomParamsUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'implementation', + type: 'address', + }, + ], + name: 'Upgraded', + type: 'event', + }, + { + inputs: [], + name: 'BAN_PERCENT', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REPORTS_BEFORE_SLASH_S', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REPORTS_BEFORE_SLASH_V', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REPORT_THRESHOLD_PER_BLOCK', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'SLASHES_BEFORE_BAN_S', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'SLASHES_BEFORE_BAN_V', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'SLASH_PERCENT', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'VERSION', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'acceptOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'dnodes', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getActiveVNodes', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + internalType: 'string', + name: 'nodeApiBaseUrl', + type: 'string', + }, + ], + internalType: 'struct ValidatorV1.ActiveValidator[]', + name: '', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDNodes', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getDNodesLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '_nodeWallet', + type: 'address', + }, + ], + name: 'getNodeInfo', + outputs: [ + { + components: [ + { + internalType: 'address', + name: 'ownerWallet', + type: 'address', + }, + { + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + internalType: 'enum ValidatorV1.NodeType', + name: 'nodeType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'nodeTokens', + type: 'uint256', + }, + { + internalType: 'string', + name: 'nodeApiBaseUrl', + type: 'string', + }, + { + components: [ + { + internalType: 'uint16', + name: 'reportCounter', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'slashCounter', + type: 'uint16', + }, + { + internalType: 'uint128[]', + name: 'reportedInBlocks', + type: 'uint128[]', + }, + { + internalType: 'address[]', + name: 'reportedBy', + type: 'address[]', + }, + { + internalType: 'uint128[]', + name: 'reportedKeys', + type: 'uint128[]', + }, + ], + internalType: 'struct ValidatorV1.NodeCounters', + name: 'counters', + type: 'tuple', + }, + { + internalType: 'enum ValidatorV1.NodeStatus', + name: 'status', + type: 'uint8', + }, + ], + internalType: 'struct ValidatorV1.NodeInfo', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getSNodes', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getSNodesLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVNodes', + outputs: [ + { + internalType: 'address[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVNodesLength', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint16', + name: 'protocolVersion_', + type: 'uint16', + }, + { + internalType: 'address', + name: 'pushToken_', + type: 'address', + }, + { + internalType: 'uint16', + name: 'valPerBlockTarget_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'nodeRandomMinCount_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'nodeRandomPingCount_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'REPORTS_BEFORE_SLASH_V_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'REPORTS_BEFORE_SLASH_S_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'SLASHES_BEFORE_BAN_V_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'SLASHES_BEFORE_BAN_S_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'SLASH_PERCENT_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'BAN_PERCENT_', + type: 'uint16', + }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'minStakeD', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'minStakeS', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'minStakeV', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + name: 'nodeMap', + outputs: [ + { + internalType: 'address', + name: 'ownerWallet', + type: 'address', + }, + { + internalType: 'address', + name: 'nodeWallet', + type: 'address', + }, + { + internalType: 'enum ValidatorV1.NodeType', + name: 'nodeType', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'nodeTokens', + type: 'uint256', + }, + { + internalType: 'string', + name: 'nodeApiBaseUrl', + type: 'string', + }, + { + components: [ + { + internalType: 'uint16', + name: 'reportCounter', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'slashCounter', + type: 'uint16', + }, + { + internalType: 'uint128[]', + name: 'reportedInBlocks', + type: 'uint128[]', + }, + { + internalType: 'address[]', + name: 'reportedBy', + type: 'address[]', + }, + { + internalType: 'uint128[]', + name: 'reportedKeys', + type: 'uint128[]', + }, + ], + internalType: 'struct ValidatorV1.NodeCounters', + name: 'counters', + type: 'tuple', + }, + { + internalType: 'enum ValidatorV1.NodeStatus', + name: 'status', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nodeRandomMinCount', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nodeRandomPingCount', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'pendingOwner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolVersion', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'proxiableUUID', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from_', + type: 'address', + }, + { + internalType: 'address', + name: 'to_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount_', + type: 'uint256', + }, + ], + name: 'redistributeStaked', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'nodeTokens_', + type: 'uint256', + }, + { + internalType: 'enum ValidatorV1.NodeType', + name: 'nodeType_', + type: 'uint8', + }, + { + internalType: 'string', + name: 'nodeApiBaseUrl_', + type: 'string', + }, + { + internalType: 'address', + name: 'nodeWallet_', + type: 'address', + }, + ], + name: 'registerNodeAndStake', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'enum ValidatorV1.NodeType', + name: 'targetNodeType_', + type: 'uint8', + }, + { + internalType: 'bytes', + name: 'voteBlob_', + type: 'bytes', + }, + { + internalType: 'bytes[]', + name: 'signatures_', + type: 'bytes[]', + }, + ], + name: 'reportNode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'addr_', + type: 'address', + }, + ], + name: 'setStorageContract', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'snodes', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'storageContract', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalFees', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'totalStaked', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to_', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount_', + type: 'uint256', + }, + ], + name: 'unstakeFees', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'nodeWallet_', + type: 'address', + }, + ], + name: 'unstakeNode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint16', + name: 'valPerBlockTarget_', + type: 'uint16', + }, + ], + name: 'updateBlockParams', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint16', + name: 'nodeRandomMinCount_', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'nodeRandomPingCount_', + type: 'uint16', + }, + ], + name: 'updateRandomParams', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + ], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newImplementation', + type: 'address', + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'valPerBlock', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'valPerBlockTarget', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'vnodes', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'vnodesActive', + outputs: [ + { + internalType: 'uint16', + name: '', + type: 'uint16', + }, + ], + stateMutability: 'view', + type: 'function', + }, +]; diff --git a/packages/d-node-notif/src/lib/alias/getAliasInfo.ts b/packages/d-node-notif/src/lib/alias/getAliasInfo.ts index a1636293e..c98c8e37e 100644 --- a/packages/d-node-notif/src/lib/alias/getAliasInfo.ts +++ b/packages/d-node-notif/src/lib/alias/getAliasInfo.ts @@ -25,7 +25,7 @@ export const getAliasInfo = async (options: GetAliasInfoOptionsType) => { const aliasChainId: number = ALIAS_CHAIN_ID[aliasChain][env]; const _alias = getCAIPWithChainId(alias, aliasChainId, 'Alias'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/alias`; const requestUrl = `${apiEndpoint}/${_alias}/channel`; diff --git a/packages/d-node-notif/src/lib/channels/_getSubscribers.ts b/packages/d-node-notif/src/lib/channels/_getSubscribers.ts index 60a05a764..10cf311ba 100644 --- a/packages/d-node-notif/src/lib/channels/_getSubscribers.ts +++ b/packages/d-node-notif/src/lib/channels/_getSubscribers.ts @@ -34,7 +34,7 @@ export const _getSubscribers = async ( const chainId = channelCAIPDetails.networkId; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/channels/_get_subscribers`; const requestUrl = `${apiEndpoint}`; diff --git a/packages/d-node-notif/src/lib/channels/getChannel.ts b/packages/d-node-notif/src/lib/channels/getChannel.ts index cd24d0011..976a10b86 100644 --- a/packages/d-node-notif/src/lib/channels/getChannel.ts +++ b/packages/d-node-notif/src/lib/channels/getChannel.ts @@ -17,7 +17,7 @@ export const getChannel = async (options: GetChannelOptionsType) => { const { channel, env = Constants.ENV.PROD, raw = true } = options || {}; const _channel = await getCAIPAddress(env, channel, 'Channel'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/channels`; const requestUrl = `${apiEndpoint}/${_channel}`; diff --git a/packages/d-node-notif/src/lib/channels/getChannelNotifications.ts b/packages/d-node-notif/src/lib/channels/getChannelNotifications.ts index b934999d7..9364ea824 100644 --- a/packages/d-node-notif/src/lib/channels/getChannelNotifications.ts +++ b/packages/d-node-notif/src/lib/channels/getChannelNotifications.ts @@ -25,7 +25,7 @@ export const getChannelNotifications = async ( } = options || {}; const _channel = await getCAIPAddress(env, channel, 'Channel'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v2/channels`; const query = getQueryParams( filter diff --git a/packages/d-node-notif/src/lib/channels/getChannels.ts b/packages/d-node-notif/src/lib/channels/getChannels.ts index 0b463a96b..d9411ab64 100644 --- a/packages/d-node-notif/src/lib/channels/getChannels.ts +++ b/packages/d-node-notif/src/lib/channels/getChannels.ts @@ -27,7 +27,7 @@ export const getChannels = async (options: getChannelsOptionsType) => { order = CONSTANTS.FILTER.CHANNEL_LIST.ORDER.DESCENDING, } = options || {}; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/channels`; const requestUrl = `${apiEndpoint}?page=${page}&limit=${limit}&sort=${sort}&order=${order}`; diff --git a/packages/d-node-notif/src/lib/channels/getDelegates.ts b/packages/d-node-notif/src/lib/channels/getDelegates.ts index c2a81cbfa..1cf3233e7 100644 --- a/packages/d-node-notif/src/lib/channels/getDelegates.ts +++ b/packages/d-node-notif/src/lib/channels/getDelegates.ts @@ -1,34 +1,26 @@ -import { - getCAIPAddress, - getAPIBaseUrls -} from '../helpers'; +import { getCAIPAddress, getAPIBaseUrls } from '../helpers'; import Constants, { ENV } from '../constants'; import { axiosGet } from '../utils/axiosUtil'; /** - * GET v1/channels/${channelAddressInCAIP}/delegates + * GET v1/channels/${channelAddressInCAIP}/delegates */ export type GetDelegatesOptionsType = { /** address of the channel */ channel: string; env?: ENV; -} +}; /** * Returns the list of addresses that the channel has delegated to */ -export const getDelegates = async ( - options : GetDelegatesOptionsType -) => { - const { - channel, - env = Constants.ENV.PROD, - } = options || {}; +export const getDelegates = async (options: GetDelegatesOptionsType) => { + const { channel, env = Constants.ENV.PROD } = options || {}; const _channel = await getCAIPAddress(env, channel, 'Channel'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/channels`; const requestUrl = `${apiEndpoint}/${_channel}/delegates`; @@ -37,4 +29,4 @@ export const getDelegates = async ( .catch((err) => { console.error(`[EPNS-SDK] - API ${requestUrl}: `, err); }); -} +}; diff --git a/packages/d-node-notif/src/lib/channels/getSubscribers.ts b/packages/d-node-notif/src/lib/channels/getSubscribers.ts index ee9090f5c..f8836f413 100644 --- a/packages/d-node-notif/src/lib/channels/getSubscribers.ts +++ b/packages/d-node-notif/src/lib/channels/getSubscribers.ts @@ -9,66 +9,62 @@ import { parseSubscrbersApiResponse } from '../utils/parseSubscribersAPI'; */ export type GetChannelSubscribersOptionsType = { - channel: string; // plain ETH Format only - page?: number, - limit?: number, - category?: number, - setting?: boolean, - env?: ENV, - raw?: boolean -} + channel: string; // plain ETH Format only + page?: number; + limit?: number; + category?: number; + setting?: boolean; + env?: ENV; + raw?: boolean; +}; export const getSubscribers = async ( options: GetChannelSubscribersOptionsType ): Promise<Subscribers> => { - try { - const { - channel, - page = 1, - limit = 10, - category = null, - setting = false, - env = Constants.ENV.PROD, - raw = true + channel, + page = 1, + limit = 10, + category = null, + setting = false, + env = Constants.ENV.PROD, + raw = true, } = options || {}; try { - if (channel == null || channel.length == 0) { - throw new Error(`channel cannot be null or empty`); - } + if (channel == null || channel.length == 0) { + throw new Error(`channel cannot be null or empty`); + } - if (page <= 0) { - throw new Error("page must be greater than 0"); - } + if (page <= 0) { + throw new Error('page must be greater than 0'); + } - if (limit <= 0) { - throw new Error("limit must be greater than 0"); - } + if (limit <= 0) { + throw new Error('limit must be greater than 0'); + } - if (limit > 30) { - throw new Error("limit must be lesser than or equal to 30"); - } - const _channel = await getCAIPAddress(env, channel, 'Channel'); - const API_BASE_URL = getAPIBaseUrls(env); - let apiEndpoint = `${API_BASE_URL}/v1/channels/${_channel}/subscribers?page=${page}&limit=${limit}&setting=${setting}`; - if(category){ - apiEndpoint = apiEndpoint+`&category=${category}` - } - return await axiosGet(apiEndpoint) - .then((response) => { - if(raw) - return response.data - else - return parseSubscrbersApiResponse(response.data) - }) - .catch((err) => { - console.error(`[Push SDK] - API ${apiEndpoint}: `, err); - }); + if (limit > 30) { + throw new Error('limit must be lesser than or equal to 30'); + } + const _channel = await getCAIPAddress(env, channel, 'Channel'); + const API_BASE_URL = await getAPIBaseUrls(env); + let apiEndpoint = `${API_BASE_URL}/v1/channels/${_channel}/subscribers?page=${page}&limit=${limit}&setting=${setting}`; + if (category) { + apiEndpoint = apiEndpoint + `&category=${category}`; + } + return await axiosGet(apiEndpoint) + .then((response) => { + if (raw) return response.data; + else return parseSubscrbersApiResponse(response.data); + }) + .catch((err) => { + console.error(`[Push SDK] - API ${apiEndpoint}: `, err); + }); } catch (err) { - console.error(`[Push SDK] - API - Error - API send() -: `, err); - throw Error(`[Push SDK] - API - Error - API send() -: ${err}`); + console.error(`[Push SDK] - API - Error - API send() -: `, err); + throw Error(`[Push SDK] - API - Error - API send() -: ${err}`); } } catch (err) { console.error(`[Push SDK] - API - Error - API send() -: `, err); diff --git a/packages/d-node-notif/src/lib/channels/search.ts b/packages/d-node-notif/src/lib/channels/search.ts index 0abe5a628..f001e15fb 100644 --- a/packages/d-node-notif/src/lib/channels/search.ts +++ b/packages/d-node-notif/src/lib/channels/search.ts @@ -1,11 +1,11 @@ import { getAPIBaseUrls, getQueryParams, getLimit } from '../helpers'; -import Constants, {ENV} from '../constants'; +import Constants, { ENV } from '../constants'; import { axiosGet } from '../utils/axiosUtil'; /** - * GET /v1/channels/search/ + * GET /v1/channels/search/ * optional params: page=(1)&limit=(20{min:1}{max:30})&query=(searchquery) - * + * */ export type SearchChannelOptionsType = { @@ -13,11 +13,9 @@ export type SearchChannelOptionsType = { env?: ENV; page?: number; limit?: number; -} +}; -export const search = async ( - options: SearchChannelOptionsType -) => { +export const search = async (options: SearchChannelOptionsType) => { const { query, env = Constants.ENV.PROD, @@ -26,12 +24,12 @@ export const search = async ( } = options || {}; if (!query) throw Error('"query" not provided!'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/channels/search/`; const queryObj = { page, limit: getLimit(limit), - query: query + query: query, }; const requestUrl = `${apiEndpoint}?${getQueryParams(queryObj)}`; return axiosGet(requestUrl) @@ -39,4 +37,4 @@ export const search = async ( .catch((err) => { console.error(`[Push SDK] - API ${requestUrl}: `, err); }); -} +}; diff --git a/packages/d-node-notif/src/lib/chat/helpers/service.ts b/packages/d-node-notif/src/lib/chat/helpers/service.ts index 2ba85e554..baae8fd3e 100644 --- a/packages/d-node-notif/src/lib/chat/helpers/service.ts +++ b/packages/d-node-notif/src/lib/chat/helpers/service.ts @@ -35,7 +35,7 @@ export const createUserService = async (options: CreateUserOptionsType) => { } = options || {}; let { user } = options || {}; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const requestUrl = `${API_BASE_URL}/v2/users/`; @@ -88,7 +88,7 @@ export const authUpdateUserService = async (options: CreateUserOptionsType) => { env = Constants.ENV.PROD, } = options || {}; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const requestUrl = `${API_BASE_URL}/v2/users/${walletToPCAIP10(user)}/auth`; diff --git a/packages/d-node-notif/src/lib/config.ts b/packages/d-node-notif/src/lib/config.ts index 2fe58b612..fe88edc0d 100644 --- a/packages/d-node-notif/src/lib/config.ts +++ b/packages/d-node-notif/src/lib/config.ts @@ -2,6 +2,7 @@ import { ENV } from './constants'; import { coreABI } from './abis/core'; import { commABI } from './abis/comm'; import { tokenABI } from './abis/token'; +import { validatorABI } from './abis/validator'; import { mainnet, polygon, @@ -20,6 +21,7 @@ import { polygonZkEvmCardona, cyberTestnet, cyber, + localhost, } from 'viem/chains'; // for methods not needing the entire config @@ -30,7 +32,7 @@ export const API_BASE_URL = { /** * **This is for local development only** */ - [ENV.LOCAL]: 'http://localhost:4000/apis', + [ENV.LOCAL]: 'http://localhost:4001/apis', }; const BLOCKCHAIN_NETWORK = { @@ -69,6 +71,7 @@ export const ETH_CHAIN_ID = { [ENV.DEV]: 11155111, [ENV.LOCAL]: 11155111, }; + export const ALIAS_CHAIN_ID: { [key: string]: { [key in ENV]: number }; } = { @@ -197,7 +200,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', }, }; @@ -347,13 +350,14 @@ const CONFIG = { EPNS_COMMUNICATOR_CONTRACT: '0xA1DF3E68D085aa6918bcc2506b24e499830Db0eB', }, [BLOCKCHAIN_NETWORK.CYBER_CONNECT_TESTNET]: { - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x9cb3bd7550B5c92baA056Fc0F08132f49508145F', }, }, }; export default CONFIG; + export const TOKEN = { [ENV.PROD]: '0xf418588522d5dd018b425E472991E52EBBeEEEEE', [ENV.STAGING]: '0x37c779a1564DCc0e3914aB130e0e787d93e21804', @@ -374,10 +378,12 @@ export const MIN_TOKEN_BALANCE = { [ENV.DEV]: 50, [ENV.LOCAL]: 50, }; + export const ABIS = { CORE: coreABI, COMM: commABI, TOKEN: tokenABI, + VALIDATOR: validatorABI, }; export const CHANNEL_TYPE = { @@ -525,27 +531,27 @@ export const VIEM_CONFIG = { [ENV.LOCAL]: { [BLOCKCHAIN_NETWORK.ETH_SEPOLIA]: { NETWORK: sepolia, - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x9dDCD7ed7151afab43044E4D694FA064742C428c', }, [BLOCKCHAIN_NETWORK.POLYGON_AMOY]: { NETWORK: polygonAmoy, - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x9cb3bd7550b5c92baa056fc0f08132f49508145f', }, [BLOCKCHAIN_NETWORK.BSC_TESTNET]: { NETWORK: bscTestnet, - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x4132061E3349ff36cFfCadA460E10Bd4f31F7ea8', }, [BLOCKCHAIN_NETWORK.OPTIMISM_TESTNET]: { NETWORK: optimismSepolia, - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x754787358fac861ef904c92d54f7adb659779317', }, [BLOCKCHAIN_NETWORK.POLYGON_ZK_EVM_TESTNET]: { NETWORK: polygonZkEvmCardona, - API_BASE_URL: API_BASE_URL[ENV.DEV], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x9cb3bd7550b5c92baa056fc0f08132f49508145f', }, [BLOCKCHAIN_NETWORK.ARBITRUM_TESTNET]: { @@ -565,7 +571,7 @@ export const VIEM_CONFIG = { }, [BLOCKCHAIN_NETWORK.CYBER_CONNECT_TESTNET]: { NETWORK: cyberTestnet, - API_BASE_URL: API_BASE_URL[ENV.STAGING], + API_BASE_URL: API_BASE_URL[ENV.LOCAL], EPNS_COMMUNICATOR_CONTRACT: '0x9cb3bd7550B5c92baA056Fc0F08132f49508145F', }, }, @@ -579,3 +585,22 @@ export const ALPHA_FEATURE_CONFIG = { feature: [] as string[], }, }; + +export const VALIDATOR_CONFIG = { + [ENV.PROD]: { + NETWORK: mainnet, + VALIDATOR_CONTRACT: 'TODO', + }, + [ENV.STAGING]: { + NETWORK: sepolia, + VALIDATOR_CONTRACT: 'TODO', + }, + [ENV.DEV]: { + NETWORK: sepolia, + VALIDATOR_CONTRACT: 'TODO', + }, + [ENV.LOCAL]: { + NETWORK: localhost, + VALIDATOR_CONTRACT: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9', + }, +}; diff --git a/packages/d-node-notif/src/lib/helpers/config.ts b/packages/d-node-notif/src/lib/helpers/config.ts index 3a48744dc..29812a4ed 100644 --- a/packages/d-node-notif/src/lib/helpers/config.ts +++ b/packages/d-node-notif/src/lib/helpers/config.ts @@ -1,21 +1,21 @@ import CONFIG, { API_BASE_URL, ConfigType } from '../config'; -import {ENV} from '../constants'; +import { ENV } from '../constants'; +import { PushValidator } from '../pushValidator/pushValidator'; /** * This config helper returns the API url as well as the * EPNS communicator contract method address */ export const getConfig = ( - env: ENV, + env: ENV, { blockchain, - networkId + networkId, }: { - blockchain: string, - networkId: string + blockchain: string; + networkId: string; } ): ConfigType => { - const blockchainSelector = `${blockchain}:${networkId}`; const configuration = CONFIG[env][blockchainSelector]; @@ -25,17 +25,17 @@ export const getConfig = ( env: ${env}, blockchain: ${blockchain}, networkId: ${networkId} - `) + `); } return configuration; }; - /** * This config helper returns only the API urls */ -export function getAPIBaseUrls(env: ENV) { +export async function getAPIBaseUrls(env: ENV) { if (!env) throw Error('ENV not provided!'); - return API_BASE_URL[env]; -} \ No newline at end of file + const pushValidator = await PushValidator.initalize({ env }); + return `${pushValidator.activeValidatorURL}/apis`; +} diff --git a/packages/d-node-notif/src/lib/helpers/crypto.ts b/packages/d-node-notif/src/lib/helpers/crypto.ts index f71c071db..d21be8ddb 100644 --- a/packages/d-node-notif/src/lib/helpers/crypto.ts +++ b/packages/d-node-notif/src/lib/helpers/crypto.ts @@ -583,3 +583,11 @@ export const validatePssword = (password: string) => { throw new Error('Password must contain at least one special character!'); } }; + +export const getRandomElement = <T>(array: T[]): T => { + if (array.length === 0) { + throw new Error('Array is empty'); + } + const randomIndex = Math.floor(Math.random() * array.length); + return array[randomIndex]; +}; diff --git a/packages/d-node-notif/src/lib/payloads/sendNotifications.ts b/packages/d-node-notif/src/lib/payloads/sendNotifications.ts index ea02b3c12..36b68c035 100644 --- a/packages/d-node-notif/src/lib/payloads/sendNotifications.ts +++ b/packages/d-node-notif/src/lib/payloads/sendNotifications.ts @@ -155,7 +155,7 @@ export async function sendNotification(options: ISendNotificationInputOptions) { const uuid = getUUID(); const chainId = parseInt(channelCAIPDetails.networkId, 10); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); let COMMUNICATOR_CONTRACT = ''; if (senderType === 0) { const { EPNS_COMMUNICATOR_CONTRACT } = getConfig(env, channelCAIPDetails); diff --git a/packages/d-node-notif/src/lib/pushNotification/pushNotificationBase.ts b/packages/d-node-notif/src/lib/pushNotification/pushNotificationBase.ts index 9953abbde..78a15374f 100644 --- a/packages/d-node-notif/src/lib/pushNotification/pushNotificationBase.ts +++ b/packages/d-node-notif/src/lib/pushNotification/pushNotificationBase.ts @@ -917,7 +917,7 @@ export class PushNotificationBaseClass { * @returns Channel info for the alias */ private async getAliasInfo(aliasInCaip: string) { - const API_BASE_URL = getAPIBaseUrls(this.env!); + const API_BASE_URL = await getAPIBaseUrls(this.env!); const apiEndpoint = `${API_BASE_URL}/v1/alias`; const requestUrl = `${apiEndpoint}/${aliasInCaip}/channel`; diff --git a/packages/d-node-notif/src/lib/pushValidator/pushValidator.ts b/packages/d-node-notif/src/lib/pushValidator/pushValidator.ts new file mode 100644 index 000000000..4f517aa96 --- /dev/null +++ b/packages/d-node-notif/src/lib/pushValidator/pushValidator.ts @@ -0,0 +1,144 @@ +import axios from 'axios'; +import { getRandomElement } from '../helpers'; +import { + ActiveValidator, + PingReply, + TokenReply, + ValidatorContract, +} from './pushValidatorTypes'; +import { axiosGet } from '../utils/axiosUtil'; +import { createPublicClient, getContract, http } from 'viem'; +import * as config from '../config'; +import { ENV } from '../constants'; + +/** + * @description Push validator class is used for the following: + * - Interact with validator.sol ( Only Read calls ) + * - Get token to interact with a random validator node + * - Ping a random validator node to check if it is alive + */ +export class PushValidator { + private static instance: PushValidator; + private validatorContractClient: ValidatorContract; + /** + * @dev - active validator URL ( Used for Get calls to a validator node ) + */ + public activeValidatorURL: string; + public env: ENV; + + private constructor( + activeValidatorURL: string, + env: ENV, + validatorContractClient: ValidatorContract + ) { + this.activeValidatorURL = activeValidatorURL; + this.env = env; + this.validatorContractClient = validatorContractClient; + } + + static initalize = async (options?: { env: ENV }): Promise<PushValidator> => { + const settings = options || { env: ENV.STAGING }; + + /** + * @dev - If instance is not created or env is different, create a new instance + */ + if ( + !PushValidator.instance || + PushValidator.instance.env !== settings.env + ) { + const validatorContractClient = + PushValidator.createValidatorContractClient(settings.env); + const activeValidator = await PushValidator.getActiveValidator( + validatorContractClient + ); + PushValidator.instance = new PushValidator( + activeValidator.nodeApiBaseUrl, + settings.env, + validatorContractClient + ); + } + return PushValidator.instance; + }; + + /** + * @description Get validator node token + * @returns Token reply object with API token and validator URL + */ + getToken = async (): Promise<TokenReply | null> => { + const activeValidator = await PushValidator.getActiveValidator( + this.validatorContractClient + ); + const requestUrl = `${activeValidator.nodeApiBaseUrl}/apis/v1/messaging/validatorToken`; + return await axiosGet(requestUrl) + .then((response) => { + if (response.status != 200) { + throw new Error( + `error status: ${response.status} data: ${response.data}` + ); + } + return response.data; + }) + .catch((err) => { + console.error(`[Push SDK] - API ${requestUrl}: `, err); + return null; + }); + }; + + /** + * @description Ping validator + * @param validatorUrl - Validator URL to ping (default is active validator URL) + * @returns Ping reply object + */ + ping = async ( + validatorUrl: string = this.activeValidatorURL + ): Promise<PingReply | null> => { + const requestUrl = `${validatorUrl}/apis/v1/messaging/ping`; + return await axiosGet(requestUrl) + .then((response) => { + if (response.status != 200) { + throw new Error( + `error status: ${response.status} data: ${response.data}` + ); + } + return response.data; + }) + .catch((err) => { + console.error(`[Push SDK] - API ${requestUrl}: `, err); + return null; + }); + }; + + /** + * @description Get active validator + * @returns Active validator object + */ + private static getActiveValidator = async ( + validatorContractClient: ValidatorContract + ): Promise<ActiveValidator> => { + const activeValidators = + await validatorContractClient.read.getActiveVNodes(); + return getRandomElement(activeValidators); + }; + + /** + * @description Create validator contract client + * @param env - Environment + * @dev - Currently only supports public client + * @returns Validator contract client + */ + private static createValidatorContractClient = ( + env: ENV + ): ValidatorContract => { + const client = createPublicClient({ + chain: config.VALIDATOR_CONFIG[env].NETWORK, + transport: http(), + }); + return getContract({ + abi: config.ABIS.VALIDATOR, + address: config.VALIDATOR_CONFIG[env].VALIDATOR_CONTRACT as `0x${string}`, + client: { + public: client, + }, + }) as any; + }; +} diff --git a/packages/d-node-notif/src/lib/pushValidator/pushValidatorTypes.ts b/packages/d-node-notif/src/lib/pushValidator/pushValidatorTypes.ts new file mode 100644 index 000000000..3cf10ebe8 --- /dev/null +++ b/packages/d-node-notif/src/lib/pushValidator/pushValidatorTypes.ts @@ -0,0 +1,44 @@ +export type TokenReply = { validatorToken: string; validatorUrl: string }; + +export type PingReply = { + nodeId: string; + tsMillis: number; + status: string; +}; + +export type ActiveValidator = { + nodeWallet: string; + nodeApiBaseUrl: string; +}; + +/** + * @description Validator contract interface ( VIEM CLIENT ) + */ +export type ValidatorContract = { + read: { + getActiveVNodes(): Promise<ActiveValidator[]>; + nodeMap(address: string): Promise<NodeInfo>; + }; +}; + +type NodeInfo = { + ownerWallet: string; + nodeWallet: string; + nodeType: NodeType; + nodeApiBaseUrl: string; + status: NodeStatus; +}; + +enum NodeType { + VNode = 0, // validator 0 + SNode = 1, // storage 1 + DNode = 2, // delivery 2 +} + +enum NodeStatus { + OK, + Reported, + Slashed, + BannedAndUnstaked, + Unstaked, +} diff --git a/packages/d-node-notif/src/lib/user/getDelegations.ts b/packages/d-node-notif/src/lib/user/getDelegations.ts index fe7fc175a..3497cc10a 100644 --- a/packages/d-node-notif/src/lib/user/getDelegations.ts +++ b/packages/d-node-notif/src/lib/user/getDelegations.ts @@ -1,7 +1,4 @@ -import { - getCAIPAddress, - getAPIBaseUrls -} from '../helpers'; +import { getCAIPAddress, getAPIBaseUrls } from '../helpers'; import Constants, { ENV } from '../constants'; import { axiosGet } from '../utils/axiosUtil'; @@ -13,22 +10,17 @@ export type UserDelegationsOptionsType = { /** wallet address of user */ user: string; env?: ENV; -} +}; /** * Returns the list of channels that the user has been delegated to */ -export const getDelegations = async ( - options : UserDelegationsOptionsType -) => { - const { - user, - env = Constants.ENV.PROD, - } = options || {}; +export const getDelegations = async (options: UserDelegationsOptionsType) => { + const { user, env = Constants.ENV.PROD } = options || {}; const _user = await getCAIPAddress(env, user, 'User'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/users/${_user}/delegations`; const requestUrl = `${apiEndpoint}`; @@ -37,4 +29,4 @@ export const getDelegations = async ( .catch((err) => { console.error(`[EPNS-SDK] - API ${requestUrl}: `, err); }); -} +}; diff --git a/packages/d-node-notif/src/lib/user/getFeeds.ts b/packages/d-node-notif/src/lib/user/getFeeds.ts index 4317838f8..6594499bf 100644 --- a/packages/d-node-notif/src/lib/user/getFeeds.ts +++ b/packages/d-node-notif/src/lib/user/getFeeds.ts @@ -4,7 +4,7 @@ import { getQueryParams, getLimit, } from '../helpers'; -import Constants, {ENV} from '../constants'; +import Constants, { ENV } from '../constants'; import { parseApiResponse } from '../utils'; import { axiosGet } from '../utils/axiosUtil'; @@ -15,11 +15,9 @@ export type FeedsOptionsType = { limit?: number; spam?: boolean; raw?: boolean; -} +}; -export const getFeeds = async ( - options: FeedsOptionsType -) => { +export const getFeeds = async (options: FeedsOptionsType) => { const { user, env = Constants.ENV.PROD, @@ -30,13 +28,13 @@ export const getFeeds = async ( } = options || {}; const _user = await getCAIPAddress(env, user, 'User'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/users/${_user}/feeds`; const queryObj = { page, limit: getLimit(limit), - spam + spam, }; const requestUrl = `${apiEndpoint}?${getQueryParams(queryObj)}`; @@ -50,4 +48,4 @@ export const getFeeds = async ( .catch((err) => { console.error(`[Push SDK] - API ${requestUrl}: `, err); }); -} +}; diff --git a/packages/d-node-notif/src/lib/user/getFeedsPerChannel.ts b/packages/d-node-notif/src/lib/user/getFeedsPerChannel.ts index a82dcc3e2..e0c0a3bb1 100644 --- a/packages/d-node-notif/src/lib/user/getFeedsPerChannel.ts +++ b/packages/d-node-notif/src/lib/user/getFeedsPerChannel.ts @@ -32,7 +32,7 @@ export const getFeedsPerChannel = async ( } = options || {}; const _user = await getCAIPAddress(env, user, 'User'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); if (channels.length == 0) { throw new Error('channels cannot be empty'); } diff --git a/packages/d-node-notif/src/lib/user/getSubscriptions.ts b/packages/d-node-notif/src/lib/user/getSubscriptions.ts index d67d2f994..ed88d38c2 100644 --- a/packages/d-node-notif/src/lib/user/getSubscriptions.ts +++ b/packages/d-node-notif/src/lib/user/getSubscriptions.ts @@ -21,14 +21,15 @@ export const getSubscriptions = async ( } = options || {}; const _user = await getCAIPAddress(env, user, 'User'); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v1/users/${_user}/subscriptions`; - const query = channel? getQueryParams({ - channel: channel - }): "" + const query = channel + ? getQueryParams({ + channel: channel, + }) + : ''; const requestUrl = `${apiEndpoint}?${query}`; - return axiosGet(requestUrl) .then((response) => { if (raw) { diff --git a/packages/d-node-notif/src/lib/user/getUser.ts b/packages/d-node-notif/src/lib/user/getUser.ts index ee67b568b..aefb69cfe 100644 --- a/packages/d-node-notif/src/lib/user/getUser.ts +++ b/packages/d-node-notif/src/lib/user/getUser.ts @@ -11,7 +11,7 @@ export const get = async (options: AccountEnvOptionsType): Promise<IUser> => { throw new Error(`Invalid address!`); } const caip10 = walletToPCAIP10(account); - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const requestUrl = `${API_BASE_URL}/v2/users/?caip10=${caip10}`; return axiosGet(requestUrl) .then(async (response) => { diff --git a/packages/d-node-notif/src/lib/user/getUsersBatch.ts b/packages/d-node-notif/src/lib/user/getUsersBatch.ts index 03b3b05a0..74e7845d0 100644 --- a/packages/d-node-notif/src/lib/user/getUsersBatch.ts +++ b/packages/d-node-notif/src/lib/user/getUsersBatch.ts @@ -13,7 +13,7 @@ export interface GetBatchType { export const getBatch = async (options: GetBatchType): Promise<IUser> => { const { env = Constants.ENV.PROD, userIds } = options || {}; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const requestUrl = `${API_BASE_URL}/v2/users/batch`; const MAX_USER_IDS_LENGTH = 100; diff --git a/packages/d-node-notif/src/lib/user/profile.updateUser.ts b/packages/d-node-notif/src/lib/user/profile.updateUser.ts index e33d76bad..31d1fdbf3 100644 --- a/packages/d-node-notif/src/lib/user/profile.updateUser.ts +++ b/packages/d-node-notif/src/lib/user/profile.updateUser.ts @@ -102,7 +102,7 @@ export const profileUpdateCore = async ( const body = { ...updatedProfile, verificationProof }; - const API_BASE_URL = getAPIBaseUrls(env); + const API_BASE_URL = await getAPIBaseUrls(env); const apiEndpoint = `${API_BASE_URL}/v2/users/${user.did}/profile`; // Report Progress diff --git a/packages/d-node-notif/tests/.env.sample b/packages/d-node-notif/tests/.env.sample index 1111df0ea..5beb47713 100644 --- a/packages/d-node-notif/tests/.env.sample +++ b/packages/d-node-notif/tests/.env.sample @@ -1,6 +1,6 @@ # MAKE A COPY OF THIS AND FILL WITH YOUR CREDENTIALS AND NAME IT .env (Remove .sample Part) -# ENVIRONMENT | 'STAGING' or 'PROD' or 'DEV' +# ENVIRONMENT | 'STAGING' or 'PROD' or 'DEV' or 'LOCAL' ENV=env_name ## CHANNEL WITH ALIAS diff --git a/packages/d-node-notif/tests/lib/initialize/initialize.test.ts b/packages/d-node-notif/tests/lib/initialize/initialize.test.ts new file mode 100644 index 000000000..fe6f12c06 --- /dev/null +++ b/packages/d-node-notif/tests/lib/initialize/initialize.test.ts @@ -0,0 +1,22 @@ +import { PushAPI } from '../../../src/lib/pushAPI/PushAPI'; +import { expect } from 'chai'; +import { ethers } from 'ethers'; +import { ENV } from '../../../src/lib/constants'; + +describe('PushAPI.channel functionality', () => { + // accessing env dynamically using process.env + const envMode = process.env.ENV as keyof typeof ENV; + const env = ENV[envMode]; + + let signer: ethers.Wallet; + + beforeEach(async () => { + signer = ethers.Wallet.createRandom(); + }); + + it('Initialize user with validator node', async () => { + await PushAPI.initialize(signer, { + env, + }); + }); +}); diff --git a/packages/d-node-notif/tests/lib/pushValidator/pushValidator.test.ts b/packages/d-node-notif/tests/lib/pushValidator/pushValidator.test.ts new file mode 100644 index 000000000..a7c4cd894 --- /dev/null +++ b/packages/d-node-notif/tests/lib/pushValidator/pushValidator.test.ts @@ -0,0 +1,57 @@ +import { PushValidator } from '../../../src/lib/pushValidator/pushValidator'; +import { expect } from 'chai'; +import { ethers } from 'ethers'; +import { ENV } from '../../../src/lib/constants'; +import { ActiveValidator } from '../../../src/lib/pushValidator/pushValidatorTypes'; + +describe.only('PushValidator Class', () => { + // accessing env dynamically using process.env + const envMode = process.env.ENV as keyof typeof ENV; + const env = ENV[envMode]; + + it('Initialize PushValidator', async () => { + const validatorInstance = await PushValidator.initalize({ env }); + expect(validatorInstance.env).to.equal(env); + + /** + * @dev - TS is a funny language, add `any` and access private properties + */ + const activeValidators = ( + (await ( + validatorInstance as any + ).validatorContractClient.read.getActiveVNodes()) as [] + ).map((each) => { + return (each as any).nodeApiBaseUrl; + }); + + expect(validatorInstance.activeValidatorURL).to.be.oneOf(activeValidators); + }); + it('Ping every active validator node', async () => { + const validatorInstance = await PushValidator.initalize({ env }); + + const activeValidators: ActiveValidator[] = await ( + validatorInstance as any + ).validatorContractClient.read.getActiveVNodes(); + + for (const each of activeValidators) { + const pingReply = await validatorInstance.ping(each.nodeApiBaseUrl); + expect(pingReply).to.not.be.null; + expect(pingReply?.nodeId).to.equal(each.nodeWallet); + expect(pingReply?.status).to.equal(1); + } + }); + it('Ping active read validator node', async () => { + const validatorInstance = await PushValidator.initalize({ env }); + // default active read validator + const pingReply = await validatorInstance.ping(); + expect(pingReply).to.not.be.null; + expect(pingReply?.status).to.equal(1); + }); + it('Get token from random active validator node', async () => { + const validatorInstance = await PushValidator.initalize({ env }); + const token = await validatorInstance.getToken(); + expect(token).to.not.be.null; + expect(token?.validatorToken).to.be.string; + expect(token?.validatorUrl).to.be.string; + }); +});