@medialane/sdk 0.56.0 → 0.57.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
 
@@ -8590,39 +8590,12 @@ var SUPPORTED_TOKENS = [
8590
8590
  ];
8591
8591
  var DEFAULT_CURRENCY = "USDC";
8592
8592
 
8593
- // src/utils/bigint.ts
8594
- function stringifyBigInts(obj) {
8595
- if (typeof obj === "bigint") {
8596
- return obj.toString();
8597
- }
8598
- if (Array.isArray(obj)) {
8599
- return obj.map(stringifyBigInts);
8600
- }
8601
- if (obj !== null && typeof obj === "object") {
8602
- return Object.fromEntries(
8603
- Object.entries(obj).map(([key, value]) => [
8604
- key,
8605
- stringifyBigInts(value)
8606
- ])
8607
- );
8608
- }
8609
- return obj;
8610
- }
8611
-
8612
8593
  // src/utils/token.ts
8613
8594
  function parseAmount(human, decimals) {
8614
8595
  const [whole, frac = ""] = human.split(".");
8615
8596
  const fracPadded = frac.padEnd(decimals, "0").slice(0, decimals);
8616
8597
  return (BigInt(whole) * BigInt(10) ** BigInt(decimals) + BigInt(fracPadded)).toString();
8617
8598
  }
8618
- function formatAmount(raw, decimals) {
8619
- const value = BigInt(raw);
8620
- const factor = BigInt(Math.pow(10, decimals));
8621
- const whole = value / factor;
8622
- const remainder = value % factor;
8623
- const fractional = remainder.toString().padStart(decimals, "0");
8624
- return `${whole}.${fractional}`;
8625
- }
8626
8599
  function getTokenByAddress(address) {
8627
8600
  const lower = address.toLowerCase();
8628
8601
  return SUPPORTED_TOKENS.find((t) => t.address.toLowerCase() === lower);
@@ -8651,6 +8624,25 @@ function buildFeeCall(p, cfg) {
8651
8624
  };
8652
8625
  }
8653
8626
 
8627
+ // src/utils/bigint.ts
8628
+ function stringifyBigInts(obj) {
8629
+ if (typeof obj === "bigint") {
8630
+ return obj.toString();
8631
+ }
8632
+ if (Array.isArray(obj)) {
8633
+ return obj.map(stringifyBigInts);
8634
+ }
8635
+ if (obj !== null && typeof obj === "object") {
8636
+ return Object.fromEntries(
8637
+ Object.entries(obj).map(([key, value]) => [
8638
+ key,
8639
+ stringifyBigInts(value)
8640
+ ])
8641
+ );
8642
+ }
8643
+ return obj;
8644
+ }
8645
+
8654
8646
  // src/utils/rpc.ts
8655
8647
  var PUBLIC_RPC_FALLBACKS = [
8656
8648
  "https://rpc.starknet.lava.build"
@@ -8755,6 +8747,94 @@ function getProvider(config) {
8755
8747
  return p;
8756
8748
  }
8757
8749
 
8750
+ // src/starknet/marketplace/build.ts
8751
+ function contractFor(cfg) {
8752
+ return new Contract(IPMarketplaceABI, cfg.marketplaceContract, getProvider(cfg));
8753
+ }
8754
+ function buildListingOrder(i, cfg) {
8755
+ const orderParams = {
8756
+ offerer: i.offerer,
8757
+ marketplace: cfg.marketplaceContract,
8758
+ offer: { item_type: "ERC721", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: "1" },
8759
+ consideration: {
8760
+ item_type: "ERC20",
8761
+ token: i.paymentTokenAddress,
8762
+ identifier_or_criteria: "0",
8763
+ amount: i.priceWei,
8764
+ recipient: i.offerer
8765
+ },
8766
+ royalty_max_bps: i.royaltyMaxBps,
8767
+ start_time: String(i.startTime),
8768
+ end_time: String(i.endTime),
8769
+ salt: i.salt,
8770
+ counter: i.counter
8771
+ };
8772
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
8773
+ return { orderParams, typedData };
8774
+ }
8775
+ function buildOfferOrder(i, cfg) {
8776
+ const orderParams = {
8777
+ offerer: i.offerer,
8778
+ marketplace: cfg.marketplaceContract,
8779
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWei },
8780
+ consideration: {
8781
+ item_type: "ERC721",
8782
+ token: i.nftContract,
8783
+ identifier_or_criteria: i.tokenId,
8784
+ amount: "1",
8785
+ recipient: i.offerer
8786
+ },
8787
+ royalty_max_bps: i.royaltyMaxBps,
8788
+ start_time: String(i.startTime),
8789
+ end_time: String(i.endTime),
8790
+ salt: i.salt,
8791
+ counter: i.counter
8792
+ };
8793
+ const typedData = stringifyBigInts(buildOrderTypedData(orderParams, getChainId(cfg)));
8794
+ return { orderParams, typedData };
8795
+ }
8796
+ function registerPayload(orderParams, signature) {
8797
+ return stringifyBigInts({
8798
+ parameters: {
8799
+ ...orderParams,
8800
+ offer: { ...orderParams.offer, item_type: shortString.encodeShortString(orderParams.offer.item_type) },
8801
+ consideration: {
8802
+ ...orderParams.consideration,
8803
+ item_type: shortString.encodeShortString(orderParams.consideration.item_type)
8804
+ }
8805
+ },
8806
+ signature
8807
+ });
8808
+ }
8809
+ function buildRegisterCalls(a, cfg) {
8810
+ const registerCall = contractFor(cfg).populate("register_order", [registerPayload(a.orderParams, a.signature)]);
8811
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
8812
+ }
8813
+ function buildFulfillCalls(a, cfg) {
8814
+ const u = cairo.uint256(a.totalPrice);
8815
+ const approve = {
8816
+ contractAddress: a.paymentToken,
8817
+ entrypoint: "approve",
8818
+ calldata: [cfg.marketplaceContract, u.low.toString(), u.high.toString()]
8819
+ };
8820
+ const fulfill = contractFor(cfg).populate("fulfill_order", [a.orderHash]);
8821
+ const fee = buildFeeCall(
8822
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
8823
+ cfg.feeConfig
8824
+ );
8825
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
8826
+ }
8827
+ function buildCancelCalls(a, cfg) {
8828
+ const cancelRequest = stringifyBigInts({
8829
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
8830
+ signature: a.signature
8831
+ });
8832
+ return [contractFor(cfg).populate("cancel_order", [cancelRequest])];
8833
+ }
8834
+ function buildCancelTypedData(orderHash, offerer, cfg) {
8835
+ return stringifyBigInts(buildCancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg)));
8836
+ }
8837
+
8758
8838
  // src/starknet/marketplace/orders.ts
8759
8839
  var _contractCache = /* @__PURE__ */ new WeakMap();
8760
8840
  function makeContract(config) {
@@ -8779,46 +8859,22 @@ async function createListing(account, params, config) {
8779
8859
  const endTime = now + durationSeconds;
8780
8860
  const counter = (await contract.get_counter(account.address)).toString();
8781
8861
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
8782
- const orderParams = {
8783
- offerer: account.address,
8784
- marketplace: config.marketplaceContract,
8785
- offer: {
8786
- item_type: "ERC721",
8787
- token: nftContract,
8788
- identifier_or_criteria: tokenId,
8789
- amount: "1"
8790
- },
8791
- consideration: {
8792
- item_type: "ERC20",
8793
- token: token.address,
8794
- identifier_or_criteria: "0",
8795
- amount: priceWei,
8796
- recipient: account.address
8797
- },
8798
- royalty_max_bps: royaltyMaxBps,
8799
- start_time: startTime.toString(),
8800
- end_time: endTime.toString(),
8801
- salt: generateSalt(),
8802
- counter
8803
- };
8804
- const chainId = getChainId(config);
8805
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
8806
- const signature = await account.signMessage(typedData);
8807
- const signatureArray = toSignatureArray(signature);
8808
- const registerPayload = stringifyBigInts({
8809
- parameters: {
8810
- ...orderParams,
8811
- offer: {
8812
- ...orderParams.offer,
8813
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
8814
- },
8815
- consideration: {
8816
- ...orderParams.consideration,
8817
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
8818
- }
8862
+ const { orderParams, typedData } = buildListingOrder(
8863
+ {
8864
+ offerer: account.address,
8865
+ nftContract,
8866
+ tokenId,
8867
+ priceWei,
8868
+ paymentTokenAddress: token.address,
8869
+ royaltyMaxBps,
8870
+ startTime,
8871
+ endTime,
8872
+ salt: generateSalt(),
8873
+ counter
8819
8874
  },
8820
- signature: signatureArray
8821
- });
8875
+ config
8876
+ );
8877
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
8822
8878
  const tokenIdUint256 = cairo.uint256(tokenId);
8823
8879
  let isAlreadyApproved = false;
8824
8880
  try {
@@ -8830,19 +8886,19 @@ async function createListing(account, params, config) {
8830
8886
  isAlreadyApproved = BigInt(result[0]).toString() === BigInt(config.marketplaceContract).toString();
8831
8887
  } catch {
8832
8888
  }
8833
- const registerCall = contract.populate("register_order", [registerPayload]);
8834
- const calls = isAlreadyApproved ? [registerCall] : [
8835
- {
8836
- contractAddress: nftContract,
8837
- entrypoint: "approve",
8838
- calldata: [
8839
- config.marketplaceContract,
8840
- tokenIdUint256.low.toString(),
8841
- tokenIdUint256.high.toString()
8842
- ]
8843
- },
8844
- registerCall
8845
- ];
8889
+ const approve = {
8890
+ contractAddress: nftContract,
8891
+ entrypoint: "approve",
8892
+ calldata: [
8893
+ config.marketplaceContract,
8894
+ tokenIdUint256.low.toString(),
8895
+ tokenIdUint256.high.toString()
8896
+ ]
8897
+ };
8898
+ const calls = buildRegisterCalls(
8899
+ { orderParams, signature: signatureArray, approvalNeeded: !isAlreadyApproved, approve },
8900
+ config
8901
+ );
8846
8902
  try {
8847
8903
  const tx = await account.execute(calls);
8848
8904
  await provider.waitForTransaction(tx.transaction_hash);
@@ -8861,46 +8917,22 @@ async function makeOffer(account, params, config) {
8861
8917
  const endTime = now + durationSeconds;
8862
8918
  const counter = (await contract.get_counter(account.address)).toString();
8863
8919
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
8864
- const orderParams = {
8865
- offerer: account.address,
8866
- marketplace: config.marketplaceContract,
8867
- offer: {
8868
- item_type: "ERC20",
8869
- token: token.address,
8870
- identifier_or_criteria: "0",
8871
- amount: priceWei
8872
- },
8873
- consideration: {
8874
- item_type: "ERC721",
8875
- token: nftContract,
8876
- identifier_or_criteria: tokenId,
8877
- amount: "1",
8878
- recipient: account.address
8879
- },
8880
- royalty_max_bps: royaltyMaxBps,
8881
- start_time: startTime.toString(),
8882
- end_time: endTime.toString(),
8883
- salt: generateSalt(),
8884
- counter
8885
- };
8886
- const chainId = getChainId(config);
8887
- const typedData = stringifyBigInts(buildOrderTypedData(orderParams, chainId));
8888
- const signature = await account.signMessage(typedData);
8889
- const signatureArray = toSignatureArray(signature);
8890
- const registerPayload = stringifyBigInts({
8891
- parameters: {
8892
- ...orderParams,
8893
- offer: {
8894
- ...orderParams.offer,
8895
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
8896
- },
8897
- consideration: {
8898
- ...orderParams.consideration,
8899
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
8900
- }
8920
+ const { orderParams, typedData } = buildOfferOrder(
8921
+ {
8922
+ offerer: account.address,
8923
+ nftContract,
8924
+ tokenId,
8925
+ priceWei,
8926
+ paymentTokenAddress: token.address,
8927
+ royaltyMaxBps,
8928
+ startTime,
8929
+ endTime,
8930
+ salt: generateSalt(),
8931
+ counter
8901
8932
  },
8902
- signature: signatureArray
8903
- });
8933
+ config
8934
+ );
8935
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
8904
8936
  const amountUint256 = cairo.uint256(priceWei);
8905
8937
  const approveCall = {
8906
8938
  contractAddress: token.address,
@@ -8911,9 +8943,12 @@ async function makeOffer(account, params, config) {
8911
8943
  amountUint256.high.toString()
8912
8944
  ]
8913
8945
  };
8914
- const registerCall = contract.populate("register_order", [registerPayload]);
8946
+ const calls = buildRegisterCalls(
8947
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
8948
+ config
8949
+ );
8915
8950
  try {
8916
- const tx = await account.execute([approveCall, registerCall]);
8951
+ const tx = await account.execute(calls);
8917
8952
  await provider.waitForTransaction(tx.transaction_hash);
8918
8953
  return { txHash: tx.transaction_hash };
8919
8954
  } catch (err) {
@@ -8922,23 +8957,8 @@ async function makeOffer(account, params, config) {
8922
8957
  }
8923
8958
  async function fulfillOrder(account, params, config) {
8924
8959
  const { orderHash, paymentToken, totalPrice } = params;
8925
- const { contract, provider } = makeContract(config);
8926
- const totalPriceU256 = cairo.uint256(totalPrice);
8927
- const approveCall = {
8928
- contractAddress: paymentToken,
8929
- entrypoint: "approve",
8930
- calldata: [
8931
- config.marketplaceContract,
8932
- totalPriceU256.low.toString(),
8933
- totalPriceU256.high.toString()
8934
- ]
8935
- };
8936
- const fulfillCall = contract.populate("fulfill_order", [orderHash]);
8937
- const feeCall = buildFeeCall(
8938
- { surface: "marketplace", token: paymentToken, grossAmount: BigInt(totalPrice) },
8939
- config.feeConfig
8940
- );
8941
- const calls = feeCall ? [approveCall, fulfillCall, feeCall] : [approveCall, fulfillCall];
8960
+ const { provider } = makeContract(config);
8961
+ const calls = buildFulfillCalls({ orderHash, paymentToken, totalPrice }, config);
8942
8962
  try {
8943
8963
  const tx = await account.execute(calls);
8944
8964
  await provider.waitForTransaction(tx.transaction_hash);
@@ -8949,24 +8969,12 @@ async function fulfillOrder(account, params, config) {
8949
8969
  }
8950
8970
  async function cancelOrder(account, params, config) {
8951
8971
  const { orderHash } = params;
8952
- const { contract, provider } = makeContract(config);
8953
- const chainId = getChainId(config);
8954
- const cancelParams = {
8955
- order_hash: orderHash,
8956
- offerer: account.address
8957
- };
8958
- const typedData = stringifyBigInts(
8959
- buildCancellationTypedData(cancelParams, chainId)
8960
- );
8961
- const signature = await account.signMessage(typedData);
8962
- const signatureArray = toSignatureArray(signature);
8963
- const cancelRequest = stringifyBigInts({
8964
- cancelation: cancelParams,
8965
- signature: signatureArray
8966
- });
8967
- const call = contract.populate("cancel_order", [cancelRequest]);
8972
+ const { provider } = makeContract(config);
8973
+ const typedData = buildCancelTypedData(orderHash, account.address, config);
8974
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
8975
+ const calls = buildCancelCalls({ orderHash, offerer: account.address, signature: signatureArray }, config);
8968
8976
  try {
8969
- const tx = await account.execute(call);
8977
+ const tx = await account.execute(calls);
8970
8978
  await provider.waitForTransaction(tx.transaction_hash);
8971
8979
  return { txHash: tx.transaction_hash };
8972
8980
  } catch (err) {
@@ -9113,6 +9121,100 @@ var MarketplaceModule = class {
9113
9121
  return buildCancellationTypedData(params, chainId);
9114
9122
  }
9115
9123
  };
9124
+ function contractFor2(cfg) {
9125
+ return new Contract(Medialane1155ABI, cfg.marketplace1155Contract, getProvider(cfg));
9126
+ }
9127
+ function buildListing1155Order(i, cfg) {
9128
+ const orderParams = {
9129
+ offerer: i.offerer,
9130
+ marketplace: cfg.marketplace1155Contract,
9131
+ offer: { item_type: "ERC1155", token: i.nftContract, identifier_or_criteria: i.tokenId, amount: i.quantity },
9132
+ consideration: {
9133
+ item_type: "ERC20",
9134
+ token: i.paymentTokenAddress,
9135
+ identifier_or_criteria: "0",
9136
+ amount: i.priceWeiPerUnit,
9137
+ recipient: i.offerer
9138
+ },
9139
+ royalty_max_bps: i.royaltyMaxBps,
9140
+ start_time: String(i.startTime),
9141
+ end_time: String(i.endTime),
9142
+ salt: i.salt,
9143
+ counter: i.counter
9144
+ };
9145
+ const typedData = stringifyBigInts(
9146
+ build1155OrderTypedData(orderParams, getChainId(cfg))
9147
+ );
9148
+ return { orderParams, typedData };
9149
+ }
9150
+ function buildOffer1155Order(i, cfg) {
9151
+ const orderParams = {
9152
+ offerer: i.offerer,
9153
+ marketplace: cfg.marketplace1155Contract,
9154
+ offer: { item_type: "ERC20", token: i.paymentTokenAddress, identifier_or_criteria: "0", amount: i.priceWeiPerUnit },
9155
+ consideration: {
9156
+ item_type: "ERC1155",
9157
+ token: i.nftContract,
9158
+ identifier_or_criteria: i.tokenId,
9159
+ amount: i.quantity,
9160
+ recipient: i.offerer
9161
+ },
9162
+ royalty_max_bps: i.royaltyMaxBps,
9163
+ start_time: String(i.startTime),
9164
+ end_time: String(i.endTime),
9165
+ salt: i.salt,
9166
+ counter: i.counter
9167
+ };
9168
+ const typedData = stringifyBigInts(
9169
+ build1155OrderTypedData(orderParams, getChainId(cfg))
9170
+ );
9171
+ return { orderParams, typedData };
9172
+ }
9173
+ function registerPayload2(orderParams, signature) {
9174
+ return stringifyBigInts({
9175
+ parameters: {
9176
+ ...orderParams,
9177
+ offer: { ...orderParams.offer, item_type: shortString.encodeShortString(orderParams.offer.item_type) },
9178
+ consideration: {
9179
+ ...orderParams.consideration,
9180
+ item_type: shortString.encodeShortString(orderParams.consideration.item_type)
9181
+ }
9182
+ },
9183
+ signature
9184
+ });
9185
+ }
9186
+ function buildRegister1155Calls(a, cfg) {
9187
+ const registerCall = contractFor2(cfg).populate("register_order", [registerPayload2(a.orderParams, a.signature)]);
9188
+ return a.approvalNeeded ? [a.approve, registerCall] : [registerCall];
9189
+ }
9190
+ function buildFulfill1155Calls(a, cfg) {
9191
+ const u = cairo.uint256(a.totalPrice);
9192
+ const approve = {
9193
+ contractAddress: a.paymentToken,
9194
+ entrypoint: "approve",
9195
+ calldata: [cfg.marketplace1155Contract, u.low.toString(), u.high.toString()]
9196
+ };
9197
+ const fulfill = contractFor2(cfg).populate("fulfill_order", [a.orderHash, a.quantity]);
9198
+ const fee = buildFeeCall(
9199
+ { surface: "marketplace", token: a.paymentToken, grossAmount: BigInt(a.totalPrice) },
9200
+ cfg.feeConfig
9201
+ );
9202
+ return fee ? [approve, fulfill, fee] : [approve, fulfill];
9203
+ }
9204
+ function buildCancel1155Calls(a, cfg) {
9205
+ const cancelPayload = stringifyBigInts({
9206
+ cancelation: { order_hash: a.orderHash, offerer: a.offerer },
9207
+ signature: a.signature
9208
+ });
9209
+ return [contractFor2(cfg).populate("cancel_order", [cancelPayload])];
9210
+ }
9211
+ function buildCancel1155TypedData(orderHash, offerer, cfg) {
9212
+ return stringifyBigInts(
9213
+ build1155CancellationTypedData({ order_hash: orderHash, offerer }, getChainId(cfg))
9214
+ );
9215
+ }
9216
+
9217
+ // src/starknet/marketplace1155/orders.ts
9116
9218
  var _contractCache2 = /* @__PURE__ */ new WeakMap();
9117
9219
  function getContract(config) {
9118
9220
  let c = _contractCache2.get(config);
@@ -9141,53 +9243,27 @@ async function createListing1155(account, params, config) {
9141
9243
  const token = resolveToken(currency);
9142
9244
  const priceWei = parseAmount(pricePerUnit, token.decimals);
9143
9245
  const now = Math.floor(Date.now() / 1e3);
9246
+ const startTime = now + START_TIME_BUFFER_SECS;
9144
9247
  const endTime = now + durationSeconds;
9145
- const chainId = getChainId(config);
9146
9248
  const counter = (await contract.get_counter(account.address)).toString();
9147
9249
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
9148
- const orderParams = {
9149
- offerer: account.address,
9150
- marketplace: config.marketplace1155Contract,
9151
- offer: {
9152
- item_type: "ERC1155",
9153
- token: nftContract,
9154
- identifier_or_criteria: tokenId,
9155
- amount
9156
- // ERC-1155 leg amount = unit quantity
9157
- },
9158
- consideration: {
9159
- item_type: "ERC20",
9160
- token: token.address,
9161
- identifier_or_criteria: "0",
9162
- amount: priceWei,
9163
- // payment leg amount = price PER UNIT
9164
- recipient: account.address
9250
+ const { orderParams, typedData } = buildListing1155Order(
9251
+ {
9252
+ offerer: account.address,
9253
+ nftContract,
9254
+ tokenId,
9255
+ quantity: amount,
9256
+ priceWeiPerUnit: priceWei,
9257
+ paymentTokenAddress: token.address,
9258
+ royaltyMaxBps,
9259
+ startTime,
9260
+ endTime,
9261
+ salt: generateSalt(),
9262
+ counter
9165
9263
  },
9166
- royalty_max_bps: royaltyMaxBps,
9167
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
9168
- end_time: endTime.toString(),
9169
- salt: generateSalt(),
9170
- counter
9171
- };
9172
- const typedData = stringifyBigInts(
9173
- build1155OrderTypedData(orderParams, chainId)
9264
+ config
9174
9265
  );
9175
- const signature = await account.signMessage(typedData);
9176
- const signatureArray = toSignatureArray(signature);
9177
- const orderPayload = stringifyBigInts({
9178
- parameters: {
9179
- ...orderParams,
9180
- offer: {
9181
- ...orderParams.offer,
9182
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
9183
- },
9184
- consideration: {
9185
- ...orderParams.consideration,
9186
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
9187
- }
9188
- },
9189
- signature: signatureArray
9190
- });
9266
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
9191
9267
  let isApproved = false;
9192
9268
  try {
9193
9269
  const result = await provider.callContract({
@@ -9198,15 +9274,15 @@ async function createListing1155(account, params, config) {
9198
9274
  isApproved = BigInt(result[0]) === 1n;
9199
9275
  } catch {
9200
9276
  }
9201
- const registerCall = contract.populate("register_order", [orderPayload]);
9202
- const calls = isApproved ? [registerCall] : [
9203
- {
9204
- contractAddress: nftContract,
9205
- entrypoint: "set_approval_for_all",
9206
- calldata: [config.marketplace1155Contract, "1"]
9207
- },
9208
- registerCall
9209
- ];
9277
+ const approve = {
9278
+ contractAddress: nftContract,
9279
+ entrypoint: "set_approval_for_all",
9280
+ calldata: [config.marketplace1155Contract, "1"]
9281
+ };
9282
+ const calls = buildRegister1155Calls(
9283
+ { orderParams, signature: signatureArray, approvalNeeded: !isApproved, approve },
9284
+ config
9285
+ );
9210
9286
  try {
9211
9287
  const tx = await account.execute(calls);
9212
9288
  await provider.waitForTransaction(tx.transaction_hash);
@@ -9217,21 +9293,10 @@ async function createListing1155(account, params, config) {
9217
9293
  }
9218
9294
  async function fulfillOrder1155(account, params, config) {
9219
9295
  const { orderHash, paymentToken, totalPrice, quantity = "1" } = params;
9220
- const contract = getContract(config);
9221
9296
  const provider = getProvider(config);
9222
- const totalPriceU256 = cairo.uint256(totalPrice);
9223
- const approveCall = {
9224
- contractAddress: paymentToken,
9225
- entrypoint: "approve",
9226
- calldata: [
9227
- config.marketplace1155Contract,
9228
- totalPriceU256.low.toString(),
9229
- totalPriceU256.high.toString()
9230
- ]
9231
- };
9232
- const fulfillCall = contract.populate("fulfill_order", [orderHash, quantity]);
9297
+ const calls = buildFulfill1155Calls({ orderHash, paymentToken, totalPrice, quantity }, config);
9233
9298
  try {
9234
- const tx = await account.execute([approveCall, fulfillCall]);
9299
+ const tx = await account.execute(calls);
9235
9300
  await provider.waitForTransaction(tx.transaction_hash);
9236
9301
  return { txHash: tx.transaction_hash };
9237
9302
  } catch (err) {
@@ -9240,25 +9305,12 @@ async function fulfillOrder1155(account, params, config) {
9240
9305
  }
9241
9306
  async function cancelOrder1155(account, params, config) {
9242
9307
  const { orderHash } = params;
9243
- const contract = getContract(config);
9244
9308
  const provider = getProvider(config);
9245
- const chainId = getChainId(config);
9246
- const cancelParams = {
9247
- order_hash: orderHash,
9248
- offerer: account.address
9249
- };
9250
- const typedData = stringifyBigInts(
9251
- build1155CancellationTypedData(cancelParams, chainId)
9252
- );
9253
- const signature = await account.signMessage(typedData);
9254
- const signatureArray = toSignatureArray(signature);
9255
- const cancelPayload = stringifyBigInts({
9256
- cancelation: cancelParams,
9257
- signature: signatureArray
9258
- });
9259
- const cancelCall = contract.populate("cancel_order", [cancelPayload]);
9309
+ const typedData = buildCancel1155TypedData(orderHash, account.address, config);
9310
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
9311
+ const calls = buildCancel1155Calls({ orderHash, offerer: account.address, signature: signatureArray }, config);
9260
9312
  try {
9261
- const tx = await account.execute(cancelCall);
9313
+ const tx = await account.execute(calls);
9262
9314
  await provider.waitForTransaction(tx.transaction_hash);
9263
9315
  return { txHash: tx.transaction_hash };
9264
9316
  } catch (err) {
@@ -9276,56 +9328,30 @@ async function makeOffer1155(account, params, config) {
9276
9328
  } = params;
9277
9329
  const contract = getContract(config);
9278
9330
  const provider = getProvider(config);
9279
- const chainId = getChainId(config);
9280
9331
  const token = resolveToken(currency);
9281
9332
  const priceWei = parseAmount(price, token.decimals);
9282
9333
  const now = Math.floor(Date.now() / 1e3);
9334
+ const startTime = now + START_TIME_BUFFER_SECS;
9283
9335
  const endTime = now + durationSeconds;
9284
9336
  const counter = (await contract.get_counter(account.address)).toString();
9285
9337
  const royaltyMaxBps = await resolveRoyaltyMaxBps(provider, nftContract, tokenId, params.royaltyMaxBps);
9286
- const orderParams = {
9287
- offerer: account.address,
9288
- marketplace: config.marketplace1155Contract,
9289
- offer: {
9290
- item_type: "ERC20",
9291
- token: token.address,
9292
- identifier_or_criteria: "0",
9293
- amount: priceWei
9294
- // price PER UNIT
9295
- },
9296
- consideration: {
9297
- item_type: "ERC1155",
9298
- token: nftContract,
9299
- identifier_or_criteria: tokenId,
9300
- amount,
9301
- // unit quantity
9302
- recipient: account.address
9338
+ const { orderParams, typedData } = buildOffer1155Order(
9339
+ {
9340
+ offerer: account.address,
9341
+ nftContract,
9342
+ tokenId,
9343
+ quantity: amount,
9344
+ priceWeiPerUnit: priceWei,
9345
+ paymentTokenAddress: token.address,
9346
+ royaltyMaxBps,
9347
+ startTime,
9348
+ endTime,
9349
+ salt: generateSalt(),
9350
+ counter
9303
9351
  },
9304
- royalty_max_bps: royaltyMaxBps,
9305
- start_time: (now + START_TIME_BUFFER_SECS).toString(),
9306
- end_time: endTime.toString(),
9307
- salt: generateSalt(),
9308
- counter
9309
- };
9310
- const typedData = stringifyBigInts(
9311
- build1155OrderTypedData(orderParams, chainId)
9352
+ config
9312
9353
  );
9313
- const signature = await account.signMessage(typedData);
9314
- const signatureArray = toSignatureArray(signature);
9315
- const registerPayload = stringifyBigInts({
9316
- parameters: {
9317
- ...orderParams,
9318
- offer: {
9319
- ...orderParams.offer,
9320
- item_type: shortString.encodeShortString(orderParams.offer.item_type)
9321
- },
9322
- consideration: {
9323
- ...orderParams.consideration,
9324
- item_type: shortString.encodeShortString(orderParams.consideration.item_type)
9325
- }
9326
- },
9327
- signature: signatureArray
9328
- });
9354
+ const signatureArray = toSignatureArray(await account.signMessage(typedData));
9329
9355
  const totalWei = BigInt(priceWei) * BigInt(amount);
9330
9356
  const amountU256 = cairo.uint256(totalWei.toString());
9331
9357
  const approveCall = {
@@ -9337,9 +9363,12 @@ async function makeOffer1155(account, params, config) {
9337
9363
  amountU256.high.toString()
9338
9364
  ]
9339
9365
  };
9340
- const registerCall = contract.populate("register_order", [registerPayload]);
9366
+ const calls = buildRegister1155Calls(
9367
+ { orderParams, signature: signatureArray, approvalNeeded: true, approve: approveCall },
9368
+ config
9369
+ );
9341
9370
  try {
9342
- const tx = await account.execute([approveCall, registerCall]);
9371
+ const tx = await account.execute(calls);
9343
9372
  await provider.waitForTransaction(tx.transaction_hash);
9344
9373
  return { txHash: tx.transaction_hash };
9345
9374
  } catch (err) {
@@ -10885,94 +10914,147 @@ var StarknetVenue = class {
10885
10914
  constructor(deps) {
10886
10915
  this.deps = deps;
10887
10916
  this.chain = "STARKNET";
10888
- this.m721 = new MarketplaceModule(deps.config);
10889
- this.m1155 = new Medialane1155Module(deps.config);
10890
10917
  }
10891
- incrementCounter(signer) {
10892
- return this.m721.incrementCounter(signer);
10918
+ async incrementCounter(signer) {
10919
+ return signer.execute([
10920
+ { contractAddress: this.deps.config.marketplaceContract, entrypoint: "increment_counter", calldata: [] }
10921
+ ]);
10893
10922
  }
10894
10923
  getOrderDetails(orderRef) {
10895
- return this.m721.getOrderDetails(orderRef);
10924
+ return getOrderDetails(orderRef, this.deps.config);
10896
10925
  }
10897
- getCounter(address) {
10898
- return this.m721.getCounter(address);
10926
+ async getCounter(address) {
10927
+ return this.readCounter(this.deps.config.marketplaceContract, address);
10899
10928
  }
10900
10929
  async fulfillOrder(signer, orderRef, opts) {
10901
10930
  const o = await this.deps.resolveOrder(orderRef);
10902
10931
  const quantity = opts?.quantity ?? "1";
10903
10932
  const totalPrice = (BigInt(o.unitPrice) * BigInt(quantity)).toString();
10904
- if (o.standard === "ERC1155") {
10905
- return this.m1155.fulfillOrder(signer, {
10906
- orderHash: orderRef,
10907
- paymentToken: o.paymentToken,
10908
- totalPrice,
10909
- quantity
10910
- });
10911
- }
10912
- return this.m721.fulfillOrder(signer, {
10913
- orderHash: orderRef,
10914
- paymentToken: o.paymentToken,
10915
- totalPrice
10916
- });
10933
+ 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);
10934
+ return signer.execute(calls);
10917
10935
  }
10918
10936
  async cancelOrder(signer, orderRef) {
10919
10937
  const o = await this.deps.resolveOrder(orderRef);
10920
- if (o.standard === "ERC1155") {
10921
- return this.m1155.cancelOrder(signer, { orderHash: orderRef });
10922
- }
10923
- return this.m721.cancelOrder(signer, { orderHash: orderRef });
10938
+ const typedData = o.standard === "ERC1155" ? buildCancel1155TypedData(orderRef, signer.address, this.deps.config) : buildCancelTypedData(orderRef, signer.address, this.deps.config);
10939
+ const signature = await signer.signTypedData(typedData);
10940
+ 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);
10941
+ return signer.execute(calls);
10924
10942
  }
10925
10943
  async registerOrder(signer, p) {
10926
10944
  const standard = await this.deps.resolveStandard(p.asset.contract);
10927
- const token = resolveToken(p.paymentToken);
10928
- const humanPrice = formatAmount(p.amount, token.decimals);
10929
- const durationSeconds = this.durationSeconds(p.endTime);
10945
+ const paymentTokenAddress = resolveToken(p.paymentToken).address;
10930
10946
  const royaltyMaxBps = String(p.royaltyMaxBps);
10947
+ const startTime = Math.floor(Date.now() / 1e3) + START_TIME_BUFFER_SECS;
10948
+ const endTime = p.endTime && p.endTime > 0 ? p.endTime : startTime + NO_EXPIRY_SECONDS;
10931
10949
  const quantity = p.quantity ?? "1";
10932
- let txHash;
10950
+ const marketplace = standard === "ERC1155" ? this.deps.config.marketplace1155Contract : this.deps.config.marketplaceContract;
10951
+ const counter = String(await this.readCounter(marketplace, signer.address));
10952
+ let typedData;
10953
+ let buildCalls;
10933
10954
  if (standard === "ERC1155") {
10934
- if (p.side === "listing") {
10935
- const res = await this.m1155.createListing(signer, {
10955
+ const built = (p.side === "listing" ? buildListing1155Order : buildOffer1155Order)(
10956
+ {
10957
+ offerer: signer.address,
10936
10958
  nftContract: p.asset.contract,
10937
10959
  tokenId: p.asset.tokenId,
10938
- amount: quantity,
10939
- pricePerUnit: humanPrice,
10940
- currency: p.paymentToken,
10941
- durationSeconds,
10942
- royaltyMaxBps
10943
- });
10944
- txHash = res.txHash;
10945
- } else {
10946
- const totalHuman = formatAmount((BigInt(p.amount) * BigInt(quantity)).toString(), token.decimals);
10947
- const res = await this.m1155.makeOffer(signer, {
10960
+ quantity,
10961
+ priceWeiPerUnit: p.amount,
10962
+ paymentTokenAddress,
10963
+ royaltyMaxBps,
10964
+ startTime,
10965
+ endTime,
10966
+ salt: p.salt,
10967
+ counter
10968
+ },
10969
+ this.deps.config
10970
+ );
10971
+ typedData = built.typedData;
10972
+ const approval = p.side === "listing" ? await this.approval1155ForListing(signer.address, p.asset.contract) : this.approvalForErc20(paymentTokenAddress, (BigInt(p.amount) * BigInt(quantity)).toString(), marketplace);
10973
+ buildCalls = (sig) => buildRegister1155Calls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
10974
+ } else {
10975
+ const built = (p.side === "listing" ? buildListingOrder : buildOfferOrder)(
10976
+ {
10977
+ offerer: signer.address,
10948
10978
  nftContract: p.asset.contract,
10949
10979
  tokenId: p.asset.tokenId,
10950
- amount: quantity,
10951
- price: totalHuman,
10952
- currency: p.paymentToken,
10953
- durationSeconds,
10954
- royaltyMaxBps
10955
- });
10956
- txHash = res.txHash;
10957
- }
10958
- } else {
10959
- const params = {
10960
- nftContract: p.asset.contract,
10961
- tokenId: p.asset.tokenId,
10962
- price: humanPrice,
10963
- currency: p.paymentToken,
10964
- durationSeconds,
10965
- royaltyMaxBps
10966
- };
10967
- const res = p.side === "listing" ? await this.m721.createListing(signer, params) : await this.m721.makeOffer(signer, params);
10968
- txHash = res.txHash;
10980
+ priceWei: p.amount,
10981
+ paymentTokenAddress,
10982
+ royaltyMaxBps,
10983
+ startTime,
10984
+ endTime,
10985
+ salt: p.salt,
10986
+ counter
10987
+ },
10988
+ this.deps.config
10989
+ );
10990
+ typedData = built.typedData;
10991
+ const approval = p.side === "listing" ? await this.approval721ForListing(signer.address, p.asset.contract, p.asset.tokenId) : this.approvalForErc20(paymentTokenAddress, p.amount, marketplace);
10992
+ buildCalls = (sig) => buildRegisterCalls({ orderParams: built.orderParams, signature: sig, ...approval }, this.deps.config);
10969
10993
  }
10994
+ const signature = await signer.signTypedData(typedData);
10995
+ const { txHash } = await signer.execute(buildCalls(signature));
10970
10996
  const orderRef = await this.orderRefFromReceipt(txHash);
10971
10997
  return { txHash, orderRef };
10972
10998
  }
10973
- durationSeconds(endTime) {
10974
- if (!endTime) return NO_EXPIRY_SECONDS;
10975
- return Math.max(1, endTime - Math.floor(Date.now() / 1e3));
10999
+ // ─── reads (all on deps.provider) ─────────────────────────────────────────
11000
+ async readCounter(marketplace, address) {
11001
+ const res = await this.deps.provider.callContract({
11002
+ contractAddress: marketplace,
11003
+ entrypoint: "get_counter",
11004
+ calldata: [address]
11005
+ });
11006
+ return BigInt(res[0] ?? "0");
11007
+ }
11008
+ /** 721 listing approval: `get_approved(tokenId) == marketplace` ⇒ no approve. */
11009
+ async approval721ForListing(_owner, nftContract, tokenId) {
11010
+ const id = cairo.uint256(tokenId);
11011
+ const approve = {
11012
+ contractAddress: nftContract,
11013
+ entrypoint: "approve",
11014
+ calldata: [this.deps.config.marketplaceContract, id.low.toString(), id.high.toString()]
11015
+ };
11016
+ let approved = false;
11017
+ try {
11018
+ const res = await this.deps.provider.callContract({
11019
+ contractAddress: nftContract,
11020
+ entrypoint: "get_approved",
11021
+ calldata: [id.low.toString(), id.high.toString()]
11022
+ });
11023
+ approved = BigInt(res[0]).toString() === BigInt(this.deps.config.marketplaceContract).toString();
11024
+ } catch {
11025
+ }
11026
+ return { approvalNeeded: !approved, approve };
11027
+ }
11028
+ /** 1155 listing approval: `is_approved_for_all(owner, marketplace)`. */
11029
+ async approval1155ForListing(owner, nftContract) {
11030
+ const approve = {
11031
+ contractAddress: nftContract,
11032
+ entrypoint: "set_approval_for_all",
11033
+ calldata: [this.deps.config.marketplace1155Contract, "1"]
11034
+ };
11035
+ let approved = false;
11036
+ try {
11037
+ const res = await this.deps.provider.callContract({
11038
+ contractAddress: nftContract,
11039
+ entrypoint: "is_approved_for_all",
11040
+ calldata: [owner, this.deps.config.marketplace1155Contract]
11041
+ });
11042
+ approved = BigInt(res[0]) === 1n;
11043
+ } catch {
11044
+ }
11045
+ return { approvalNeeded: !approved, approve };
11046
+ }
11047
+ /** Offers always approve the ERC-20 spend (no read). */
11048
+ approvalForErc20(token, amountWei, marketplace) {
11049
+ const u = cairo.uint256(amountWei);
11050
+ return {
11051
+ approvalNeeded: true,
11052
+ approve: {
11053
+ contractAddress: token,
11054
+ entrypoint: "approve",
11055
+ calldata: [marketplace, u.low.toString(), u.high.toString()]
11056
+ }
11057
+ };
10976
11058
  }
10977
11059
  /** The canonical Starknet order id = the contract-emitted `OrderCreated`
10978
11060
  * hash (`keys[1]`), which is exactly what the indexer stores. */