Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/lazy loading contracts #609

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1355,7 +1355,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

> 2 May 2022

- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- Adding v0.19.21 Changelog updates [`c93cdc5`](https://github.com/nevermined-io/sdk-js/commit/c93cdc55f139a43db4130ccb0f80924d2645a931)

#### [v0.19.21](https://github.com/nevermined-io/sdk-js/compare/v0.19.20...v0.19.21)
Expand Down Expand Up @@ -1618,7 +1618,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

> 18 January 2022

- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- [wip] Create agreement+pay in one transaction [`#183`](https://github.com/nevermined-io/sdk-js/pull/183)
- Adapting to contracts `v1.3.3` [`#177`](https://github.com/nevermined-io/sdk-js/pull/177)
- Adding v0.17.2 Changelog updates [`5eddda4`](https://github.com/nevermined-io/sdk-js/commit/5eddda43954e013e6e6f7344c9a877d801aacb5c)
Expand Down Expand Up @@ -2124,7 +2124,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- Feature/sync develop [`#268`](https://github.com/nevermined-io/sdk-js/pull/268)
- Quick fix for non-eip1559 networks [`#266`](https://github.com/nevermined-io/sdk-js/pull/266)
- integrate Permissions and refactor search query [`#264`](https://github.com/nevermined-io/sdk-js/pull/264)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- Get the keeper version from the artifacts instead of package version [`#244`](https://github.com/nevermined-io/sdk-js/pull/244)
- replace `metadata-api` url by `marketplace-api` and sort type [`#243`](https://github.com/nevermined-io/sdk-js/pull/243)
- fixing issues with BigNumbers [`#246`](https://github.com/nevermined-io/sdk-js/pull/246)
Expand Down Expand Up @@ -2163,7 +2163,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- Feature/190 add did to sec markets [`#191`](https://github.com/nevermined-io/sdk-js/pull/191)
- Adding utility methods for getting nft token uri [`#189`](https://github.com/nevermined-io/sdk-js/pull/189)
- Lint ... [`#187`](https://github.com/nevermined-io/sdk-js/pull/187)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- [wip] Create agreement+pay in one transaction [`#183`](https://github.com/nevermined-io/sdk-js/pull/183)
- Adapting to contracts `v1.3.3` [`#177`](https://github.com/nevermined-io/sdk-js/pull/177)
- Correct typo in route [`#184`](https://github.com/nevermined-io/sdk-js/pull/184)
Expand Down
2 changes: 2 additions & 0 deletions src/keeper/Keeper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ export class Keeper extends Instantiable {
this.utils = {
eventHandler: new EventHandler(),
}

console.log('version', this.didRegistry)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cleanup

// version
this.network = {
chainId,
Expand Down
59 changes: 45 additions & 14 deletions src/keeper/contracts/ContractBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
TransactionReceipt,
ethers,
} from 'ethers'
import { jsonReplacer, parseUnits } from '../../sdk'
import { ContractHandler, jsonReplacer, parseUnits } from '../../sdk'
import { ZeroDevAccountSigner } from '@zerodev/sdk'
export interface TxParameters {
value?: string
Expand All @@ -24,16 +24,33 @@ export interface TxParameters {
progress?: (data: any) => void
}

const lazyLoad = {
get(target: any, prop: any, receiver: any) {
if (!target.initialized) {
;(async () => {
await target.init()
target.initialized = true
})()
}
return Reflect.get(target, prop, receiver)
},
}

export abstract class ContractBase extends Instantiable {
public readonly contractName: string
public contract: ethers.BaseContract = null
public events: ContractEvent | SubgraphEvent = null
public contract: ethers.BaseContract
public events: ContractEvent | SubgraphEvent
public version: string
public address: string
public optional: boolean
private initialized = false

constructor(contractName: string) {
constructor(contractName: string, config: InstantiableConfig, optional = false) {
super()
this.contractName = contractName
this.setInstanceConfig(config)
this.optional = optional
return new Proxy(this, lazyLoad)
}

public getSignatureOfMethod(methodName: string, args: any[] = []): string {
Expand All @@ -46,19 +63,33 @@ export abstract class ContractBase extends Instantiable {
return foundMethod.inputs
}

protected async init(config: InstantiableConfig, optional = false) {
this.setInstanceConfig(config)
this.contract = await this.nevermined.utils.contractHandler.get(
this.contractName,
optional,
config.artifactsFolder,
)
this.address = await this.contract.getAddress()
/**
* Initialize a contract
*
* @param address - Overrides the address in the artifact
* @param abi - Uses this abi instead of searching on the artifacts folder.
*/
protected async init(address?: string, abi?: { abi: ethers.Interface | ethers.InterfaceAbi }) {
if (address) {
await new ContractHandler(this.instanceConfig).checkExists(address)
}

// load the contract
if (abi) {
this.contract = new ethers.Contract(address, abi.abi, this.web3)
} else {
this.contract = await this.nevermined.utils.contractHandler.get(
this.contractName,
this.optional,
this.config.artifactsFolder,
address,
)
}

try {
this.version = await this.nevermined.utils.contractHandler.getVersion(
this.contractName,
config.artifactsFolder,
this.config.artifactsFolder,
)
} catch {
throw new KeeperError(`${this.contractName} not available on this network.`)
Expand All @@ -73,7 +104,7 @@ export abstract class ContractBase extends Instantiable {
await this.nevermined.keeper.getNetworkName(),
)
} else {
this.events = ContractEvent.getInstance(this, eventEmitter, config.nevermined, this.web3)
this.events = ContractEvent.getInstance(this, eventEmitter, this.nevermined, this.web3)
}
}

Expand Down
21 changes: 11 additions & 10 deletions src/keeper/contracts/CustomToken.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import { Token } from './Token'
import { InstantiableConfig } from '../../Instantiable.abstract'
import { ethers } from 'ethers'
import { ContractHandler } from '../ContractHandler'

export class CustomToken extends Token {
private overrideAddress?: string

public static async getInstanceByAddress(
config: InstantiableConfig,
address: string,
): Promise<CustomToken> {
const token: CustomToken = new Token(process.env.TOKEN_CONTRACT_NAME || 'Custom-Token')
token.setInstanceConfig(config)

await new ContractHandler(config).checkExists(address)

token.contract = new ethers.Contract(address, Token.ERC20_ABI, token.web3)
token.address = await token.contract.getAddress()

const token: CustomToken = new CustomToken(
process.env.TOKEN_CONTRACT_NAME || 'Custom-Token',
config,
)
token.overrideAddress = address
return token
}

protected async init() {
super.init(this.overrideAddress, { abi: Token.ERC20_ABI })
}
}
3 changes: 1 addition & 2 deletions src/keeper/contracts/DIDRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import {

export class DIDRegistry extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<DIDRegistry> {
const didRegistry: DIDRegistry = new DIDRegistry('DIDRegistry')
await didRegistry.init(config)
const didRegistry: DIDRegistry = new DIDRegistry('DIDRegistry', config)
return didRegistry
}

Expand Down
3 changes: 1 addition & 2 deletions src/keeper/contracts/Dispenser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { InstantiableConfig } from '../../Instantiable.abstract'
import { parseUnits } from '../../sdk'
export class Dispenser extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<Dispenser> {
const dispenser: Dispenser = new Dispenser('Dispenser')
await dispenser.init(config, true)
const dispenser: Dispenser = new Dispenser('Dispenser', config, true)
return dispenser
}

Expand Down
22 changes: 5 additions & 17 deletions src/keeper/contracts/GenericContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,20 @@ import { InstantiableConfig } from '../../Instantiable.abstract'
import { ContractTransactionReceipt, ethers } from 'ethers'

export class GenericContract extends ContractBase {
protected fixedAddress: string
private overrideAddress: string

public static async getInstance(
config: InstantiableConfig,
contractName: string,
address?: string,
): Promise<GenericContract> {
const contract: GenericContract = new GenericContract(contractName, address)
await contract.init(config)
const contract: GenericContract = new GenericContract(contractName, config)
contract.overrideAddress = address
return contract
}

private constructor(contractName: string, address?: string) {
super(contractName)
this.fixedAddress = address
}

protected async init(config: InstantiableConfig, optional = false) {
this.setInstanceConfig(config)

this.contract = await this.nevermined.utils.contractHandler.get(
this.contractName,
optional,
config.artifactsFolder,
this.fixedAddress,
)
protected async init() {
super.init(this.overrideAddress)
}

public async call<T>(name: string, args: any[], from?: string): Promise<T> {
Expand Down
45 changes: 17 additions & 28 deletions src/keeper/contracts/Nft1155Contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,22 @@ import { Account } from '../../nevermined'
import { TxParameters } from './ContractBase'
import { ethers } from 'ethers'
import { NFTContractsBase } from './NFTContractsBase'
import { ContractHandler } from '../ContractHandler'
import { ContractEvent, EventHandler } from '../../events'

/**
* NFTs contracts DTO allowing to manage Nevermined ERC-1155 NFTs
*/
export class Nft1155Contract extends NFTContractsBase {
private overrideAddress?: string
private overrideAbi?: { abi: ethers.Interface | ethers.InterfaceAbi }

public static async getInstance(
config: InstantiableConfig,
address?: string,
contractName = 'NFT1155Upgradeable',
artifactsFolder = config.artifactsFolder,
): Promise<Nft1155Contract> {
const nft: Nft1155Contract = new Nft1155Contract(contractName)
await nft.init(config)

if (address) {
const networkName = await nft.nevermined.keeper.getNetworkName()

// We don't have a subgraph for NFT1155 so we can only use ContractEvent
const eventEmitter = new EventHandler()
nft.events = ContractEvent.getInstance(nft, eventEmitter, config.nevermined, config.web3)

const solidityABI = await ContractHandler.getABI(contractName, artifactsFolder, networkName)
await new ContractHandler(config).checkExists(address)
nft.contract = new ethers.Contract(address, solidityABI.abi, nft.web3)
nft.address = await nft.contract.getAddress()
}

const nft: Nft1155Contract = new Nft1155Contract(contractName, config)
nft.overrideAddress = address
return nft
}

Expand All @@ -42,20 +29,22 @@ export class Nft1155Contract extends NFTContractsBase {
solidityABI: any,
): Promise<Nft1155Contract> {
const contractName = solidityABI.contractName
const nft: Nft1155Contract = new Nft1155Contract(contractName)
nft.setInstanceConfig(config)

// We don't have a subgraph for NFT1155 so we can only use ContractEvent
const eventEmitter = new EventHandler()
nft.events = ContractEvent.getInstance(nft, eventEmitter, config.nevermined, config.web3)

await new ContractHandler(config).checkExists(address)
nft.contract = new ethers.Contract(address, solidityABI.abi, nft.web3)
nft.address = await nft.contract.getAddress()
const nft: Nft1155Contract = new Nft1155Contract(contractName, config)

nft.overrideAddress = address
nft.overrideAbi = solidityABI
return nft
}

protected async init() {
await super.init(this.overrideAddress, this.overrideAbi)
if (this.overrideAddress) {
// We don't have a subgraph for NFT1155 so we can only use ContractEvent
const eventEmitter = new EventHandler()
this.events = ContractEvent.getInstance(this, eventEmitter, this.nevermined, this.web3)
}
}

/**
* Creates a contract clone of an existing contract instance
*
Expand Down
47 changes: 18 additions & 29 deletions src/keeper/contracts/Nft721Contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,20 @@ import { InstantiableConfig } from '../../Instantiable.abstract'
import { didZeroX, zeroX } from '../../utils'
import { Account } from '../../nevermined'
import { ethers } from 'ethers'
import { ContractEvent, EventHandler } from '../../events'
import { NFTContractsBase } from './NFTContractsBase'
import { ContractHandler } from '../ContractHandler'
import { ContractEvent, EventHandler } from '../../events'

export class Nft721Contract extends NFTContractsBase {
private overrideAddress?: string
private overrideAbi?: { abi: ethers.Interface | ethers.InterfaceAbi }

public static async getInstance(
config: InstantiableConfig,
address: string,
contractName = 'NFT721Upgradeable',
artifactsFolder = config.artifactsFolder,
): Promise<Nft721Contract> {
const nft: Nft721Contract = new Nft721Contract(contractName)
nft.setInstanceConfig(config)
const networkName = await nft.nevermined.keeper.getNetworkName()

// We don't have a subgraph for NFT721 so we can only use ContractEvent
const eventEmitter = new EventHandler()
nft.events = ContractEvent.getInstance(nft, eventEmitter, config.nevermined, config.web3)

const solidityABI = await ContractHandler.getABI(contractName, artifactsFolder, networkName)

console.log(`Checking Address =${address}=`)
await new ContractHandler(config).checkExists(address)
nft.contract = new ethers.Contract(address, solidityABI.abi, nft.web3)
nft.address = await nft.contract.getAddress()

const nft: Nft721Contract = new Nft721Contract(contractName, config)
nft.overrideAddress = address
return nft
}

Expand All @@ -38,20 +26,21 @@ export class Nft721Contract extends NFTContractsBase {
solidityABI: any,
): Promise<Nft721Contract> {
const contractName = solidityABI.contractName
const nft: Nft721Contract = new Nft721Contract(contractName)
nft.setInstanceConfig(config)

// We don't have a subgraph for NFT721 so we can only use ContractEvent
const eventEmitter = new EventHandler()
nft.events = ContractEvent.getInstance(nft, eventEmitter, config.nevermined, config.web3)

await new ContractHandler(config).checkExists(address)
nft.contract = new ethers.Contract(address, solidityABI.abi, nft.web3)
nft.address = await nft.contract.getAddress()

const nft: Nft721Contract = new Nft721Contract(contractName, config)
nft.overrideAddress = address
nft.overrideAbi = solidityABI
return nft
}

protected async init() {
await super.init(this.overrideAddress, this.overrideAbi)
if (this.overrideAddress) {
// We don't have a subgraph for NFT721 so we can only use ContractEvent
const eventEmitter = new EventHandler()
this.events = ContractEvent.getInstance(this, eventEmitter, this.nevermined, this.web3)
}
}

/**
* Creates a contract clone of an existing contract instance
*
Expand Down
7 changes: 5 additions & 2 deletions src/keeper/contracts/Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ export class Token extends ContractBase {
]

public static async getInstance(config: InstantiableConfig): Promise<Token> {
const token: Token = new Token(process.env.TOKEN_CONTRACT_NAME || 'NeverminedToken')
await token.init(config, true)
const token: Token = new Token(
process.env.TOKEN_CONTRACT_NAME || 'NeverminedToken',
config,
true,
)
return token
}

Expand Down
Loading
Loading