Skip to content

Commit

Permalink
quick-start must await this.start() (#104)
Browse files Browse the repository at this point in the history
* quick-start must await this.start()
* made relevant changes to the models
* deprecates loadContract() function

* better documentation on start()

* eager replace of loadContract ate some that it shouldn't

* cerc20 missing start of underlying erc20

* missing ethUtils start on loophole.ts

* linted
  • Loading branch information
moshmage authored Apr 18, 2023
1 parent ed78e18 commit 1b9bca9
Show file tree
Hide file tree
Showing 32 changed files with 227 additions and 197 deletions.
29 changes: 17 additions & 12 deletions src/base/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class Model<Methods = any> {
else this.web3Connection = new Web3Connection(web3Connection);

if (this.web3Connection.started)
this.loadAbi();
this.loadAbi(); // cannot call start because start is async, has to be called by user-land
}
/* eslint-enable complexity */

Expand All @@ -63,17 +63,20 @@ export class Model<Methods = any> {
get account(): Account { return this.connection.Account; }

/**
* Permissive way of initializing the contract, used primarily for deploys and options.autoStart = true
* Prefer to use {@link loadContract}
* Initialize the underlying web3js contract
*/
loadAbi() {
this._contract = new Web3Contract(this.web3, this.abi, this.contractAddress);
this._contract = new Web3Contract(this.web3, this.abi, this._contractAddress);
}

/**
* Preferred way of initializing and loading a contract, use this function to customize contract loading,
* initializing any other dependencies the contract might have when extending from Model
* Deprecated - async capabilities on this function will affect autoStart: true option, use `start()` instead
* if you need async abilities.
*
* ~~Preferred~~ Alternative way of initializing and loading a contract, ~~use this function to customize contract loading,
* initializing any other dependencies the contract might have when extending from Model~~
* @throws Errors.MissingContractAddress
* @deprecated
*/
loadContract() {
if (!this.contractAddress)
Expand All @@ -90,18 +93,20 @@ export class Model<Methods = any> {
const connected = await this.web3Connection.connect();

if (connected)
this.loadContract();
await this.start();

return connected;
}

/**
* Alias for Web3Connection.start();
* Will load contract if success
* Will load contract (via {@link loadAbi}) if success; use this function to customize contract loading, initializing any other
* dependencies the contract might have when extending from Model.
* @void
*/
async start() {
await this.web3Connection.start();
this.loadContract();
this.loadAbi();
}

/**
Expand Down Expand Up @@ -137,7 +142,7 @@ export class Model<Methods = any> {
debug,
customTransactionHandler: cb
}: Partial<Web3ConnectionOptions> = {}): Promise<TransactionReceipt> {
const from = (await this.web3.eth.givenProvider.request({method: 'eth_requestAccounts'}))[0];
const from = (await this.web3.eth.givenProvider.request({method: 'eth_requestAccounts'}))?.[0];

return new Promise<TransactionReceipt>(async (resolve, reject) => {
try {
Expand All @@ -162,10 +167,10 @@ export class Model<Methods = any> {
*/
async deploy(deployOptions: DeployOptions, account?: Account) {
return this.contract.deploy(this.abi, deployOptions, account)
.then(tx => {
.then(async tx => {
if (this.web3Connection.options.restartModelOnDeploy && tx.contractAddress) {
this._contractAddress = tx.contractAddress;
this.loadContract();
await this.start();
}
return tx;
})
Expand Down
6 changes: 3 additions & 3 deletions src/base/web3-connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export class Web3Connection {
constructor(readonly options: Web3ConnectionOptions) {
const {web3CustomProvider: provider = null, autoStart = true} = options;

if (options.restartModelOnDeploy === undefined)
this.options.restartModelOnDeploy = true;

if (autoStart || (provider && typeof provider !== "string" && provider?.connected)) {
this.start();
}

if (options.restartModelOnDeploy === undefined)
this.options.restartModelOnDeploy = true;
}
/* eslint-enable complexity */

Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/methods/erc721-standard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface ERC721StandardMethods {
owner(): ContractCallMethod<string>;
ownerOf(tokenId: number): ContractCallMethod<string>;
safeTransferFrom(from: string, to: string, tokenId: number): ContractSendMethod;
safeTransferFrom(from: string, to: string, tokenId: number, _data: undefined): ContractSendMethod;
safeTransferFrom(from: string, to: string, tokenId: number, _data?: string): ContractSendMethod;
setApprovalForAll(operator: string, approved: boolean): ContractSendMethod;
supportsInterface(interfaceId: undefined): ContractCallMethod<boolean>;
supportsInterface(interfaceId?: string): ContractCallMethod<boolean>;
symbol(): ContractCallMethod<string>;
tokenByIndex(index: number): ContractCallMethod<number>;
tokenOfOwnerByIndex(owner: string, index: number): ContractCallMethod<number>;
Expand Down
19 changes: 6 additions & 13 deletions src/models/cerc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,14 @@ export class CERC20 extends Model<CERC20Methods> implements Deployable {

async start() {
await super.start();
await this.loadContract();
}

async loadContract() {
if (!this.contract)
super.loadContract();

if (!this.contractAddress)
throw new Error(Errors.MissingContractAddress);

if (!this.underlyingAddress)
throw new Error(Errors.MissingERC20UnderlyingToken);
if (this.contractAddress) {
if (!this.underlyingAddress)
throw new Error(Errors.MissingERC20UnderlyingToken);

this._erc20 = new ERC20(this.connection, this.underlyingAddress);
await this._erc20.loadContract();
this._erc20 = new ERC20(this.connection, this.underlyingAddress);
await this._erc20.start();
}
}

async deployJsonAbi(underlying_: string, initialExchangeRate_: number, decimals_: number) {
Expand Down
20 changes: 8 additions & 12 deletions src/models/erc20-distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,16 @@ export class ERC20Distribution extends Model<ERC20DistributionMethods> implement
get pausable() { return this._pausable }
get ownable() { return this._ownable }

async loadContract() {
if (!this.contract)
super.loadContract();

this._ownable = new Ownable(this);
this._pausable = new Pausable(this);

this._erc20 = new ERC20(this.connection, await this.callTx(this.contract.methods.erc20()));
await this._erc20.loadContract();
}

async start() {
await super.start();
await this.loadContract();

if (this.contract) {
this._ownable = new Ownable(this);
this._pausable = new Pausable(this);

this._erc20 = new ERC20(this.connection, await this.callTx(this.contract.methods.erc20()));
await this._erc20.start();
}
}

async deployJsonAbi() {
Expand Down
16 changes: 6 additions & 10 deletions src/models/erc20-token-lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,14 @@ export class Erc20TokenLock extends Model<ERC20TokenLockMethods> implements Depl

async start() {
await super.start();
await this.loadContract();
}

async loadContract() {
if (!this.contract)
super.loadContract();

this._ownable = new Ownable(this);
this._pausable = new Pausable(this);
if (this.contract) {
this._ownable = new Ownable(this);
this._pausable = new Pausable(this);

this._erc20 = new ERC20(this.connection, await this.getERC20TokenAddress());
await this._erc20.loadContract();
this._erc20 = new ERC20(this.connection, await this.getERC20TokenAddress());
await this._erc20.start();
}
}

deployJsonAbi(erc20ContractAddress: string) {
Expand Down
14 changes: 5 additions & 9 deletions src/models/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,11 @@ export class ERC20 extends Model<ERC20Methods> implements Deployable {

async start() {
await super.start();
await this.loadContract();
}

async loadContract() {
if (!this.contract)
super.loadContract();

this._ownable = new Ownable(this);

this._decimals = await this.callTx(this.contract.methods.decimals()) || 18;
if (this.contractAddress) {
this._ownable = new Ownable(this);
this._decimals = await this.callTx(this.contract.methods.decimals()) || 18;
}
}

async name(): Promise<string> {
Expand Down Expand Up @@ -62,6 +57,7 @@ export class ERC20 extends Model<ERC20Methods> implements Deployable {
}

/**
* use {@link transfer}
* @deprecated
*/
async transferTokenAmount(toAddress: string, amount: string | number) {
Expand Down
9 changes: 6 additions & 3 deletions src/models/erc4626.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ export class ERC4626 extends Model<ERC4626Methods> implements Deployable {
return this.deploy(deployOptions, this.connection.Account);
}

async loadContract() {
super.loadContract();
async start() {
await super.start();

if (!this.contract)
return;

this._decimals = await this.decimals();
this._asset = new ERC20(this.connection, await this.assetAddress());
await this._asset.loadContract();
await this._asset.start();
}

async allowance(owner: string, spender: string) {
Expand Down
7 changes: 3 additions & 4 deletions src/models/erc721-collectibles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export class ERC721Collectibles extends Model<ERC721CollectiblesMethods> impleme

async loadContract() {
if (!this.contract)
super.loadContract();
return;

const contractAddress = this._purchaseToken || await this.callTx(this.contract.methods._purchaseToken());
this._erc20 = new ERC20(this.connection, contractAddress);
await this._erc20.loadContract();
await this._erc20.start();
}

async start() {
Expand Down Expand Up @@ -178,7 +178,6 @@ export class ERC721Collectibles extends Model<ERC721CollectiblesMethods> impleme
async setPricePerPack(newPrice: string | number) {
newPrice = toSmartContractDecimals(newPrice, this.erc20.decimals);
return this.sendTx(this.contract.methods.setPricePerPack(newPrice));
// return this.sendTx(this.contract.methods.setPricePerPack(newPrice));
}

async setPurchaseTokenAddress(purchaseToken: string) {
Expand Down Expand Up @@ -246,7 +245,7 @@ export class ERC721Collectibles extends Model<ERC721CollectiblesMethods> impleme
}

async getRegisteredIDs(_address: string) {
return (await this.callTx(this.contract.methods.getRegisteredIDs(_address))).map(id => +id);
return (await this.callTx(this.contract.methods.getRegisteredIDs(_address)))?.map(id => +id);
}

}
69 changes: 67 additions & 2 deletions src/models/erc721-standard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Web3ConnectionOptions} from '@interfaces/web3-connection-options';
import ERC721Standard from '@abi/ERC721Standard.json';
import {AbiItem} from 'web3-utils';
import {Deployable} from '@interfaces/deployable';
import {TransactionReceipt} from "@interfaces/web3-core";

export class Erc721Standard extends Model<ERC721StandardMethods> implements Deployable {

Expand All @@ -24,11 +25,75 @@ export class Erc721Standard extends Model<ERC721StandardMethods> implements Depl
return this.sendTx(this.contract.methods.setTokenURI(tokenId, uri));
}

async mint(to: string, tokenId: number, data?: string) {
async mint(to: string, tokenId: number, data = "0x0") {
return this.sendTx(this.contract.methods.mint(to, tokenId, data))
}

deployJsonAbi(name: string, symbol: string) {
async totalSupply() {
return this.callTx(this.contract.methods.totalSupply())
}

async approve(address: string, tokenId: number): Promise<TransactionReceipt> {
return this.sendTx(this.contract.methods.approve(address, tokenId));
}

async getApproved(tokenId: number) {
return this.callTx(this.contract.methods.getApproved(tokenId));
}

async isApprovedForAll(owner:string, operator: string) {
return this.callTx(this.contract.methods.isApprovedForAll(owner, operator));
}

async setApprovalForAll(owner:string, approved: boolean) {
return this.sendTx(this.contract.methods.setApprovalForAll(owner, approved));
}

async balanceOf(address: string): Promise<TransactionReceipt> {
return this.sendTx(this.contract.methods.balanceOf(address));
}

async safeTransferFrom(from: string, to: string, tokenId: number, data = "0x0") {
return this.sendTx(this.contract.methods.safeTransferFrom(from, to, tokenId, data))
}

async transferFrom(from: string, to: string, tokenId: number) {
return this.sendTx(this.contract.methods.safeTransferFrom(from, to, tokenId))
}

async transferOwnership(newOwner: string) {
return this.sendTx(this.contract.methods.transferOwnership(newOwner))
}

async supportsInterface(interfaceId: string) {
return this.callTx(this.contract.methods.supportsInterface(interfaceId))
}

async symbol() {
return this.callTx(this.contract.methods.symbol())
}

async name() {
return this.callTx(this.contract.methods.name())
}

async owner() {
return this.callTx(this.contract.methods.owner())
}

async ownerOf(tokenId: number) {
return this.callTx(this.contract.methods.ownerOf(tokenId))
}

async tokenByIndex(index: number) {
return this.callTx(this.contract.methods.tokenByIndex(index))
}

async tokenOfOwnerByIndex(owner: string, index: number) {
return this.callTx(this.contract.methods.tokenOfOwnerByIndex(owner, index))
}

async deployJsonAbi(name: string, symbol: string) {
const options = {
data: ERC721Standard.bytecode,
arguments: [name, symbol]
Expand Down
Loading

0 comments on commit 1b9bca9

Please sign in to comment.