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