UNPKG

@georgeroman/wyvern-v2-sdk

Version:

Wyvern V2 SDK

235 lines 8.81 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const abi_1 = require("@ethersproject/abi"); const bytes_1 = require("@ethersproject/bytes"); const contracts_1 = require("@ethersproject/contracts"); const hash_1 = require("@ethersproject/hash"); const solidity_1 = require("@ethersproject/solidity"); const wallet_1 = require("@ethersproject/wallet"); const Erc20_json_1 = __importDefault(require("../abis/Erc20.json")); const Erc721_json_1 = __importDefault(require("../abis/Erc721.json")); const Erc1155_json_1 = __importDefault(require("../abis/Erc1155.json")); const ProxyRegistry_json_1 = __importDefault(require("../abis/ProxyRegistry.json")); const types_1 = require("../types"); const utils_1 = require("../utils"); const address_1 = __importDefault(require("../utils/address")); const __1 = require(".."); const WYVERN_ORDER_FIELDS = [ "address", "address", "address", "uint", "uint", "uint", "uint", "address", "uint8", "uint8", "uint8", "address", "uint8", "bytes", "bytes", "address", "bytes", "address", "uint", "uint", "uint", "uint", "uint", // salt ]; const SIGNATURE_FIELDS = [ "uint8", "bytes32", "bytes32", // s ]; class OrderHelper { static async isApproved(provider, order) { try { const chainId = (await provider.getNetwork()).chainId; if (order.side === types_1.Side.BUY) { const paymentToken = new contracts_1.Contract(order.paymentToken, new abi_1.Interface(Erc20_json_1.default)); const allowance = await paymentToken .connect(provider) .allowance(order.maker, address_1.default.tokenTransferProxy(chainId)); return (0, utils_1.bn)(allowance).gte((0, utils_1.bn)(order.basePrice)); } else { const proxyRegistry = new contracts_1.Contract(address_1.default.proxyRegistry(chainId), new abi_1.Interface(ProxyRegistry_json_1.default)); const proxy = await proxyRegistry .connect(provider) .proxies(order.maker); if (!proxy) { return false; } if (__1.Builders.Erc721.SingleItem.isWellFormatted(order)) { const token = new contracts_1.Contract(order.target, new abi_1.Interface(Erc721_json_1.default)); const isApprovedForAll = await token .connect(provider) .isApprovedForAll(order.maker, proxy); if (!isApprovedForAll) { const tokenId = __1.Builders.Erc721.SingleItem.extractTokenId(order); const approved = await token.connect(provider).getApproved(tokenId); return approved && approved.toLowerCase() === proxy.toLowerCase(); } return isApprovedForAll; } else if (__1.Builders.Erc1155.SingleItem.isWellFormatted(order)) { const token = new contracts_1.Contract(order.target, new abi_1.Interface(Erc1155_json_1.default)); return token.connect(provider).isApprovedForAll(order.maker, proxy); } else { return false; } } } catch { return false; } } static normalize(order) { // - convert all BigNumbers to string // - lowercase all strings return { exchange: order.exchange.toLowerCase(), maker: order.maker.toLowerCase(), taker: order.taker.toLowerCase(), makerRelayerFee: order.makerRelayerFee.toString(), takerRelayerFee: order.takerRelayerFee.toString(), feeRecipient: order.feeRecipient.toLowerCase(), side: order.side, saleKind: order.saleKind, target: order.target.toLowerCase(), howToCall: order.howToCall, calldata: order.calldata.toLowerCase(), replacementPattern: order.replacementPattern.toLowerCase(), staticTarget: order.staticTarget.toLowerCase(), staticExtradata: order.staticExtradata.toLowerCase(), paymentToken: order.paymentToken.toLowerCase(), basePrice: order.basePrice.toString(), extra: order.extra.toString(), listingTime: order.listingTime.toString(), expirationTime: order.expirationTime.toString(), salt: order.salt.toString(), v: order.v, r: order.r.toLowerCase(), s: order.s.toLowerCase(), }; } static rawHash(order) { // Return the raw order hash return (0, solidity_1.keccak256)(WYVERN_ORDER_FIELDS, this.toRaw(order)); } static hash(order) { // Return the EIP191 prefix hash return (0, hash_1.hashMessage)((0, bytes_1.arrayify)(this.rawHash(order))); } static encode(order) { // Skip `makerProtocolFee`, `takerProtocolFee` and `feeMethod` since // these will always have the same value regardless of the order return abi_1.defaultAbiCoder.encode([ ...WYVERN_ORDER_FIELDS.filter((_, index) => ![5, 6, 8].includes(index)), ...SIGNATURE_FIELDS, ], [ ...this.toRaw(order).filter((_, index) => ![5, 6, 8].includes(index)), order.v, order.r, order.s, ]); } static decode(order) { try { const result = abi_1.defaultAbiCoder.decode([ ...WYVERN_ORDER_FIELDS.filter((_, index) => ![5, 6, 8].includes(index)), ...SIGNATURE_FIELDS, ], order); return this.normalize({ exchange: result[0], maker: result[1], taker: result[2], makerRelayerFee: result[3], takerRelayerFee: result[4], feeRecipient: result[5], side: result[6], saleKind: result[7], target: result[8], howToCall: result[9], calldata: result[10], replacementPattern: result[11], staticTarget: result[12], staticExtradata: result[13], paymentToken: result[14], basePrice: result[15], extra: result[16], listingTime: result[17], expirationTime: result[18], salt: result[19], v: result[20], r: result[21], s: result[22], }); } catch { return undefined; } } static async sign(signer, order) { const rawWyvernOrderHash = (0, solidity_1.keccak256)(WYVERN_ORDER_FIELDS, this.toRaw(order)); // Sign the order hash and populate the signature fields await signer .signMessage((0, bytes_1.arrayify)(rawWyvernOrderHash)) .then(bytes_1.splitSignature) .then(({ v, r, s }) => { order = { ...order, v, r, s }; }); return order; } static verifySignature(order) { const rawWyvernOrderHash = (0, solidity_1.keccak256)(WYVERN_ORDER_FIELDS, this.toRaw(order)); try { const signerAddress = (0, wallet_1.verifyMessage)((0, bytes_1.arrayify)(rawWyvernOrderHash), { v: order.v, r: order.r, s: order.s, }); return signerAddress.toLowerCase() === order.maker.toLowerCase(); } catch { return false; } } static toRaw(order) { // Construct raw order including all fields needed by Wyvern return [ order.exchange, order.maker, order.taker, order.makerRelayerFee, order.takerRelayerFee, 0, 0, order.feeRecipient, 1, order.side, order.saleKind, order.target, order.howToCall, order.calldata, order.replacementPattern, order.staticTarget, order.staticExtradata, order.paymentToken, order.basePrice, order.extra, order.listingTime, order.expirationTime, order.salt, ]; } } exports.default = OrderHelper; //# sourceMappingURL=order.js.map