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