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