Skip to content
This repository was archived by the owner on Aug 30, 2022. It is now read-only.

Commit a55ae71

Browse files
Fix ERC1155 lazyminting from base extensions (#560)
* Fix ERC1155 lazyminting from base extensions * also fix claiM + add test
1 parent 4c60c1c commit a55ae71

File tree

6 files changed

+113
-35
lines changed

6 files changed

+113
-35
lines changed

docs/sdk.editiondrop.getclaimtransaction.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ getClaimTransaction(destinationAddress: string, tokenId: BigNumberish, quantity:
1616

1717
| Parameter | Type | Description |
1818
| --- | --- | --- |
19-
| destinationAddress | string | |
20-
| tokenId | BigNumberish | |
21-
| quantity | BigNumberish | |
22-
| checkERC20Allowance | boolean | <i>(Optional)</i> |
19+
| destinationAddress | string | Address you want to send the token to |
20+
| tokenId | BigNumberish | Id of the token you want to claim |
21+
| quantity | BigNumberish | Quantity of the tokens you want to claim |
22+
| checkERC20Allowance | boolean | <i>(Optional)</i> Optional, check if the wallet has enough ERC20 allowance to claim the tokens, and if not, approve the transfer |
2323

2424
<b>Returns:</b>
2525

src/contracts/edition-drop.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,23 +264,37 @@ export class EditionDrop extends Erc1155<DropERC1155> {
264264
/**
265265
* Construct a claim transaction without executing it.
266266
* This is useful for estimating the gas cost of a claim transaction, overriding transaction options and having fine grained control over the transaction execution.
267-
* @param destinationAddress
268-
* @param tokenId
269-
* @param quantity
270-
* @param checkERC20Allowance
267+
* @param destinationAddress - Address you want to send the token to
268+
* @param tokenId - Id of the token you want to claim
269+
* @param quantity - Quantity of the tokens you want to claim
270+
* @param checkERC20Allowance - Optional, check if the wallet has enough ERC20 allowance to claim the tokens, and if not, approve the transfer
271+
* @param claimData - Optional claim verification data (e.g. price, allowlist proof, etc...)
271272
*/
272273
public async getClaimTransaction(
273274
destinationAddress: string,
274275
tokenId: BigNumberish,
275276
quantity: BigNumberish,
276277
checkERC20Allowance = true, // TODO split up allowance checks
277278
): Promise<TransactionTask> {
278-
return this._claim.getClaimTransaction(
279-
destinationAddress,
279+
const claimVerification = await this._claim.conditions.prepareClaim(
280280
tokenId,
281281
quantity,
282282
checkERC20Allowance,
283283
);
284+
return TransactionTask.make({
285+
contractWrapper: this.contractWrapper,
286+
functionName: "claim",
287+
args: [
288+
destinationAddress,
289+
tokenId,
290+
quantity,
291+
claimVerification.currencyAddress,
292+
claimVerification.price,
293+
claimVerification.proofs,
294+
claimVerification.maxQuantityPerTransaction,
295+
],
296+
overrides: claimVerification.overrides,
297+
});
284298
}
285299

286300
/**
@@ -312,12 +326,13 @@ export class EditionDrop extends Erc1155<DropERC1155> {
312326
quantity: BigNumberish,
313327
checkERC20Allowance = true,
314328
): Promise<TransactionResult> {
315-
return this._claim.to(
329+
const tx = await this.getClaimTransaction(
316330
destinationAddress,
317331
tokenId,
318332
quantity,
319333
checkERC20Allowance,
320334
);
335+
return await tx.execute();
321336
}
322337

323338
/**

src/core/classes/drop-erc1155-claim-conditions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ export class DropErc1155ClaimConditions<
474474
const encoded = [];
475475

476476
// keep the old merkle roots from other tokenIds
477-
for (const key of Object.keys(metadata.merkle)) {
477+
for (const key of Object.keys(metadata.merkle || {})) {
478478
merkleInfo[key] = metadata.merkle[key];
479479
}
480480

src/core/classes/erc-1155-claimable.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ContractWrapper } from "./contract-wrapper";
77
import { ContractMetadata } from "./contract-metadata";
88
import { CustomContractSchema } from "../../schema/contracts/custom";
99
import { ClaimVerification } from "../../types/claim-conditions/claim-conditions";
10-
import { BigNumberish } from "ethers";
10+
import { BigNumberish, ethers } from "ethers";
1111
import { TransactionResult } from "../types";
1212
import { TransactionTask } from "./TransactionTask";
1313

@@ -75,8 +75,11 @@ export class Erc1155Claimable implements DetectableFeature {
7575
quantity,
7676
claimVerification.currencyAddress,
7777
claimVerification.price,
78-
claimVerification.proofs,
79-
claimVerification.maxQuantityPerTransaction,
78+
{
79+
proof: claimVerification.proofs,
80+
maxQuantityInAllowlist: claimVerification.maxQuantityPerTransaction,
81+
},
82+
ethers.utils.toUtf8Bytes(""),
8083
],
8184
overrides: claimVerification.overrides,
8285
});
@@ -112,21 +115,6 @@ export class Erc1155Claimable implements DetectableFeature {
112115
checkERC20Allowance = true,
113116
claimData?: ClaimVerification,
114117
): Promise<TransactionResult> {
115-
let claimVerification = claimData;
116-
if (this.conditions && !claimData) {
117-
claimVerification = await this.conditions.prepareClaim(
118-
tokenId,
119-
quantity,
120-
checkERC20Allowance,
121-
);
122-
}
123-
124-
if (!claimVerification) {
125-
throw new Error(
126-
"Claim verification Data is required - either pass it in as 'claimData' or set claim conditions via 'conditions.set()'",
127-
);
128-
}
129-
130118
const tx = await this.getClaimTransaction(
131119
destinationAddress,
132120
tokenId,

src/core/classes/erc-1155-droppable.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { TokensLazyMintedEvent } from "contracts/LazyMint";
2-
import { detectContractFeature } from "../../common/feature-detection";
2+
import {
3+
detectContractFeature,
4+
hasFunction,
5+
} from "../../common/feature-detection";
36
import { uploadOrExtractURIs } from "../../common/nft";
47
import {
58
FEATURE_EDITION_DROPPABLE,
@@ -19,6 +22,8 @@ import { ContractWrapper } from "./contract-wrapper";
1922
import { Erc1155 } from "./erc-1155";
2023
import { Erc1155Claimable } from "./erc-1155-claimable";
2124
import { DelayedReveal } from "./delayed-reveal";
25+
import { TokenERC721 } from "contracts";
26+
import { ethers } from "ethers";
2227

2328
export class Erc1155Droppable implements DetectableFeature {
2429
featureName = FEATURE_EDITION_DROPPABLE.name;
@@ -136,10 +141,22 @@ export class Erc1155Droppable implements DetectableFeature {
136141
);
137142
}
138143
}
139-
const receipt = await this.contractWrapper.sendTransaction("lazyMint", [
140-
batch.length,
141-
`${baseUri.endsWith("/") ? baseUri : `${baseUri}/`}`,
142-
]);
144+
const isLegacyEditionDropContract =
145+
await this.isLegacyEditionDropContract();
146+
let receipt;
147+
if (isLegacyEditionDropContract) {
148+
receipt = await this.contractWrapper.sendTransaction("lazyMint", [
149+
batch.length,
150+
`${baseUri.endsWith("/") ? baseUri : `${baseUri}/`}`,
151+
]);
152+
} else {
153+
// new contracts/extensions have support for delayed reveal that adds an extra parameter to lazyMint
154+
receipt = await this.contractWrapper.sendTransaction("lazyMint", [
155+
batch.length,
156+
`${baseUri.endsWith("/") ? baseUri : `${baseUri}/`}`,
157+
ethers.utils.toUtf8Bytes(""),
158+
]);
159+
}
143160
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
144161
"TokensLazyMinted",
145162
receipt?.logs,
@@ -191,4 +208,19 @@ export class Erc1155Droppable implements DetectableFeature {
191208
}
192209
return undefined;
193210
}
211+
212+
private async isLegacyEditionDropContract() {
213+
if (hasFunction<TokenERC721>("contractType", this.contractWrapper)) {
214+
try {
215+
const contractType = ethers.utils.toUtf8String(
216+
await this.contractWrapper.readContract.contractType(),
217+
);
218+
return contractType.includes("DropERC1155");
219+
} catch (e) {
220+
return false;
221+
}
222+
} else {
223+
return false;
224+
}
225+
}
194226
}

test/publisher.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,49 @@ describe("Publishing", async () => {
384384
expect(nftsAfter[1].owner).to.equal(AddressZero);
385385
});
386386

387+
it("ERC1155Drop base feature detection", async () => {
388+
const ipfsUri = "ipfs://QmZsZcLS3fAtPw2EyZGbHxkdeofTxNtqMoXNWLc79sRXWa";
389+
const addr = await sdk.deployer.deployContractFromUri(ipfsUri, [
390+
"test",
391+
"test",
392+
]);
393+
const c = await sdk.getContract(addr);
394+
395+
invariant(c.edition, "edition must be defined");
396+
invariant(c.edition.query, "query must be defined");
397+
invariant(c.edition.drop, "drop must be defined");
398+
invariant(c.edition.drop.claim, "claim conditions must be defined");
399+
400+
const nftsBefore = await c.edition.query.all();
401+
expect(nftsBefore.length).to.equal(0);
402+
403+
const tx = await c.edition.drop.lazyMint([
404+
{
405+
name: "cool nft 1",
406+
},
407+
{
408+
name: "cool nft 2",
409+
},
410+
]);
411+
expect(tx.length).to.eq(2);
412+
413+
await c.edition.drop.claim.conditions.set(0, [
414+
{
415+
price: "0",
416+
maxQuantity: 2,
417+
startTime: new Date(0),
418+
},
419+
]);
420+
await c.edition.drop.claim.to(adminWallet.address, 0, 1);
421+
422+
const nftsAfter = await c.edition.query.all();
423+
expect(nftsAfter.length).to.equal(2);
424+
expect(nftsAfter[0].metadata.name).to.equal("cool nft 1");
425+
expect(nftsAfter[0].supply.toNumber()).to.equal(1);
426+
expect(nftsAfter[1].metadata.name).to.equal("cool nft 2");
427+
expect(nftsAfter[1].supply.toNumber()).to.equal(0);
428+
});
429+
387430
it("Constructor params with tuples", async () => {
388431
const ipfsUri = "ipfs://QmZQa56Cj1gFnZgKSkvGE5uzhaQrQV3nU6upDWDusCaCwY/0";
389432
const addr = await sdk.deployer.deployContractFromUri(ipfsUri, [

0 commit comments

Comments
 (0)