diff --git a/src/constants.ts b/src/constants.ts index 20edc41..3b34d5a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -143,10 +143,10 @@ export const AVAILABLE_SPLITTER_CHAINS = [FORK_MAPPING["0x00000000"], FORK_MAPPI export const CHAIN_CONFIGURATION = { [AVAILABLE_SPLITTER_CHAINS[0]]: { - SPLITMAIN_ADDRESS: "0xfC8a305728051367797DADE6Aa0344E0987f5286", - MULTICALL_ADDRESS: "0xcA11bde05977b3631167028862bE2a173976CA11", - OWR_FACTORY_ADDRESS: "0xc0961353fcc43a99e3041db07ac646720e116256", - RETROACTIVE_FUNDING_ADDRESS: "0x43F641fA70e09f0326ac66b4Ef0C416EaEcBC6f5" + SPLITMAIN_ADDRESS: "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE", + MULTICALL_ADDRESS: "0xeefba1e63905ef1d7acba5a8513c70307c1ce441", + OWR_FACTORY_ADDRESS: "0x119acd7844cbdd5fc09b1c6a4408f490c8f7f522", + RETROACTIVE_FUNDING_ADDRESS: "0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d" }, [AVAILABLE_SPLITTER_CHAINS[1]]: { diff --git a/src/index.ts b/src/index.ts index 4775b63..8ce88e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -147,9 +147,10 @@ export class Client extends Base { const retroActiveFundingRecipient = { account: CHAIN_CONFIGURATION[this.chainId].RETROACTIVE_FUNDING_ADDRESS, percentAllocation: RETROACTIVE_FUNDING_SPLIT } - splitRecipients.push(retroActiveFundingRecipient) + const copiedSplitRecipients= [...splitRecipients] + copiedSplitRecipients.push(retroActiveFundingRecipient) - const { accounts, percentAllocations } = formatSplitRecipients(splitRecipients) + const { accounts, percentAllocations } = formatSplitRecipients(copiedSplitRecipients) const predictedSplitterAddress = await predictSplitterAddress({ signer: this.signer, accounts, percentAllocations, chainId:this.chainId }); const isSplitterDeployed = await isContractAvailable( predictedSplitterAddress, diff --git a/src/types.ts b/src/types.ts index eb338ff..1d78479 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,6 +5,9 @@ export enum FORK_MAPPING { /** Mainnet. */ '0x00000000' = 1, + /** Goerli/Prater. */ + '0x00001020' = 5, + /** Gnosis Chain. */ '0x00000064' = 100, diff --git a/test/methods.test.ts b/test/methods.test.ts index 8496b93..006e8ec 100644 --- a/test/methods.test.ts +++ b/test/methods.test.ts @@ -1,4 +1,4 @@ -import { ethers } from 'ethers'; +import { ethers, JsonRpcProvider } from 'ethers'; import { Client, validateClusterLock } from '../src/index'; import { clusterConfigV1X7, @@ -14,6 +14,9 @@ import { validatePayload } from '../src/ajv'; import { HttpResponse, http } from 'msw'; import { setupServer } from 'msw/node'; import { hashTermsAndConditions } from '../src/verification/termsAndConditions'; +import * as utils from '../src/utils'; +import * as splitsHelpers from '../src/splitHelpers'; + /* eslint no-new: 0 */ describe('Cluster Client', () => { @@ -21,22 +24,15 @@ describe('Cluster Client', () => { '0x1f6c94e6c070393a68c1aa6073a21cb1fd57f0e14d2a475a2958990ab728c2fd'; const mnemonic = ethers.Wallet.createRandom().mnemonic?.phrase ?? ''; const privateKey = ethers.Wallet.fromPhrase(mnemonic).privateKey; - const wallet = new ethers.Wallet(privateKey); - const mockSigner = wallet.connect(null); + const provider = new JsonRpcProvider(`https://ethereum-holesky.publicnode.com`); + const wallet = new ethers.Wallet(privateKey, provider); + const mockSigner = wallet.connect(provider); const clientInstance = new Client( - { baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 5 }, + { baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, mockSigner, ); - // test('throws invalid ChainId when it is equal to 1', async () => { - // try { - // new Client({ chainId: 1 }, mockSigner) - // } catch (error: any) { - // expect(error.message).toBe('Obol-SDK is in Beta phase, mainnet is not yet supported') - // } - // }) - test('createTermsAndConditions should return "successful authorization"', async () => { clientInstance['request'] = jest .fn() @@ -190,7 +186,7 @@ describe('Cluster Client', () => { describe('Cluster Client without a signer', () => { const clientInstance = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', - chainId: 5, + chainId: 17000, }); test('createClusterDefinition should throw an error without signer', async () => { @@ -281,3 +277,82 @@ describe('Cluster Client without a signer', () => { ); }); }); + +describe('createObolRewardSplit', () => { + + jest.spyOn(utils, 'isContractAvailable').mockImplementation(() => Promise.resolve(true)); + jest.spyOn(splitsHelpers, 'predictSplitterAddress').mockImplementation(() => Promise.resolve("0xPredictedAddress")); + jest.spyOn(splitsHelpers, 'handleDeployRewardsSplitter').mockImplementation(() => Promise.resolve({ + withdrawal_address: '0xWithdrawalAddress', + fee_recipient_address: '0xFeeRecipientAddress', + })); + + + // const isContractAvailable = jest.fn().mockReturnValue( + // Promise.resolve(true)); + + // jest.mock('../src/splitHelpers', () => ({ + // ...jest.requireActual('../src/splitHelpers'), + // predictSplitterAddress: jest.fn().mockReturnValue( + // Promise.resolve("0xPredictedAddress")), + // handleDeployRewardsSplitter: jest.fn().mockReturnValue( + // Promise.resolve({ + // withdrawal_address: '0xWithdrawalAddress', + // fee_recipient_address: '0xFeeRecipientAddress', + // })), + // })); + + // jest.mock('../src/utils', () => + // isContractAvailable + // ); + + const mnemonic = ethers.Wallet.createRandom().mnemonic?.phrase ?? ''; + const privateKey = ethers.Wallet.fromPhrase(mnemonic).privateKey; + const provider = new JsonRpcProvider(`https://ethereum-holesky.publicnode.com`); + const wallet = new ethers.Wallet(privateKey, provider); + const mockSigner = wallet.connect(provider); + + const clientInstance = new Client( + { baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, + mockSigner, + ); + + const clientInstanceWithourSigner = new Client( + { baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, + ); + const mockSplitRecipients = [{ account: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC', percentAllocation: 99 }]; + const mockPrincipalRecipient = '0x86B8145c98e5BD25BA722645b15eD65f024a87EC'; + const mockValidatorsSize = 2; + + + it('should throw an error if signer is not defined', async () => { + await expect( + clientInstanceWithourSigner.createObolRewardSplit({ splitRecipients: mockSplitRecipients, principalRecipient: mockPrincipalRecipient, validatorsSize: mockValidatorsSize }) + ).rejects.toThrow('Signer is required in createObolRewardSplit'); + }); + + it('should throw an error if chainId is not supported', async () => { + const unsupportedSplitterChainClient = new Client( + { baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 100 }, + mockSigner, + ); + await expect( + unsupportedSplitterChainClient.createObolRewardSplit({ splitRecipients: mockSplitRecipients, principalRecipient: mockPrincipalRecipient, validatorsSize: mockValidatorsSize }) + ).rejects.toThrow(`Splitter configuration is not supported on 100 chain`); + }); + + + it('should return the correct withdrawal and fee recipient addresses', async () => { + const result = await clientInstance.createObolRewardSplit({ + splitRecipients: mockSplitRecipients, + principalRecipient: mockPrincipalRecipient, + validatorsSize: mockValidatorsSize, + }); + + expect(result).toEqual({ + withdrawal_address: '0xWithdrawalAddress', + fee_recipient_address: '0xFeeRecipientAddress', + }); + }); + +}); diff --git a/test/sdk-package-test/yarn.lock b/test/sdk-package-test/yarn.lock index 7a31771..1397fd1 100644 --- a/test/sdk-package-test/yarn.lock +++ b/test/sdk-package-test/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@adraffy/ens-normalize@https://github.com/ricmoo/ens-normalize.js": +"@adraffy/ens-normalize@git+https://github.com/ricmoo/ens-normalize.js.git": version "1.9.0" - resolved "https://github.com/ricmoo/ens-normalize.js#2d040533e57e4f25f9a7cc4715e219658ad454b5" + resolved "git+https://github.com/ricmoo/ens-normalize.js.git#2d040533e57e4f25f9a7cc4715e219658ad454b5" "@ampproject/remapping@^2.2.0": version "2.3.0" @@ -1022,9 +1022,9 @@ integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/superagent@^8.1.0": - version "8.1.8" - resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-8.1.8.tgz#c1080987a3770f26707778caebb86da532d6a24a" - integrity sha512-nTqHJ2OTa7PFEpLahzSEEeFeqbMpmcN7OeayiOc7v+xk+/vyTKljRe+o4MPqSnPeRCMvtxuLG+5QqluUVQJOnA== + version "8.1.9" + resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-8.1.9.tgz#28bfe4658e469838ed0bf66d898354bcab21f49f" + integrity sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ== dependencies: "@types/cookiejar" "^2.1.5" "@types/methods" "^1.1.4" @@ -1673,9 +1673,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001646: - version "1.0.30001651" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138" - integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg== + version "1.0.30001653" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz#b8af452f8f33b1c77f122780a4aecebea0caca56" + integrity sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw== chalk@^2.4.2: version "2.4.2" @@ -1720,9 +1720,9 @@ cids@^1.0.0, cids@^1.1.5: uint8arrays "^3.0.0" cjs-module-lexer@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" - integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== + version "1.4.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz#677de7ed7efff67cc40c9bf1897fea79d41b5215" + integrity sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g== class-is@^1.1.0: version "1.1.0" @@ -2173,9 +2173,9 @@ eslint-import-resolver-node@^0.3.9: resolve "^1.22.4" eslint-module-utils@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" - integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== + version "2.8.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz#2ecad69d71e1fa81f17f7f24d5d3e46b168de663" + integrity sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg== dependencies: debug "^3.2.7"