@georgeroman/wyvern-v2-sdk
Advanced tools
Comparing version 0.0.24 to 0.0.25
@@ -8,10 +8,10 @@ import { BigNumberish } from "@ethersproject/bignumber"; | ||
staticTarget: string; | ||
tokenIds: BigNumberish[]; | ||
tokenIds: string[]; | ||
paymentToken: string; | ||
basePrice: BigNumberish; | ||
fee: BigNumberish; | ||
basePrice: string; | ||
fee: string; | ||
feeRecipient: string; | ||
listingTime: BigNumberish; | ||
expirationTime: BigNumberish; | ||
salt: BigNumberish; | ||
listingTime: string; | ||
expirationTime: string; | ||
salt: string; | ||
v?: number; | ||
@@ -18,0 +18,0 @@ r?: string; |
@@ -12,4 +12,4 @@ "use strict"; | ||
const types_1 = require("../../types"); | ||
const utils_1 = require("../utils"); | ||
const ERC721_json_1 = __importDefault(require("../../abis/ERC721.json")); | ||
const utils_1 = require("../../utils"); | ||
const Erc721_json_1 = __importDefault(require("../../abis/Erc721.json")); | ||
const PROVIDE_ROOT_REPLACEMENT_PATTERN = (numMerkleTreeLevels) => | ||
@@ -122,3 +122,3 @@ // "root" field | ||
try { | ||
const result = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", order.calldata); | ||
const result = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", order.calldata); | ||
return result.tokenId.toString(); | ||
@@ -131,3 +131,3 @@ } | ||
static sell(params) { | ||
const calldata = new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [ | ||
const calldata = new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
params.maker, | ||
@@ -152,3 +152,3 @@ constants_1.AddressZero, | ||
makerRelayerFee: params.fee, | ||
takerRelayerFee: 0, | ||
takerRelayerFee: "0", | ||
feeRecipient: params.feeRecipient, | ||
@@ -165,3 +165,3 @@ side: types_1.Side.SELL, | ||
basePrice: params.basePrice, | ||
extra: 0, | ||
extra: "0", | ||
listingTime: params.listingTime, | ||
@@ -171,10 +171,8 @@ expirationTime: params.expirationTime, | ||
v: params.v || 0, | ||
r: params.r || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: params.s || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
r: params.r || utils_1.Bytes32Zero, | ||
s: params.s || utils_1.Bytes32Zero, | ||
}); | ||
} | ||
static buy(params) { | ||
const calldata = new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [ | ||
const calldata = new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
constants_1.AddressZero, | ||
@@ -198,3 +196,3 @@ params.maker, | ||
taker: constants_1.AddressZero, | ||
makerRelayerFee: 0, | ||
makerRelayerFee: "0", | ||
takerRelayerFee: params.fee, | ||
@@ -212,3 +210,3 @@ feeRecipient: params.feeRecipient, | ||
basePrice: params.basePrice, | ||
extra: 0, | ||
extra: "0", | ||
listingTime: params.listingTime, | ||
@@ -218,6 +216,4 @@ expirationTime: params.expirationTime, | ||
v: params.v || 0, | ||
r: params.r || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: params.s || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
r: params.r || utils_1.Bytes32Zero, | ||
s: params.s || utils_1.Bytes32Zero, | ||
}); | ||
@@ -233,3 +229,3 @@ } | ||
} | ||
const buyCalldata = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", buyOrder.calldata); | ||
const buyCalldata = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", buyOrder.calldata); | ||
// Make sure the sell order's calldata (the beginning portion of it) has the following format: | ||
@@ -243,3 +239,3 @@ // "transferFrom(address(0), buyer, tokenId)" | ||
} | ||
const calldata = new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [ | ||
const calldata = new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
seller, | ||
@@ -267,9 +263,9 @@ constants_1.AddressZero, | ||
basePrice: buyOrder.basePrice, | ||
extra: 0, | ||
listingTime: (0, utils_1.getListingTime)(), | ||
expirationTime: 0, | ||
salt: (0, utils_1.getSalt)(), | ||
extra: "0", | ||
listingTime: (0, utils_1.getListingTime)().toString(), | ||
expirationTime: "0", | ||
salt: (0, utils_1.getSalt)().toString(), | ||
v: 0, | ||
r: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
r: utils_1.Bytes32Zero, | ||
s: utils_1.Bytes32Zero, | ||
}); | ||
@@ -285,3 +281,3 @@ } | ||
} | ||
const sellCalldata = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", sellOrder.calldata); | ||
const sellCalldata = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", sellOrder.calldata); | ||
// Make sure the sell order's calldata (the beginning portion of it) has the following format: | ||
@@ -295,3 +291,3 @@ // "transferFrom(seller, address(0), tokenId)" | ||
} | ||
const calldata = new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [ | ||
const calldata = new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
constants_1.AddressZero, | ||
@@ -319,9 +315,9 @@ buyer, | ||
basePrice: sellOrder.basePrice, | ||
extra: 0, | ||
listingTime: (0, utils_1.getListingTime)(), | ||
expirationTime: 0, | ||
salt: (0, utils_1.getSalt)(), | ||
extra: "0", | ||
listingTime: (0, utils_1.getListingTime)().toString(), | ||
expirationTime: "0", | ||
salt: (0, utils_1.getSalt)().toString(), | ||
v: 0, | ||
r: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
r: utils_1.Bytes32Zero, | ||
s: utils_1.Bytes32Zero, | ||
}); | ||
@@ -328,0 +324,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import { BigNumberish } from "@ethersproject/bignumber"; | ||
import { Order } from "../../types"; | ||
@@ -7,11 +6,11 @@ declare type RequiredOrderParams = { | ||
target: string; | ||
tokenId: BigNumberish; | ||
tokenId: string; | ||
paymentToken: string; | ||
basePrice: BigNumberish; | ||
fee: BigNumberish; | ||
basePrice: string; | ||
fee: string; | ||
feeRecipient: string; | ||
listingTime: BigNumberish; | ||
expirationTime: BigNumberish; | ||
salt: BigNumberish; | ||
extra?: BigNumberish; | ||
listingTime: string; | ||
expirationTime: string; | ||
salt: string; | ||
extra?: string; | ||
v?: number; | ||
@@ -22,11 +21,11 @@ r?: string; | ||
export default class SingleItemErc721OrderBuilder { | ||
static extractTokenId(order: Order): string | undefined; | ||
static extractTokenId(order: Order): [string, string] | undefined; | ||
static isSell(order: Order, tokenId: string): boolean; | ||
static isBuy(order: Order, tokenId: string): boolean; | ||
static sell(params: RequiredOrderParams): Order; | ||
static buy(params: RequiredOrderParams): Order; | ||
static matchingSell(seller: string, buyOrder: Order): Order; | ||
static matchingBuy(buyer: string, sellOrder: Order): Order; | ||
static sell(params: RequiredOrderParams): Order | undefined; | ||
static buy(params: RequiredOrderParams): Order | undefined; | ||
static matchingSell(seller: string, buyOrder: Order): Order | undefined; | ||
static matchingBuy(buyer: string, sellOrder: Order): Order | undefined; | ||
} | ||
export {}; | ||
//# sourceMappingURL=single-item.d.ts.map |
@@ -10,11 +10,17 @@ "use strict"; | ||
const types_1 = require("../../types"); | ||
const utils_1 = require("../utils"); | ||
const ERC721_json_1 = __importDefault(require("../../abis/ERC721.json")); | ||
const utils_1 = require("../../utils"); | ||
const Erc721_json_1 = __importDefault(require("../../abis/Erc721.json")); | ||
// ERC721 calldata format: | ||
// transferFrom(from, to, tokenId) | ||
// ERC721 replacement pattern format: | ||
// 4 bytes - "transferFrom" function signature | ||
// 64 bytes - "from" | ||
// 64 bytes - "to" | ||
// 64 bytes - "tokenId" | ||
const REPLACEMENT_PATTERN_BUY = "0x00000000" + "f".repeat(64) + "0".repeat(64) + "0".repeat(64); | ||
const REPLACEMENT_PATTERN_SELL = "0x00000000" + "0".repeat(64) + "f".repeat(64) + "0".repeat(64); | ||
class SingleItemErc721OrderBuilder { | ||
// --------------- Public --------------- | ||
static extractTokenId(order) { | ||
try { | ||
const result = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", order.calldata); | ||
const result = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", order.calldata); | ||
return result.tokenId.toString(); | ||
@@ -27,190 +33,218 @@ } | ||
static isSell(order, tokenId) { | ||
// Build a mock order that is for sure well-formatted | ||
const built = this.sell({ | ||
...order, | ||
tokenId, | ||
fee: 0, | ||
}); | ||
// Make sure the built order's fields match the given order | ||
return (order.calldata === built.calldata && | ||
order.replacementPattern === built.replacementPattern); | ||
try { | ||
// Build a mock order that is for sure well-formatted | ||
const built = this.sell({ | ||
...order, | ||
tokenId, | ||
fee: "0", | ||
}); | ||
if (!built) { | ||
return false; | ||
} | ||
// Make sure the built order's fields match the given order | ||
return (order.calldata === built.calldata && | ||
order.replacementPattern === built.replacementPattern); | ||
} | ||
catch { | ||
return false; | ||
} | ||
} | ||
static isBuy(order, tokenId) { | ||
// Build a mock order that is for sure well-formatted | ||
const built = this.buy({ | ||
...order, | ||
tokenId, | ||
fee: 0, | ||
}); | ||
// Make sure the built order's fields match the given order | ||
return (order.calldata === built.calldata && | ||
order.replacementPattern === built.replacementPattern); | ||
try { | ||
// Build a mock order that is for sure well-formatted | ||
const built = this.buy({ | ||
...order, | ||
tokenId, | ||
fee: "0", | ||
}); | ||
if (!built) { | ||
return false; | ||
} | ||
// Make sure the built order's fields match the given order | ||
return (order.calldata === built.calldata && | ||
order.replacementPattern === built.replacementPattern); | ||
} | ||
catch { | ||
return false; | ||
} | ||
} | ||
static sell(params) { | ||
if ((0, utils_1.bn)(params.extra || 0).gt(0)) { | ||
if ((0, utils_1.bn)(params.listingTime).gte((0, utils_1.bn)(params.expirationTime))) { | ||
throw new Error("Invalid listing/expiration time"); | ||
try { | ||
const isDutchAuction = (0, utils_1.bn)(params.extra || 0).gt(0); | ||
if (isDutchAuction) { | ||
if ((0, utils_1.bn)(params.listingTime).gte((0, utils_1.bn)(params.expirationTime))) { | ||
throw new Error("Invalid listing/expiration time"); | ||
} | ||
} | ||
return order_1.default.normalize({ | ||
exchange: params.exchange, | ||
maker: params.maker, | ||
taker: constants_1.AddressZero, | ||
makerRelayerFee: params.fee, | ||
takerRelayerFee: "0", | ||
feeRecipient: params.feeRecipient, | ||
side: types_1.Side.SELL, | ||
saleKind: isDutchAuction | ||
? types_1.SaleKind.DUTCH_AUCTION | ||
: types_1.SaleKind.FIXED_PRICE, | ||
target: params.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
params.maker, | ||
constants_1.AddressZero, | ||
params.tokenId, | ||
]), | ||
replacementPattern: REPLACEMENT_PATTERN_SELL, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: params.paymentToken, | ||
basePrice: params.basePrice, | ||
extra: params.extra || "0", | ||
listingTime: params.listingTime, | ||
expirationTime: params.expirationTime, | ||
salt: params.salt, | ||
v: params.v || 0, | ||
r: params.r || utils_1.Bytes32Zero, | ||
s: params.s || utils_1.Bytes32Zero, | ||
}); | ||
} | ||
return order_1.default.normalize({ | ||
exchange: params.exchange, | ||
maker: params.maker, | ||
taker: constants_1.AddressZero, | ||
makerRelayerFee: params.fee, | ||
takerRelayerFee: 0, | ||
feeRecipient: params.feeRecipient, | ||
side: types_1.Side.SELL, | ||
saleKind: (0, utils_1.bn)(params.extra || 0).gt(0) | ||
? types_1.SaleKind.DUTCH_AUCTION | ||
: types_1.SaleKind.FIXED_PRICE, | ||
target: params.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [params.maker, constants_1.AddressZero, params.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_SELL, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: params.paymentToken, | ||
basePrice: params.basePrice, | ||
extra: params.extra || 0, | ||
listingTime: params.listingTime, | ||
expirationTime: params.expirationTime, | ||
salt: params.salt, | ||
v: params.v || 0, | ||
r: params.r || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: params.s || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
}); | ||
catch { | ||
return undefined; | ||
} | ||
} | ||
static buy(params) { | ||
if ((0, utils_1.bn)(params.extra || 0).gt(0)) { | ||
if ((0, utils_1.bn)(params.listingTime).gte((0, utils_1.bn)(params.expirationTime))) { | ||
throw new Error("Invalid listing/expiration time"); | ||
} | ||
try { | ||
return order_1.default.normalize({ | ||
exchange: params.exchange, | ||
maker: params.maker, | ||
taker: constants_1.AddressZero, | ||
makerRelayerFee: "0", | ||
takerRelayerFee: params.fee, | ||
feeRecipient: params.feeRecipient, | ||
side: types_1.Side.BUY, | ||
// Notice: we don't support dutch auction buys | ||
saleKind: types_1.SaleKind.FIXED_PRICE, | ||
target: params.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [ | ||
constants_1.AddressZero, | ||
params.maker, | ||
params.tokenId, | ||
]), | ||
replacementPattern: REPLACEMENT_PATTERN_BUY, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: params.paymentToken, | ||
basePrice: params.basePrice, | ||
extra: params.extra || "0", | ||
listingTime: params.listingTime, | ||
expirationTime: params.expirationTime, | ||
salt: params.salt, | ||
v: params.v || 0, | ||
r: params.r || utils_1.Bytes32Zero, | ||
s: params.s || utils_1.Bytes32Zero, | ||
}); | ||
} | ||
return order_1.default.normalize({ | ||
exchange: params.exchange, | ||
maker: params.maker, | ||
taker: constants_1.AddressZero, | ||
makerRelayerFee: 0, | ||
takerRelayerFee: params.fee, | ||
feeRecipient: params.feeRecipient, | ||
side: types_1.Side.BUY, | ||
saleKind: (0, utils_1.bn)(params.extra || 0).gt(0) | ||
? types_1.SaleKind.DUTCH_AUCTION | ||
: types_1.SaleKind.FIXED_PRICE, | ||
target: params.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [constants_1.AddressZero, params.maker, params.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_BUY, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: params.paymentToken, | ||
basePrice: params.basePrice, | ||
extra: params.extra || 0, | ||
listingTime: params.listingTime, | ||
expirationTime: params.expirationTime, | ||
salt: params.salt, | ||
v: params.v || 0, | ||
r: params.r || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: params.s || | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
}); | ||
catch { | ||
return undefined; | ||
} | ||
} | ||
static matchingSell(seller, buyOrder) { | ||
if (buyOrder.side !== types_1.Side.BUY) { | ||
throw new Error("Invalid buy order side"); | ||
try { | ||
if (buyOrder.side !== types_1.Side.BUY) { | ||
throw new Error("Invalid buy order side"); | ||
} | ||
if (buyOrder.replacementPattern !== REPLACEMENT_PATTERN_BUY) { | ||
throw new Error("Invalid buy order replacement pattern"); | ||
} | ||
// Notice: we don't support dutch auction buys | ||
if (buyOrder.saleKind !== types_1.SaleKind.FIXED_PRICE) { | ||
throw new Error("Unsupported sale kind"); | ||
} | ||
// The buy order's calldata must have the following format: | ||
// "transferFrom(address(0), buyer, tokenId)" | ||
const buyCalldata = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", buyOrder.calldata); | ||
if (buyCalldata.to.toLowerCase() !== buyOrder.maker.toLowerCase()) { | ||
throw new Error("Invalid buy order calldata"); | ||
} | ||
return order_1.default.normalize({ | ||
exchange: buyOrder.exchange, | ||
maker: seller, | ||
taker: buyOrder.maker, | ||
makerRelayerFee: buyOrder.makerRelayerFee, | ||
takerRelayerFee: buyOrder.takerRelayerFee, | ||
feeRecipient: constants_1.AddressZero, | ||
side: types_1.Side.SELL, | ||
saleKind: types_1.SaleKind.FIXED_PRICE, | ||
target: buyOrder.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [seller, constants_1.AddressZero, buyCalldata.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_SELL, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: buyOrder.paymentToken, | ||
basePrice: buyOrder.basePrice, | ||
extra: "0", | ||
listingTime: (0, utils_1.getListingTime)().toString(), | ||
expirationTime: "0", | ||
salt: (0, utils_1.getSalt)().toString(), | ||
v: 0, | ||
r: utils_1.Bytes32Zero, | ||
s: utils_1.Bytes32Zero, | ||
}); | ||
} | ||
if (buyOrder.replacementPattern !== REPLACEMENT_PATTERN_BUY) { | ||
throw new Error("Invalid buy order replacement pattern"); | ||
catch { | ||
return undefined; | ||
} | ||
const buyCalldata = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", buyOrder.calldata); | ||
// Make sure the buy order's calldata has the following format: | ||
// "transferFrom(address(0), buyer, tokenId)" | ||
if (buyCalldata.to.toLowerCase() !== buyOrder.maker.toLowerCase()) { | ||
throw new Error("Invalid buy order calldata"); | ||
} | ||
if (buyCalldata.from !== constants_1.AddressZero) { | ||
throw new Error("Invalid buy order calldata"); | ||
} | ||
// As in https://github.com/ProjectWyvern/wyvern-ethereum/blob/bfca101b2407e4938398fccd8d1c485394db7e01/contracts/exchange/SaleKindInterface.sol#L70-L87 | ||
const basePrice = buyOrder.saleKind === types_1.SaleKind.FIXED_PRICE | ||
? (0, utils_1.bn)(buyOrder.basePrice) | ||
: (0, utils_1.bn)(buyOrder.basePrice).add((0, utils_1.bn)(buyOrder.extra) | ||
.mul((0, utils_1.bn)((0, utils_1.getDutchAuctionBuyTime)()).sub((0, utils_1.bn)(buyOrder.listingTime))) | ||
.div((0, utils_1.bn)(buyOrder.expirationTime).sub((0, utils_1.bn)(buyOrder.listingTime)))); | ||
return order_1.default.normalize({ | ||
exchange: buyOrder.exchange, | ||
maker: seller, | ||
taker: buyOrder.maker, | ||
makerRelayerFee: buyOrder.makerRelayerFee, | ||
takerRelayerFee: buyOrder.takerRelayerFee, | ||
feeRecipient: constants_1.AddressZero, | ||
side: types_1.Side.SELL, | ||
saleKind: types_1.SaleKind.FIXED_PRICE, | ||
target: buyOrder.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [seller, constants_1.AddressZero, buyCalldata.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_SELL, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: buyOrder.paymentToken, | ||
basePrice, | ||
extra: 0, | ||
listingTime: (0, utils_1.getListingTime)(), | ||
expirationTime: 0, | ||
salt: (0, utils_1.getSalt)(), | ||
v: 0, | ||
r: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
}); | ||
} | ||
static matchingBuy(buyer, sellOrder) { | ||
if (sellOrder.side !== types_1.Side.SELL) { | ||
throw new Error("Invalid sell order side"); | ||
try { | ||
if (sellOrder.side !== types_1.Side.SELL) { | ||
throw new Error("Invalid sell order side"); | ||
} | ||
if (sellOrder.replacementPattern !== REPLACEMENT_PATTERN_SELL) { | ||
throw new Error("Invalid sell order replacement pattern"); | ||
} | ||
// The sell order's calldata must have the following format: | ||
// "transferFrom(seller, address(0), tokenId)" | ||
const sellCalldata = new abi_1.Interface(Erc721_json_1.default).decodeFunctionData("transferFrom", sellOrder.calldata); | ||
if (sellCalldata.from.toLowerCase() !== sellOrder.maker.toLowerCase()) { | ||
throw new Error("Invalid buy order calldata"); | ||
} | ||
// As in https://github.com/ProjectWyvern/wyvern-ethereum/blob/bfca101b2407e4938398fccd8d1c485394db7e01/contracts/exchange/SaleKindInterface.sol#L70-L87 | ||
const listingTime = (0, utils_1.getListingTime)(); | ||
const basePrice = sellOrder.saleKind === types_1.SaleKind.FIXED_PRICE | ||
? (0, utils_1.bn)(sellOrder.basePrice) | ||
: (0, utils_1.bn)(sellOrder.basePrice).sub((0, utils_1.bn)(sellOrder.extra) | ||
.mul(listingTime.sub((0, utils_1.bn)(sellOrder.listingTime))) | ||
.div((0, utils_1.bn)(sellOrder.expirationTime).sub((0, utils_1.bn)(sellOrder.listingTime)))); | ||
return order_1.default.normalize({ | ||
exchange: sellOrder.exchange, | ||
maker: buyer, | ||
taker: sellOrder.maker, | ||
makerRelayerFee: sellOrder.makerRelayerFee, | ||
takerRelayerFee: sellOrder.takerRelayerFee, | ||
feeRecipient: constants_1.AddressZero, | ||
side: types_1.Side.BUY, | ||
saleKind: types_1.SaleKind.FIXED_PRICE, | ||
target: sellOrder.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(Erc721_json_1.default).encodeFunctionData("transferFrom", [constants_1.AddressZero, buyer, sellCalldata.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_BUY, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: sellOrder.paymentToken, | ||
basePrice: basePrice.toString(), | ||
extra: "0", | ||
listingTime: listingTime.toString(), | ||
expirationTime: "0", | ||
salt: (0, utils_1.getSalt)().toString(), | ||
v: 0, | ||
r: utils_1.Bytes32Zero, | ||
s: utils_1.Bytes32Zero, | ||
}); | ||
} | ||
if (sellOrder.replacementPattern !== REPLACEMENT_PATTERN_SELL) { | ||
throw new Error("Invalid sell order replacement pattern"); | ||
catch { | ||
return undefined; | ||
} | ||
const sellCalldata = new abi_1.Interface(ERC721_json_1.default).decodeFunctionData("transferFrom", sellOrder.calldata); | ||
// Make sure the sell order's calldata has the following format: | ||
// "transferFrom(seller, address(0), tokenId)" | ||
if (sellCalldata.from.toLowerCase() !== sellOrder.maker.toLowerCase()) { | ||
throw new Error("Invalid sell order calldata"); | ||
} | ||
if (sellCalldata.to !== constants_1.AddressZero) { | ||
throw new Error("Invalid sell order calldata"); | ||
} | ||
// As in https://github.com/ProjectWyvern/wyvern-ethereum/blob/bfca101b2407e4938398fccd8d1c485394db7e01/contracts/exchange/SaleKindInterface.sol#L70-L87 | ||
const basePrice = sellOrder.saleKind === types_1.SaleKind.FIXED_PRICE | ||
? (0, utils_1.bn)(sellOrder.basePrice) | ||
: (0, utils_1.bn)(sellOrder.basePrice).sub((0, utils_1.bn)(sellOrder.extra) | ||
.mul((0, utils_1.bn)((0, utils_1.getDutchAuctionSellTime)()).sub((0, utils_1.bn)(sellOrder.listingTime))) | ||
.div((0, utils_1.bn)(sellOrder.expirationTime).sub((0, utils_1.bn)(sellOrder.listingTime)))); | ||
return order_1.default.normalize({ | ||
exchange: sellOrder.exchange, | ||
maker: buyer, | ||
taker: sellOrder.maker, | ||
makerRelayerFee: sellOrder.makerRelayerFee, | ||
takerRelayerFee: sellOrder.takerRelayerFee, | ||
feeRecipient: constants_1.AddressZero, | ||
side: types_1.Side.BUY, | ||
saleKind: types_1.SaleKind.FIXED_PRICE, | ||
target: sellOrder.target, | ||
howToCall: types_1.HowToCall.CALL, | ||
calldata: new abi_1.Interface(ERC721_json_1.default).encodeFunctionData("transferFrom", [constants_1.AddressZero, buyer, sellCalldata.tokenId]), | ||
replacementPattern: REPLACEMENT_PATTERN_BUY, | ||
staticTarget: constants_1.AddressZero, | ||
staticExtradata: "0x", | ||
paymentToken: sellOrder.paymentToken, | ||
basePrice, | ||
extra: 0, | ||
listingTime: (0, utils_1.getListingTime)(), | ||
expirationTime: 0, | ||
salt: (0, utils_1.getSalt)(), | ||
v: 0, | ||
r: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
s: "0x0000000000000000000000000000000000000000000000000000000000000000", | ||
}); | ||
} | ||
@@ -217,0 +251,0 @@ } |
@@ -7,3 +7,4 @@ import { Signer } from "@ethersproject/abstract-signer"; | ||
static erc721All(approver: Signer, token: string, operator: string): Promise<any>; | ||
static erc1155All(approver: Signer, token: string, operator: string): Promise<any>; | ||
} | ||
//# sourceMappingURL=approval.d.ts.map |
@@ -7,8 +7,8 @@ "use strict"; | ||
const contracts_1 = require("@ethersproject/contracts"); | ||
const ERC20_json_1 = __importDefault(require("../abis/ERC20.json")); | ||
const ERC721_json_1 = __importDefault(require("../abis/ERC721.json")); | ||
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")); | ||
class ApprovalHelper { | ||
// --------------- Public --------------- | ||
static async erc20(approver, token, spender, amount) { | ||
return new contracts_1.Contract(token, ERC20_json_1.default) | ||
return new contracts_1.Contract(token, Erc20_json_1.default) | ||
.connect(approver) | ||
@@ -18,3 +18,3 @@ .approve(spender, amount); | ||
static async erc721(approver, token, to, tokenId) { | ||
return new contracts_1.Contract(token, ERC721_json_1.default) | ||
return new contracts_1.Contract(token, Erc721_json_1.default) | ||
.connect(approver) | ||
@@ -24,8 +24,13 @@ .approve(to, tokenId); | ||
static async erc721All(approver, token, operator) { | ||
return new contracts_1.Contract(token, ERC721_json_1.default) | ||
return new contracts_1.Contract(token, Erc721_json_1.default) | ||
.connect(approver) | ||
.setApprovalForAll(operator, true); | ||
} | ||
static async erc1155All(approver, token, operator) { | ||
return new contracts_1.Contract(token, Erc1155_json_1.default) | ||
.connect(approver) | ||
.setApprovalForAll(operator, true); | ||
} | ||
} | ||
exports.default = ApprovalHelper; | ||
//# sourceMappingURL=approval.js.map |
@@ -39,5 +39,4 @@ "use strict"; | ||
class OrderHelper { | ||
// --------------- Public --------------- | ||
static normalize(order) { | ||
// Convert all strings to lowercase and all bignumbers to strings | ||
// Lowercase all strings for consistency | ||
return { | ||
@@ -47,4 +46,4 @@ exchange: order.exchange.toLowerCase(), | ||
taker: order.taker.toLowerCase(), | ||
makerRelayerFee: order.makerRelayerFee.toString(), | ||
takerRelayerFee: order.takerRelayerFee.toString(), | ||
makerRelayerFee: order.makerRelayerFee, | ||
takerRelayerFee: order.takerRelayerFee, | ||
feeRecipient: order.feeRecipient.toLowerCase(), | ||
@@ -60,7 +59,7 @@ side: order.side, | ||
paymentToken: order.paymentToken.toLowerCase(), | ||
basePrice: order.basePrice.toString(), | ||
extra: order.extra.toString(), | ||
listingTime: order.listingTime.toString(), | ||
expirationTime: order.expirationTime.toString(), | ||
salt: order.salt.toString(), | ||
basePrice: order.basePrice, | ||
extra: order.extra, | ||
listingTime: order.listingTime, | ||
expirationTime: order.expirationTime, | ||
salt: order.salt, | ||
v: order.v, | ||
@@ -77,8 +76,8 @@ r: order.r, | ||
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([ | ||
// Skip `makerProtocolFee`, `takerProtocolFee` and `feeMethod` | ||
...WYVERN_ORDER_FIELDS.filter((_, index) => ![5, 6, 8].includes(index)), | ||
...SIGNATURE_FIELDS, | ||
], [ | ||
// Skip `makerProtocolFee`, `takerProtocolFee` and `feeMethod` | ||
...this.toRaw(order).filter((_, index) => ![5, 6, 8].includes(index)), | ||
@@ -92,3 +91,2 @@ order.v, | ||
const result = abi_1.defaultAbiCoder.decode([ | ||
// Remove `makerProtocolFee`, `takerProtocolFee` and `feeMethod` | ||
...WYVERN_ORDER_FIELDS.filter((_, index) => ![5, 6, 8].includes(index)), | ||
@@ -148,3 +146,2 @@ ...SIGNATURE_FIELDS, | ||
} | ||
// --------------- Private --------------- | ||
static toRaw(order) { | ||
@@ -151,0 +148,0 @@ // Construct raw order including all fields needed by Wyvern |
import { Signer } from "@ethersproject/abstract-signer"; | ||
import { BigNumberish } from "@ethersproject/bignumber"; | ||
export default class WethHelper { | ||
static deposit(depositor: Signer, value: BigNumberish): Promise<any>; | ||
static withdraw(withdrawer: Signer, value: BigNumberish): Promise<any>; | ||
private static getWethAddress; | ||
static deposit(depositor: Signer, weth: string, value: BigNumberish): Promise<any>; | ||
static withdraw(withdrawer: Signer, weth: string, value: BigNumberish): Promise<any>; | ||
} | ||
//# sourceMappingURL=weth.d.ts.map |
@@ -7,32 +7,16 @@ "use strict"; | ||
const contracts_1 = require("@ethersproject/contracts"); | ||
const WETH_json_1 = __importDefault(require("../abis/WETH.json")); | ||
const wethAddresses = { | ||
1: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", | ||
4: "0xc778417e063141139fce010982780140aa0cd5ab", | ||
}; | ||
const Weth_json_1 = __importDefault(require("../abis/Weth.json")); | ||
class WethHelper { | ||
// --------------- Public --------------- | ||
static async deposit(depositor, value) { | ||
const wethAddress = await this.getWethAddress(depositor); | ||
return new contracts_1.Contract(wethAddress, WETH_json_1.default) | ||
static async deposit(depositor, weth, value) { | ||
return new contracts_1.Contract(weth, Weth_json_1.default) | ||
.connect(depositor) | ||
.deposit({ value }); | ||
} | ||
static async withdraw(withdrawer, value) { | ||
const wethAddress = await this.getWethAddress(withdrawer); | ||
return new contracts_1.Contract(wethAddress, WETH_json_1.default) | ||
static async withdraw(withdrawer, weth, value) { | ||
return new contracts_1.Contract(weth, Weth_json_1.default) | ||
.connect(withdrawer) | ||
.withdraw(value); | ||
} | ||
// --------------- Private --------------- | ||
static async getWethAddress(signer) { | ||
const chainId = await signer.getChainId(); | ||
const address = wethAddresses[chainId]; | ||
if (!address) { | ||
throw new Error("Unsupported chain id"); | ||
} | ||
return address; | ||
} | ||
} | ||
exports.default = WethHelper; | ||
//# sourceMappingURL=weth.js.map |
@@ -9,6 +9,5 @@ "use strict"; | ||
const types_1 = require("../types"); | ||
const utils_1 = require("../utils"); | ||
const Exchange_json_1 = __importDefault(require("../abis/Exchange.json")); | ||
const order_1 = __importDefault(require("./order")); | ||
class WyvernHelper { | ||
// --------------- Public --------------- | ||
static async match(relayer, buyOrder, sellOrder) { | ||
@@ -72,24 +71,12 @@ if (buyOrder.side !== types_1.Side.BUY) { | ||
.connect(relayer) | ||
.atomicMatch_(addrs, uints, feeMethodsSidesKindsHowToCalls, buyOrder.calldata, sellOrder.calldata, buyOrder.replacementPattern, sellOrder.replacementPattern, buyOrder.staticExtradata, sellOrder.staticExtradata, [buyOrder.v, sellOrder.v], [ | ||
buyOrder.r, | ||
buyOrder.s, | ||
sellOrder.r, | ||
sellOrder.s, | ||
"0x0000000000000000000000000000000000000000000000000000000000000000", | ||
], { | ||
value: | ||
// TODO: Support dutch auction buy orders (in that case we need | ||
// to pass the sell order's base price as the value) | ||
sellOrder.paymentToken === constants_1.AddressZero ? buyOrder.basePrice : 0, | ||
.atomicMatch_(addrs, uints, feeMethodsSidesKindsHowToCalls, buyOrder.calldata, sellOrder.calldata, buyOrder.replacementPattern, sellOrder.replacementPattern, buyOrder.staticExtradata, sellOrder.staticExtradata, [buyOrder.v, sellOrder.v], [buyOrder.r, buyOrder.s, sellOrder.r, sellOrder.s, utils_1.Bytes32Zero], { | ||
value: sellOrder.paymentToken === constants_1.AddressZero ? buyOrder.basePrice : 0, | ||
}); | ||
} | ||
static async cancel(relayer, order) { | ||
if (!order_1.default.verifySignature(order)) { | ||
throw new Error("Invalid signature"); | ||
const makerAddress = order.maker; | ||
const relayerAddress = await relayer.getAddress(); | ||
if (makerAddress.toLowerCase() !== relayerAddress.toLowerCase()) { | ||
throw new Error("Relayer must match maker"); | ||
} | ||
const makerAddress = order.maker.toLowerCase(); | ||
const relayerAddress = (await relayer.getAddress()).toLowerCase(); | ||
if (makerAddress !== relayerAddress) { | ||
throw new Error("Relayer unauthorized to cancel order"); | ||
} | ||
const addrs = [ | ||
@@ -96,0 +83,0 @@ order.exchange, |
import AnyItemErc721OrderBuilder from "./builders/erc721/any-item"; | ||
import SingleItemErc721OrderBuilder from "./builders/erc721/single-item"; | ||
import SingleItemErc1155OrderBuilder from "./builders/erc1155/single-item"; | ||
import ApprovalHelper from "./helpers/approval"; | ||
@@ -7,2 +8,3 @@ import OrderHelper from "./helpers/order"; | ||
import WyvernHelper from "./helpers/wyvern"; | ||
import AddressUtils from "./utils/address"; | ||
import { Order } from "./types"; | ||
@@ -14,2 +16,5 @@ declare const Builders: { | ||
}; | ||
Erc1155: { | ||
SingleItem: typeof SingleItemErc1155OrderBuilder; | ||
}; | ||
}; | ||
@@ -22,3 +27,6 @@ declare const Helpers: { | ||
}; | ||
export { Builders, Helpers, Order }; | ||
declare const Utils: { | ||
Address: typeof AddressUtils; | ||
}; | ||
export { Order, Builders, Helpers, Utils }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -6,5 +6,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Helpers = exports.Builders = void 0; | ||
exports.Utils = exports.Helpers = exports.Builders = void 0; | ||
const any_item_1 = __importDefault(require("./builders/erc721/any-item")); | ||
const single_item_1 = __importDefault(require("./builders/erc721/single-item")); | ||
const single_item_2 = __importDefault(require("./builders/erc1155/single-item")); | ||
const approval_1 = __importDefault(require("./helpers/approval")); | ||
@@ -14,2 +15,3 @@ const order_1 = __importDefault(require("./helpers/order")); | ||
const wyvern_1 = __importDefault(require("./helpers/wyvern")); | ||
const address_1 = __importDefault(require("./utils/address")); | ||
const Builders = { | ||
@@ -20,2 +22,5 @@ Erc721: { | ||
}, | ||
Erc1155: { | ||
SingleItem: single_item_2.default, | ||
}, | ||
}; | ||
@@ -30,2 +35,6 @@ exports.Builders = Builders; | ||
exports.Helpers = Helpers; | ||
const Utils = { | ||
Address: address_1.default, | ||
}; | ||
exports.Utils = Utils; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,1 @@ | ||
import { BigNumberish } from "@ethersproject/bignumber"; | ||
export declare enum HowToCall { | ||
@@ -18,4 +17,4 @@ CALL = 0, | ||
taker: string; | ||
makerRelayerFee: BigNumberish; | ||
takerRelayerFee: BigNumberish; | ||
makerRelayerFee: string; | ||
takerRelayerFee: string; | ||
feeRecipient: string; | ||
@@ -31,7 +30,7 @@ side: Side; | ||
paymentToken: string; | ||
basePrice: BigNumberish; | ||
extra: BigNumberish; | ||
listingTime: BigNumberish; | ||
expirationTime: BigNumberish; | ||
salt: BigNumberish; | ||
basePrice: string; | ||
extra: string; | ||
listingTime: string; | ||
expirationTime: string; | ||
salt: string; | ||
v: number; | ||
@@ -38,0 +37,0 @@ r: string; |
{ | ||
"name": "@georgeroman/wyvern-v2-sdk", | ||
"version": "0.0.24", | ||
"version": "0.0.25", | ||
"description": "Wyvern V2 SDK", | ||
@@ -23,3 +23,3 @@ "keywords": [ | ||
"build": "tsc", | ||
"clean": "rm -rf dist && rm tsconfig.tsbuildinfo", | ||
"clean": "rm -rf dist && rm -rf tsconfig.tsbuildinfo", | ||
"prepublishOnly": "yarn clean && yarn build" | ||
@@ -26,0 +26,0 @@ }, |
@@ -19,10 +19,10 @@ # Reservoir Wyvern V2 SDK | ||
target: erc721.address, | ||
tokenId: 0, | ||
tokenId: "0", | ||
paymentToken: AddressZero, | ||
basePrice: parseEther("1"), | ||
fee: 250, | ||
basePrice: parseEther("1").toString(), | ||
fee: "250", | ||
feeRecipient: feeRecipient.address, | ||
listingTime: Math.floor(Date.now() / 1000) - 300, | ||
expirationTime: 0, | ||
salt: 0, | ||
listingTime: (Math.floor(Date.now() / 1000) - 300).toString(), | ||
expirationTime: "0", | ||
salt: "0", | ||
}); | ||
@@ -29,0 +29,0 @@ // Sign the sell order |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
142999
53
3165