@zero-tech/zauction-sdk 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +3 -2
  2. package/src/actions/acceptBid.ts +167 -0
  3. package/src/actions/approveDomainTransfer.ts +25 -0
  4. package/src/actions/approveSpender.ts +27 -0
  5. package/src/actions/buyNow.ts +109 -0
  6. package/src/actions/cancelBid.ts +37 -0
  7. package/src/actions/getBuyNowListing.ts +65 -0
  8. package/src/actions/getPaymentTokenAllowance.ts +30 -0
  9. package/src/actions/index.ts +11 -0
  10. package/src/actions/isZAuctionApproved.ts +20 -0
  11. package/src/actions/placeBid.ts +102 -0
  12. package/src/actions/setBuyNowPrice.ts +56 -0
  13. package/src/actions/setNetworkPaymentToken.ts +46 -0
  14. package/src/api/actions/encodeBid.ts +44 -0
  15. package/src/api/actions/encodeCancelMessage.ts +24 -0
  16. package/src/api/actions/helpers.ts +61 -0
  17. package/src/api/actions/index.ts +6 -0
  18. package/src/api/actions/listBidsForAccount.ts +24 -0
  19. package/src/api/actions/listBidsForTokens.ts +39 -0
  20. package/src/api/actions/submitBid.ts +28 -0
  21. package/src/api/actions/submitCancelMessage.ts +30 -0
  22. package/src/api/client.ts +78 -0
  23. package/src/api/index.ts +1 -0
  24. package/src/api/types.ts +47 -0
  25. package/src/contracts/index.ts +53 -0
  26. package/src/contracts/types/IERC20.d.ts +294 -0
  27. package/src/contracts/types/IERC721.d.ts +472 -0
  28. package/src/contracts/types/IZNSHub.d.ts +578 -0
  29. package/src/contracts/types/ZAuction.d.ts +1487 -0
  30. package/src/contracts/types/ZAuctionV1.d.ts +440 -0
  31. package/src/contracts/types/commons.ts +36 -0
  32. package/src/contracts/types/factories/IERC20__factory.ts +203 -0
  33. package/src/contracts/types/factories/IERC721__factory.ts +308 -0
  34. package/src/contracts/types/factories/IZNSHub__factory.ts +311 -0
  35. package/src/contracts/types/factories/ZAuctionV1__factory.ts +326 -0
  36. package/src/contracts/types/factories/ZAuction__factory.ts +1033 -0
  37. package/src/contracts/types/index.ts +14 -0
  38. package/src/index.ts +468 -0
  39. package/src/subgraph/actions/index.ts +4 -0
  40. package/src/subgraph/actions/listAllBuyNowListings.ts +69 -0
  41. package/src/subgraph/actions/listAllSales.ts +57 -0
  42. package/src/subgraph/actions/listBuyNowSales.ts +44 -0
  43. package/src/subgraph/actions/listSales.ts +33 -0
  44. package/src/subgraph/client.ts +62 -0
  45. package/src/subgraph/helpers/index.ts +39 -0
  46. package/src/subgraph/index.ts +1 -0
  47. package/src/subgraph/queries.ts +75 -0
  48. package/src/subgraph/types.ts +58 -0
  49. package/src/types.ts +181 -0
  50. package/src/utilities/index.ts +2 -0
  51. package/src/utilities/logging.ts +27 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zero-tech/zauction-sdk",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "repository": "git@github.com:zer0-os/zAuction-SDK.git",
@@ -10,7 +10,8 @@
10
10
  "yarn": ">=1.15.2"
11
11
  },
12
12
  "files": [
13
- "lib/"
13
+ "lib/",
14
+ "src/"
14
15
  ],
15
16
  "scripts": {
16
17
  "build": "tsc --build --verbose ./tsconfig.build.json",
@@ -0,0 +1,167 @@
1
+ import { ethers } from "ethers";
2
+ import {
3
+ getERC721Contract,
4
+ getZAuctionContract,
5
+ getZAuctionV1Contract,
6
+ getZnsHubContract,
7
+ } from "../contracts";
8
+ import { IERC721, IZNSHub, ZAuction, ZAuctionV1 } from "../contracts/types";
9
+ import { Bid, Config } from "../types";
10
+ import { getLogger } from "../utilities";
11
+
12
+ const logger = getLogger("actions:acceptBid");
13
+
14
+ const verifyAccount = async (
15
+ zAuction: ZAuction | ZAuctionV1,
16
+ data: string,
17
+ signedMessage: string,
18
+ bidder: string
19
+ ): Promise<void> => {
20
+ const unsignedMessage = await zAuction.toEthSignedMessageHash(
21
+ ethers.utils.arrayify(data)
22
+ );
23
+
24
+ const recoveredAccount = await zAuction.recover(
25
+ unsignedMessage,
26
+ signedMessage
27
+ );
28
+
29
+ if (recoveredAccount !== bidder) {
30
+ throw Error("Recovered incorrect account");
31
+ }
32
+ };
33
+
34
+ // Accept a bid for a domain, supporting legacy bids
35
+ export const acceptBid = async (
36
+ bid: Bid,
37
+ signer: ethers.Signer,
38
+ config: Config
39
+ ): Promise<ethers.ContractTransaction> => {
40
+ logger.trace(
41
+ `Calling to accept a bid by user ${bid.bidder} with bidNonce of ${bid.bidNonce}`
42
+ );
43
+
44
+ // If not explicitly v2 bid, then assume v1
45
+ const isVersion2 = bid.version === "2.0";
46
+
47
+ // route to legacy if version 1.0
48
+ const zAuctionAddress = isVersion2
49
+ ? config.zAuctionAddress
50
+ : config.zAuctionLegacyAddress;
51
+
52
+ const hub: IZNSHub = await getZnsHubContract(signer, config.znsHubAddress);
53
+ const domainContract = await hub.getRegistrarForDomain(bid.tokenId);
54
+ const nftContract: IERC721 = await getERC721Contract(signer, domainContract);
55
+
56
+ const owner = await nftContract.ownerOf(bid.tokenId);
57
+ const signerAddress = await signer.getAddress();
58
+
59
+ if (owner !== signerAddress) {
60
+ throw Error("Cannot accept a bid for a domain that is not yours");
61
+ }
62
+ if (owner === bid.bidder) {
63
+ throw Error("Cannot sell to self");
64
+ }
65
+
66
+ if (isVersion2) {
67
+ const zAuction: ZAuction = await getZAuctionContract(
68
+ signer,
69
+ zAuctionAddress
70
+ );
71
+
72
+ if (bid.bidToken) {
73
+ // v2.1 bid
74
+ logger.trace(
75
+ `v2.1 Bid: Payment token for domain ${bid.tokenId} is ${bid.bidToken}`
76
+ );
77
+
78
+ const data = await zAuction.createBidV2(
79
+ bid.bidNonce,
80
+ bid.amount,
81
+ bid.tokenId,
82
+ "0",
83
+ bid.startBlock,
84
+ bid.expireBlock,
85
+ bid.bidToken
86
+ );
87
+
88
+ await verifyAccount(zAuction, data, bid.signedMessage, bid.bidder);
89
+
90
+ const tx = await zAuction.connect(signer).acceptBidV2(
91
+ bid.signedMessage,
92
+ bid.bidNonce,
93
+ bid.bidder,
94
+ bid.amount,
95
+ bid.tokenId,
96
+ "0", // minimum bid as string
97
+ bid.startBlock,
98
+ bid.expireBlock,
99
+ bid.bidToken
100
+ );
101
+
102
+ return tx;
103
+ }
104
+ // v2.0 bid
105
+ logger.trace(
106
+ `v2.0 Bid: Payment token for domain ${bid.tokenId} is ${config.wildTokenAddress}`
107
+ );
108
+ const data = await zAuction.createBid(
109
+ bid.bidNonce,
110
+ bid.amount,
111
+ bid.contract,
112
+ bid.tokenId,
113
+ "0",
114
+ bid.startBlock,
115
+ bid.expireBlock
116
+ );
117
+
118
+ await verifyAccount(zAuction, data, bid.signedMessage, bid.bidder);
119
+
120
+ const tx = await zAuction.connect(signer).acceptBid(
121
+ bid.signedMessage,
122
+ bid.bidNonce,
123
+ bid.bidder,
124
+ bid.amount,
125
+ bid.tokenId,
126
+ "0", // minimum bid
127
+ bid.startBlock,
128
+ bid.expireBlock
129
+ );
130
+ return tx;
131
+ }
132
+ //v1 legacy bid
133
+ const zAuctionV1: ZAuctionV1 = await getZAuctionV1Contract(
134
+ signer,
135
+ zAuctionAddress
136
+ );
137
+
138
+ logger.trace(
139
+ `v1.0 Bid: Payment token for domain ${bid.tokenId} is ${config.wildTokenAddress}`
140
+ );
141
+ const data = await zAuctionV1.createBid(
142
+ bid.bidNonce,
143
+ bid.amount,
144
+ bid.contract,
145
+ bid.tokenId,
146
+ "0",
147
+ bid.startBlock,
148
+ bid.expireBlock
149
+ );
150
+
151
+ await verifyAccount(zAuctionV1, data, bid.signedMessage, bid.bidder);
152
+
153
+ // For any v1 bid this will always return the default registrar
154
+ // const registrar = await hub.getRegistrarForDomain(bid.tokenId);
155
+ const tx = await zAuctionV1.connect(signer).acceptBid(
156
+ bid.signedMessage,
157
+ bid.bidNonce,
158
+ bid.bidder,
159
+ bid.amount,
160
+ bid.contract,
161
+ bid.tokenId,
162
+ "0", // minimum bid as string
163
+ bid.startBlock,
164
+ bid.expireBlock
165
+ );
166
+ return tx;
167
+ };
@@ -0,0 +1,25 @@
1
+ import { ethers } from "ethers";
2
+ import { getERC721Contract } from "../contracts";
3
+
4
+ import { getLogger } from "../utilities";
5
+
6
+ const logger = getLogger("actions:approveDomainTransfer");
7
+
8
+ // Approve zAuction to transfer domains on behalf of the signer
9
+ export const approveDomainTransfer = async (
10
+ domainContractAddress: string,
11
+ zAuctionAddress: string,
12
+ signer: ethers.Signer
13
+ ): Promise<ethers.ContractTransaction> => {
14
+ const signerAddress = await signer.getAddress();
15
+ const nftContract = await getERC721Contract(signer, domainContractAddress);
16
+
17
+ const tx = await nftContract
18
+ .connect(signer)
19
+ .setApprovalForAll(zAuctionAddress, true);
20
+
21
+ logger.trace(
22
+ `User ${signerAddress} has approved zAuction to transfer domains from ${domainContractAddress}`
23
+ );
24
+ return tx;
25
+ };
@@ -0,0 +1,27 @@
1
+ import { ethers } from "ethers";
2
+ import { getERC20Contract } from "../contracts";
3
+ import { IERC20 } from "../contracts/types";
4
+ import { getLogger } from "../utilities";
5
+
6
+ const logger = getLogger("actions:approveSpender");
7
+
8
+ // Approve zAuction to spend ERC20 tokens on behalf of the signer
9
+ export const approveSpender = async (
10
+ paymentTokenAddress: string,
11
+ zAuctionAddress: string,
12
+ signer: ethers.Signer
13
+ ): Promise<ethers.ContractTransaction> => {
14
+ const signerAddress = await signer.getAddress();
15
+
16
+ const paymentToken: IERC20 = await getERC20Contract(
17
+ signer,
18
+ paymentTokenAddress
19
+ );
20
+ const tx = await paymentToken
21
+ .connect(signer)
22
+ .approve(zAuctionAddress, ethers.constants.MaxUint256);
23
+ logger.trace(
24
+ `User ${signerAddress} has approved zAuction to spend ${paymentToken}`
25
+ );
26
+ return tx;
27
+ };
@@ -0,0 +1,109 @@
1
+ import { ethers } from "ethers";
2
+ import {
3
+ getERC721Contract,
4
+ getZAuctionContract,
5
+ getZnsHubContract,
6
+ } from "../contracts";
7
+ import { ZAuction } from "../contracts/types";
8
+ import { BuyNowParams, Config, BuyNowListing } from "../types";
9
+ import { getPaymentTokenAllowance } from "./getPaymentTokenAllowance";
10
+ import { isZAuctionApprovedNftTransfer } from "./isZAuctionApproved";
11
+ import { getLogger } from "../utilities";
12
+
13
+ const logger = getLogger("actions:buyNow");
14
+
15
+ // Perform an immediate buy, supporting legacy domain listings
16
+ export const buyNow = async (
17
+ params: BuyNowParams,
18
+ signer: ethers.Signer,
19
+ config: Config
20
+ ): Promise<ethers.ContractTransaction> => {
21
+ const buyer = await signer.getAddress();
22
+
23
+ logger.trace(
24
+ `Calling from user ${buyer} for domain ${params.tokenId} to buy now`
25
+ );
26
+ const hub = await getZnsHubContract(signer, config.znsHubAddress);
27
+ const tokenContract = await hub.getRegistrarForDomain(params.tokenId);
28
+
29
+ const nftContract = await getERC721Contract(signer, tokenContract);
30
+
31
+ const seller = await nftContract.ownerOf(params.tokenId);
32
+
33
+ const isApproved = await isZAuctionApprovedNftTransfer(
34
+ seller,
35
+ config.zAuctionAddress,
36
+ nftContract
37
+ );
38
+
39
+ if (!isApproved) {
40
+ throw Error("Seller did not approve zAuction to transfer NFT");
41
+ }
42
+
43
+ if (seller === buyer) {
44
+ throw Error("Cannot sell a domain to yourself");
45
+ }
46
+
47
+ const zAuction: ZAuction = await getZAuctionContract(
48
+ signer,
49
+ config.zAuctionAddress
50
+ );
51
+
52
+ const listing: BuyNowListing = await zAuction.priceInfo(params.tokenId);
53
+
54
+ if (listing.price.eq("0")) {
55
+ throw Error("Domain is not for sale");
56
+ }
57
+ if (!listing.price.eq(params.amount)) {
58
+ throw Error("Incorrect buyNow price given");
59
+ }
60
+
61
+ if (
62
+ !listing.paymentToken ||
63
+ listing.paymentToken === ethers.constants.AddressZero
64
+ ) {
65
+ logger.trace(
66
+ `Payment token for domain ${params.tokenId} is ${config.wildTokenAddress}`
67
+ );
68
+ // If no bidToken exists it is not a v2.1 listing, use WILD
69
+ const allowance = await getPaymentTokenAllowance(
70
+ buyer,
71
+ config.wildTokenAddress,
72
+ config.web3Provider,
73
+ config.zAuctionAddress
74
+ );
75
+
76
+ // Ensure buyer has approved zAuction to transfer tokens on their behalf
77
+ if (allowance.lt(params.amount)) {
78
+ throw Error("zAuction is not approved to transfer this many tokens");
79
+ }
80
+
81
+ const tx = await zAuction
82
+ .connect(signer)
83
+ .buyNow(params.amount, params.tokenId);
84
+
85
+ return tx;
86
+ }
87
+
88
+ logger.trace(
89
+ `Payment token for domain ${params.tokenId} is ${listing.paymentToken}`
90
+ );
91
+
92
+ const allowance = await getPaymentTokenAllowance(
93
+ buyer,
94
+ listing.paymentToken,
95
+ config.web3Provider,
96
+ config.zAuctionAddress
97
+ );
98
+
99
+ // Ensure buyer has approved zAuction to transfer tokens on their behalf
100
+ if (allowance.lt(params.amount)) {
101
+ throw Error("zAuction is not approved to transfer this many tokens");
102
+ }
103
+
104
+ const tx = await zAuction
105
+ .connect(signer)
106
+ .buyNowV2(params.amount, params.tokenId);
107
+
108
+ return tx;
109
+ };
@@ -0,0 +1,37 @@
1
+ import { ethers } from "ethers";
2
+ import { ApiClient } from "../api";
3
+ import { getZAuctionContract } from "../contracts";
4
+ import { Bid } from "../types";
5
+ import { getLogger } from "../utilities";
6
+
7
+ const logger = getLogger("actions:cancelBid");
8
+
9
+ // Cancel a bid for a domain, supporting legacy bids
10
+ export const cancelBid = async (
11
+ bid: Bid,
12
+ cancelOnChain: boolean,
13
+ apiClient: ApiClient,
14
+ zAuctionAddress: string,
15
+ signer: ethers.Signer
16
+ ): Promise<ethers.ContractTransaction | void> => {
17
+ logger.trace(
18
+ `Calling to cancel a bid by user ${bid.bidder} with bid nonce of ${bid.bidNonce}`
19
+ );
20
+ const encodedCancelMessage = await apiClient.encodeCancelBid(
21
+ bid.signedMessage
22
+ );
23
+ const signedCancelMessage = await signer.signMessage(encodedCancelMessage);
24
+
25
+ // Always cancel the bid through the API
26
+ await apiClient.submitCancelBid(signedCancelMessage, bid.signedMessage);
27
+
28
+ // If enabled, also cancel the bid with the zAuction smart contract
29
+ if (cancelOnChain) {
30
+ const zAuction = await getZAuctionContract(signer, zAuctionAddress);
31
+
32
+ const account = await signer.getAddress();
33
+
34
+ const tx = await zAuction.connect(signer).cancelBid(account, bid.bidNonce);
35
+ return tx;
36
+ }
37
+ };
@@ -0,0 +1,65 @@
1
+ import { ethers } from "ethers";
2
+ import {
3
+ getERC721Contract,
4
+ getZAuctionContract,
5
+ getZnsHubContract,
6
+ } from "../contracts";
7
+ import { BuyNowListing, Config } from "../types";
8
+ import { Maybe, getLogger } from "../utilities";
9
+
10
+ const logger = getLogger("actions:getBuyNowListing");
11
+
12
+ export const getBuyNowListing = async (
13
+ tokenId: string,
14
+ config: Config
15
+ ): Promise<Maybe<BuyNowListing>> => {
16
+ if (!tokenId || tokenId === ethers.constants.HashZero) {
17
+ throw Error("Must provide a valid tokenId");
18
+ }
19
+
20
+ const contract = await getZAuctionContract(
21
+ config.web3Provider,
22
+ config.zAuctionAddress
23
+ );
24
+
25
+ const hub = await getZnsHubContract(
26
+ config.web3Provider,
27
+ config.znsHubAddress
28
+ );
29
+
30
+ const registrarAddress = await hub.getRegistrarForDomain(tokenId);
31
+
32
+ const tokenContract = await getERC721Contract(
33
+ config.web3Provider,
34
+ registrarAddress
35
+ );
36
+
37
+ const owner = await tokenContract.ownerOf(tokenId);
38
+ const listing: BuyNowListing = await contract.priceInfo(tokenId);
39
+
40
+ if (listing.holder !== owner) {
41
+ logger.trace(
42
+ `Domain with ID ${tokenId} has changed owners since this buyNow listing was created so it is invalid`
43
+ );
44
+ return undefined;
45
+ }
46
+
47
+ if (listing.price.eq("0")) {
48
+ logger.trace(
49
+ `Domain with ID ${tokenId} is currently not listed for buyNow`
50
+ );
51
+ return undefined;
52
+ }
53
+
54
+ if (listing.paymentToken === ethers.constants.AddressZero) {
55
+ // Object is readonly, must make a new listing with payment token info
56
+ const newListing: BuyNowListing = {
57
+ holder: listing.holder,
58
+ price: listing.price,
59
+ paymentToken: config.wildTokenAddress,
60
+ };
61
+ return newListing;
62
+ }
63
+
64
+ return listing;
65
+ };
@@ -0,0 +1,30 @@
1
+ import { ethers } from "ethers";
2
+ import { getERC20Contract } from "../contracts";
3
+ import { IERC20 } from "../contracts/types";
4
+ import { getLogger } from "../utilities";
5
+
6
+ const logger = getLogger("actions:getPaymentTokenAllowance");
7
+
8
+ // Return the amount the given account has allowed zAuction to spend on its behalf
9
+ export const getPaymentTokenAllowance = async (
10
+ account: string,
11
+ paymentTokenAddress: string,
12
+ provider: ethers.providers.Provider | ethers.Signer,
13
+ zAuctionAddress: string
14
+ ): Promise<ethers.BigNumber> => {
15
+ logger.trace(
16
+ `Calling to get allowance for user ${account} with payment token ${paymentTokenAddress}`
17
+ );
18
+ const paymentToken: IERC20 = await getERC20Contract(
19
+ provider,
20
+ paymentTokenAddress
21
+ );
22
+ const allowance = await paymentToken.allowance(account, zAuctionAddress);
23
+
24
+ logger.trace(
25
+ `User ${account} has allowance of ${ethers.utils
26
+ .formatEther(allowance)
27
+ .toString()} for payment token ${paymentToken}`
28
+ );
29
+ return allowance;
30
+ };
@@ -0,0 +1,11 @@
1
+ export * from "./placeBid";
2
+ export * from "./isZAuctionApproved";
3
+ export * from "./acceptBid";
4
+ export * from "./cancelBid";
5
+ export * from "./buyNow";
6
+ export * from "./approveSpender";
7
+ export * from "./approveDomainTransfer";
8
+ export * from "./getPaymentTokenAllowance";
9
+ export * from "./getBuyNowListing";
10
+ export * from "./setNetworkPaymentToken";
11
+ export * from "./setBuyNowPrice";
@@ -0,0 +1,20 @@
1
+ import { IERC721 } from "../contracts/types";
2
+ import { getLogger } from "../utilities";
3
+
4
+ const logger = getLogger("actions:isZAuctionApprovedNftTransfer");
5
+
6
+ // Check whether or not zAuction is approved to transfer NFTs for the user
7
+ export const isZAuctionApprovedNftTransfer = async (
8
+ account: string,
9
+ zAuctionAddress: string,
10
+ nftContract: IERC721
11
+ ): Promise<boolean> => {
12
+ const isApproved = await nftContract.isApprovedForAll(
13
+ account,
14
+ zAuctionAddress
15
+ );
16
+ logger.trace(
17
+ `User ${account} has approved zAuction to transfer NFTs: ${isApproved}`
18
+ );
19
+ return isApproved;
20
+ };
@@ -0,0 +1,102 @@
1
+ import { ethers } from "ethers";
2
+ import { BidParameters, SignableBid, SignedBid } from "../api/types";
3
+ import { getZAuctionContract, getZnsHubContract } from "../contracts";
4
+
5
+ import {
6
+ PlaceBidStatus,
7
+ PlaceBidStatusCallback,
8
+ NewBidParameters,
9
+ Config,
10
+ } from "../types";
11
+ import { Maybe } from "../utilities";
12
+ import { getLogger } from "../utilities";
13
+
14
+ const logger = getLogger("actions:placeBid");
15
+
16
+ type SignMessageFunction = (
17
+ message: string | ethers.utils.Bytes
18
+ ) => Promise<string>;
19
+ type EncodeBidFunction = (bidParams: BidParameters) => Promise<SignableBid>;
20
+ type SubmitBidFunction = (signedBid: SignedBid) => Promise<void>;
21
+
22
+ export interface PlaceBidActionParameters {
23
+ bid: NewBidParameters;
24
+ config: Config;
25
+ bidder: string;
26
+ encodeBid: EncodeBidFunction;
27
+ signMessage: SignMessageFunction;
28
+ submitBid: SubmitBidFunction;
29
+ statusCallback?: PlaceBidStatusCallback;
30
+ }
31
+
32
+ export const placeBid = async (
33
+ params: PlaceBidActionParameters
34
+ ): Promise<void> => {
35
+ params.statusCallback ? params.statusCallback(PlaceBidStatus.Encoding) : null;
36
+
37
+ const contract = await getZAuctionContract(
38
+ params.config.web3Provider,
39
+ params.config.zAuctionAddress
40
+ );
41
+ const paymentToken = await contract.getPaymentTokenForDomain(
42
+ params.bid.tokenId
43
+ );
44
+ logger.trace(
45
+ `Calling to place a bid by user ${params.bidder} for ${params.bid.bidAmount} of ERC20 token ${paymentToken} on domain ${params.bid.tokenId}`
46
+ );
47
+
48
+ const hub = await getZnsHubContract(
49
+ params.config.web3Provider,
50
+ params.config.znsHubAddress
51
+ );
52
+ const registrar = await hub.getRegistrarForDomain(params.bid.tokenId);
53
+
54
+ let signableBid: Maybe<SignableBid>;
55
+
56
+ const bidParams: BidParameters = {
57
+ bidder: params.bidder,
58
+ tokenId: params.bid.tokenId,
59
+ contract: registrar,
60
+ amount: params.bid.bidAmount,
61
+ startBlock: params.bid.startBlock ?? "0",
62
+ expireBlock: params.bid.expireBlock ?? "9999999999",
63
+ bidToken: paymentToken,
64
+ };
65
+ try {
66
+ signableBid = await params.encodeBid(bidParams);
67
+ } catch (e) {
68
+ throw Error(`Failed to encode bid: ${e}`);
69
+ }
70
+
71
+ params.statusCallback ? params.statusCallback(PlaceBidStatus.Signing) : null;
72
+
73
+ let signedBidMessage: Maybe<string>;
74
+ try {
75
+ signedBidMessage = await params.signMessage(
76
+ ethers.utils.arrayify(signableBid.message)
77
+ );
78
+ } catch (e) {
79
+ throw Error(`Failed to sign bid message: ${e}`);
80
+ }
81
+
82
+ params.statusCallback
83
+ ? params.statusCallback(PlaceBidStatus.Submitting)
84
+ : null;
85
+
86
+ try {
87
+ await params.submitBid({
88
+ bid: signableBid.bid,
89
+ signedMessage: signedBidMessage,
90
+ } as SignedBid);
91
+ } catch (e) {
92
+ throw Error(`Failed to submit bid: ${e}`);
93
+ }
94
+
95
+ logger.trace(
96
+ `Bid with bidNonce of ${signableBid.bid.bidNonce} submitted successfully`
97
+ );
98
+
99
+ params.statusCallback
100
+ ? params.statusCallback(PlaceBidStatus.Completed)
101
+ : null;
102
+ };
@@ -0,0 +1,56 @@
1
+ import { ethers } from "ethers";
2
+ import {
3
+ getERC721Contract,
4
+ getZAuctionContract,
5
+ getZnsHubContract,
6
+ } from "../contracts";
7
+ import { IZNSHub } from "../contracts/types";
8
+ import { BuyNowParams } from "../types";
9
+
10
+ import { isZAuctionApprovedNftTransfer } from "./isZAuctionApproved";
11
+
12
+ export const setBuyNowPrice = async (
13
+ params: BuyNowParams,
14
+ signer: ethers.Signer,
15
+ znsHubAddress: string,
16
+ zAuctionAddress: string
17
+ ): Promise<ethers.ContractTransaction> => {
18
+ const hub: IZNSHub = await getZnsHubContract(signer, znsHubAddress);
19
+ const domainContract = await hub.getRegistrarForDomain(params.tokenId);
20
+
21
+ const nftContract = await getERC721Contract(signer, domainContract);
22
+
23
+ const owner = await nftContract.ownerOf(params.tokenId);
24
+ const givenSeller = await signer.getAddress();
25
+
26
+ if (givenSeller !== owner) {
27
+ throw Error("Cannot set the price of a domain that is not yours");
28
+ }
29
+
30
+ // Seller must have approved zAuction to transfer their NFT(s)
31
+ // before being able to set a buy price
32
+ const isApproved = await isZAuctionApprovedNftTransfer(
33
+ owner,
34
+ zAuctionAddress,
35
+ nftContract
36
+ );
37
+
38
+ if (!isApproved) {
39
+ throw Error("Seller did not approve zAuction to transfer NFT");
40
+ }
41
+
42
+ const contract = await getZAuctionContract(signer, zAuctionAddress);
43
+
44
+ const listing = await contract.priceInfo(params.tokenId);
45
+
46
+ if (listing.price.eq(params.amount)) {
47
+ throw Error(
48
+ "Unable to set price if a listing with that price already exists"
49
+ );
50
+ }
51
+
52
+ const tx = await contract
53
+ .connect(signer)
54
+ .setBuyPrice(params.amount, params.tokenId);
55
+ return tx;
56
+ };