From c0617530dbc0221aa84cc9c3b356f21b5def6609 Mon Sep 17 00:00:00 2001 From: Rodolphe Marques Date: Wed, 20 Sep 2023 12:02:19 +0200 Subject: [PATCH] feat: initial support for zerodev --- .github/workflows/release-github.yml | 2 +- .github/workflows/release-npm.yml | 2 +- .github/workflows/testing-nightly.yml | 10 +-- .github/workflows/testing-node.yml | 2 +- .github/workflows/testing.yml | 4 +- .nvmrc | 2 +- integration/external/Zerodev.test.ts | 90 +++++++++++++++++++++++++++ package.json | 1 + src/keeper/contracts/ContractBase.ts | 13 +++- src/models/NeverminedOptions.ts | 3 + 10 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 integration/external/Zerodev.test.ts diff --git a/.github/workflows/release-github.yml b/.github/workflows/release-github.yml index 63d353d27..7c3c16151 100644 --- a/.github/workflows/release-github.yml +++ b/.github/workflows/release-github.yml @@ -19,7 +19,7 @@ jobs: # Build process - uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: 18 - name: Set version to env run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index d8c659568..eb8bf61fe 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: '16' + node-version: 18 registry-url: https://registry.npmjs.org/ - run: yarn install --frozen-lockfile --ignore-engines - run: npm publish --access public diff --git a/.github/workflows/testing-nightly.yml b/.github/workflows/testing-nightly.yml index 0ad806eb1..4d678317c 100644 --- a/.github/workflows/testing-nightly.yml +++ b/.github/workflows/testing-nightly.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Install dependencies run: | @@ -55,7 +55,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: nevermined-io/nvm-tools-actions@v0.14.0 with: token: ${{ secrets.API_TOKEN_GITHUB }} @@ -97,7 +97,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: nevermined-io/nvm-tools-actions@v0.14.0 with: token: ${{ secrets.API_TOKEN_GITHUB }} @@ -131,7 +131,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: nevermined-io/nvm-tools-actions@v0.14.0 with: token: ${{ secrets.API_TOKEN_GITHUB }} @@ -167,7 +167,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Install dependencies run: | diff --git a/.github/workflows/testing-node.yml b/.github/workflows/testing-node.yml index 6d5a045f9..36849872b 100644 --- a/.github/workflows/testing-node.yml +++ b/.github/workflows/testing-node.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: actions/checkout@v3 with: repository: nevermined-io/node diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 095a5f425..03d644dfe 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - uses: nevermined-io/nvm-tools-actions@v0.14.0 with: token: ${{ secrets.API_TOKEN_GITHUB }} @@ -55,7 +55,7 @@ jobs: token: ${{ secrets.API_TOKEN_GITHUB }} - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 18 - name: Deploy contracts run: | diff --git a/.nvmrc b/.nvmrc index dae199aec..3c032078a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v12 +18 diff --git a/integration/external/Zerodev.test.ts b/integration/external/Zerodev.test.ts new file mode 100644 index 000000000..c3a9a9361 --- /dev/null +++ b/integration/external/Zerodev.test.ts @@ -0,0 +1,90 @@ +import { HDNodeWallet, Wallet } from 'ethers' +import { assert } from 'chai' +import { ZeroDevEthersProvider, convertEthersSignerToAccountSigner } from '@zerodev/sdk' +import { + Account, + AssetAttributes, + AssetPrice, + EthSignJWT, + Nevermined, + NeverminedOptions, +} from '../../src' +import { getMetadata } from '../utils' + +describe('Nevermined sdk with zerodev', () => { + let projectId: string + let owner: HDNodeWallet + let config: NeverminedOptions + let nevermined: Nevermined + let account: Account + let zerodevProvider: ZeroDevEthersProvider<'ECDSA'> + + before(async () => { + projectId = process.env.PROJECT_ID! + owner = Wallet.createRandom() + account = new Account(await owner.getAddress()) + const infuraToken = process.env.INFURA_TOKEN! + + config = { + marketplaceUri: 'https://marketplace-api.mumbai.nevermined.app', + neverminedNodeUri: 'https://node.mumbai.nevermined.app', + graphHttpUri: 'https://api.thegraph.com/subgraphs/name/nevermined-io/public', + neverminedNodeAddress: '0x5838B5512cF9f12FE9f2beccB20eb47211F9B0bc', + artifactsFolder: './artifacts', + web3ProviderUri: `https://polygon-mumbai.infura.io/v3/${infuraToken}`, + } + }) + + it('should instantiate nevermined sdk with a zerodev provider', async () => { + zerodevProvider = await ZeroDevEthersProvider.init('ECDSA', { + projectId, + owner: convertEthersSignerToAccountSigner(owner as any), + }) + + nevermined = await Nevermined.getInstance({ + ...config, + zerodevProvider: zerodevProvider, + }) + + assert.isDefined(nevermined) + }) + + it('should login to the marketplace api', async () => { + const accountSigner = zerodevProvider.getAccountSigner() + + const clientAssertion = await new EthSignJWT({ + iss: account.getId(), + }) + .setProtectedHeader({ alg: 'ES256K' }) + .setIssuedAt() + .setExpirationTime('1h') + .ethSign(accountSigner as any) + + await nevermined.services.marketplace.login(clientAssertion) + }) + + it('should request some nevermined tokens', async () => { + const accountSigner = zerodevProvider.getAccountSigner() + const accountAddress = await accountSigner.getAddress() + + console.log('requesting tokens for account', accountAddress) + const result = await nevermined.keeper.dispenser.requestTokens(10, accountAddress) + assert.isDefined(result) + }) + + it('should create a new asset with zerodev provider', async () => { + const assetAttributes = AssetAttributes.getInstance({ + metadata: getMetadata(), + services: [ + { + serviceType: 'access', + price: new AssetPrice(await owner.getAddress(), 0n), + }, + ], + providers: [config.neverminedNodeAddress], + }) + + const ddo = await nevermined.assets.create(assetAttributes, account) + assert.isDefined(ddo) + }) +}) diff --git a/package.json b/package.json index 0f25b381f..e66f28644 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "homepage": "https://github.com/nevermined-io/sdk-js#readme", "dependencies": { "@apollo/client": "^3.7.16", + "@zerodev/sdk": "^4.0.17", "assert": "^2.0.0", "cross-fetch": "^4.0.0", "crypto-browserify": "^3.12.0", diff --git a/src/keeper/contracts/ContractBase.ts b/src/keeper/contracts/ContractBase.ts index 5a87ea048..6e59a857e 100644 --- a/src/keeper/contracts/ContractBase.ts +++ b/src/keeper/contracts/ContractBase.ts @@ -3,6 +3,7 @@ import { ContractEvent, EventHandler, SubgraphEvent } from '../../events' import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' import { KeeperError } from '../../errors' import { + Contract, ContractTransactionReceipt, ContractTransactionResponse, FunctionFragment, @@ -143,13 +144,13 @@ export abstract class ContractBase extends Instantiable { }) } - const transactionReceipt: ContractTransactionReceipt = await transactionResponse.wait() + // const transactionReceipt: ContractTransactionReceipt = await transactionResponse.wait() if (progress) { progress({ stage: 'receipt', args: this.searchMethodInputs(name, args), - transactionReceipt, + // transactionReceipt, method: name, from, value, @@ -159,7 +160,7 @@ export abstract class ContractBase extends Instantiable { }) } - return transactionReceipt + return transactionResponse as any } public async send( @@ -168,6 +169,12 @@ export abstract class ContractBase extends Instantiable { args: any[], params: TxParameters = {}, ): Promise { + if (this.config.zerodevProvider) { + const signer = this.config.zerodevProvider.getAccountSigner() + const contract = new Contract(this.address, this.contract.interface, signer as any) + return await this.internalSend(name, from, args, params, contract, params.progress) + } + if (params.signer) { const paramsFixed = { ...params, signer: undefined } const contract = this.contract.connect(params.signer) diff --git a/src/models/NeverminedOptions.ts b/src/models/NeverminedOptions.ts index 82eb17872..3ce241324 100644 --- a/src/models/NeverminedOptions.ts +++ b/src/models/NeverminedOptions.ts @@ -1,6 +1,7 @@ import { ethers } from 'ethers' import { LogLevel } from '../utils' import { AaveConfig } from './' +import { ZeroDevEthersProvider } from '@zerodev/sdk' export class NeverminedOptions { /** @@ -83,4 +84,6 @@ export class NeverminedOptions { * Use a gas station to calculate transaction fees */ public gasStationUri?: string + + public zerodevProvider?: ZeroDevEthersProvider<'ECDSA'> }