@medialane/sdk 0.59.0 → 0.60.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.
@@ -10488,39 +10488,12 @@ var SUPPORTED_TOKENS = [
10488
10488
  ];
10489
10489
  var DEFAULT_CURRENCY = "USDC";
10490
10490
 
10491
- // src/utils/bigint.ts
10492
- function stringifyBigInts(obj) {
10493
- if (typeof obj === "bigint") {
10494
- return obj.toString();
10495
- }
10496
- if (Array.isArray(obj)) {
10497
- return obj.map(stringifyBigInts);
10498
- }
10499
- if (obj !== null && typeof obj === "object") {
10500
- return Object.fromEntries(
10501
- Object.entries(obj).map(([key, value]) => [
10502
- key,
10503
- stringifyBigInts(value)
10504
- ])
10505
- );
10506
- }
10507
- return obj;
10508
- }
10509
-
10510
10491
  // src/utils/token.ts
10511
10492
  function parseAmount(human, decimals) {
10512
10493
  const [whole, frac = ""] = human.split(".");
10513
10494
  const fracPadded = frac.padEnd(decimals, "0").slice(0, decimals);
10514
10495
  return (BigInt(whole) * BigInt(10) ** BigInt(decimals) + BigInt(fracPadded)).toString();
10515
10496
  }
10516
- function formatAmount(raw, decimals) {
10517
- const value = BigInt(raw);
10518
- const factor = BigInt(Math.pow(10, decimals));
10519
- const whole = value / factor;
10520
- const remainder = value % factor;
10521
- const fractional = remainder.toString().padStart(decimals, "0");
10522
- return `${whole}.${fractional}`;
10523
- }
10524
10497
  function getTokenByAddress(address) {
10525
10498
  const lower = address.toLowerCase();
10526
10499
  return SUPPORTED_TOKENS.find((t) => t.address.toLowerCase() === lower);
@@ -10549,6 +10522,25 @@ function buildFeeCall(p, cfg) {
10549
10522
  };
10550
10523
  }
10551
10524
 
10525
+ // src/utils/bigint.ts
10526
+ function stringifyBigInts(obj) {
10527
+ if (typeof obj === "bigint") {
10528
+ return obj.toString();
10529
+ }
10530
+ if (Array.isArray(obj)) {
10531
+ return obj.map(stringifyBigInts);
10532
+ }
10533
+ if (obj !== null && typeof obj === "object") {
10534
+ return Object.fromEntries(
10535
+ Object.entries(obj).map(([key, value]) => [
10536
+ key,
10537
+ stringifyBigInts(value)
10538
+ ])
10539
+ );
10540
+ }
10541
+ return obj;
10542
+ }
10543
+
10552
10544
  // src/utils/rpc.ts
10553
10545
  var PUBLIC_RPC_FALLBACKS = [
10554
10546
  "https://rpc.starknet.lava.build"
@@ -10653,6 +10645,94 @@ function getProvider(config) {
10653
10645
  return p;
10654
10646
  }
10655
10647
 
10648
+ // src/starknet/marketplace/build.ts
10649
+ function contractFor(cfg) {
10650
+ return new starknet.Contract(IPMarketplaceABI, cfg.marketplaceContract, getProvider(cfg));
10651
+ }
10652
+ function buildListingOrder(i, cfg) {
10653
+ const orderParams = {
10654
+ offerer: i.offerer,
10655
+ marketplace: cfg.marketplaceContract,
10656
+ offer: { item_type: "ERC721", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: "1" },
10657
+ consideration: {
10658
+ item_type: "ERC20",
10659
+ token: i.paymentTokenAddress,
10660
+ identifier_or_criteria: "0",
10661
+ amount: i.priceWei,
10662
+ recipient: i.offerer
10663
+ },
10664
+ royalty_max_bps: i.royaltyMaxBps,
10665
+ start_time: String(i.startTime),
10666
+ end_time: String(i.endTime),
10667
+ salt: i.salt,
10668
+ counter: i.counter
10669
+ };
10670
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
10671
+ return { orderParams, typedData };
10672
+ }
10673
+ function buildOfferOrder(i, cfg) {
10674
+ const orderParams = {
10675
+ offerer: i.offerer,
10676
+ marketplace: cfg.marketplaceContract,
10677
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWei },
10678
+ consideration: {
10679
+ item_type: "ERC721",
10680
+ token: i.nftContract,
10681
+ identifier_or_criteria: i.tokenId,
10682
+ amount: "1",
10683
+ recipient: i.offerer
10684
+ },
10685
+ royalty_max_bps: i.royaltyMaxBps,
10686
+ start_time: String(i.startTime),
10687
+ end_time: String(i.endTime),
10688
+ salt: i.salt,
10689
+ counter: i.counter
10690
+ };
10691
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
10692
+ return { orderParams, typedData };
10693
+ }
10694
+ function registerPayload(orderParams, signature) {
10695
+ return stringifyBigInts({
10696
+ parameters: {
10697
+ ...orderParams,
10698
+ offer: { ...orderParams.offer, item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type) },
10699
+ consideration: {
10700
+ ...orderParams.consideration,
10701
+ item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
10702
+ }
10703
+ },
10704
+ signature
10705
+ });
10706
+ }
10707
+ function buildRegisterCalls(a, cfg) {
10708
+ const registerCall = contractFor(cfg).populate("register_order", [registerPayload(a.orderParams, a.signature)]);
10709
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
10710
+ }
10711
+ function buildFulfillCalls(a, cfg) {
10712
+ const u = starknet.cairo.uint256(a.totalPrice);
10713
+ const approve = {
10714
+ contractAddress: a.paymentToken,
10715
+ entrypoint: "approve",
10716
+ calldata: [cfg.marketplaceContract, u.low.toString(), u.high.toString()]
10717
+ };
10718
+ const fulfill = contractFor(cfg).populate("fulfill_order", [a.orderHash]);
10719
+ const fee = buildFeeCall(
10720
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
10721
+ cfg.feeConfig
10722
+ );
10723
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
10724
+ }
10725
+ function buildCancelCalls(a, cfg) {
10726
+ const cancelRequest = stringifyBigInts({
10727
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
10728
+ signature: a.signature
10729
+ });
10730
+ return [contractFor(cfg).populate("cancel_order", [cancelRequest])];
10731
+ }
10732
+ function buildCancelTypedData(orderHash, offerer, cfg) {
10733
+ return stringifyBigInts(buildCancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg)));
10734
+ }
10735
+
10656
10736
  // src/starknet/marketplace/orders.ts
10657
10737
  var _contractCache = /* @__PURE__ */ new WeakMap();
10658
10738
  function makeContract(config) {
@@ -10677,46 +10757,22 @@ async function createListing(account, params, config) {
10677
10757
  const endTime = now + durationSeconds;
10678
10758
  const counter = (await contract.get_counter(account.address)).toString();
10679
10759
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
10680
- const orderParams = {
10681
- offerer: account.address,
10682
- marketplace: config.marketplaceContract,
10683
- offer: {
10684
- item_type: "ERC721",
10685
- token: nftContract,
10686
- identifier_or_criteria: tokenId,
10687
- amount: "1"
10688
- },
10689
- consideration: {
10690
- item_type: "ERC20",
10691
- token: token.address,
10692
- identifier_or_criteria: "0",
10693
- amount: priceWei,
10694
- recipient: account.address
10695
- },
10696
- royalty_max_bps: royaltyMaxBps,
10697
- start_time: startTime.toString(),
10698
- end_time: endTime.toString(),
10699
- salt: generateSalt(),
10700
- counter
10701
- };
10702
- const chainId = getChainId(config);
10703
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
10704
- const signature = await account.signMessage(typedData);
10705
- const signatureArray = toSignatureArray(signature);
10706
- const registerPayload = stringifyBigInts({
10707
- parameters: {
10708
- ...orderParams,
10709
- offer: {
10710
- ...orderParams.offer,
10711
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
10712
- },
10713
- consideration: {
10714
- ...orderParams.consideration,
10715
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
10716
- }
10760
+ const { orderParams, typedData } = buildListingOrder(
10761
+ {
10762
+ offerer: account.address,
10763
+ nftContract,
10764
+ tokenId,
10765
+ priceWei,
10766
+ paymentTokenAddress: token.address,
10767
+ royaltyMaxBps,
10768
+ startTime,
10769
+ endTime,
10770
+ salt: generateSalt(),
10771
+ counter
10717
10772
  },
10718
- signature: signatureArray
10719
- });
10773
+ config
10774
+ );
10775
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
10720
10776
  const tokenIdUint256 = starknet.cairo.uint256(tokenId);
10721
10777
  let isAlreadyApproved = false;
10722
10778
  try {
@@ -10728,19 +10784,19 @@ async function createListing(account, params, config) {
10728
10784
  isAlreadyApproved = BigInt(result[0]).toString() === BigInt(config.marketplaceContract).toString();
10729
10785
  } catch {
10730
10786
  }
10731
- const registerCall = contract.populate("register_order", [registerPayload]);
10732
- const calls = isAlreadyApproved ? [registerCall] : [
10733
- {
10734
- contractAddress: nftContract,
10735
- entrypoint: "approve",
10736
- calldata: [
10737
- config.marketplaceContract,
10738
- tokenIdUint256.low.toString(),
10739
- tokenIdUint256.high.toString()
10740
- ]
10741
- },
10742
- registerCall
10743
- ];
10787
+ const approve = {
10788
+ contractAddress: nftContract,
10789
+ entrypoint: "approve",
10790
+ calldata: [
10791
+ config.marketplaceContract,
10792
+ tokenIdUint256.low.toString(),
10793
+ tokenIdUint256.high.toString()
10794
+ ]
10795
+ };
10796
+ const calls = buildRegisterCalls(
10797
+ { orderParams, signature: signatureArray, approvalNeeded: !isAlreadyApproved, approve },
10798
+ config
10799
+ );
10744
10800
  try {
10745
10801
  const tx = await account.execute(calls);
10746
10802
  await provider.waitForTransaction(tx.transaction_hash);
@@ -10759,46 +10815,22 @@ async function makeOffer(account, params, config) {
10759
10815
  const endTime = now + durationSeconds;
10760
10816
  const counter = (await contract.get_counter(account.address)).toString();
10761
10817
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
10762
- const orderParams = {
10763
- offerer: account.address,
10764
- marketplace: config.marketplaceContract,
10765
- offer: {
10766
- item_type: "ERC20",
10767
- token: token.address,
10768
- identifier_or_criteria: "0",
10769
- amount: priceWei
10770
- },
10771
- consideration: {
10772
- item_type: "ERC721",
10773
- token: nftContract,
10774
- identifier_or_criteria: tokenId,
10775
- amount: "1",
10776
- recipient: account.address
10777
- },
10778
- royalty_max_bps: royaltyMaxBps,
10779
- start_time: startTime.toString(),
10780
- end_time: endTime.toString(),
10781
- salt: generateSalt(),
10782
- counter
10783
- };
10784
- const chainId = getChainId(config);
10785
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
10786
- const signature = await account.signMessage(typedData);
10787
- const signatureArray = toSignatureArray(signature);
10788
- const registerPayload = stringifyBigInts({
10789
- parameters: {
10790
- ...orderParams,
10791
- offer: {
10792
- ...orderParams.offer,
10793
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
10794
- },
10795
- consideration: {
10796
- ...orderParams.consideration,
10797
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
10798
- }
10818
+ const { orderParams, typedData } = buildOfferOrder(
10819
+ {
10820
+ offerer: account.address,
10821
+ nftContract,
10822
+ tokenId,
10823
+ priceWei,
10824
+ paymentTokenAddress: token.address,
10825
+ royaltyMaxBps,
10826
+ startTime,
10827
+ endTime,
10828
+ salt: generateSalt(),
10829
+ counter
10799
10830
  },
10800
- signature: signatureArray
10801
- });
10831
+ config
10832
+ );
10833
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
10802
10834
  const amountUint256 = starknet.cairo.uint256(priceWei);
10803
10835
  const approveCall = {
10804
10836
  contractAddress: token.address,
@@ -10809,9 +10841,12 @@ async function makeOffer(account, params, config) {
10809
10841
  amountUint256.high.toString()
10810
10842
  ]
10811
10843
  };
10812
- const registerCall = contract.populate("register_order", [registerPayload]);
10844
+ const calls = buildRegisterCalls(
10845
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
10846
+ config
10847
+ );
10813
10848
  try {
10814
- const tx = await account.execute([approveCall, registerCall]);
10849
+ const tx = await account.execute(calls);
10815
10850
  await provider.waitForTransaction(tx.transaction_hash);
10816
10851
  return { txHash: tx.transaction_hash };
10817
10852
  } catch (err) {
@@ -10820,23 +10855,8 @@ async function makeOffer(account, params, config) {
10820
10855
  }
10821
10856
  async function fulfillOrder(account, params, config) {
10822
10857
  const { orderHash, paymentToken, totalPrice } = params;
10823
- const { contract, provider } = makeContract(config);
10824
- const totalPriceU256 = starknet.cairo.uint256(totalPrice);
10825
- const approveCall = {
10826
- contractAddress: paymentToken,
10827
- entrypoint: "approve",
10828
- calldata: [
10829
- config.marketplaceContract,
10830
- totalPriceU256.low.toString(),
10831
- totalPriceU256.high.toString()
10832
- ]
10833
- };
10834
- const fulfillCall = contract.populate("fulfill_order", [orderHash]);
10835
- const feeCall = buildFeeCall(
10836
- { surface: "marketplace", token: paymentToken, grossAmount: BigInt(totalPrice) },
10837
- config.feeConfig
10838
- );
10839
- const calls = feeCall ? [approveCall, fulfillCall, feeCall] : [approveCall, fulfillCall];
10858
+ const { provider } = makeContract(config);
10859
+ const calls = buildFulfillCalls({ orderHash, paymentToken, totalPrice }, config);
10840
10860
  try {
10841
10861
  const tx = await account.execute(calls);
10842
10862
  await provider.waitForTransaction(tx.transaction_hash);
@@ -10847,24 +10867,12 @@ async function fulfillOrder(account, params, config) {
10847
10867
  }
10848
10868
  async function cancelOrder(account, params, config) {
10849
10869
  const { orderHash } = params;
10850
- const { contract, provider } = makeContract(config);
10851
- const chainId = getChainId(config);
10852
- const cancelParams = {
10853
- order_hash: orderHash,
10854
- offerer: account.address
10855
- };
10856
- const typedData = stringifyBigInts(
10857
- buildCancellationTypedData(cancelParams, chainId)
10858
- );
10859
- const signature = await account.signMessage(typedData);
10860
- const signatureArray = toSignatureArray(signature);
10861
- const cancelRequest = stringifyBigInts({
10862
- cancelation: cancelParams,
10863
- signature: signatureArray
10864
- });
10865
- const call = contract.populate("cancel_order", [cancelRequest]);
10870
+ const { provider } = makeContract(config);
10871
+ const typedData = buildCancelTypedData(orderHash, account.address, config);
10872
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
10873
+ const calls = buildCancelCalls({ orderHash, offerer: account.address, signature: signatureArray }, config);
10866
10874
  try {
10867
- const tx = await account.execute(call);
10875
+ const tx = await account.execute(calls);
10868
10876
  await provider.waitForTransaction(tx.transaction_hash);
10869
10877
  return { txHash: tx.transaction_hash };
10870
10878
  } catch (err) {
@@ -11011,6 +11019,100 @@ var MarketplaceModule = class {
11011
11019
  return buildCancellationTypedData(params, chainId);
11012
11020
  }
11013
11021
  };
11022
+ function contractFor2(cfg) {
11023
+ return new starknet.Contract(Medialane1155ABI, cfg.marketplace1155Contract, getProvider(cfg));
11024
+ }
11025
+ function buildListing1155Order(i, cfg) {
11026
+ const orderParams = {
11027
+ offerer: i.offerer,
11028
+ marketplace: cfg.marketplace1155Contract,
11029
+ offer: { item_type: "ERC1155", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: i.quantity },
11030
+ consideration: {
11031
+ item_type: "ERC20",
11032
+ token: i.paymentTokenAddress,
11033
+ identifier_or_criteria: "0",
11034
+ amount: i.priceWeiPerUnit,
11035
+ recipient: i.offerer
11036
+ },
11037
+ royalty_max_bps: i.royaltyMaxBps,
11038
+ start_time: String(i.startTime),
11039
+ end_time: String(i.endTime),
11040
+ salt: i.salt,
11041
+ counter: i.counter
11042
+ };
11043
+ const typedData = stringifyBigInts(
11044
+ build1155OrderTypedData(orderParams, getChainId(cfg))
11045
+ );
11046
+ return { orderParams, typedData };
11047
+ }
11048
+ function buildOffer1155Order(i, cfg) {
11049
+ const orderParams = {
11050
+ offerer: i.offerer,
11051
+ marketplace: cfg.marketplace1155Contract,
11052
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWeiPerUnit },
11053
+ consideration: {
11054
+ item_type: "ERC1155",
11055
+ token: i.nftContract,
11056
+ identifier_or_criteria: i.tokenId,
11057
+ amount: i.quantity,
11058
+ recipient: i.offerer
11059
+ },
11060
+ royalty_max_bps: i.royaltyMaxBps,
11061
+ start_time: String(i.startTime),
11062
+ end_time: String(i.endTime),
11063
+ salt: i.salt,
11064
+ counter: i.counter
11065
+ };
11066
+ const typedData = stringifyBigInts(
11067
+ build1155OrderTypedData(orderParams, getChainId(cfg))
11068
+ );
11069
+ return { orderParams, typedData };
11070
+ }
11071
+ function registerPayload2(orderParams, signature) {
11072
+ return stringifyBigInts({
11073
+ parameters: {
11074
+ ...orderParams,
11075
+ offer: { ...orderParams.offer, item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type) },
11076
+ consideration: {
11077
+ ...orderParams.consideration,
11078
+ item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11079
+ }
11080
+ },
11081
+ signature
11082
+ });
11083
+ }
11084
+ function buildRegister1155Calls(a, cfg) {
11085
+ const registerCall = contractFor2(cfg).populate("register_order", [registerPayload2(a.orderParams, a.signature)]);
11086
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
11087
+ }
11088
+ function buildFulfill1155Calls(a, cfg) {
11089
+ const u = starknet.cairo.uint256(a.totalPrice);
11090
+ const approve = {
11091
+ contractAddress: a.paymentToken,
11092
+ entrypoint: "approve",
11093
+ calldata: [cfg.marketplace1155Contract, u.low.toString(), u.high.toString()]
11094
+ };
11095
+ const fulfill = contractFor2(cfg).populate("fulfill_order", [a.orderHash, a.quantity]);
11096
+ const fee = buildFeeCall(
11097
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
11098
+ cfg.feeConfig
11099
+ );
11100
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
11101
+ }
11102
+ function buildCancel1155Calls(a, cfg) {
11103
+ const cancelPayload = stringifyBigInts({
11104
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
11105
+ signature: a.signature
11106
+ });
11107
+ return [contractFor2(cfg).populate("cancel_order", [cancelPayload])];
11108
+ }
11109
+ function buildCancel1155TypedData(orderHash, offerer, cfg) {
11110
+ return stringifyBigInts(
11111
+ build1155CancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg))
11112
+ );
11113
+ }
11114
+
11115
+ // src/starknet/marketplace1155/orders.ts
11014
11116
  var _contractCache2 = /* @__PURE__ */ new WeakMap();
11015
11117
  function getContract(config) {
11016
11118
  let c = _contractCache2.get(config);
@@ -11039,53 +11141,27 @@ async function createListing1155(account, params, config) {
11039
11141
  const token = resolveToken(currency);
11040
11142
  const priceWei = parseAmount(pricePerUnit, token.decimals);
11041
11143
  const now = Math.floor(Date.now() / 1e3);
11144
+ const startTime = now + START_TIME_BUFFER_SECS;
11042
11145
  const endTime = now + durationSeconds;
11043
- const chainId = getChainId(config);
11044
11146
  const counter = (await contract.get_counter(account.address)).toString();
11045
11147
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11046
- const orderParams = {
11047
- offerer: account.address,
11048
- marketplace: config.marketplace1155Contract,
11049
- offer: {
11050
- item_type: "ERC1155",
11051
- token: nftContract,
11052
- identifier_or_criteria: tokenId,
11053
- amount
11054
- // ERC-1155 leg amount = unit quantity
11055
- },
11056
- consideration: {
11057
- item_type: "ERC20",
11058
- token: token.address,
11059
- identifier_or_criteria: "0",
11060
- amount: priceWei,
11061
- // payment leg amount = price PER UNIT
11062
- recipient: account.address
11148
+ const { orderParams, typedData } = buildListing1155Order(
11149
+ {
11150
+ offerer: account.address,
11151
+ nftContract,
11152
+ tokenId,
11153
+ quantity: amount,
11154
+ priceWeiPerUnit: priceWei,
11155
+ paymentTokenAddress: token.address,
11156
+ royaltyMaxBps,
11157
+ startTime,
11158
+ endTime,
11159
+ salt: generateSalt(),
11160
+ counter
11063
11161
  },
11064
- royalty_max_bps: royaltyMaxBps,
11065
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
11066
- end_time: endTime.toString(),
11067
- salt: generateSalt(),
11068
- counter
11069
- };
11070
- const typedData = stringifyBigInts(
11071
- build1155OrderTypedData(orderParams, chainId)
11162
+ config
11072
11163
  );
11073
- const signature = await account.signMessage(typedData);
11074
- const signatureArray = toSignatureArray(signature);
11075
- const orderPayload = stringifyBigInts({
11076
- parameters: {
11077
- ...orderParams,
11078
- offer: {
11079
- ...orderParams.offer,
11080
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
11081
- },
11082
- consideration: {
11083
- ...orderParams.consideration,
11084
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11085
- }
11086
- },
11087
- signature: signatureArray
11088
- });
11164
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11089
11165
  let isApproved = false;
11090
11166
  try {
11091
11167
  const result = await provider.callContract({
@@ -11096,15 +11172,15 @@ async function createListing1155(account, params, config) {
11096
11172
  isApproved = BigInt(result[0]) === 1n;
11097
11173
  } catch {
11098
11174
  }
11099
- const registerCall = contract.populate("register_order", [orderPayload]);
11100
- const calls = isApproved ? [registerCall] : [
11101
- {
11102
- contractAddress: nftContract,
11103
- entrypoint: "set_approval_for_all",
11104
- calldata: [config.marketplace1155Contract, "1"]
11105
- },
11106
- registerCall
11107
- ];
11175
+ const approve = {
11176
+ contractAddress: nftContract,
11177
+ entrypoint: "set_approval_for_all",
11178
+ calldata: [config.marketplace1155Contract, "1"]
11179
+ };
11180
+ const calls = buildRegister1155Calls(
11181
+ { orderParams, signature: signatureArray, approvalNeeded: !isApproved, approve },
11182
+ config
11183
+ );
11108
11184
  try {
11109
11185
  const tx = await account.execute(calls);
11110
11186
  await provider.waitForTransaction(tx.transaction_hash);
@@ -11115,21 +11191,10 @@ async function createListing1155(account, params, config) {
11115
11191
  }
11116
11192
  async function fulfillOrder1155(account, params, config) {
11117
11193
  const { orderHash, paymentToken, totalPrice, quantity = "1" } = params;
11118
- const contract = getContract(config);
11119
11194
  const provider = getProvider(config);
11120
- const totalPriceU256 = starknet.cairo.uint256(totalPrice);
11121
- const approveCall = {
11122
- contractAddress: paymentToken,
11123
- entrypoint: "approve",
11124
- calldata: [
11125
- config.marketplace1155Contract,
11126
- totalPriceU256.low.toString(),
11127
- totalPriceU256.high.toString()
11128
- ]
11129
- };
11130
- const fulfillCall = contract.populate("fulfill_order", [orderHash, quantity]);
11195
+ const calls = buildFulfill1155Calls({ orderHash, paymentToken, totalPrice, quantity }, config);
11131
11196
  try {
11132
- const tx = await account.execute([approveCall, fulfillCall]);
11197
+ const tx = await account.execute(calls);
11133
11198
  await provider.waitForTransaction(tx.transaction_hash);
11134
11199
  return { txHash: tx.transaction_hash };
11135
11200
  } catch (err) {
@@ -11138,25 +11203,12 @@ async function fulfillOrder1155(account, params, config) {
11138
11203
  }
11139
11204
  async function cancelOrder1155(account, params, config) {
11140
11205
  const { orderHash } = params;
11141
- const contract = getContract(config);
11142
11206
  const provider = getProvider(config);
11143
- const chainId = getChainId(config);
11144
- const cancelParams = {
11145
- order_hash: orderHash,
11146
- offerer: account.address
11147
- };
11148
- const typedData = stringifyBigInts(
11149
- build1155CancellationTypedData(cancelParams, chainId)
11150
- );
11151
- const signature = await account.signMessage(typedData);
11152
- const signatureArray = toSignatureArray(signature);
11153
- const cancelPayload = stringifyBigInts({
11154
- cancelation: cancelParams,
11155
- signature: signatureArray
11156
- });
11157
- const cancelCall = contract.populate("cancel_order", [cancelPayload]);
11207
+ const typedData = buildCancel1155TypedData(orderHash, account.address, config);
11208
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11209
+ const calls = buildCancel1155Calls({ orderHash, offerer: account.address, signature: signatureArray }, config);
11158
11210
  try {
11159
- const tx = await account.execute(cancelCall);
11211
+ const tx = await account.execute(calls);
11160
11212
  await provider.waitForTransaction(tx.transaction_hash);
11161
11213
  return { txHash: tx.transaction_hash };
11162
11214
  } catch (err) {
@@ -11174,56 +11226,30 @@ async function makeOffer1155(account, params, config) {
11174
11226
  } = params;
11175
11227
  const contract = getContract(config);
11176
11228
  const provider = getProvider(config);
11177
- const chainId = getChainId(config);
11178
11229
  const token = resolveToken(currency);
11179
11230
  const priceWei = parseAmount(price, token.decimals);
11180
11231
  const now = Math.floor(Date.now() / 1e3);
11232
+ const startTime = now + START_TIME_BUFFER_SECS;
11181
11233
  const endTime = now + durationSeconds;
11182
11234
  const counter = (await contract.get_counter(account.address)).toString();
11183
11235
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
11184
- const orderParams = {
11185
- offerer: account.address,
11186
- marketplace: config.marketplace1155Contract,
11187
- offer: {
11188
- item_type: "ERC20",
11189
- token: token.address,
11190
- identifier_or_criteria: "0",
11191
- amount: priceWei
11192
- // price PER UNIT
11193
- },
11194
- consideration: {
11195
- item_type: "ERC1155",
11196
- token: nftContract,
11197
- identifier_or_criteria: tokenId,
11198
- amount,
11199
- // unit quantity
11200
- recipient: account.address
11236
+ const { orderParams, typedData } = buildOffer1155Order(
11237
+ {
11238
+ offerer: account.address,
11239
+ nftContract,
11240
+ tokenId,
11241
+ quantity: amount,
11242
+ priceWeiPerUnit: priceWei,
11243
+ paymentTokenAddress: token.address,
11244
+ royaltyMaxBps,
11245
+ startTime,
11246
+ endTime,
11247
+ salt: generateSalt(),
11248
+ counter
11201
11249
  },
11202
- royalty_max_bps: royaltyMaxBps,
11203
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
11204
- end_time: endTime.toString(),
11205
- salt: generateSalt(),
11206
- counter
11207
- };
11208
- const typedData = stringifyBigInts(
11209
- build1155OrderTypedData(orderParams, chainId)
11250
+ config
11210
11251
  );
11211
- const signature = await account.signMessage(typedData);
11212
- const signatureArray = toSignatureArray(signature);
11213
- const registerPayload = stringifyBigInts({
11214
- parameters: {
11215
- ...orderParams,
11216
- offer: {
11217
- ...orderParams.offer,
11218
- item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
11219
- },
11220
- consideration: {
11221
- ...orderParams.consideration,
11222
- item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
11223
- }
11224
- },
11225
- signature: signatureArray
11226
- });
11252
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
11227
11253
  const totalWei = BigInt(priceWei) * BigInt(amount);
11228
11254
  const amountU256 = starknet.cairo.uint256(totalWei.toString());
11229
11255
  const approveCall = {
@@ -11235,9 +11261,12 @@ async function makeOffer1155(account, params, config) {
11235
11261
  amountU256.high.toString()
11236
11262
  ]
11237
11263
  };
11238
- const registerCall = contract.populate("register_order", [registerPayload]);
11264
+ const calls = buildRegister1155Calls(
11265
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
11266
+ config
11267
+ );
11239
11268
  try {
11240
- const tx = await account.execute([approveCall, registerCall]);
11269
+ const tx = await account.execute(calls);
11241
11270
  await provider.waitForTransaction(tx.transaction_hash);
11242
11271
  return { txHash: tx.transaction_hash };
11243
11272
  } catch (err) {
@@ -12837,94 +12866,147 @@ var StarknetVenue = class {
12837
12866
  constructor(deps) {
12838
12867
  this.deps = deps;
12839
12868
  this.chain = "STARKNET";
12840
- this.m721 = new MarketplaceModule(deps.config);
12841
- this.m1155 = new Medialane1155Module(deps.config);
12842
12869
  }
12843
- incrementCounter(signer) {
12844
- return this.m721.incrementCounter(signer);
12870
+ async incrementCounter(signer) {
12871
+ return signer.execute([
12872
+ { contractAddress: this.deps.config.marketplaceContract, entrypoint: "increment_counter", calldata: [] }
12873
+ ]);
12845
12874
  }
12846
12875
  getOrderDetails(orderRef) {
12847
- return this.m721.getOrderDetails(orderRef);
12876
+ return getOrderDetails(orderRef, this.deps.config);
12848
12877
  }
12849
- getCounter(address) {
12850
- return this.m721.getCounter(address);
12878
+ async getCounter(address) {
12879
+ return this.readCounter(this.deps.config.marketplaceContract, address);
12851
12880
  }
12852
12881
  async fulfillOrder(signer, orderRef, opts) {
12853
12882
  const o = await this.deps.resolveOrder(orderRef);
12854
12883
  const quantity = opts?.quantity ?? "1";
12855
12884
  const totalPrice = (BigInt(o.unitPrice) * BigInt(quantity)).toString();
12856
- if (o.standard === "ERC1155") {
12857
- return this.m1155.fulfillOrder(signer, {
12858
- orderHash: orderRef,
12859
- paymentToken: o.paymentToken,
12860
- totalPrice,
12861
- quantity
12862
- });
12863
- }
12864
- return this.m721.fulfillOrder(signer, {
12865
- orderHash: orderRef,
12866
- paymentToken: o.paymentToken,
12867
- totalPrice
12868
- });
12885
+ 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);
12886
+ return signer.execute(calls);
12869
12887
  }
12870
12888
  async cancelOrder(signer, orderRef) {
12871
12889
  const o = await this.deps.resolveOrder(orderRef);
12872
- if (o.standard === "ERC1155") {
12873
- return this.m1155.cancelOrder(signer, { orderHash: orderRef });
12874
- }
12875
- return this.m721.cancelOrder(signer, { orderHash: orderRef });
12890
+ const typedData = o.standard === "ERC1155" ? buildCancel1155TypedData(orderRef, signer.address, this.deps.config) : buildCancelTypedData(orderRef, signer.address, this.deps.config);
12891
+ const signature = await signer.signTypedData(typedData);
12892
+ 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);
12893
+ return signer.execute(calls);
12876
12894
  }
12877
12895
  async registerOrder(signer, p) {
12878
12896
  const standard = await this.deps.resolveStandard(p.asset.contract);
12879
- const token = resolveToken(p.paymentToken);
12880
- const humanPrice = formatAmount(p.amount, token.decimals);
12881
- const durationSeconds = this.durationSeconds(p.endTime);
12897
+ const paymentTokenAddress = resolveToken(p.paymentToken).address;
12882
12898
  const royaltyMaxBps = String(p.royaltyMaxBps);
12899
+ const startTime = Math.floor(Date.now() / 1e3) + START_TIME_BUFFER_SECS;
12900
+ const endTime = p.endTime && p.endTime > 0 ? p.endTime : startTime + NO_EXPIRY_SECONDS;
12883
12901
  const quantity = p.quantity ?? "1";
12884
- let txHash;
12902
+ const marketplace = standard === "ERC1155" ? this.deps.config.marketplace1155Contract : this.deps.config.marketplaceContract;
12903
+ const counter = String(await this.readCounter(marketplace, signer.address));
12904
+ let typedData;
12905
+ let buildCalls;
12885
12906
  if (standard === "ERC1155") {
12886
- if (p.side === "listing") {
12887
- const res = await this.m1155.createListing(signer, {
12907
+ const built = (p.side === "listing" ? buildListing1155Order : buildOffer1155Order)(
12908
+ {
12909
+ offerer: signer.address,
12888
12910
  nftContract: p.asset.contract,
12889
12911
  tokenId: p.asset.tokenId,
12890
- amount: quantity,
12891
- pricePerUnit: humanPrice,
12892
- currency: p.paymentToken,
12893
- durationSeconds,
12894
- royaltyMaxBps
12895
- });
12896
- txHash = res.txHash;
12897
- } else {
12898
- const totalHuman = formatAmount((BigInt(p.amount) * BigInt(quantity)).toString(), token.decimals);
12899
- const res = await this.m1155.makeOffer(signer, {
12912
+ quantity,
12913
+ priceWeiPerUnit: p.amount,
12914
+ paymentTokenAddress,
12915
+ royaltyMaxBps,
12916
+ startTime,
12917
+ endTime,
12918
+ salt: p.salt,
12919
+ counter
12920
+ },
12921
+ this.deps.config
12922
+ );
12923
+ typedData = built.typedData;
12924
+ const approval = p.side === "listing" ? await this.approval1155ForListing(signer.address, p.asset.contract) : this.approvalForErc20(paymentTokenAddress, (BigInt(p.amount) * BigInt(quantity)).toString(), marketplace);
12925
+ buildCalls = (sig) => buildRegister1155Calls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
12926
+ } else {
12927
+ const built = (p.side === "listing" ? buildListingOrder : buildOfferOrder)(
12928
+ {
12929
+ offerer: signer.address,
12900
12930
  nftContract: p.asset.contract,
12901
12931
  tokenId: p.asset.tokenId,
12902
- amount: quantity,
12903
- price: totalHuman,
12904
- currency: p.paymentToken,
12905
- durationSeconds,
12906
- royaltyMaxBps
12907
- });
12908
- txHash = res.txHash;
12909
- }
12910
- } else {
12911
- const params = {
12912
- nftContract: p.asset.contract,
12913
- tokenId: p.asset.tokenId,
12914
- price: humanPrice,
12915
- currency: p.paymentToken,
12916
- durationSeconds,
12917
- royaltyMaxBps
12918
- };
12919
- const res = p.side === "listing" ? await this.m721.createListing(signer, params) : await this.m721.makeOffer(signer, params);
12920
- txHash = res.txHash;
12932
+ priceWei: p.amount,
12933
+ paymentTokenAddress,
12934
+ royaltyMaxBps,
12935
+ startTime,
12936
+ endTime,
12937
+ salt: p.salt,
12938
+ counter
12939
+ },
12940
+ this.deps.config
12941
+ );
12942
+ typedData = built.typedData;
12943
+ const approval = p.side === "listing" ? await this.approval721ForListing(signer.address, p.asset.contract, p.asset.tokenId) : this.approvalForErc20(paymentTokenAddress, p.amount, marketplace);
12944
+ buildCalls = (sig) => buildRegisterCalls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
12921
12945
  }
12946
+ const signature = await signer.signTypedData(typedData);
12947
+ const { txHash } = await signer.execute(buildCalls(signature));
12922
12948
  const orderRef = await this.orderRefFromReceipt(txHash);
12923
12949
  return { txHash, orderRef };
12924
12950
  }
12925
- durationSeconds(endTime) {
12926
- if (!endTime) return NO_EXPIRY_SECONDS;
12927
- return Math.max(1, endTime - Math.floor(Date.now() / 1e3));
12951
+ // ─── reads (all on deps.provider) ─────────────────────────────────────────
12952
+ async readCounter(marketplace, address) {
12953
+ const res = await this.deps.provider.callContract({
12954
+ contractAddress: marketplace,
12955
+ entrypoint: "get_counter",
12956
+ calldata: [address]
12957
+ });
12958
+ return BigInt(res[0] ?? "0");
12959
+ }
12960
+ /** 721 listing approval: `get_approved(tokenId) == marketplace` ⇒ no approve. */
12961
+ async approval721ForListing(_owner, nftContract, tokenId) {
12962
+ const id = starknet.cairo.uint256(tokenId);
12963
+ const approve = {
12964
+ contractAddress: nftContract,
12965
+ entrypoint: "approve",
12966
+ calldata: [this.deps.config.marketplaceContract, id.low.toString(), id.high.toString()]
12967
+ };
12968
+ let approved = false;
12969
+ try {
12970
+ const res = await this.deps.provider.callContract({
12971
+ contractAddress: nftContract,
12972
+ entrypoint: "get_approved",
12973
+ calldata: [id.low.toString(), id.high.toString()]
12974
+ });
12975
+ approved = BigInt(res[0]).toString() === BigInt(this.deps.config.marketplaceContract).toString();
12976
+ } catch {
12977
+ }
12978
+ return { approvalNeeded: !approved, approve };
12979
+ }
12980
+ /** 1155 listing approval: `is_approved_for_all(owner, marketplace)`. */
12981
+ async approval1155ForListing(owner, nftContract) {
12982
+ const approve = {
12983
+ contractAddress: nftContract,
12984
+ entrypoint: "set_approval_for_all",
12985
+ calldata: [this.deps.config.marketplace1155Contract, "1"]
12986
+ };
12987
+ let approved = false;
12988
+ try {
12989
+ const res = await this.deps.provider.callContract({
12990
+ contractAddress: nftContract,
12991
+ entrypoint: "is_approved_for_all",
12992
+ calldata: [owner, this.deps.config.marketplace1155Contract]
12993
+ });
12994
+ approved = BigInt(res[0]) === 1n;
12995
+ } catch {
12996
+ }
12997
+ return { approvalNeeded: !approved, approve };
12998
+ }
12999
+ /** Offers always approve the ERC-20 spend (no read). */
13000
+ approvalForErc20(token, amountWei, marketplace) {
13001
+ const u = starknet.cairo.uint256(amountWei);
13002
+ return {
13003
+ approvalNeeded: true,
13004
+ approve: {
13005
+ contractAddress: token,
13006
+ entrypoint: "approve",
13007
+ calldata: [marketplace, u.low.toString(), u.high.toString()]
13008
+ }
13009
+ };
12928
13010
  }
12929
13011
  /** The canonical Starknet order id = the contract-emitted `OrderCreated`
12930
13012
  * hash (`keys[1]`), which is exactly what the indexer stores. */