ufomarketplace-sdk-new
Version:
SDK to interact with set ufo marketplace contracts
382 lines (336 loc) • 15.2 kB
text/typescript
import { ethers, BaseContract, BigNumber, Signer, ContractTransaction } from 'ethers';
import {
UFOMarketplaceConfig,
NFTInfo,
UAPClaimInfo,
BucketInfo,
WeaponInfo,
LootBuySellInfo,
PurchaseType,
} from './types';
import {
SuperGalaticFactory,
SuperGalaticFactory__factory,
ERC20Upgradeable,
ERC20Upgradeable__factory,
ERC721Upgradeable,
ERC721Upgradeable__factory,
ERC20__factory,
ERC20,
UfoMarketplace,
UfoMarketplace__factory,
ERC721EnumerableUpgradeable,
ERC721EnumerableUpgradeable__factory,
} from './wrapper';
import { BigNumber as DecimalBigNumber } from 'bignumber.js';
import { GENSIS_NFT_USDT_PRICE, NETWORK_ID, USER_CURRENCY } from './constants/constants';
const exponent = new DecimalBigNumber('10').pow(18);
const usdtExponent = new DecimalBigNumber('10').pow(6);
const MAX_INT = BigNumber.from('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
export class ufoMarketplaceSDK {
private signer: Signer;
private config: UFOMarketplaceConfig;
private galaticFactory: SuperGalaticFactory;
private plasma: ERC20Upgradeable | null;
private usdtToken: ERC20 | null;
private wETHToken: ERC20;
private netId: number;
constructor(_signer: Signer, _config: UFOMarketplaceConfig, _netID: string) {
this.signer = _signer;
this.config = _config;
this.galaticFactory = new SuperGalaticFactory__factory(_signer).attach(_config.ufoSuperGalaticFactory);
let netId = parseInt(_netID);
this.netId = netId;
switch (netId) {
case NETWORK_ID.ETHEREUM:
case NETWORK_ID.SEPOLIA:
if (_config.ufoConfig.plasmaTokenOnEth != null && _config.ufoConfig.plasmaTokenOnEth != undefined) {
this.plasma = new ERC20Upgradeable__factory(this.signer).attach(_config.ufoConfig.plasmaTokenOnEth);
}
this.wETHToken = new ERC20__factory(this.signer).attach(_config.ufoConfig.WETHOnEth);
break;
case NETWORK_ID.BEAM:
case NETWORK_ID.BEAM_TESTNET:
this.plasma = new ERC20Upgradeable__factory(this.signer).attach(_config.ufoConfig.plasmaTokenOnBeamTestNet);
this.wETHToken = new ERC20__factory(this.signer).attach(_config.ufoConfig.WETHOnBeamTestNet);
this.usdtToken = new ERC20__factory(this.signer).attach(_config.ufoConfig.usdtTokenOnBeamTestNet);
break;
}
}
public async sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
public async nftHasApprovalToMarketplace(contractAddr: string, nftId: string): Promise<boolean> {
let nftContract: ERC721Upgradeable = new ERC721Upgradeable__factory(this.signer).attach(contractAddr);
const _temp = new DecimalBigNumber(nftId);
if (_temp.isNegative()) {
throw new Error(`${nftId} is a negative amount`);
}
return (await nftContract.getApproved(nftId)) == this.config.ufoMarketplace;
}
public async approveNftToMarketplace(contractAddr: string, nftId: string): Promise<ContractTransaction> {
let nftContract: ERC721Upgradeable = new ERC721Upgradeable__factory(this.signer).attach(contractAddr);
const _temp = new DecimalBigNumber(nftId);
if (_temp.isNegative()) {
throw new Error(`${nftId} is a negative amount`);
}
return nftContract.approve(this.config.ufoMarketplace, nftId);
}
public async wETHAllowance(amount: string): Promise<boolean> {
const addr = await this.signer.getAddress();
const allowance = await this.wETHToken.allowance(addr, this.config.ufoMarketplace);
const _temp = new DecimalBigNumber(amount);
return new DecimalBigNumber(allowance.toString()).gte(_temp);
}
public async wETHBalance(): Promise<string> {
const addr = await this.signer.getAddress();
let balance = await this.wETHToken.balanceOf(addr);
const balStr = ethers.utils.formatEther(balance);
return balStr;
}
public async getNFTCurrentSupply(contractAddr: string): Promise<number> {
let nftContract: ERC721EnumerableUpgradeable = ERC721EnumerableUpgradeable__factory.connect(
contractAddr,
this.signer
);
return (await nftContract.totalSupply()).toNumber();
}
public async revealNft(): Promise<ContractTransaction> {
return await this.galaticFactory.registerForMint();
}
public async test(): Promise<void> {
console.log("========1========");
await this.sleep(5000);
console.log("=========2=======");
}
public async batchMintGalaticNFT(
categoryIds: [number],
amounts: [number],
type: PurchaseType,
merkleProof: string[]
): Promise<ContractTransaction> {
console.log('======', categoryIds, amounts, type, merkleProof);
switch (type) {
case PurchaseType.PLASMA:
return this.batchMintGalaticNFTByPlasma(categoryIds, amounts, merkleProof);
case PurchaseType.BEAM:
return this.batchMintGalaticNFTByBeam(categoryIds, amounts, merkleProof);
case PurchaseType.USDT:
return this.batchMintGalaticNFTByUsdt(categoryIds, amounts, merkleProof);
}
}
private async batchMintGalaticNFTByPlasma(
categoryIds: [number],
amounts: [number],
merkleProof: string[]
): Promise<ContractTransaction> {
return this.galaticFactory.mintBatchSuperGalatic(categoryIds, amounts, merkleProof!);
}
private async batchMintGalaticNFTByBeam(
categoryIds: [number],
amounts: [number],
merkleProof: string[]
): Promise<ContractTransaction> {
let totalCount = amounts.reduce((acc, curr) => {
return acc + curr;
}, 0);
await this.sleep(5000);
let nftPriceInBeam = await this.galaticFactory.beamAmountPerNft();
let nativeTokenAmount = BigNumber.from(totalCount).mul(nftPriceInBeam).mul("250").toString();
return this.galaticFactory.mintWithBeam(categoryIds, amounts, merkleProof, {
value: nativeTokenAmount,
gasLimit: BigNumber.from('2500000'),
});
}
private async batchMintGalaticNFTByUsdt(
categoryIds: [number],
amounts: [number],
merkleProof: string[]
): Promise<ContractTransaction> {
// Estimate gas for the transaction
// const gasEstimate = await this.galaticFactory.estimateGas.mintSuperGalaticByUSDT(categoryIds, amounts, merkleProof);
// console.log("===============gas============", gasEstimate.toString());
// // Execute the transaction with the estimated gas
await this.sleep(5000);
return this.galaticFactory.mintWithUSDT(categoryIds, amounts, merkleProof, {
gasLimit: BigNumber.from('2500000'), //gasEstimate.mul(120).div(100) // Add 20% buffer to gas estimate
});
}
public async plasmaAmountPerNFT(): Promise<string> {
let plasmaAmount = await this.galaticFactory.plasmaAmountPerNFT();
return new DecimalBigNumber(plasmaAmount.toString()).div(exponent).toString();
}
//wETH
public async getWETHAllowanceOfNFTFactory(): Promise<string> {
if (this.wETHToken == null || this.wETHToken == undefined)
throw new Error('check the wETHToken contract of correct network');
let allowance = await this.wETHToken.allowance(await this.signer.getAddress(), this.galaticFactory.address);
let ret = new DecimalBigNumber(allowance.toString()).div(exponent).toString();
return ret;
}
public async getWETHAllowanceOfMarketplace(): Promise<string> {
if (this.wETHToken == null || this.wETHToken == undefined)
throw new Error('check the wETHToken contract of correct network');
let allowance = await this.wETHToken.allowance(await this.signer.getAddress(), this.config.ufoMarketplace);
let ret = new DecimalBigNumber(allowance.toString()).div(exponent).toString();
return ret;
}
private getAddressOfPriceToken(token_unit): string {
console.log('getAddressOfPriceToken', this.netId);
switch (this.netId) {
case NETWORK_ID.BEAM_TESTNET:
if (token_unit == USER_CURRENCY['WETH']) {
return this.config.ufoConfig.WETHOnBeamTestNet;
} else if (token_unit == USER_CURRENCY['UFO']) {
return this.config.ufoConfig.ufoTokenOnBeamTestNet;
} else {
return this.config.ufoConfig.usdtTokenOnBeamTestNet;
}
case NETWORK_ID.BEAM:
if (token_unit == USER_CURRENCY['WETH']) {
return this.config.ufoConfig.WETHOnBeamTestNet;
} else if (token_unit == USER_CURRENCY['UFO']) {
return this.config.ufoConfig.ufoTokenOnBeamTestNet;
} else {
return this.config.ufoConfig.usdtTokenOnBeamTestNet;
}
default:
return '000000';
}
}
public async approveToken(price_unit: string, spender: string, amount: string): Promise<ContractTransaction> {
let address: string = this.getAddressOfPriceToken(price_unit);
let token: ERC20 = new ERC20__factory(this.signer).attach(address);
return token.approve(spender, amount);
}
public async hasApprovalToken(price_unit: string, spnder: string, amount: string): Promise<boolean> {
let address: string = this.getAddressOfPriceToken(price_unit);
let token: ERC20 = new ERC20__factory(this.signer).attach(address);
let allowance = await token.allowance(await this.signer.getAddress(), spnder);
console.log('allowance======', allowance);
let ret = new DecimalBigNumber(allowance.toString()).gte(new DecimalBigNumber(amount));
return ret;
}
public async approveWETHToMarketplace(): Promise<ContractTransaction> {
return this.wETHToken.approve(this.config.ufoMarketplace, MAX_INT);
}
public async approveWETHToNFTFactory(amount: BigNumber): Promise<ContractTransaction> {
if (amount) {
return this.wETHToken.approve(this.config.ufoSuperGalaticFactory, amount);
} else {
return this.wETHToken.approve(this.config.ufoSuperGalaticFactory, MAX_INT);
}
}
public async hasWETHApprovalOfMarketplace(amount: string): Promise<boolean> {
const _temp = new DecimalBigNumber(amount);
if (_temp.isNegative()) {
throw new Error(`${amount} is a negative amount`);
}
let allowance = await this.getWETHAllowanceOfMarketplace();
return new DecimalBigNumber(allowance).gte(_temp);
}
//plasma function
public async hasPlasmaApprovalOfNFTFactory(amount: string): Promise<boolean> {
const _temp = new DecimalBigNumber(amount);
if (_temp.isNegative()) {
throw new Error(`${amount} is a negative amount`);
}
let allowance = await this.getPlasmaAllowanceOfNFTFactory();
return new DecimalBigNumber(allowance).gte(_temp);
}
public async approveUsdtToNFTFactory(price: number): Promise<ContractTransaction> {
return this.usdtToken.approve(this.galaticFactory.address, usdtExponent.multipliedBy(price).toFixed());
}
public async approvePlasmaToNFTFactory(price: number): Promise<ContractTransaction> {
return this.plasma.approve(this.galaticFactory.address, exponent.multipliedBy(price).toFixed());
}
public async approvePlasmaToMarketplace(): Promise<ContractTransaction> {
return this.plasma.approve(this.galaticFactory.address, MAX_INT);
}
private async getPlasmaAllowanceOfNFTFactory(): Promise<string> {
if (this.plasma == null || this.plasma == undefined)
throw new Error('check the Plasma contract of correct network');
let allowance = await this.plasma.allowance(await this.signer.getAddress(), this.galaticFactory.address);
let ret = new DecimalBigNumber(allowance.toString()).div(exponent).toString();
return ret;
}
public async getNftAddresses(): Promise<string[]> {
let res: string[] = [];
for (let i = 0; i < 10; i++) {
let addr = await this.galaticFactory.nftContracts(i);
res.push(addr);
}
return res;
}
/**
* buy and sell weapon
* buy and sell type depends on buySellType variable of LootBuySellInfo structre
*/
public async buySellWeaponNFT(
v: BigNumber,
r: string,
s: string,
data: LootBuySellInfo
): Promise<ContractTransaction> {
const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
return marketplaceContract.buySellLootBoxes(v, r, s, data);
}
/**
* this function is called by buyer to purchase the
*/
public async purchaseLoot(quantity: BigNumber, tokenType: BigNumber): Promise<ContractTransaction> {
return this.galaticFactory.purchaseLootbox(quantity, tokenType);
}
/**
* this function is called by sender to send some loot as gift
* this function is depricated because this function only transfer the loot box to receiver
*/
// public async sendLootasGift(quantity: BigNumber, receiver: string): Promise<ContractTransaction> {
// const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
// return marketplaceContract.giftLootBoxes(quantity, receiver);
// }
/**
* this function is called by buyer to purchase the
*/
public async purchaseLootAndSendGift(
quantity: BigNumber,
giftReceiver: string,
tokenType: BigNumber
): Promise<ContractTransaction> {
return this.galaticFactory.purchaseLootboxAndSendGift(quantity, giftReceiver, tokenType);
}
/**
* this function is called by opener who open the loot
*/
public async openLoot(v: BigNumber, r: string, s: string, data: WeaponInfo): Promise<ContractTransaction> {
return this.galaticFactory.openLootBoxBySignature(v, r, s, data);
}
/**
* update the weapon by weapon owner
*/
public async updateWeapon(weaponId: BigNumber): Promise<ContractTransaction> {
return this.galaticFactory.updateWeapon(weaponId);
}
/**
* this function is called by buyer on fixed sell item
*/
public async buyNFT(v: BigNumber, r: string, s: string, data: NFTInfo): Promise<ContractTransaction> {
const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
return marketplaceContract.buySellItem(v, r, s, data);
}
/**
* this function is called by seller on auction sell. seller accept one bid in many bids
*/
public async sellNFT(v: BigNumber, r: string, s: string, data: NFTInfo): Promise<ContractTransaction> {
const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
return marketplaceContract.buySellItem(v, r, s, data);
}
public async claimUAP(v: BigNumber, r: string, s: string, data: UAPClaimInfo): Promise<ContractTransaction> {
const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
return marketplaceContract.claimUAP(v, r, s, data);
}
public async purchaseCartItems(v: BigNumber, r: string, s: string, data: BucketInfo): Promise<ContractTransaction> {
const marketplaceContract = new UfoMarketplace__factory(this.signer).attach(this.config.ufoMarketplace);
return marketplaceContract.buyCartItems(v, r, s, data);
}
}