@medialane/sdk 0.62.0 → 0.63.0

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.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { keccak_256 } from '@noble/hashes/sha3.js';
3
3
  import { base58, base32 } from '@scure/base';
4
- import { hash, num, cairo, Contract, uint256, RpcProvider, CairoOption, CairoOptionVariant, ec, encode, TypedDataRevision, shortString, constants } from 'starknet';
4
+ import { hash, num, cairo, Contract, uint256, RpcProvider, CairoOption, CairoOptionVariant, ec, encode, TypedDataRevision, constants, shortString } from 'starknet';
5
5
 
6
6
  // src/config.ts
7
7
 
@@ -35,9 +35,9 @@ var COORDINATES = {
35
35
  creatorCoinFactoryClassHash: "0x51765926b1344c9a20b8cd4b5abe7b7d47375ae97cf6804db3ea5d4b05a9b55",
36
36
  creatorCoinStartBlock: 10474544,
37
37
  ekuboCore: "0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b",
38
- ipTicketsFactory: "0x0664c2d6a4da9ee3ff053ceeba7579c01f2fedfd9d2b57b4c07af3734bd4acab",
39
- ipTicketCollectionClassHash: "0x086f59c416e365e2bee4ceff9f1dcb96198f2342d50ba4621f60b831863adb6",
40
- ipTicketsStartBlock: 11404656,
38
+ ipTicketsFactory: "0x03ffef4162fe2c44e17d6be2aad3553cab0ac2274cd0b1bb3fafb12fd66695c1",
39
+ ipTicketCollectionClassHash: "0x036393fb4241ed55bd12d8b328ed877d08100fadf9150a650e2b84cbab95e1d4",
40
+ ipTicketsStartBlock: 11689800,
41
41
  ipClubRegistry: "0x00e189c619b6bb07d78973a149641c59c37eb0716f8584d7520bce12d303eede",
42
42
  ipClubNftClassHash: "0x02bc9b20cca21b04245e9215bf7121f4d7295b195890e449b472b573017fb889",
43
43
  ipClubStartBlock: 11404776,
@@ -11490,6 +11490,14 @@ function toSignatureArray(sig) {
11490
11490
  const s = sig;
11491
11491
  return [s.r.toString(), s.s.toString()];
11492
11492
  }
11493
+ function newContract(abi, address, providerOrAccount) {
11494
+ const C = Contract;
11495
+ return C.length === 1 ? new Contract({ abi, address, providerOrAccount }) : new Contract(
11496
+ abi,
11497
+ address,
11498
+ providerOrAccount
11499
+ );
11500
+ }
11493
11501
  function getChainId(config) {
11494
11502
  if (config.chain !== "STARKNET") {
11495
11503
  throw new Error(`SNIP-12 signing is Starknet-only; got chain "${config.chain}"`);
@@ -11514,17 +11522,101 @@ function getProvider(config) {
11514
11522
  return p;
11515
11523
  }
11516
11524
 
11525
+ // src/starknet/marketplace/build.ts
11526
+ function contractFor(cfg) {
11527
+ return newContract(IPMarketplaceABI, cfg.marketplaceContract, getProvider(cfg));
11528
+ }
11529
+ function buildListingOrder(i, cfg) {
11530
+ const orderParams = {
11531
+ offerer: i.offerer,
11532
+ marketplace: cfg.marketplaceContract,
11533
+ offer: { item_type: "ERC721", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: "1" },
11534
+ consideration: {
11535
+ item_type: "ERC20",
11536
+ token: i.paymentTokenAddress,
11537
+ identifier_or_criteria: "0",
11538
+ amount: i.priceWei,
11539
+ recipient: i.offerer
11540
+ },
11541
+ royalty_max_bps: i.royaltyMaxBps,
11542
+ start_time: String(i.startTime),
11543
+ end_time: String(i.endTime),
11544
+ salt: i.salt,
11545
+ counter: i.counter
11546
+ };
11547
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
11548
+ return { orderParams, typedData };
11549
+ }
11550
+ function buildOfferOrder(i, cfg) {
11551
+ const orderParams = {
11552
+ offerer: i.offerer,
11553
+ marketplace: cfg.marketplaceContract,
11554
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWei },
11555
+ consideration: {
11556
+ item_type: "ERC721",
11557
+ token: i.nftContract,
11558
+ identifier_or_criteria: i.tokenId,
11559
+ amount: "1",
11560
+ recipient: i.offerer
11561
+ },
11562
+ royalty_max_bps: i.royaltyMaxBps,
11563
+ start_time: String(i.startTime),
11564
+ end_time: String(i.endTime),
11565
+ salt: i.salt,
11566
+ counter: i.counter
11567
+ };
11568
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
11569
+ return { orderParams, typedData };
11570
+ }
11571
+ function registerPayload(orderParams, signature) {
11572
+ return stringifyBigInts({
11573
+ parameters: {
11574
+ ...orderParams,
11575
+ offer: { ...orderParams.offer, item_type: shortString.encodeShortString(orderParams.offer.item_type) },
11576
+ consideration: {
11577
+ ...orderParams.consideration,
11578
+ item_type: shortString.encodeShortString(orderParams.consideration.item_type)
11579
+ }
11580
+ },
11581
+ signature
11582
+ });
11583
+ }
11584
+ function buildRegisterCalls(a, cfg) {
11585
+ const registerCall = contractFor(cfg).populate("register_order", [registerPayload(a.orderParams, a.signature)]);
11586
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
11587
+ }
11588
+ function buildFulfillCalls(a, cfg) {
11589
+ const u = cairo.uint256(a.totalPrice);
11590
+ const approve = {
11591
+ contractAddress: a.paymentToken,
11592
+ entrypoint: "approve",
11593
+ calldata: [cfg.marketplaceContract, u.low.toString(), u.high.toString()]
11594
+ };
11595
+ const fulfill = contractFor(cfg).populate("fulfill_order", [a.orderHash]);
11596
+ const fee = buildFeeCall(
11597
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
11598
+ cfg.feeConfig
11599
+ );
11600
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
11601
+ }
11602
+ function buildCancelCalls(a, cfg) {
11603
+ const cancelRequest = stringifyBigInts({
11604
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
11605
+ signature: a.signature
11606
+ });
11607
+ return [contractFor(cfg).populate("cancel_order", [cancelRequest])];
11608
+ }
11609
+ function buildCancelTypedData(orderHash, offerer, cfg) {
11610
+ return stringifyBigInts(buildCancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg)));
11611
+ }
11612
+
11517
11613
  // src/starknet/marketplace/orders.ts
11518
11614
  var _contractCache = /* @__PURE__ */ new WeakMap();
11519
11615
  function makeContract(config) {
11520
11616
  const cached = _contractCache.get(config);
11521
11617
  const provider = getProvider(config);
11522
11618
  if (cached) return { ...cached, provider };
11523
- const contract = new Contract(
11524
- IPMarketplaceABI,
11525
- config.marketplaceContract,
11526
- provider
11527
- );
11619
+ const contract = newContract(IPMarketplaceABI, config.marketplaceContract, provider);
11528
11620
  _contractCache.set(config, { contract });
11529
11621
  return { contract, provider };
11530
11622
  }
@@ -11538,46 +11630,22 @@ async function createListing(account, params, config) {
11538
11630
  const endTime = now + durationSeconds;
11539
11631
  const counter = (await contract.get_counter(account.address)).toString();
11540
11632
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11541
- const orderParams = {
11542
- offerer: account.address,
11543
- marketplace: config.marketplaceContract,
11544
- offer: {
11545
- item_type: "ERC721",
11546
- token: nftContract,
11547
- identifier_or_criteria: tokenId,
11548
- amount: "1"
11549
- },
11550
- consideration: {
11551
- item_type: "ERC20",
11552
- token: token.address,
11553
- identifier_or_criteria: "0",
11554
- amount: priceWei,
11555
- recipient: account.address
11556
- },
11557
- royalty_max_bps: royaltyMaxBps,
11558
- start_time: startTime.toString(),
11559
- end_time: endTime.toString(),
11560
- salt: generateSalt(),
11561
- counter
11562
- };
11563
- const chainId = getChainId(config);
11564
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
11565
- const signature = await account.signMessage(typedData);
11566
- const signatureArray = toSignatureArray(signature);
11567
- const registerPayload = stringifyBigInts({
11568
- parameters: {
11569
- ...orderParams,
11570
- offer: {
11571
- ...orderParams.offer,
11572
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
11573
- },
11574
- consideration: {
11575
- ...orderParams.consideration,
11576
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
11577
- }
11633
+ const { orderParams, typedData } = buildListingOrder(
11634
+ {
11635
+ offerer: account.address,
11636
+ nftContract,
11637
+ tokenId,
11638
+ priceWei,
11639
+ paymentTokenAddress: token.address,
11640
+ royaltyMaxBps,
11641
+ startTime,
11642
+ endTime,
11643
+ salt: generateSalt(),
11644
+ counter
11578
11645
  },
11579
- signature: signatureArray
11580
- });
11646
+ config
11647
+ );
11648
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11581
11649
  const tokenIdUint256 = cairo.uint256(tokenId);
11582
11650
  let isAlreadyApproved = false;
11583
11651
  try {
@@ -11589,19 +11657,19 @@ async function createListing(account, params, config) {
11589
11657
  isAlreadyApproved = BigInt(result[0]).toString() === BigInt(config.marketplaceContract).toString();
11590
11658
  } catch {
11591
11659
  }
11592
- const registerCall = contract.populate("register_order", [registerPayload]);
11593
- const calls = isAlreadyApproved ? [registerCall] : [
11594
- {
11595
- contractAddress: nftContract,
11596
- entrypoint: "approve",
11597
- calldata: [
11598
- config.marketplaceContract,
11599
- tokenIdUint256.low.toString(),
11600
- tokenIdUint256.high.toString()
11601
- ]
11602
- },
11603
- registerCall
11604
- ];
11660
+ const approve = {
11661
+ contractAddress: nftContract,
11662
+ entrypoint: "approve",
11663
+ calldata: [
11664
+ config.marketplaceContract,
11665
+ tokenIdUint256.low.toString(),
11666
+ tokenIdUint256.high.toString()
11667
+ ]
11668
+ };
11669
+ const calls = buildRegisterCalls(
11670
+ { orderParams, signature: signatureArray, approvalNeeded: !isAlreadyApproved, approve },
11671
+ config
11672
+ );
11605
11673
  try {
11606
11674
  const tx = await account.execute(calls);
11607
11675
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11620,46 +11688,22 @@ async function makeOffer(account, params, config) {
11620
11688
  const endTime = now + durationSeconds;
11621
11689
  const counter = (await contract.get_counter(account.address)).toString();
11622
11690
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11623
- const orderParams = {
11624
- offerer: account.address,
11625
- marketplace: config.marketplaceContract,
11626
- offer: {
11627
- item_type: "ERC20",
11628
- token: token.address,
11629
- identifier_or_criteria: "0",
11630
- amount: priceWei
11631
- },
11632
- consideration: {
11633
- item_type: "ERC721",
11634
- token: nftContract,
11635
- identifier_or_criteria: tokenId,
11636
- amount: "1",
11637
- recipient: account.address
11638
- },
11639
- royalty_max_bps: royaltyMaxBps,
11640
- start_time: startTime.toString(),
11641
- end_time: endTime.toString(),
11642
- salt: generateSalt(),
11643
- counter
11644
- };
11645
- const chainId = getChainId(config);
11646
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
11647
- const signature = await account.signMessage(typedData);
11648
- const signatureArray = toSignatureArray(signature);
11649
- const registerPayload = stringifyBigInts({
11650
- parameters: {
11651
- ...orderParams,
11652
- offer: {
11653
- ...orderParams.offer,
11654
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
11655
- },
11656
- consideration: {
11657
- ...orderParams.consideration,
11658
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
11659
- }
11691
+ const { orderParams, typedData } = buildOfferOrder(
11692
+ {
11693
+ offerer: account.address,
11694
+ nftContract,
11695
+ tokenId,
11696
+ priceWei,
11697
+ paymentTokenAddress: token.address,
11698
+ royaltyMaxBps,
11699
+ startTime,
11700
+ endTime,
11701
+ salt: generateSalt(),
11702
+ counter
11660
11703
  },
11661
- signature: signatureArray
11662
- });
11704
+ config
11705
+ );
11706
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11663
11707
  const amountUint256 = cairo.uint256(priceWei);
11664
11708
  const approveCall = {
11665
11709
  contractAddress: token.address,
@@ -11670,9 +11714,12 @@ async function makeOffer(account, params, config) {
11670
11714
  amountUint256.high.toString()
11671
11715
  ]
11672
11716
  };
11673
- const registerCall = contract.populate("register_order", [registerPayload]);
11717
+ const calls = buildRegisterCalls(
11718
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
11719
+ config
11720
+ );
11674
11721
  try {
11675
- const tx = await account.execute([approveCall, registerCall]);
11722
+ const tx = await account.execute(calls);
11676
11723
  await provider.waitForTransaction(tx.transaction_hash);
11677
11724
  return { txHash: tx.transaction_hash };
11678
11725
  } catch (err) {
@@ -11681,23 +11728,8 @@ async function makeOffer(account, params, config) {
11681
11728
  }
11682
11729
  async function fulfillOrder(account, params, config) {
11683
11730
  const { orderHash, paymentToken, totalPrice } = params;
11684
- const { contract, provider } = makeContract(config);
11685
- const totalPriceU256 = cairo.uint256(totalPrice);
11686
- const approveCall = {
11687
- contractAddress: paymentToken,
11688
- entrypoint: "approve",
11689
- calldata: [
11690
- config.marketplaceContract,
11691
- totalPriceU256.low.toString(),
11692
- totalPriceU256.high.toString()
11693
- ]
11694
- };
11695
- const fulfillCall = contract.populate("fulfill_order", [orderHash]);
11696
- const feeCall = buildFeeCall(
11697
- { surface: "marketplace", token: paymentToken, grossAmount: BigInt(totalPrice) },
11698
- config.feeConfig
11699
- );
11700
- const calls = feeCall ? [approveCall, fulfillCall, feeCall] : [approveCall, fulfillCall];
11731
+ const { provider } = makeContract(config);
11732
+ const calls = buildFulfillCalls({ orderHash, paymentToken, totalPrice }, config);
11701
11733
  try {
11702
11734
  const tx = await account.execute(calls);
11703
11735
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11708,24 +11740,12 @@ async function fulfillOrder(account, params, config) {
11708
11740
  }
11709
11741
  async function cancelOrder(account, params, config) {
11710
11742
  const { orderHash } = params;
11711
- const { contract, provider } = makeContract(config);
11712
- const chainId = getChainId(config);
11713
- const cancelParams = {
11714
- order_hash: orderHash,
11715
- offerer: account.address
11716
- };
11717
- const typedData = stringifyBigInts(
11718
- buildCancellationTypedData(cancelParams, chainId)
11719
- );
11720
- const signature = await account.signMessage(typedData);
11721
- const signatureArray = toSignatureArray(signature);
11722
- const cancelRequest = stringifyBigInts({
11723
- cancelation: cancelParams,
11724
- signature: signatureArray
11725
- });
11726
- const call = contract.populate("cancel_order", [cancelRequest]);
11743
+ const { provider } = makeContract(config);
11744
+ const typedData = buildCancelTypedData(orderHash, account.address, config);
11745
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11746
+ const calls = buildCancelCalls({ orderHash, offerer: account.address, signature: signatureArray }, config);
11727
11747
  try {
11728
- const tx = await account.execute(call);
11748
+ const tx = await account.execute(calls);
11729
11749
  await provider.waitForTransaction(tx.transaction_hash);
11730
11750
  return { txHash: tx.transaction_hash };
11731
11751
  } catch (err) {
@@ -11872,16 +11892,106 @@ var MarketplaceModule = class {
11872
11892
  return buildCancellationTypedData(params, chainId);
11873
11893
  }
11874
11894
  };
11895
+ function contractFor2(cfg) {
11896
+ return newContract(Medialane1155ABI, cfg.marketplace1155Contract, getProvider(cfg));
11897
+ }
11898
+ function buildListing1155Order(i, cfg) {
11899
+ const orderParams = {
11900
+ offerer: i.offerer,
11901
+ marketplace: cfg.marketplace1155Contract,
11902
+ offer: { item_type: "ERC1155", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: i.quantity },
11903
+ consideration: {
11904
+ item_type: "ERC20",
11905
+ token: i.paymentTokenAddress,
11906
+ identifier_or_criteria: "0",
11907
+ amount: i.priceWeiPerUnit,
11908
+ recipient: i.offerer
11909
+ },
11910
+ royalty_max_bps: i.royaltyMaxBps,
11911
+ start_time: String(i.startTime),
11912
+ end_time: String(i.endTime),
11913
+ salt: i.salt,
11914
+ counter: i.counter
11915
+ };
11916
+ const typedData = stringifyBigInts(
11917
+ build1155OrderTypedData(orderParams, getChainId(cfg))
11918
+ );
11919
+ return { orderParams, typedData };
11920
+ }
11921
+ function buildOffer1155Order(i, cfg) {
11922
+ const orderParams = {
11923
+ offerer: i.offerer,
11924
+ marketplace: cfg.marketplace1155Contract,
11925
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWeiPerUnit },
11926
+ consideration: {
11927
+ item_type: "ERC1155",
11928
+ token: i.nftContract,
11929
+ identifier_or_criteria: i.tokenId,
11930
+ amount: i.quantity,
11931
+ recipient: i.offerer
11932
+ },
11933
+ royalty_max_bps: i.royaltyMaxBps,
11934
+ start_time: String(i.startTime),
11935
+ end_time: String(i.endTime),
11936
+ salt: i.salt,
11937
+ counter: i.counter
11938
+ };
11939
+ const typedData = stringifyBigInts(
11940
+ build1155OrderTypedData(orderParams, getChainId(cfg))
11941
+ );
11942
+ return { orderParams, typedData };
11943
+ }
11944
+ function registerPayload2(orderParams, signature) {
11945
+ return stringifyBigInts({
11946
+ parameters: {
11947
+ ...orderParams,
11948
+ offer: { ...orderParams.offer, item_type: shortString.encodeShortString(orderParams.offer.item_type) },
11949
+ consideration: {
11950
+ ...orderParams.consideration,
11951
+ item_type: shortString.encodeShortString(orderParams.consideration.item_type)
11952
+ }
11953
+ },
11954
+ signature
11955
+ });
11956
+ }
11957
+ function buildRegister1155Calls(a, cfg) {
11958
+ const registerCall = contractFor2(cfg).populate("register_order", [registerPayload2(a.orderParams, a.signature)]);
11959
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
11960
+ }
11961
+ function buildFulfill1155Calls(a, cfg) {
11962
+ const u = cairo.uint256(a.totalPrice);
11963
+ const approve = {
11964
+ contractAddress: a.paymentToken,
11965
+ entrypoint: "approve",
11966
+ calldata: [cfg.marketplace1155Contract, u.low.toString(), u.high.toString()]
11967
+ };
11968
+ const fulfill = contractFor2(cfg).populate("fulfill_order", [a.orderHash, a.quantity]);
11969
+ const fee = buildFeeCall(
11970
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
11971
+ cfg.feeConfig
11972
+ );
11973
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
11974
+ }
11975
+ function buildCancel1155Calls(a, cfg) {
11976
+ const cancelPayload = stringifyBigInts({
11977
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
11978
+ signature: a.signature
11979
+ });
11980
+ return [contractFor2(cfg).populate("cancel_order", [cancelPayload])];
11981
+ }
11982
+ function buildCancel1155TypedData(orderHash, offerer, cfg) {
11983
+ return stringifyBigInts(
11984
+ build1155CancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg))
11985
+ );
11986
+ }
11987
+
11988
+ // src/starknet/marketplace1155/orders.ts
11875
11989
  var _contractCache2 = /* @__PURE__ */ new WeakMap();
11876
11990
  function getContract(config) {
11877
11991
  let c = _contractCache2.get(config);
11878
11992
  if (!c) {
11879
11993
  const provider = getProvider(config);
11880
- c = new Contract(
11881
- Medialane1155ABI,
11882
- config.marketplace1155Contract,
11883
- provider
11884
- );
11994
+ c = newContract(Medialane1155ABI, config.marketplace1155Contract, provider);
11885
11995
  _contractCache2.set(config, c);
11886
11996
  }
11887
11997
  return c;
@@ -11900,53 +12010,27 @@ async function createListing1155(account, params, config) {
11900
12010
  const token = resolveToken(currency);
11901
12011
  const priceWei = parseAmount(pricePerUnit, token.decimals);
11902
12012
  const now = Math.floor(Date.now() / 1e3);
12013
+ const startTime = now + START_TIME_BUFFER_SECS;
11903
12014
  const endTime = now + durationSeconds;
11904
- const chainId = getChainId(config);
11905
12015
  const counter = (await contract.get_counter(account.address)).toString();
11906
12016
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11907
- const orderParams = {
11908
- offerer: account.address,
11909
- marketplace: config.marketplace1155Contract,
11910
- offer: {
11911
- item_type: "ERC1155",
11912
- token: nftContract,
11913
- identifier_or_criteria: tokenId,
11914
- amount
11915
- // ERC-1155 leg amount = unit quantity
11916
- },
11917
- consideration: {
11918
- item_type: "ERC20",
11919
- token: token.address,
11920
- identifier_or_criteria: "0",
11921
- amount: priceWei,
11922
- // payment leg amount = price PER UNIT
11923
- recipient: account.address
12017
+ const { orderParams, typedData } = buildListing1155Order(
12018
+ {
12019
+ offerer: account.address,
12020
+ nftContract,
12021
+ tokenId,
12022
+ quantity: amount,
12023
+ priceWeiPerUnit: priceWei,
12024
+ paymentTokenAddress: token.address,
12025
+ royaltyMaxBps,
12026
+ startTime,
12027
+ endTime,
12028
+ salt: generateSalt(),
12029
+ counter
11924
12030
  },
11925
- royalty_max_bps: royaltyMaxBps,
11926
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
11927
- end_time: endTime.toString(),
11928
- salt: generateSalt(),
11929
- counter
11930
- };
11931
- const typedData = stringifyBigInts(
11932
- build1155OrderTypedData(orderParams, chainId)
12031
+ config
11933
12032
  );
11934
- const signature = await account.signMessage(typedData);
11935
- const signatureArray = toSignatureArray(signature);
11936
- const orderPayload = stringifyBigInts({
11937
- parameters: {
11938
- ...orderParams,
11939
- offer: {
11940
- ...orderParams.offer,
11941
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
11942
- },
11943
- consideration: {
11944
- ...orderParams.consideration,
11945
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
11946
- }
11947
- },
11948
- signature: signatureArray
11949
- });
12033
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11950
12034
  let isApproved = false;
11951
12035
  try {
11952
12036
  const result = await provider.callContract({
@@ -11957,15 +12041,15 @@ async function createListing1155(account, params, config) {
11957
12041
  isApproved = BigInt(result[0]) === 1n;
11958
12042
  } catch {
11959
12043
  }
11960
- const registerCall = contract.populate("register_order", [orderPayload]);
11961
- const calls = isApproved ? [registerCall] : [
11962
- {
11963
- contractAddress: nftContract,
11964
- entrypoint: "set_approval_for_all",
11965
- calldata: [config.marketplace1155Contract, "1"]
11966
- },
11967
- registerCall
11968
- ];
12044
+ const approve = {
12045
+ contractAddress: nftContract,
12046
+ entrypoint: "set_approval_for_all",
12047
+ calldata: [config.marketplace1155Contract, "1"]
12048
+ };
12049
+ const calls = buildRegister1155Calls(
12050
+ { orderParams, signature: signatureArray, approvalNeeded: !isApproved, approve },
12051
+ config
12052
+ );
11969
12053
  try {
11970
12054
  const tx = await account.execute(calls);
11971
12055
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11976,21 +12060,10 @@ async function createListing1155(account, params, config) {
11976
12060
  }
11977
12061
  async function fulfillOrder1155(account, params, config) {
11978
12062
  const { orderHash, paymentToken, totalPrice, quantity = "1" } = params;
11979
- const contract = getContract(config);
11980
12063
  const provider = getProvider(config);
11981
- const totalPriceU256 = cairo.uint256(totalPrice);
11982
- const approveCall = {
11983
- contractAddress: paymentToken,
11984
- entrypoint: "approve",
11985
- calldata: [
11986
- config.marketplace1155Contract,
11987
- totalPriceU256.low.toString(),
11988
- totalPriceU256.high.toString()
11989
- ]
11990
- };
11991
- const fulfillCall = contract.populate("fulfill_order", [orderHash, quantity]);
12064
+ const calls = buildFulfill1155Calls({ orderHash, paymentToken, totalPrice, quantity }, config);
11992
12065
  try {
11993
- const tx = await account.execute([approveCall, fulfillCall]);
12066
+ const tx = await account.execute(calls);
11994
12067
  await provider.waitForTransaction(tx.transaction_hash);
11995
12068
  return { txHash: tx.transaction_hash };
11996
12069
  } catch (err) {
@@ -11999,25 +12072,12 @@ async function fulfillOrder1155(account, params, config) {
11999
12072
  }
12000
12073
  async function cancelOrder1155(account, params, config) {
12001
12074
  const { orderHash } = params;
12002
- const contract = getContract(config);
12003
12075
  const provider = getProvider(config);
12004
- const chainId = getChainId(config);
12005
- const cancelParams = {
12006
- order_hash: orderHash,
12007
- offerer: account.address
12008
- };
12009
- const typedData = stringifyBigInts(
12010
- build1155CancellationTypedData(cancelParams, chainId)
12011
- );
12012
- const signature = await account.signMessage(typedData);
12013
- const signatureArray = toSignatureArray(signature);
12014
- const cancelPayload = stringifyBigInts({
12015
- cancelation: cancelParams,
12016
- signature: signatureArray
12017
- });
12018
- const cancelCall = contract.populate("cancel_order", [cancelPayload]);
12076
+ const typedData = buildCancel1155TypedData(orderHash, account.address, config);
12077
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
12078
+ const calls = buildCancel1155Calls({ orderHash, offerer: account.address, signature: signatureArray }, config);
12019
12079
  try {
12020
- const tx = await account.execute(cancelCall);
12080
+ const tx = await account.execute(calls);
12021
12081
  await provider.waitForTransaction(tx.transaction_hash);
12022
12082
  return { txHash: tx.transaction_hash };
12023
12083
  } catch (err) {
@@ -12035,56 +12095,30 @@ async function makeOffer1155(account, params, config) {
12035
12095
  } = params;
12036
12096
  const contract = getContract(config);
12037
12097
  const provider = getProvider(config);
12038
- const chainId = getChainId(config);
12039
12098
  const token = resolveToken(currency);
12040
12099
  const priceWei = parseAmount(price, token.decimals);
12041
12100
  const now = Math.floor(Date.now() / 1e3);
12101
+ const startTime = now + START_TIME_BUFFER_SECS;
12042
12102
  const endTime = now + durationSeconds;
12043
12103
  const counter = (await contract.get_counter(account.address)).toString();
12044
12104
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
12045
- const orderParams = {
12046
- offerer: account.address,
12047
- marketplace: config.marketplace1155Contract,
12048
- offer: {
12049
- item_type: "ERC20",
12050
- token: token.address,
12051
- identifier_or_criteria: "0",
12052
- amount: priceWei
12053
- // price PER UNIT
12054
- },
12055
- consideration: {
12056
- item_type: "ERC1155",
12057
- token: nftContract,
12058
- identifier_or_criteria: tokenId,
12059
- amount,
12060
- // unit quantity
12061
- recipient: account.address
12105
+ const { orderParams, typedData } = buildOffer1155Order(
12106
+ {
12107
+ offerer: account.address,
12108
+ nftContract,
12109
+ tokenId,
12110
+ quantity: amount,
12111
+ priceWeiPerUnit: priceWei,
12112
+ paymentTokenAddress: token.address,
12113
+ royaltyMaxBps,
12114
+ startTime,
12115
+ endTime,
12116
+ salt: generateSalt(),
12117
+ counter
12062
12118
  },
12063
- royalty_max_bps: royaltyMaxBps,
12064
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
12065
- end_time: endTime.toString(),
12066
- salt: generateSalt(),
12067
- counter
12068
- };
12069
- const typedData = stringifyBigInts(
12070
- build1155OrderTypedData(orderParams, chainId)
12119
+ config
12071
12120
  );
12072
- const signature = await account.signMessage(typedData);
12073
- const signatureArray = toSignatureArray(signature);
12074
- const registerPayload = stringifyBigInts({
12075
- parameters: {
12076
- ...orderParams,
12077
- offer: {
12078
- ...orderParams.offer,
12079
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
12080
- },
12081
- consideration: {
12082
- ...orderParams.consideration,
12083
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
12084
- }
12085
- },
12086
- signature: signatureArray
12087
- });
12121
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
12088
12122
  const totalWei = BigInt(priceWei) * BigInt(amount);
12089
12123
  const amountU256 = cairo.uint256(totalWei.toString());
12090
12124
  const approveCall = {
@@ -12096,9 +12130,12 @@ async function makeOffer1155(account, params, config) {
12096
12130
  amountU256.high.toString()
12097
12131
  ]
12098
12132
  };
12099
- const registerCall = contract.populate("register_order", [registerPayload]);
12133
+ const calls = buildRegister1155Calls(
12134
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
12135
+ config
12136
+ );
12100
12137
  try {
12101
- const tx = await account.execute([approveCall, registerCall]);
12138
+ const tx = await account.execute(calls);
12102
12139
  await provider.waitForTransaction(tx.transaction_hash);
12103
12140
  return { txHash: tx.transaction_hash };
12104
12141
  } catch (err) {
@@ -12988,94 +13025,147 @@ var StarknetVenue = class {
12988
13025
  constructor(deps) {
12989
13026
  this.deps = deps;
12990
13027
  this.chain = "STARKNET";
12991
- this.m721 = new MarketplaceModule(deps.config);
12992
- this.m1155 = new Medialane1155Module(deps.config);
12993
13028
  }
12994
- incrementCounter(signer) {
12995
- return this.m721.incrementCounter(signer);
13029
+ async incrementCounter(signer) {
13030
+ return signer.execute([
13031
+ { contractAddress: this.deps.config.marketplaceContract, entrypoint: "increment_counter", calldata: [] }
13032
+ ]);
12996
13033
  }
12997
13034
  getOrderDetails(orderRef) {
12998
- return this.m721.getOrderDetails(orderRef);
13035
+ return getOrderDetails(orderRef, this.deps.config);
12999
13036
  }
13000
- getCounter(address) {
13001
- return this.m721.getCounter(address);
13037
+ async getCounter(address) {
13038
+ return this.readCounter(this.deps.config.marketplaceContract, address);
13002
13039
  }
13003
13040
  async fulfillOrder(signer, orderRef, opts) {
13004
13041
  const o = await this.deps.resolveOrder(orderRef);
13005
13042
  const quantity = opts?.quantity ?? "1";
13006
13043
  const totalPrice = (BigInt(o.unitPrice) * BigInt(quantity)).toString();
13007
- if (o.standard === "ERC1155") {
13008
- return this.m1155.fulfillOrder(signer, {
13009
- orderHash: orderRef,
13010
- paymentToken: o.paymentToken,
13011
- totalPrice,
13012
- quantity
13013
- });
13014
- }
13015
- return this.m721.fulfillOrder(signer, {
13016
- orderHash: orderRef,
13017
- paymentToken: o.paymentToken,
13018
- totalPrice
13019
- });
13044
+ const calls = o.standard === "ERC1155" ? buildFulfill1155Calls({ orderHash: orderRef, paymentToken: o.paymentToken, totalPrice, quantity }, this.deps.config) : buildFulfillCalls({ orderHash: orderRef, paymentToken: o.paymentToken, totalPrice }, this.deps.config);
13045
+ return signer.execute(calls);
13020
13046
  }
13021
13047
  async cancelOrder(signer, orderRef) {
13022
13048
  const o = await this.deps.resolveOrder(orderRef);
13023
- if (o.standard === "ERC1155") {
13024
- return this.m1155.cancelOrder(signer, { orderHash: orderRef });
13025
- }
13026
- return this.m721.cancelOrder(signer, { orderHash: orderRef });
13049
+ const typedData = o.standard === "ERC1155" ? buildCancel1155TypedData(orderRef, signer.address, this.deps.config) : buildCancelTypedData(orderRef, signer.address, this.deps.config);
13050
+ const signature = await signer.signTypedData(typedData);
13051
+ const calls = o.standard === "ERC1155" ? buildCancel1155Calls({ orderHash: orderRef, offerer: signer.address, signature }, this.deps.config) : buildCancelCalls({ orderHash: orderRef, offerer: signer.address, signature }, this.deps.config);
13052
+ return signer.execute(calls);
13027
13053
  }
13028
13054
  async registerOrder(signer, p) {
13029
13055
  const standard = await this.deps.resolveStandard(p.asset.contract);
13030
- const token = resolveToken(p.paymentToken);
13031
- const humanPrice = formatAmount(p.amount, token.decimals);
13032
- const durationSeconds = this.durationSeconds(p.endTime);
13056
+ const paymentTokenAddress = resolveToken(p.paymentToken).address;
13033
13057
  const royaltyMaxBps = String(p.royaltyMaxBps);
13058
+ const startTime = Math.floor(Date.now() / 1e3) + START_TIME_BUFFER_SECS;
13059
+ const endTime = p.endTime && p.endTime > 0 ? p.endTime : startTime + NO_EXPIRY_SECONDS;
13034
13060
  const quantity = p.quantity ?? "1";
13035
- let txHash;
13061
+ const marketplace = standard === "ERC1155" ? this.deps.config.marketplace1155Contract : this.deps.config.marketplaceContract;
13062
+ const counter = String(await this.readCounter(marketplace, signer.address));
13063
+ let typedData;
13064
+ let buildCalls;
13036
13065
  if (standard === "ERC1155") {
13037
- if (p.side === "listing") {
13038
- const res = await this.m1155.createListing(signer, {
13066
+ const built = (p.side === "listing" ? buildListing1155Order : buildOffer1155Order)(
13067
+ {
13068
+ offerer: signer.address,
13039
13069
  nftContract: p.asset.contract,
13040
13070
  tokenId: p.asset.tokenId,
13041
- amount: quantity,
13042
- pricePerUnit: humanPrice,
13043
- currency: p.paymentToken,
13044
- durationSeconds,
13045
- royaltyMaxBps
13046
- });
13047
- txHash = res.txHash;
13048
- } else {
13049
- const totalHuman = formatAmount((BigInt(p.amount) * BigInt(quantity)).toString(), token.decimals);
13050
- const res = await this.m1155.makeOffer(signer, {
13071
+ quantity,
13072
+ priceWeiPerUnit: p.amount,
13073
+ paymentTokenAddress,
13074
+ royaltyMaxBps,
13075
+ startTime,
13076
+ endTime,
13077
+ salt: p.salt,
13078
+ counter
13079
+ },
13080
+ this.deps.config
13081
+ );
13082
+ typedData = built.typedData;
13083
+ const approval = p.side === "listing" ? await this.approval1155ForListing(signer.address, p.asset.contract) : this.approvalForErc20(paymentTokenAddress, (BigInt(p.amount) * BigInt(quantity)).toString(), marketplace);
13084
+ buildCalls = (sig) => buildRegister1155Calls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
13085
+ } else {
13086
+ const built = (p.side === "listing" ? buildListingOrder : buildOfferOrder)(
13087
+ {
13088
+ offerer: signer.address,
13051
13089
  nftContract: p.asset.contract,
13052
13090
  tokenId: p.asset.tokenId,
13053
- amount: quantity,
13054
- price: totalHuman,
13055
- currency: p.paymentToken,
13056
- durationSeconds,
13057
- royaltyMaxBps
13058
- });
13059
- txHash = res.txHash;
13060
- }
13061
- } else {
13062
- const params = {
13063
- nftContract: p.asset.contract,
13064
- tokenId: p.asset.tokenId,
13065
- price: humanPrice,
13066
- currency: p.paymentToken,
13067
- durationSeconds,
13068
- royaltyMaxBps
13069
- };
13070
- const res = p.side === "listing" ? await this.m721.createListing(signer, params) : await this.m721.makeOffer(signer, params);
13071
- txHash = res.txHash;
13091
+ priceWei: p.amount,
13092
+ paymentTokenAddress,
13093
+ royaltyMaxBps,
13094
+ startTime,
13095
+ endTime,
13096
+ salt: p.salt,
13097
+ counter
13098
+ },
13099
+ this.deps.config
13100
+ );
13101
+ typedData = built.typedData;
13102
+ const approval = p.side === "listing" ? await this.approval721ForListing(signer.address, p.asset.contract, p.asset.tokenId) : this.approvalForErc20(paymentTokenAddress, p.amount, marketplace);
13103
+ buildCalls = (sig) => buildRegisterCalls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
13072
13104
  }
13105
+ const signature = await signer.signTypedData(typedData);
13106
+ const { txHash } = await signer.execute(buildCalls(signature));
13073
13107
  const orderRef = await this.orderRefFromReceipt(txHash);
13074
13108
  return { txHash, orderRef };
13075
13109
  }
13076
- durationSeconds(endTime) {
13077
- if (!endTime) return NO_EXPIRY_SECONDS;
13078
- return Math.max(1, endTime - Math.floor(Date.now() / 1e3));
13110
+ // ─── reads (all on deps.provider) ─────────────────────────────────────────
13111
+ async readCounter(marketplace, address) {
13112
+ const res = await this.deps.provider.callContract({
13113
+ contractAddress: marketplace,
13114
+ entrypoint: "get_counter",
13115
+ calldata: [address]
13116
+ });
13117
+ return BigInt(res[0] ?? "0");
13118
+ }
13119
+ /** 721 listing approval: `get_approved(tokenId) == marketplace` ⇒ no approve. */
13120
+ async approval721ForListing(_owner, nftContract, tokenId) {
13121
+ const id = cairo.uint256(tokenId);
13122
+ const approve = {
13123
+ contractAddress: nftContract,
13124
+ entrypoint: "approve",
13125
+ calldata: [this.deps.config.marketplaceContract, id.low.toString(), id.high.toString()]
13126
+ };
13127
+ let approved = false;
13128
+ try {
13129
+ const res = await this.deps.provider.callContract({
13130
+ contractAddress: nftContract,
13131
+ entrypoint: "get_approved",
13132
+ calldata: [id.low.toString(), id.high.toString()]
13133
+ });
13134
+ approved = BigInt(res[0]).toString() === BigInt(this.deps.config.marketplaceContract).toString();
13135
+ } catch {
13136
+ }
13137
+ return { approvalNeeded: !approved, approve };
13138
+ }
13139
+ /** 1155 listing approval: `is_approved_for_all(owner, marketplace)`. */
13140
+ async approval1155ForListing(owner, nftContract) {
13141
+ const approve = {
13142
+ contractAddress: nftContract,
13143
+ entrypoint: "set_approval_for_all",
13144
+ calldata: [this.deps.config.marketplace1155Contract, "1"]
13145
+ };
13146
+ let approved = false;
13147
+ try {
13148
+ const res = await this.deps.provider.callContract({
13149
+ contractAddress: nftContract,
13150
+ entrypoint: "is_approved_for_all",
13151
+ calldata: [owner, this.deps.config.marketplace1155Contract]
13152
+ });
13153
+ approved = BigInt(res[0]) === 1n;
13154
+ } catch {
13155
+ }
13156
+ return { approvalNeeded: !approved, approve };
13157
+ }
13158
+ /** Offers always approve the ERC-20 spend (no read). */
13159
+ approvalForErc20(token, amountWei, marketplace) {
13160
+ const u = cairo.uint256(amountWei);
13161
+ return {
13162
+ approvalNeeded: true,
13163
+ approve: {
13164
+ contractAddress: token,
13165
+ entrypoint: "approve",
13166
+ calldata: [marketplace, u.low.toString(), u.high.toString()]
13167
+ }
13168
+ };
13079
13169
  }
13080
13170
  /** The canonical Starknet order id = the contract-emitted `OrderCreated`
13081
13171
  * hash (`keys[1]`), which is exactly what the indexer stores. */