Skip to content

Commit 0aa2416

Browse files
committed
[SDK] Add erc20Value to buyFromListing transaction (#5630)
CNCT-2555 <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces the `erc20Value` parameter to the `buyFromListing` transaction, enhancing the functionality for transactions involving ERC20 tokens. It also includes tests to ensure proper handling of ERC20 transactions in the marketplace. ### Detailed summary - Added `erc20Value` to `buyFromListing` to handle ERC20 transactions. - Implemented a test case for the new `erc20Value` functionality. - Deployed an ERC20 contract for testing purposes. - Verified the correct approval transaction is generated for ERC20 purchases. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent fbb2ec9 commit 0aa2416

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

.changeset/silent-hats-melt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Add erc20Value to buyFromListing transaction

packages/thirdweb/src/extensions/marketplace/direct-listings/direct-listings.test.ts

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import {
1212
getContract,
1313
} from "../../../contract/contract.js";
1414
import { parseEventLogs } from "../../../event/actions/parse-logs.js";
15+
import { getApprovalForTransaction } from "../../../extensions/erc20/write/getApprovalForTransaction.js";
1516
import { setApprovalForAll as setApprovalForAll721 } from "../../../extensions/erc721/__generated__/IERC721A/write/setApprovalForAll.js";
1617
import { mintTo as mintToErc1155 } from "../../../extensions/erc1155/write/mintTo.js";
18+
import { deployERC20Contract } from "../../../extensions/prebuilts/deploy-erc20.js";
1719
import { sendAndConfirmTransaction } from "../../../transaction/actions/send-and-confirm-transaction.js";
1820
import { sendTransaction } from "../../../transaction/actions/send-transaction.js";
21+
import { resolvePromisedValue } from "../../../utils/promise/resolve-promised-value.js";
1922
import { balanceOf as balanceOfErc721 } from "../../erc721/__generated__/IERC721A/read/balanceOf.js";
2023
import { mintTo as mintToErc721 } from "../../erc721/write/mintTo.js";
2124
import { balanceOf as balanceOfErc1155 } from "../../erc1155/__generated__/IERC1155/read/balanceOf.js";
@@ -256,10 +259,6 @@ describe.runIf(process.env.TW_SECRET_KEY)("Marketplace Direct Listings", () => {
256259
}, 120_000);
257260

258261
it("should work with ERC1155", async () => {
259-
/**
260-
* ============ now do the same tests but for ERC1155 =============
261-
*/
262-
263262
// this should fail because we're listing more than we have
264263
await expect(
265264
sendTransaction({
@@ -395,5 +394,55 @@ describe.runIf(process.env.TW_SECRET_KEY)("Marketplace Direct Listings", () => {
395394
expect(nft1155BalanceOfAccountAAfterPurchase).toBe(1n);
396395
// expect the seller to have one less 1155 token
397396
expect(nft1155BalanceOfAccountCAfterPurchase).toBe(99n);
397+
398+
/**
399+
* buyFromListing transaction (for listing with ERC20 currency) should have proper erc20 value
400+
* so that getApprovalForTransaction can work properly
401+
*/
402+
const erc20Address = await deployERC20Contract({
403+
chain,
404+
client,
405+
account: TEST_ACCOUNT_C,
406+
type: "TokenERC20",
407+
params: {
408+
name: "MyToken",
409+
contractURI: TEST_CONTRACT_URI,
410+
},
411+
});
412+
await sendAndConfirmTransaction({
413+
transaction: createListing({
414+
contract: marketplaceContract,
415+
assetContractAddress: erc1155Contract.address,
416+
tokenId: 0n,
417+
pricePerToken: "0.01",
418+
quantity: 1n,
419+
currencyContractAddress: erc20Address,
420+
}),
421+
account: TEST_ACCOUNT_C,
422+
});
423+
// get the last listing id
424+
const _allListings = await getAllListings({
425+
contract: marketplaceContract,
426+
});
427+
const latestListing = _allListings.at(-1);
428+
expect(latestListing).toBeDefined();
429+
if (!latestListing) {
430+
throw new Error("Cannot get listings");
431+
}
432+
const buyListingTx = buyFromListing({
433+
contract: marketplaceContract,
434+
listingId: latestListing.id,
435+
quantity: 1n,
436+
recipient: TEST_ACCOUNT_C.address,
437+
});
438+
expect(await resolvePromisedValue(buyListingTx.erc20Value)).toStrictEqual({
439+
amountWei: BigInt(1e16),
440+
tokenAddress: erc20Address,
441+
});
442+
const approveTx = await getApprovalForTransaction({
443+
transaction: buyListingTx,
444+
account: TEST_ACCOUNT_A,
445+
});
446+
expect(approveTx).not.toBe(null);
398447
}, 120_000);
399448
});

packages/thirdweb/src/extensions/marketplace/direct-listings/write/buyFromListing.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ export function buyFromListing(
6666
? listing.pricePerToken * options.quantity
6767
: 0n,
6868
extraGas: 50_000n, // add extra gas to account for router call
69+
erc20Value: isNativeTokenAddress(listing.currencyContractAddress)
70+
? undefined
71+
: {
72+
amountWei: listing.pricePerToken * options.quantity,
73+
tokenAddress: listing.currencyContractAddress,
74+
},
6975
},
7076
};
7177
},

0 commit comments

Comments
 (0)