@cryptovoxels/marketplace-js
Version:
A simple JS sdk to interact with Voxels' marketplace
211 lines • 9.28 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAddressFromSigner = exports.askApproval = exports.getIsApproved = exports.getContractsByNetwork = exports.isProvider = exports.generateListingId = exports.validateListingParams = exports.handleTransaction = void 0;
const ethers_1 = require("ethers");
const constants_1 = require("./constants");
const approvalContractABI = require("../abis/approval.json");
const wrapperRegistryABI = require("../abis/wrapperRegistry.json");
const supportsInterfaceABI = require("../abis/supportsInterface.json");
//@internal
function handleTransaction(transaction) {
return __awaiter(this, void 0, void 0, function* () {
let tx;
const awaitTransaction = (trans) => __awaiter(this, void 0, void 0, function* () {
let tx;
try {
tx = yield trans.wait(1);
}
catch (error) {
const e = error;
if ((e.reason == "replaced" || e.reason == "repriced") && e.replacement) {
tx = yield awaitTransaction(e.replacement);
}
else if (e.reason == "cancelled") {
throw new Error("Transaction cancelled");
}
else {
throw new Error(e.reason || (e === null || e === void 0 ? void 0 : e.toString()));
}
}
return tx;
});
tx = yield awaitTransaction(transaction);
return tx;
});
}
exports.handleTransaction = handleTransaction;
//@internal
const validateListingParams = (listingParams) => {
var _a;
if (!ethers_1.utils.isAddress(listingParams.address || "")) {
throw Error("Address is not valid");
}
if (listingParams.address == ethers_1.constants.AddressZero) {
throw Error("Address cannot be zero address");
}
if (!listingParams.price) {
throw Error("Price is missing");
}
if (listingParams.price <= 0) {
throw Error("Price cannot be zero or lower");
}
const quantity = (_a = listingParams.quantity) !== null && _a !== void 0 ? _a : 1;
if (quantity <= 0) {
throw Error("Quantity cannot be zero or lower");
}
if (listingParams.acceptedPayment &&
!ethers_1.utils.isAddress(listingParams.acceptedPayment)) {
throw Error("AcceptedPayment address is invalid");
}
if (!listingParams.token_id) {
throw Error("Token id is missing");
}
return true;
};
exports.validateListingParams = validateListingParams;
const generateListingId = (sellerAddress, contractAddress, tokenId) => {
//using abi encoder as apparently more secure
//https://github.com/ethers-io/ethers.js/issues/468#issuecomment-475990764
return ethers_1.ethers.utils.solidityKeccak256(["address", "address", "uint256"], [sellerAddress, contractAddress, tokenId]);
};
exports.generateListingId = generateListingId;
//@internal
const isProvider = (providerOrSigner) => {
if (!!providerOrSigner._isProvider) {
return true;
}
return false;
};
exports.isProvider = isProvider;
const implementatioNeedsWrapper = (implementationAddress, providerOrSigner) => __awaiter(void 0, void 0, void 0, function* () {
// Check if implementationAddress supports ERC1155 or ERC721 and if not, check if it has a wrapper
const supportInterfaceContract = new ethers_1.ethers.Contract(implementationAddress, supportsInterfaceABI, providerOrSigner);
let needsWrapper = false;
try {
const isERC721 = yield supportInterfaceContract.supportsInterface(constants_1.ERC721_INTERFACE_ID);
if (!isERC721) {
const isERC1155 = yield supportInterfaceContract.supportsInterface(constants_1.ERC1155_INTERFACE_ID);
if (!isERC1155) {
needsWrapper = true;
}
}
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.error(err);
return false;
}
return !!needsWrapper;
});
//@internal
const getContractsByNetwork = (network) => {
return constants_1.CONTRACTS[network];
};
exports.getContractsByNetwork = getContractsByNetwork;
//@internal
const getIsApproved = (contract, implementationAddress, userWallet, network) => __awaiter(void 0, void 0, void 0, function* () {
if (!contract) {
throw Error("SDK not initialized");
}
if (!ethers_1.ethers.utils.isAddress(implementationAddress)) {
throw Error("implementationAddress is invalid");
}
if (!ethers_1.ethers.utils.isAddress(userWallet)) {
throw Error("userWallet is invalid");
}
const providerOrSigner = contract.signer || contract.provider;
// Check if implementationAddress supports ERC1155 or ERC721 and if not, check if it has a wrapper
const needsWrapper = yield implementatioNeedsWrapper(implementationAddress, providerOrSigner);
let wrapper;
if (needsWrapper) {
const wrapperRegistryContract = new ethers_1.ethers.Contract((0, exports.getContractsByNetwork)(network).wrapperRegistry, wrapperRegistryABI, providerOrSigner);
try {
let [, , wrapper_] = yield wrapperRegistryContract.fromImplementationAddress(implementationAddress);
if (wrapper_ && ethers_1.ethers.constants.AddressZero !== wrapper_) {
wrapper = wrapper_;
}
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.error(err);
return false;
}
}
const operatorToSet = wrapper || (0, exports.getContractsByNetwork)(network).marketplace;
const contractToCallInstance = new ethers_1.ethers.Contract(implementationAddress, approvalContractABI, providerOrSigner);
try {
// If we have a wrapper, this essentially becomes "wrapper.isApprovedForAll(from,wrapper)"
const isApproved = yield contractToCallInstance.isApprovedForAll(userWallet, operatorToSet);
return isApproved;
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.error(err);
return false;
}
});
exports.getIsApproved = getIsApproved;
//@internal
const askApproval = (contract, implementationAddress, userWallet, network, emit) => __awaiter(void 0, void 0, void 0, function* () {
if (!contract) {
throw Error("SDK not initialized");
}
if (!ethers_1.ethers.utils.isAddress(implementationAddress)) {
throw Error("implementationAddress is invalid");
}
if (!ethers_1.ethers.utils.isAddress(userWallet)) {
throw Error("userWallet is invalid");
}
const providerOrSigner = contract.signer || contract.provider;
const wrapperRegistryContract = new ethers_1.ethers.Contract((0, exports.getContractsByNetwork)(network).wrapperRegistry, wrapperRegistryABI, providerOrSigner);
let wrapper;
try {
let [, , wrapper_] = yield wrapperRegistryContract.fromImplementationAddress(implementationAddress);
if (wrapper_ && ethers_1.ethers.constants.AddressZero !== wrapper_) {
wrapper = wrapper_;
}
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.warn(err);
}
const operatorToSet = wrapper || (0, exports.getContractsByNetwork)(network).marketplace;
const contractToCallInstance = new ethers_1.ethers.Contract(implementationAddress, approvalContractABI, providerOrSigner);
!!emit && emit("approval:tx-start");
let tx;
try {
tx = yield contractToCallInstance.setApprovalForAll(operatorToSet, true);
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.error(err);
return false;
}
emit && emit("approval:tx-hash", { hash: tx.hash });
try {
const receipt = yield handleTransaction(tx);
emit && emit("approval:tx-mined", { hash: receipt.transactionHash });
return receipt.status == 1;
}
catch (e) {
const err = e.toString ? e.toString() : e;
console.error(err);
emit && emit("error", { error: err });
return false;
}
});
exports.askApproval = askApproval;
const getAddressFromSigner = (signer) => __awaiter(void 0, void 0, void 0, function* () {
return yield signer.getAddress();
});
exports.getAddressFromSigner = getAddressFromSigner;
//# sourceMappingURL=helpers.js.map