@medialane/sdk 0.59.0 → 0.61.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.cjs CHANGED
@@ -11636,6 +11636,14 @@ function toSignatureArray(sig) {
11636
11636
  const s = sig;
11637
11637
  return [s.r.toString(), s.s.toString()];
11638
11638
  }
11639
+ function newContract(abi, address, providerOrAccount) {
11640
+ const C = starknet.Contract;
11641
+ return C.length === 1 ? new starknet.Contract({ abi, address, providerOrAccount }) : new starknet.Contract(
11642
+ abi,
11643
+ address,
11644
+ providerOrAccount
11645
+ );
11646
+ }
11639
11647
  function getChainId(config) {
11640
11648
  if (config.chain !== "STARKNET") {
11641
11649
  throw new Error(`SNIP-12 signing is Starknet-only; got chain "${config.chain}"`);
@@ -11660,17 +11668,101 @@ function getProvider(config) {
11660
11668
  return p;
11661
11669
  }
11662
11670
 
11671
+ // src/starknet/marketplace/build.ts
11672
+ function contractFor(cfg) {
11673
+ return newContract(IPMarketplaceABI, cfg.marketplaceContract, getProvider(cfg));
11674
+ }
11675
+ function buildListingOrder(i, cfg) {
11676
+ const orderParams = {
11677
+ offerer: i.offerer,
11678
+ marketplace: cfg.marketplaceContract,
11679
+ offer: { item_type: "ERC721", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: "1" },
11680
+ consideration: {
11681
+ item_type: "ERC20",
11682
+ token: i.paymentTokenAddress,
11683
+ identifier_or_criteria: "0",
11684
+ amount: i.priceWei,
11685
+ recipient: i.offerer
11686
+ },
11687
+ royalty_max_bps: i.royaltyMaxBps,
11688
+ start_time: String(i.startTime),
11689
+ end_time: String(i.endTime),
11690
+ salt: i.salt,
11691
+ counter: i.counter
11692
+ };
11693
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
11694
+ return { orderParams, typedData };
11695
+ }
11696
+ function buildOfferOrder(i, cfg) {
11697
+ const orderParams = {
11698
+ offerer: i.offerer,
11699
+ marketplace: cfg.marketplaceContract,
11700
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWei },
11701
+ consideration: {
11702
+ item_type: "ERC721",
11703
+ token: i.nftContract,
11704
+ identifier_or_criteria: i.tokenId,
11705
+ amount: "1",
11706
+ recipient: i.offerer
11707
+ },
11708
+ royalty_max_bps: i.royaltyMaxBps,
11709
+ start_time: String(i.startTime),
11710
+ end_time: String(i.endTime),
11711
+ salt: i.salt,
11712
+ counter: i.counter
11713
+ };
11714
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
11715
+ return { orderParams, typedData };
11716
+ }
11717
+ function registerPayload(orderParams, signature) {
11718
+ return stringifyBigInts({
11719
+ parameters: {
11720
+ ...orderParams,
11721
+ offer: { ...orderParams.offer, item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type) },
11722
+ consideration: {
11723
+ ...orderParams.consideration,
11724
+ item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11725
+ }
11726
+ },
11727
+ signature
11728
+ });
11729
+ }
11730
+ function buildRegisterCalls(a, cfg) {
11731
+ const registerCall = contractFor(cfg).populate("register_order", [registerPayload(a.orderParams, a.signature)]);
11732
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
11733
+ }
11734
+ function buildFulfillCalls(a, cfg) {
11735
+ const u = starknet.cairo.uint256(a.totalPrice);
11736
+ const approve = {
11737
+ contractAddress: a.paymentToken,
11738
+ entrypoint: "approve",
11739
+ calldata: [cfg.marketplaceContract, u.low.toString(), u.high.toString()]
11740
+ };
11741
+ const fulfill = contractFor(cfg).populate("fulfill_order", [a.orderHash]);
11742
+ const fee = buildFeeCall(
11743
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
11744
+ cfg.feeConfig
11745
+ );
11746
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
11747
+ }
11748
+ function buildCancelCalls(a, cfg) {
11749
+ const cancelRequest = stringifyBigInts({
11750
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
11751
+ signature: a.signature
11752
+ });
11753
+ return [contractFor(cfg).populate("cancel_order", [cancelRequest])];
11754
+ }
11755
+ function buildCancelTypedData(orderHash, offerer, cfg) {
11756
+ return stringifyBigInts(buildCancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg)));
11757
+ }
11758
+
11663
11759
  // src/starknet/marketplace/orders.ts
11664
11760
  var _contractCache = /* @__PURE__ */ new WeakMap();
11665
11761
  function makeContract(config) {
11666
11762
  const cached = _contractCache.get(config);
11667
11763
  const provider = getProvider(config);
11668
11764
  if (cached) return { ...cached, provider };
11669
- const contract = new starknet.Contract(
11670
- IPMarketplaceABI,
11671
- config.marketplaceContract,
11672
- provider
11673
- );
11765
+ const contract = newContract(IPMarketplaceABI, config.marketplaceContract, provider);
11674
11766
  _contractCache.set(config, { contract });
11675
11767
  return { contract, provider };
11676
11768
  }
@@ -11684,46 +11776,22 @@ async function createListing(account, params, config) {
11684
11776
  const endTime = now + durationSeconds;
11685
11777
  const counter = (await contract.get_counter(account.address)).toString();
11686
11778
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11687
- const orderParams = {
11688
- offerer: account.address,
11689
- marketplace: config.marketplaceContract,
11690
- offer: {
11691
- item_type: "ERC721",
11692
- token: nftContract,
11693
- identifier_or_criteria: tokenId,
11694
- amount: "1"
11695
- },
11696
- consideration: {
11697
- item_type: "ERC20",
11698
- token: token.address,
11699
- identifier_or_criteria: "0",
11700
- amount: priceWei,
11701
- recipient: account.address
11702
- },
11703
- royalty_max_bps: royaltyMaxBps,
11704
- start_time: startTime.toString(),
11705
- end_time: endTime.toString(),
11706
- salt: generateSalt(),
11707
- counter
11708
- };
11709
- const chainId = getChainId(config);
11710
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
11711
- const signature = await account.signMessage(typedData);
11712
- const signatureArray = toSignatureArray(signature);
11713
- const registerPayload = stringifyBigInts({
11714
- parameters: {
11715
- ...orderParams,
11716
- offer: {
11717
- ...orderParams.offer,
11718
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
11719
- },
11720
- consideration: {
11721
- ...orderParams.consideration,
11722
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11723
- }
11779
+ const { orderParams, typedData } = buildListingOrder(
11780
+ {
11781
+ offerer: account.address,
11782
+ nftContract,
11783
+ tokenId,
11784
+ priceWei,
11785
+ paymentTokenAddress: token.address,
11786
+ royaltyMaxBps,
11787
+ startTime,
11788
+ endTime,
11789
+ salt: generateSalt(),
11790
+ counter
11724
11791
  },
11725
- signature: signatureArray
11726
- });
11792
+ config
11793
+ );
11794
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11727
11795
  const tokenIdUint256 = starknet.cairo.uint256(tokenId);
11728
11796
  let isAlreadyApproved = false;
11729
11797
  try {
@@ -11735,19 +11803,19 @@ async function createListing(account, params, config) {
11735
11803
  isAlreadyApproved = BigInt(result[0]).toString() === BigInt(config.marketplaceContract).toString();
11736
11804
  } catch {
11737
11805
  }
11738
- const registerCall = contract.populate("register_order", [registerPayload]);
11739
- const calls = isAlreadyApproved ? [registerCall] : [
11740
- {
11741
- contractAddress: nftContract,
11742
- entrypoint: "approve",
11743
- calldata: [
11744
- config.marketplaceContract,
11745
- tokenIdUint256.low.toString(),
11746
- tokenIdUint256.high.toString()
11747
- ]
11748
- },
11749
- registerCall
11750
- ];
11806
+ const approve = {
11807
+ contractAddress: nftContract,
11808
+ entrypoint: "approve",
11809
+ calldata: [
11810
+ config.marketplaceContract,
11811
+ tokenIdUint256.low.toString(),
11812
+ tokenIdUint256.high.toString()
11813
+ ]
11814
+ };
11815
+ const calls = buildRegisterCalls(
11816
+ { orderParams, signature: signatureArray, approvalNeeded: !isAlreadyApproved, approve },
11817
+ config
11818
+ );
11751
11819
  try {
11752
11820
  const tx = await account.execute(calls);
11753
11821
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11766,46 +11834,22 @@ async function makeOffer(account, params, config) {
11766
11834
  const endTime = now + durationSeconds;
11767
11835
  const counter = (await contract.get_counter(account.address)).toString();
11768
11836
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11769
- const orderParams = {
11770
- offerer: account.address,
11771
- marketplace: config.marketplaceContract,
11772
- offer: {
11773
- item_type: "ERC20",
11774
- token: token.address,
11775
- identifier_or_criteria: "0",
11776
- amount: priceWei
11777
- },
11778
- consideration: {
11779
- item_type: "ERC721",
11780
- token: nftContract,
11781
- identifier_or_criteria: tokenId,
11782
- amount: "1",
11783
- recipient: account.address
11784
- },
11785
- royalty_max_bps: royaltyMaxBps,
11786
- start_time: startTime.toString(),
11787
- end_time: endTime.toString(),
11788
- salt: generateSalt(),
11789
- counter
11790
- };
11791
- const chainId = getChainId(config);
11792
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
11793
- const signature = await account.signMessage(typedData);
11794
- const signatureArray = toSignatureArray(signature);
11795
- const registerPayload = stringifyBigInts({
11796
- parameters: {
11797
- ...orderParams,
11798
- offer: {
11799
- ...orderParams.offer,
11800
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
11801
- },
11802
- consideration: {
11803
- ...orderParams.consideration,
11804
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11805
- }
11837
+ const { orderParams, typedData } = buildOfferOrder(
11838
+ {
11839
+ offerer: account.address,
11840
+ nftContract,
11841
+ tokenId,
11842
+ priceWei,
11843
+ paymentTokenAddress: token.address,
11844
+ royaltyMaxBps,
11845
+ startTime,
11846
+ endTime,
11847
+ salt: generateSalt(),
11848
+ counter
11806
11849
  },
11807
- signature: signatureArray
11808
- });
11850
+ config
11851
+ );
11852
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11809
11853
  const amountUint256 = starknet.cairo.uint256(priceWei);
11810
11854
  const approveCall = {
11811
11855
  contractAddress: token.address,
@@ -11816,9 +11860,12 @@ async function makeOffer(account, params, config) {
11816
11860
  amountUint256.high.toString()
11817
11861
  ]
11818
11862
  };
11819
- const registerCall = contract.populate("register_order", [registerPayload]);
11863
+ const calls = buildRegisterCalls(
11864
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
11865
+ config
11866
+ );
11820
11867
  try {
11821
- const tx = await account.execute([approveCall, registerCall]);
11868
+ const tx = await account.execute(calls);
11822
11869
  await provider.waitForTransaction(tx.transaction_hash);
11823
11870
  return { txHash: tx.transaction_hash };
11824
11871
  } catch (err) {
@@ -11827,23 +11874,8 @@ async function makeOffer(account, params, config) {
11827
11874
  }
11828
11875
  async function fulfillOrder(account, params, config) {
11829
11876
  const { orderHash, paymentToken, totalPrice } = params;
11830
- const { contract, provider } = makeContract(config);
11831
- const totalPriceU256 = starknet.cairo.uint256(totalPrice);
11832
- const approveCall = {
11833
- contractAddress: paymentToken,
11834
- entrypoint: "approve",
11835
- calldata: [
11836
- config.marketplaceContract,
11837
- totalPriceU256.low.toString(),
11838
- totalPriceU256.high.toString()
11839
- ]
11840
- };
11841
- const fulfillCall = contract.populate("fulfill_order", [orderHash]);
11842
- const feeCall = buildFeeCall(
11843
- { surface: "marketplace", token: paymentToken, grossAmount: BigInt(totalPrice) },
11844
- config.feeConfig
11845
- );
11846
- const calls = feeCall ? [approveCall, fulfillCall, feeCall] : [approveCall, fulfillCall];
11877
+ const { provider } = makeContract(config);
11878
+ const calls = buildFulfillCalls({ orderHash, paymentToken, totalPrice }, config);
11847
11879
  try {
11848
11880
  const tx = await account.execute(calls);
11849
11881
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11854,24 +11886,12 @@ async function fulfillOrder(account, params, config) {
11854
11886
  }
11855
11887
  async function cancelOrder(account, params, config) {
11856
11888
  const { orderHash } = params;
11857
- const { contract, provider } = makeContract(config);
11858
- const chainId = getChainId(config);
11859
- const cancelParams = {
11860
- order_hash: orderHash,
11861
- offerer: account.address
11862
- };
11863
- const typedData = stringifyBigInts(
11864
- buildCancellationTypedData(cancelParams, chainId)
11865
- );
11866
- const signature = await account.signMessage(typedData);
11867
- const signatureArray = toSignatureArray(signature);
11868
- const cancelRequest = stringifyBigInts({
11869
- cancelation: cancelParams,
11870
- signature: signatureArray
11871
- });
11872
- const call = contract.populate("cancel_order", [cancelRequest]);
11889
+ const { provider } = makeContract(config);
11890
+ const typedData = buildCancelTypedData(orderHash, account.address, config);
11891
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11892
+ const calls = buildCancelCalls({ orderHash, offerer: account.address, signature: signatureArray }, config);
11873
11893
  try {
11874
- const tx = await account.execute(call);
11894
+ const tx = await account.execute(calls);
11875
11895
  await provider.waitForTransaction(tx.transaction_hash);
11876
11896
  return { txHash: tx.transaction_hash };
11877
11897
  } catch (err) {
@@ -12018,16 +12038,106 @@ var MarketplaceModule = class {
12018
12038
  return buildCancellationTypedData(params, chainId);
12019
12039
  }
12020
12040
  };
12041
+ function contractFor2(cfg) {
12042
+ return newContract(Medialane1155ABI, cfg.marketplace1155Contract, getProvider(cfg));
12043
+ }
12044
+ function buildListing1155Order(i, cfg) {
12045
+ const orderParams = {
12046
+ offerer: i.offerer,
12047
+ marketplace: cfg.marketplace1155Contract,
12048
+ offer: { item_type: "ERC1155", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: i.quantity },
12049
+ consideration: {
12050
+ item_type: "ERC20",
12051
+ token: i.paymentTokenAddress,
12052
+ identifier_or_criteria: "0",
12053
+ amount: i.priceWeiPerUnit,
12054
+ recipient: i.offerer
12055
+ },
12056
+ royalty_max_bps: i.royaltyMaxBps,
12057
+ start_time: String(i.startTime),
12058
+ end_time: String(i.endTime),
12059
+ salt: i.salt,
12060
+ counter: i.counter
12061
+ };
12062
+ const typedData = stringifyBigInts(
12063
+ build1155OrderTypedData(orderParams, getChainId(cfg))
12064
+ );
12065
+ return { orderParams, typedData };
12066
+ }
12067
+ function buildOffer1155Order(i, cfg) {
12068
+ const orderParams = {
12069
+ offerer: i.offerer,
12070
+ marketplace: cfg.marketplace1155Contract,
12071
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWeiPerUnit },
12072
+ consideration: {
12073
+ item_type: "ERC1155",
12074
+ token: i.nftContract,
12075
+ identifier_or_criteria: i.tokenId,
12076
+ amount: i.quantity,
12077
+ recipient: i.offerer
12078
+ },
12079
+ royalty_max_bps: i.royaltyMaxBps,
12080
+ start_time: String(i.startTime),
12081
+ end_time: String(i.endTime),
12082
+ salt: i.salt,
12083
+ counter: i.counter
12084
+ };
12085
+ const typedData = stringifyBigInts(
12086
+ build1155OrderTypedData(orderParams, getChainId(cfg))
12087
+ );
12088
+ return { orderParams, typedData };
12089
+ }
12090
+ function registerPayload2(orderParams, signature) {
12091
+ return stringifyBigInts({
12092
+ parameters: {
12093
+ ...orderParams,
12094
+ offer: { ...orderParams.offer, item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type) },
12095
+ consideration: {
12096
+ ...orderParams.consideration,
12097
+ item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
12098
+ }
12099
+ },
12100
+ signature
12101
+ });
12102
+ }
12103
+ function buildRegister1155Calls(a, cfg) {
12104
+ const registerCall = contractFor2(cfg).populate("register_order", [registerPayload2(a.orderParams, a.signature)]);
12105
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
12106
+ }
12107
+ function buildFulfill1155Calls(a, cfg) {
12108
+ const u = starknet.cairo.uint256(a.totalPrice);
12109
+ const approve = {
12110
+ contractAddress: a.paymentToken,
12111
+ entrypoint: "approve",
12112
+ calldata: [cfg.marketplace1155Contract, u.low.toString(), u.high.toString()]
12113
+ };
12114
+ const fulfill = contractFor2(cfg).populate("fulfill_order", [a.orderHash, a.quantity]);
12115
+ const fee = buildFeeCall(
12116
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
12117
+ cfg.feeConfig
12118
+ );
12119
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
12120
+ }
12121
+ function buildCancel1155Calls(a, cfg) {
12122
+ const cancelPayload = stringifyBigInts({
12123
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
12124
+ signature: a.signature
12125
+ });
12126
+ return [contractFor2(cfg).populate("cancel_order", [cancelPayload])];
12127
+ }
12128
+ function buildCancel1155TypedData(orderHash, offerer, cfg) {
12129
+ return stringifyBigInts(
12130
+ build1155CancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg))
12131
+ );
12132
+ }
12133
+
12134
+ // src/starknet/marketplace1155/orders.ts
12021
12135
  var _contractCache2 = /* @__PURE__ */ new WeakMap();
12022
12136
  function getContract(config) {
12023
12137
  let c = _contractCache2.get(config);
12024
12138
  if (!c) {
12025
12139
  const provider = getProvider(config);
12026
- c = new starknet.Contract(
12027
- Medialane1155ABI,
12028
- config.marketplace1155Contract,
12029
- provider
12030
- );
12140
+ c = newContract(Medialane1155ABI, config.marketplace1155Contract, provider);
12031
12141
  _contractCache2.set(config, c);
12032
12142
  }
12033
12143
  return c;
@@ -12046,53 +12156,27 @@ async function createListing1155(account, params, config) {
12046
12156
  const token = resolveToken(currency);
12047
12157
  const priceWei = parseAmount(pricePerUnit, token.decimals);
12048
12158
  const now = Math.floor(Date.now() / 1e3);
12159
+ const startTime = now + START_TIME_BUFFER_SECS;
12049
12160
  const endTime = now + durationSeconds;
12050
- const chainId = getChainId(config);
12051
12161
  const counter = (await contract.get_counter(account.address)).toString();
12052
12162
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
12053
- const orderParams = {
12054
- offerer: account.address,
12055
- marketplace: config.marketplace1155Contract,
12056
- offer: {
12057
- item_type: "ERC1155",
12058
- token: nftContract,
12059
- identifier_or_criteria: tokenId,
12060
- amount
12061
- // ERC-1155 leg amount = unit quantity
12062
- },
12063
- consideration: {
12064
- item_type: "ERC20",
12065
- token: token.address,
12066
- identifier_or_criteria: "0",
12067
- amount: priceWei,
12068
- // payment leg amount = price PER UNIT
12069
- recipient: account.address
12163
+ const { orderParams, typedData } = buildListing1155Order(
12164
+ {
12165
+ offerer: account.address,
12166
+ nftContract,
12167
+ tokenId,
12168
+ quantity: amount,
12169
+ priceWeiPerUnit: priceWei,
12170
+ paymentTokenAddress: token.address,
12171
+ royaltyMaxBps,
12172
+ startTime,
12173
+ endTime,
12174
+ salt: generateSalt(),
12175
+ counter
12070
12176
  },
12071
- royalty_max_bps: royaltyMaxBps,
12072
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
12073
- end_time: endTime.toString(),
12074
- salt: generateSalt(),
12075
- counter
12076
- };
12077
- const typedData = stringifyBigInts(
12078
- build1155OrderTypedData(orderParams, chainId)
12177
+ config
12079
12178
  );
12080
- const signature = await account.signMessage(typedData);
12081
- const signatureArray = toSignatureArray(signature);
12082
- const orderPayload = stringifyBigInts({
12083
- parameters: {
12084
- ...orderParams,
12085
- offer: {
12086
- ...orderParams.offer,
12087
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
12088
- },
12089
- consideration: {
12090
- ...orderParams.consideration,
12091
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
12092
- }
12093
- },
12094
- signature: signatureArray
12095
- });
12179
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
12096
12180
  let isApproved = false;
12097
12181
  try {
12098
12182
  const result = await provider.callContract({
@@ -12103,15 +12187,15 @@ async function createListing1155(account, params, config) {
12103
12187
  isApproved = BigInt(result[0]) === 1n;
12104
12188
  } catch {
12105
12189
  }
12106
- const registerCall = contract.populate("register_order", [orderPayload]);
12107
- const calls = isApproved ? [registerCall] : [
12108
- {
12109
- contractAddress: nftContract,
12110
- entrypoint: "set_approval_for_all",
12111
- calldata: [config.marketplace1155Contract, "1"]
12112
- },
12113
- registerCall
12114
- ];
12190
+ const approve = {
12191
+ contractAddress: nftContract,
12192
+ entrypoint: "set_approval_for_all",
12193
+ calldata: [config.marketplace1155Contract, "1"]
12194
+ };
12195
+ const calls = buildRegister1155Calls(
12196
+ { orderParams, signature: signatureArray, approvalNeeded: !isApproved, approve },
12197
+ config
12198
+ );
12115
12199
  try {
12116
12200
  const tx = await account.execute(calls);
12117
12201
  await provider.waitForTransaction(tx.transaction_hash);
@@ -12122,21 +12206,10 @@ async function createListing1155(account, params, config) {
12122
12206
  }
12123
12207
  async function fulfillOrder1155(account, params, config) {
12124
12208
  const { orderHash, paymentToken, totalPrice, quantity = "1" } = params;
12125
- const contract = getContract(config);
12126
12209
  const provider = getProvider(config);
12127
- const totalPriceU256 = starknet.cairo.uint256(totalPrice);
12128
- const approveCall = {
12129
- contractAddress: paymentToken,
12130
- entrypoint: "approve",
12131
- calldata: [
12132
- config.marketplace1155Contract,
12133
- totalPriceU256.low.toString(),
12134
- totalPriceU256.high.toString()
12135
- ]
12136
- };
12137
- const fulfillCall = contract.populate("fulfill_order", [orderHash, quantity]);
12210
+ const calls = buildFulfill1155Calls({ orderHash, paymentToken, totalPrice, quantity }, config);
12138
12211
  try {
12139
- const tx = await account.execute([approveCall, fulfillCall]);
12212
+ const tx = await account.execute(calls);
12140
12213
  await provider.waitForTransaction(tx.transaction_hash);
12141
12214
  return { txHash: tx.transaction_hash };
12142
12215
  } catch (err) {
@@ -12145,25 +12218,12 @@ async function fulfillOrder1155(account, params, config) {
12145
12218
  }
12146
12219
  async function cancelOrder1155(account, params, config) {
12147
12220
  const { orderHash } = params;
12148
- const contract = getContract(config);
12149
12221
  const provider = getProvider(config);
12150
- const chainId = getChainId(config);
12151
- const cancelParams = {
12152
- order_hash: orderHash,
12153
- offerer: account.address
12154
- };
12155
- const typedData = stringifyBigInts(
12156
- build1155CancellationTypedData(cancelParams, chainId)
12157
- );
12158
- const signature = await account.signMessage(typedData);
12159
- const signatureArray = toSignatureArray(signature);
12160
- const cancelPayload = stringifyBigInts({
12161
- cancelation: cancelParams,
12162
- signature: signatureArray
12163
- });
12164
- const cancelCall = contract.populate("cancel_order", [cancelPayload]);
12222
+ const typedData = buildCancel1155TypedData(orderHash, account.address, config);
12223
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
12224
+ const calls = buildCancel1155Calls({ orderHash, offerer: account.address, signature: signatureArray }, config);
12165
12225
  try {
12166
- const tx = await account.execute(cancelCall);
12226
+ const tx = await account.execute(calls);
12167
12227
  await provider.waitForTransaction(tx.transaction_hash);
12168
12228
  return { txHash: tx.transaction_hash };
12169
12229
  } catch (err) {
@@ -12181,56 +12241,30 @@ async function makeOffer1155(account, params, config) {
12181
12241
  } = params;
12182
12242
  const contract = getContract(config);
12183
12243
  const provider = getProvider(config);
12184
- const chainId = getChainId(config);
12185
12244
  const token = resolveToken(currency);
12186
12245
  const priceWei = parseAmount(price, token.decimals);
12187
12246
  const now = Math.floor(Date.now() / 1e3);
12247
+ const startTime = now + START_TIME_BUFFER_SECS;
12188
12248
  const endTime = now + durationSeconds;
12189
12249
  const counter = (await contract.get_counter(account.address)).toString();
12190
12250
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
12191
- const orderParams = {
12192
- offerer: account.address,
12193
- marketplace: config.marketplace1155Contract,
12194
- offer: {
12195
- item_type: "ERC20",
12196
- token: token.address,
12197
- identifier_or_criteria: "0",
12198
- amount: priceWei
12199
- // price PER UNIT
12200
- },
12201
- consideration: {
12202
- item_type: "ERC1155",
12203
- token: nftContract,
12204
- identifier_or_criteria: tokenId,
12205
- amount,
12206
- // unit quantity
12207
- recipient: account.address
12251
+ const { orderParams, typedData } = buildOffer1155Order(
12252
+ {
12253
+ offerer: account.address,
12254
+ nftContract,
12255
+ tokenId,
12256
+ quantity: amount,
12257
+ priceWeiPerUnit: priceWei,
12258
+ paymentTokenAddress: token.address,
12259
+ royaltyMaxBps,
12260
+ startTime,
12261
+ endTime,
12262
+ salt: generateSalt(),
12263
+ counter
12208
12264
  },
12209
- royalty_max_bps: royaltyMaxBps,
12210
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
12211
- end_time: endTime.toString(),
12212
- salt: generateSalt(),
12213
- counter
12214
- };
12215
- const typedData = stringifyBigInts(
12216
- build1155OrderTypedData(orderParams, chainId)
12265
+ config
12217
12266
  );
12218
- const signature = await account.signMessage(typedData);
12219
- const signatureArray = toSignatureArray(signature);
12220
- const registerPayload = stringifyBigInts({
12221
- parameters: {
12222
- ...orderParams,
12223
- offer: {
12224
- ...orderParams.offer,
12225
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
12226
- },
12227
- consideration: {
12228
- ...orderParams.consideration,
12229
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
12230
- }
12231
- },
12232
- signature: signatureArray
12233
- });
12267
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
12234
12268
  const totalWei = BigInt(priceWei) * BigInt(amount);
12235
12269
  const amountU256 = starknet.cairo.uint256(totalWei.toString());
12236
12270
  const approveCall = {
@@ -12242,9 +12276,12 @@ async function makeOffer1155(account, params, config) {
12242
12276
  amountU256.high.toString()
12243
12277
  ]
12244
12278
  };
12245
- const registerCall = contract.populate("register_order", [registerPayload]);
12279
+ const calls = buildRegister1155Calls(
12280
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
12281
+ config
12282
+ );
12246
12283
  try {
12247
- const tx = await account.execute([approveCall, registerCall]);
12284
+ const tx = await account.execute(calls);
12248
12285
  await provider.waitForTransaction(tx.transaction_hash);
12249
12286
  return { txHash: tx.transaction_hash };
12250
12287
  } catch (err) {
@@ -13116,94 +13153,147 @@ var StarknetVenue = class {
13116
13153
  constructor(deps) {
13117
13154
  this.deps = deps;
13118
13155
  this.chain = "STARKNET";
13119
- this.m721 = new MarketplaceModule(deps.config);
13120
- this.m1155 = new Medialane1155Module(deps.config);
13121
13156
  }
13122
- incrementCounter(signer) {
13123
- return this.m721.incrementCounter(signer);
13157
+ async incrementCounter(signer) {
13158
+ return signer.execute([
13159
+ { contractAddress: this.deps.config.marketplaceContract, entrypoint: "increment_counter", calldata: [] }
13160
+ ]);
13124
13161
  }
13125
13162
  getOrderDetails(orderRef) {
13126
- return this.m721.getOrderDetails(orderRef);
13163
+ return getOrderDetails(orderRef, this.deps.config);
13127
13164
  }
13128
- getCounter(address) {
13129
- return this.m721.getCounter(address);
13165
+ async getCounter(address) {
13166
+ return this.readCounter(this.deps.config.marketplaceContract, address);
13130
13167
  }
13131
13168
  async fulfillOrder(signer, orderRef, opts) {
13132
13169
  const o = await this.deps.resolveOrder(orderRef);
13133
13170
  const quantity = opts?.quantity ?? "1";
13134
13171
  const totalPrice = (BigInt(o.unitPrice) * BigInt(quantity)).toString();
13135
- if (o.standard === "ERC1155") {
13136
- return this.m1155.fulfillOrder(signer, {
13137
- orderHash: orderRef,
13138
- paymentToken: o.paymentToken,
13139
- totalPrice,
13140
- quantity
13141
- });
13142
- }
13143
- return this.m721.fulfillOrder(signer, {
13144
- orderHash: orderRef,
13145
- paymentToken: o.paymentToken,
13146
- totalPrice
13147
- });
13172
+ 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);
13173
+ return signer.execute(calls);
13148
13174
  }
13149
13175
  async cancelOrder(signer, orderRef) {
13150
13176
  const o = await this.deps.resolveOrder(orderRef);
13151
- if (o.standard === "ERC1155") {
13152
- return this.m1155.cancelOrder(signer, { orderHash: orderRef });
13153
- }
13154
- return this.m721.cancelOrder(signer, { orderHash: orderRef });
13177
+ const typedData = o.standard === "ERC1155" ? buildCancel1155TypedData(orderRef, signer.address, this.deps.config) : buildCancelTypedData(orderRef, signer.address, this.deps.config);
13178
+ const signature = await signer.signTypedData(typedData);
13179
+ 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);
13180
+ return signer.execute(calls);
13155
13181
  }
13156
13182
  async registerOrder(signer, p) {
13157
13183
  const standard = await this.deps.resolveStandard(p.asset.contract);
13158
- const token = resolveToken(p.paymentToken);
13159
- const humanPrice = formatAmount(p.amount, token.decimals);
13160
- const durationSeconds = this.durationSeconds(p.endTime);
13184
+ const paymentTokenAddress = resolveToken(p.paymentToken).address;
13161
13185
  const royaltyMaxBps = String(p.royaltyMaxBps);
13186
+ const startTime = Math.floor(Date.now() / 1e3) + START_TIME_BUFFER_SECS;
13187
+ const endTime = p.endTime && p.endTime > 0 ? p.endTime : startTime + NO_EXPIRY_SECONDS;
13162
13188
  const quantity = p.quantity ?? "1";
13163
- let txHash;
13189
+ const marketplace = standard === "ERC1155" ? this.deps.config.marketplace1155Contract : this.deps.config.marketplaceContract;
13190
+ const counter = String(await this.readCounter(marketplace, signer.address));
13191
+ let typedData;
13192
+ let buildCalls;
13164
13193
  if (standard === "ERC1155") {
13165
- if (p.side === "listing") {
13166
- const res = await this.m1155.createListing(signer, {
13194
+ const built = (p.side === "listing" ? buildListing1155Order : buildOffer1155Order)(
13195
+ {
13196
+ offerer: signer.address,
13167
13197
  nftContract: p.asset.contract,
13168
13198
  tokenId: p.asset.tokenId,
13169
- amount: quantity,
13170
- pricePerUnit: humanPrice,
13171
- currency: p.paymentToken,
13172
- durationSeconds,
13173
- royaltyMaxBps
13174
- });
13175
- txHash = res.txHash;
13176
- } else {
13177
- const totalHuman = formatAmount((BigInt(p.amount) * BigInt(quantity)).toString(), token.decimals);
13178
- const res = await this.m1155.makeOffer(signer, {
13199
+ quantity,
13200
+ priceWeiPerUnit: p.amount,
13201
+ paymentTokenAddress,
13202
+ royaltyMaxBps,
13203
+ startTime,
13204
+ endTime,
13205
+ salt: p.salt,
13206
+ counter
13207
+ },
13208
+ this.deps.config
13209
+ );
13210
+ typedData = built.typedData;
13211
+ const approval = p.side === "listing" ? await this.approval1155ForListing(signer.address, p.asset.contract) : this.approvalForErc20(paymentTokenAddress, (BigInt(p.amount) * BigInt(quantity)).toString(), marketplace);
13212
+ buildCalls = (sig) => buildRegister1155Calls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
13213
+ } else {
13214
+ const built = (p.side === "listing" ? buildListingOrder : buildOfferOrder)(
13215
+ {
13216
+ offerer: signer.address,
13179
13217
  nftContract: p.asset.contract,
13180
13218
  tokenId: p.asset.tokenId,
13181
- amount: quantity,
13182
- price: totalHuman,
13183
- currency: p.paymentToken,
13184
- durationSeconds,
13185
- royaltyMaxBps
13186
- });
13187
- txHash = res.txHash;
13188
- }
13189
- } else {
13190
- const params = {
13191
- nftContract: p.asset.contract,
13192
- tokenId: p.asset.tokenId,
13193
- price: humanPrice,
13194
- currency: p.paymentToken,
13195
- durationSeconds,
13196
- royaltyMaxBps
13197
- };
13198
- const res = p.side === "listing" ? await this.m721.createListing(signer, params) : await this.m721.makeOffer(signer, params);
13199
- txHash = res.txHash;
13219
+ priceWei: p.amount,
13220
+ paymentTokenAddress,
13221
+ royaltyMaxBps,
13222
+ startTime,
13223
+ endTime,
13224
+ salt: p.salt,
13225
+ counter
13226
+ },
13227
+ this.deps.config
13228
+ );
13229
+ typedData = built.typedData;
13230
+ const approval = p.side === "listing" ? await this.approval721ForListing(signer.address, p.asset.contract, p.asset.tokenId) : this.approvalForErc20(paymentTokenAddress, p.amount, marketplace);
13231
+ buildCalls = (sig) => buildRegisterCalls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
13200
13232
  }
13233
+ const signature = await signer.signTypedData(typedData);
13234
+ const { txHash } = await signer.execute(buildCalls(signature));
13201
13235
  const orderRef = await this.orderRefFromReceipt(txHash);
13202
13236
  return { txHash, orderRef };
13203
13237
  }
13204
- durationSeconds(endTime) {
13205
- if (!endTime) return NO_EXPIRY_SECONDS;
13206
- return Math.max(1, endTime - Math.floor(Date.now() / 1e3));
13238
+ // ─── reads (all on deps.provider) ─────────────────────────────────────────
13239
+ async readCounter(marketplace, address) {
13240
+ const res = await this.deps.provider.callContract({
13241
+ contractAddress: marketplace,
13242
+ entrypoint: "get_counter",
13243
+ calldata: [address]
13244
+ });
13245
+ return BigInt(res[0] ?? "0");
13246
+ }
13247
+ /** 721 listing approval: `get_approved(tokenId) == marketplace` ⇒ no approve. */
13248
+ async approval721ForListing(_owner, nftContract, tokenId) {
13249
+ const id = starknet.cairo.uint256(tokenId);
13250
+ const approve = {
13251
+ contractAddress: nftContract,
13252
+ entrypoint: "approve",
13253
+ calldata: [this.deps.config.marketplaceContract, id.low.toString(), id.high.toString()]
13254
+ };
13255
+ let approved = false;
13256
+ try {
13257
+ const res = await this.deps.provider.callContract({
13258
+ contractAddress: nftContract,
13259
+ entrypoint: "get_approved",
13260
+ calldata: [id.low.toString(), id.high.toString()]
13261
+ });
13262
+ approved = BigInt(res[0]).toString() === BigInt(this.deps.config.marketplaceContract).toString();
13263
+ } catch {
13264
+ }
13265
+ return { approvalNeeded: !approved, approve };
13266
+ }
13267
+ /** 1155 listing approval: `is_approved_for_all(owner, marketplace)`. */
13268
+ async approval1155ForListing(owner, nftContract) {
13269
+ const approve = {
13270
+ contractAddress: nftContract,
13271
+ entrypoint: "set_approval_for_all",
13272
+ calldata: [this.deps.config.marketplace1155Contract, "1"]
13273
+ };
13274
+ let approved = false;
13275
+ try {
13276
+ const res = await this.deps.provider.callContract({
13277
+ contractAddress: nftContract,
13278
+ entrypoint: "is_approved_for_all",
13279
+ calldata: [owner, this.deps.config.marketplace1155Contract]
13280
+ });
13281
+ approved = BigInt(res[0]) === 1n;
13282
+ } catch {
13283
+ }
13284
+ return { approvalNeeded: !approved, approve };
13285
+ }
13286
+ /** Offers always approve the ERC-20 spend (no read). */
13287
+ approvalForErc20(token, amountWei, marketplace) {
13288
+ const u = starknet.cairo.uint256(amountWei);
13289
+ return {
13290
+ approvalNeeded: true,
13291
+ approve: {
13292
+ contractAddress: token,
13293
+ entrypoint: "approve",
13294
+ calldata: [marketplace, u.low.toString(), u.high.toString()]
13295
+ }
13296
+ };
13207
13297
  }
13208
13298
  /** The canonical Starknet order id = the contract-emitted `OrderCreated`
13209
13299
  * hash (`keys[1]`), which is exactly what the indexer stores. */