@medialane/sdk 0.8.3 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +300 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -95
- package/dist/index.d.ts +151 -95
- package/dist/index.js +301 -109
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -194,6 +194,30 @@ function buildCancellationTypedData(message, chainId) {
|
|
|
194
194
|
message
|
|
195
195
|
};
|
|
196
196
|
}
|
|
197
|
+
function encodeByteArray(str) {
|
|
198
|
+
const bytes = new TextEncoder().encode(str);
|
|
199
|
+
const fullChunks = [];
|
|
200
|
+
let i = 0;
|
|
201
|
+
while (i + 31 <= bytes.length) {
|
|
202
|
+
let val = 0n;
|
|
203
|
+
for (const b of bytes.slice(i, i + 31)) {
|
|
204
|
+
val = val << 8n | BigInt(b);
|
|
205
|
+
}
|
|
206
|
+
fullChunks.push(starknet.num.toHex(val));
|
|
207
|
+
i += 31;
|
|
208
|
+
}
|
|
209
|
+
const remaining = bytes.slice(i);
|
|
210
|
+
let pendingVal = 0n;
|
|
211
|
+
for (const b of remaining) {
|
|
212
|
+
pendingVal = pendingVal << 8n | BigInt(b);
|
|
213
|
+
}
|
|
214
|
+
return [
|
|
215
|
+
fullChunks.length.toString(),
|
|
216
|
+
...fullChunks,
|
|
217
|
+
starknet.num.toHex(pendingVal),
|
|
218
|
+
remaining.length.toString()
|
|
219
|
+
];
|
|
220
|
+
}
|
|
197
221
|
|
|
198
222
|
// src/abis.ts
|
|
199
223
|
var IPMarketplaceABI = [
|
|
@@ -1679,7 +1703,7 @@ function getListableTokens() {
|
|
|
1679
1703
|
return SUPPORTED_TOKENS.filter((t) => t.listable);
|
|
1680
1704
|
}
|
|
1681
1705
|
|
|
1682
|
-
// src/marketplace/
|
|
1706
|
+
// src/marketplace/errors.ts
|
|
1683
1707
|
var MedialaneError = class extends Error {
|
|
1684
1708
|
constructor(message, code = "UNKNOWN", cause) {
|
|
1685
1709
|
super(message);
|
|
@@ -1688,6 +1712,7 @@ var MedialaneError = class extends Error {
|
|
|
1688
1712
|
this.name = "MedialaneError";
|
|
1689
1713
|
}
|
|
1690
1714
|
};
|
|
1715
|
+
var START_TIME_BUFFER_SECS = 30;
|
|
1691
1716
|
function toSignatureArray(sig) {
|
|
1692
1717
|
if (Array.isArray(sig)) return sig;
|
|
1693
1718
|
const s = sig;
|
|
@@ -1696,35 +1721,36 @@ function toSignatureArray(sig) {
|
|
|
1696
1721
|
function getChainId(_config) {
|
|
1697
1722
|
return starknet.constants.StarknetChainId.SN_MAIN;
|
|
1698
1723
|
}
|
|
1699
|
-
|
|
1724
|
+
function resolveToken(currency) {
|
|
1725
|
+
const token = SUPPORTED_TOKENS.find(
|
|
1726
|
+
(t) => t.symbol === currency.toUpperCase() || t.address.toLowerCase() === currency.toLowerCase()
|
|
1727
|
+
);
|
|
1728
|
+
if (!token) throw new MedialaneError(`Unsupported currency: ${currency}`, "INVALID_PARAMS");
|
|
1729
|
+
return token;
|
|
1730
|
+
}
|
|
1700
1731
|
var _providerCache = /* @__PURE__ */ new WeakMap();
|
|
1701
1732
|
function getProvider(config) {
|
|
1702
|
-
let
|
|
1703
|
-
if (!
|
|
1704
|
-
|
|
1705
|
-
_providerCache.set(config,
|
|
1733
|
+
let p = _providerCache.get(config);
|
|
1734
|
+
if (!p) {
|
|
1735
|
+
p = new starknet.RpcProvider({ nodeUrl: config.rpcUrl });
|
|
1736
|
+
_providerCache.set(config, p);
|
|
1706
1737
|
}
|
|
1707
|
-
return
|
|
1738
|
+
return p;
|
|
1708
1739
|
}
|
|
1740
|
+
|
|
1741
|
+
// src/marketplace/orders.ts
|
|
1742
|
+
var _contractCache = /* @__PURE__ */ new WeakMap();
|
|
1709
1743
|
function makeContract(config) {
|
|
1710
1744
|
const cached = _contractCache.get(config);
|
|
1711
|
-
if (cached) return cached;
|
|
1712
1745
|
const provider = getProvider(config);
|
|
1746
|
+
if (cached) return { ...cached, provider };
|
|
1713
1747
|
const contract = new starknet.Contract(
|
|
1714
1748
|
IPMarketplaceABI,
|
|
1715
1749
|
config.marketplaceContract,
|
|
1716
1750
|
provider
|
|
1717
1751
|
);
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
return result;
|
|
1721
|
-
}
|
|
1722
|
-
function resolveToken(currency) {
|
|
1723
|
-
const token = SUPPORTED_TOKENS.find(
|
|
1724
|
-
(t) => t.symbol === currency.toUpperCase() || t.address.toLowerCase() === currency.toLowerCase()
|
|
1725
|
-
);
|
|
1726
|
-
if (!token) throw new MedialaneError(`Unsupported currency: ${currency}`, "INVALID_PARAMS");
|
|
1727
|
-
return token;
|
|
1752
|
+
_contractCache.set(config, { contract });
|
|
1753
|
+
return { contract, provider };
|
|
1728
1754
|
}
|
|
1729
1755
|
async function createListing(account, params, config) {
|
|
1730
1756
|
const { nftContract, tokenId, price, currency = DEFAULT_CURRENCY, durationSeconds } = params;
|
|
@@ -1732,7 +1758,7 @@ async function createListing(account, params, config) {
|
|
|
1732
1758
|
const token = resolveToken(currency);
|
|
1733
1759
|
const priceWei = parseAmount(price, token.decimals);
|
|
1734
1760
|
const now = Math.floor(Date.now() / 1e3);
|
|
1735
|
-
const startTime = now +
|
|
1761
|
+
const startTime = now + START_TIME_BUFFER_SECS;
|
|
1736
1762
|
const endTime = now + durationSeconds;
|
|
1737
1763
|
const saltBytes = new Uint8Array(4);
|
|
1738
1764
|
crypto.getRandomValues(saltBytes);
|
|
@@ -1816,7 +1842,7 @@ async function makeOffer(account, params, config) {
|
|
|
1816
1842
|
const token = resolveToken(currency);
|
|
1817
1843
|
const priceWei = parseAmount(price, token.decimals);
|
|
1818
1844
|
const now = Math.floor(Date.now() / 1e3);
|
|
1819
|
-
const startTime = now +
|
|
1845
|
+
const startTime = now + START_TIME_BUFFER_SECS;
|
|
1820
1846
|
const endTime = now + durationSeconds;
|
|
1821
1847
|
const saltBytes = new Uint8Array(4);
|
|
1822
1848
|
crypto.getRandomValues(saltBytes);
|
|
@@ -1882,7 +1908,7 @@ async function makeOffer(account, params, config) {
|
|
|
1882
1908
|
}
|
|
1883
1909
|
}
|
|
1884
1910
|
async function fulfillOrder(account, params, config) {
|
|
1885
|
-
const { orderHash } = params;
|
|
1911
|
+
const { orderHash, paymentToken, totalPrice } = params;
|
|
1886
1912
|
const { contract, provider } = makeContract(config);
|
|
1887
1913
|
const currentNonce = await contract.nonces(account.address);
|
|
1888
1914
|
const chainId = getChainId();
|
|
@@ -1900,9 +1926,19 @@ async function fulfillOrder(account, params, config) {
|
|
|
1900
1926
|
fulfillment: fulfillmentParams,
|
|
1901
1927
|
signature: signatureArray
|
|
1902
1928
|
});
|
|
1903
|
-
const
|
|
1929
|
+
const totalPriceU256 = starknet.cairo.uint256(totalPrice);
|
|
1930
|
+
const approveCall = {
|
|
1931
|
+
contractAddress: paymentToken,
|
|
1932
|
+
entrypoint: "approve",
|
|
1933
|
+
calldata: [
|
|
1934
|
+
config.marketplaceContract,
|
|
1935
|
+
totalPriceU256.low.toString(),
|
|
1936
|
+
totalPriceU256.high.toString()
|
|
1937
|
+
]
|
|
1938
|
+
};
|
|
1939
|
+
const fulfillCall = contract.populate("fulfill_order", [fulfillPayload]);
|
|
1904
1940
|
try {
|
|
1905
|
-
const tx = await account.execute(
|
|
1941
|
+
const tx = await account.execute([approveCall, fulfillCall]);
|
|
1906
1942
|
await provider.waitForTransaction(tx.transaction_hash);
|
|
1907
1943
|
return { txHash: tx.transaction_hash };
|
|
1908
1944
|
} catch (err) {
|
|
@@ -1937,15 +1973,6 @@ async function cancelOrder(account, params, config) {
|
|
|
1937
1973
|
throw new MedialaneError("Failed to cancel order", "TRANSACTION_FAILED", err);
|
|
1938
1974
|
}
|
|
1939
1975
|
}
|
|
1940
|
-
function encodeByteArray(str) {
|
|
1941
|
-
const ba = starknet.byteArray.byteArrayFromString(str);
|
|
1942
|
-
return [
|
|
1943
|
-
ba.data.length.toString(),
|
|
1944
|
-
...ba.data.map((d) => starknet.num.toHex(d)),
|
|
1945
|
-
starknet.num.toHex(ba.pending_word),
|
|
1946
|
-
ba.pending_word_len.toString()
|
|
1947
|
-
];
|
|
1948
|
-
}
|
|
1949
1976
|
async function mint(account, params, config) {
|
|
1950
1977
|
const { collectionId, recipient, tokenUri, collectionContract } = params;
|
|
1951
1978
|
const provider = getProvider(config);
|
|
@@ -2028,6 +2055,14 @@ async function checkoutCart(account, items, config) {
|
|
|
2028
2055
|
throw new MedialaneError("Cart checkout failed", "TRANSACTION_FAILED", err);
|
|
2029
2056
|
}
|
|
2030
2057
|
}
|
|
2058
|
+
async function getOrderDetails(orderHash, config) {
|
|
2059
|
+
const { contract } = makeContract(config);
|
|
2060
|
+
return contract.get_order_details(orderHash);
|
|
2061
|
+
}
|
|
2062
|
+
async function getNonce(address, config) {
|
|
2063
|
+
const { contract } = makeContract(config);
|
|
2064
|
+
return BigInt((await contract.nonces(address)).toString());
|
|
2065
|
+
}
|
|
2031
2066
|
|
|
2032
2067
|
// src/marketplace/index.ts
|
|
2033
2068
|
var MarketplaceModule = class {
|
|
@@ -2056,6 +2091,13 @@ var MarketplaceModule = class {
|
|
|
2056
2091
|
createCollection(account, params) {
|
|
2057
2092
|
return createCollection(account, params, this.config);
|
|
2058
2093
|
}
|
|
2094
|
+
// ─── View calls ───────────────────────────────────────────────────────────
|
|
2095
|
+
getOrderDetails(orderHash) {
|
|
2096
|
+
return getOrderDetails(orderHash, this.config);
|
|
2097
|
+
}
|
|
2098
|
+
getNonce(address) {
|
|
2099
|
+
return getNonce(address, this.config);
|
|
2100
|
+
}
|
|
2059
2101
|
// ─── Typed data builders (for ChipiPay / custom signing flows) ───────────
|
|
2060
2102
|
buildListingTypedData(params, chainId) {
|
|
2061
2103
|
return buildOrderTypedData(params, chainId);
|
|
@@ -2146,28 +2188,11 @@ function build1155CancellationTypedData(message, chainId) {
|
|
|
2146
2188
|
message
|
|
2147
2189
|
};
|
|
2148
2190
|
}
|
|
2149
|
-
function toSignatureArray2(sig) {
|
|
2150
|
-
if (Array.isArray(sig)) return sig;
|
|
2151
|
-
const s = sig;
|
|
2152
|
-
return [s.r.toString(), s.s.toString()];
|
|
2153
|
-
}
|
|
2154
|
-
function getChainId2(_config) {
|
|
2155
|
-
return starknet.constants.StarknetChainId.SN_MAIN;
|
|
2156
|
-
}
|
|
2157
|
-
var _providerCache2 = /* @__PURE__ */ new WeakMap();
|
|
2158
2191
|
var _contractCache2 = /* @__PURE__ */ new WeakMap();
|
|
2159
|
-
function getProvider2(config) {
|
|
2160
|
-
let p = _providerCache2.get(config);
|
|
2161
|
-
if (!p) {
|
|
2162
|
-
p = new starknet.RpcProvider({ nodeUrl: config.rpcUrl });
|
|
2163
|
-
_providerCache2.set(config, p);
|
|
2164
|
-
}
|
|
2165
|
-
return p;
|
|
2166
|
-
}
|
|
2167
2192
|
function getContract(config) {
|
|
2168
2193
|
let c = _contractCache2.get(config);
|
|
2169
2194
|
if (!c) {
|
|
2170
|
-
const provider =
|
|
2195
|
+
const provider = getProvider(config);
|
|
2171
2196
|
c = new starknet.Contract(
|
|
2172
2197
|
Medialane1155ABI,
|
|
2173
2198
|
config.marketplace1155Contract,
|
|
@@ -2177,13 +2202,6 @@ function getContract(config) {
|
|
|
2177
2202
|
}
|
|
2178
2203
|
return c;
|
|
2179
2204
|
}
|
|
2180
|
-
function resolveToken2(currency) {
|
|
2181
|
-
const token = SUPPORTED_TOKENS.find(
|
|
2182
|
-
(t) => t.symbol === currency.toUpperCase() || t.address.toLowerCase() === currency.toLowerCase()
|
|
2183
|
-
);
|
|
2184
|
-
if (!token) throw new MedialaneError(`Unsupported currency: ${currency}`, "INVALID_PARAMS");
|
|
2185
|
-
return token;
|
|
2186
|
-
}
|
|
2187
2205
|
async function createListing1155(account, params, config) {
|
|
2188
2206
|
const {
|
|
2189
2207
|
nftContract,
|
|
@@ -2194,8 +2212,8 @@ async function createListing1155(account, params, config) {
|
|
|
2194
2212
|
durationSeconds
|
|
2195
2213
|
} = params;
|
|
2196
2214
|
const contract = getContract(config);
|
|
2197
|
-
const provider =
|
|
2198
|
-
const token =
|
|
2215
|
+
const provider = getProvider(config);
|
|
2216
|
+
const token = resolveToken(currency);
|
|
2199
2217
|
const priceWei = parseAmount(pricePerUnit, token.decimals);
|
|
2200
2218
|
const now = Math.floor(Date.now() / 1e3);
|
|
2201
2219
|
const endTime = now + durationSeconds;
|
|
@@ -2203,7 +2221,7 @@ async function createListing1155(account, params, config) {
|
|
|
2203
2221
|
crypto.getRandomValues(saltBytes);
|
|
2204
2222
|
const salt = new DataView(saltBytes.buffer).getUint32(0).toString();
|
|
2205
2223
|
const currentNonce = await contract.nonces(account.address);
|
|
2206
|
-
const chainId =
|
|
2224
|
+
const chainId = getChainId();
|
|
2207
2225
|
const orderParams = {
|
|
2208
2226
|
offerer: account.address,
|
|
2209
2227
|
offer: {
|
|
@@ -2221,7 +2239,7 @@ async function createListing1155(account, params, config) {
|
|
|
2221
2239
|
end_amount: priceWei,
|
|
2222
2240
|
recipient: account.address
|
|
2223
2241
|
},
|
|
2224
|
-
start_time: now.toString(),
|
|
2242
|
+
start_time: (now + START_TIME_BUFFER_SECS).toString(),
|
|
2225
2243
|
end_time: endTime.toString(),
|
|
2226
2244
|
salt,
|
|
2227
2245
|
nonce: currentNonce.toString()
|
|
@@ -2230,9 +2248,19 @@ async function createListing1155(account, params, config) {
|
|
|
2230
2248
|
build1155OrderTypedData(orderParams, chainId)
|
|
2231
2249
|
);
|
|
2232
2250
|
const signature = await account.signMessage(typedData);
|
|
2233
|
-
const signatureArray =
|
|
2251
|
+
const signatureArray = toSignatureArray(signature);
|
|
2234
2252
|
const orderPayload = stringifyBigInts({
|
|
2235
|
-
parameters:
|
|
2253
|
+
parameters: {
|
|
2254
|
+
...orderParams,
|
|
2255
|
+
offer: {
|
|
2256
|
+
...orderParams.offer,
|
|
2257
|
+
item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
|
|
2258
|
+
},
|
|
2259
|
+
consideration: {
|
|
2260
|
+
...orderParams.consideration,
|
|
2261
|
+
item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
|
|
2262
|
+
}
|
|
2263
|
+
},
|
|
2236
2264
|
signature: signatureArray
|
|
2237
2265
|
});
|
|
2238
2266
|
let isApproved = false;
|
|
@@ -2265,8 +2293,8 @@ async function createListing1155(account, params, config) {
|
|
|
2265
2293
|
async function fulfillOrder1155(account, params, config) {
|
|
2266
2294
|
const { orderHash, paymentToken, totalPrice, quantity = "1" } = params;
|
|
2267
2295
|
const contract = getContract(config);
|
|
2268
|
-
const provider =
|
|
2269
|
-
const chainId =
|
|
2296
|
+
const provider = getProvider(config);
|
|
2297
|
+
const chainId = getChainId();
|
|
2270
2298
|
const currentNonce = await contract.nonces(account.address);
|
|
2271
2299
|
const fulfillmentParams = {
|
|
2272
2300
|
order_hash: orderHash,
|
|
@@ -2278,7 +2306,7 @@ async function fulfillOrder1155(account, params, config) {
|
|
|
2278
2306
|
build1155FulfillmentTypedData(fulfillmentParams, chainId)
|
|
2279
2307
|
);
|
|
2280
2308
|
const signature = await account.signMessage(typedData);
|
|
2281
|
-
const signatureArray =
|
|
2309
|
+
const signatureArray = toSignatureArray(signature);
|
|
2282
2310
|
const fulfillPayload = stringifyBigInts({
|
|
2283
2311
|
fulfillment: fulfillmentParams,
|
|
2284
2312
|
signature: signatureArray
|
|
@@ -2305,8 +2333,8 @@ async function fulfillOrder1155(account, params, config) {
|
|
|
2305
2333
|
async function cancelOrder1155(account, params, config) {
|
|
2306
2334
|
const { orderHash } = params;
|
|
2307
2335
|
const contract = getContract(config);
|
|
2308
|
-
const provider =
|
|
2309
|
-
const chainId =
|
|
2336
|
+
const provider = getProvider(config);
|
|
2337
|
+
const chainId = getChainId();
|
|
2310
2338
|
const currentNonce = await contract.nonces(account.address);
|
|
2311
2339
|
const cancelParams = {
|
|
2312
2340
|
order_hash: orderHash,
|
|
@@ -2317,7 +2345,7 @@ async function cancelOrder1155(account, params, config) {
|
|
|
2317
2345
|
build1155CancellationTypedData(cancelParams, chainId)
|
|
2318
2346
|
);
|
|
2319
2347
|
const signature = await account.signMessage(typedData);
|
|
2320
|
-
const signatureArray =
|
|
2348
|
+
const signatureArray = toSignatureArray(signature);
|
|
2321
2349
|
const cancelPayload = stringifyBigInts({
|
|
2322
2350
|
cancelation: cancelParams,
|
|
2323
2351
|
signature: signatureArray
|
|
@@ -2331,6 +2359,148 @@ async function cancelOrder1155(account, params, config) {
|
|
|
2331
2359
|
throw new MedialaneError("Failed to cancel ERC-1155 order", "TRANSACTION_FAILED", err);
|
|
2332
2360
|
}
|
|
2333
2361
|
}
|
|
2362
|
+
async function makeOffer1155(account, params, config) {
|
|
2363
|
+
const {
|
|
2364
|
+
nftContract,
|
|
2365
|
+
tokenId,
|
|
2366
|
+
amount,
|
|
2367
|
+
price,
|
|
2368
|
+
currency = DEFAULT_CURRENCY,
|
|
2369
|
+
durationSeconds
|
|
2370
|
+
} = params;
|
|
2371
|
+
const contract = getContract(config);
|
|
2372
|
+
const provider = getProvider(config);
|
|
2373
|
+
const chainId = getChainId();
|
|
2374
|
+
const token = resolveToken(currency);
|
|
2375
|
+
const priceWei = parseAmount(price, token.decimals);
|
|
2376
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
2377
|
+
const endTime = now + durationSeconds;
|
|
2378
|
+
const saltBytes = new Uint8Array(4);
|
|
2379
|
+
crypto.getRandomValues(saltBytes);
|
|
2380
|
+
const salt = new DataView(saltBytes.buffer).getUint32(0).toString();
|
|
2381
|
+
const currentNonce = await contract.nonces(account.address);
|
|
2382
|
+
const orderParams = {
|
|
2383
|
+
offerer: account.address,
|
|
2384
|
+
offer: {
|
|
2385
|
+
item_type: "ERC20",
|
|
2386
|
+
token: token.address,
|
|
2387
|
+
identifier_or_criteria: "0",
|
|
2388
|
+
start_amount: priceWei,
|
|
2389
|
+
end_amount: priceWei
|
|
2390
|
+
},
|
|
2391
|
+
consideration: {
|
|
2392
|
+
item_type: "ERC1155",
|
|
2393
|
+
token: nftContract,
|
|
2394
|
+
identifier_or_criteria: tokenId,
|
|
2395
|
+
start_amount: amount,
|
|
2396
|
+
end_amount: amount,
|
|
2397
|
+
recipient: account.address
|
|
2398
|
+
},
|
|
2399
|
+
start_time: (now + START_TIME_BUFFER_SECS).toString(),
|
|
2400
|
+
end_time: endTime.toString(),
|
|
2401
|
+
salt,
|
|
2402
|
+
nonce: currentNonce.toString()
|
|
2403
|
+
};
|
|
2404
|
+
const typedData = stringifyBigInts(
|
|
2405
|
+
build1155OrderTypedData(orderParams, chainId)
|
|
2406
|
+
);
|
|
2407
|
+
const signature = await account.signMessage(typedData);
|
|
2408
|
+
const signatureArray = toSignatureArray(signature);
|
|
2409
|
+
const registerPayload = stringifyBigInts({
|
|
2410
|
+
parameters: {
|
|
2411
|
+
...orderParams,
|
|
2412
|
+
offer: {
|
|
2413
|
+
...orderParams.offer,
|
|
2414
|
+
item_type: starknet.shortString.encodeShortString(orderParams.offer.item_type)
|
|
2415
|
+
},
|
|
2416
|
+
consideration: {
|
|
2417
|
+
...orderParams.consideration,
|
|
2418
|
+
item_type: starknet.shortString.encodeShortString(orderParams.consideration.item_type)
|
|
2419
|
+
}
|
|
2420
|
+
},
|
|
2421
|
+
signature: signatureArray
|
|
2422
|
+
});
|
|
2423
|
+
const amountU256 = starknet.cairo.uint256(priceWei);
|
|
2424
|
+
const approveCall = {
|
|
2425
|
+
contractAddress: token.address,
|
|
2426
|
+
entrypoint: "approve",
|
|
2427
|
+
calldata: [
|
|
2428
|
+
config.marketplace1155Contract,
|
|
2429
|
+
amountU256.low.toString(),
|
|
2430
|
+
amountU256.high.toString()
|
|
2431
|
+
]
|
|
2432
|
+
};
|
|
2433
|
+
const registerCall = contract.populate("register_order", [registerPayload]);
|
|
2434
|
+
try {
|
|
2435
|
+
const tx = await account.execute([approveCall, registerCall]);
|
|
2436
|
+
await provider.waitForTransaction(tx.transaction_hash);
|
|
2437
|
+
return { txHash: tx.transaction_hash };
|
|
2438
|
+
} catch (err) {
|
|
2439
|
+
throw new MedialaneError("Failed to make ERC-1155 offer", "TRANSACTION_FAILED", err);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
async function checkoutCart1155(account, items, config) {
|
|
2443
|
+
if (items.length === 0) throw new MedialaneError("Cart is empty", "INVALID_PARAMS");
|
|
2444
|
+
const contract = getContract(config);
|
|
2445
|
+
const provider = getProvider(config);
|
|
2446
|
+
const tokenTotals = /* @__PURE__ */ new Map();
|
|
2447
|
+
for (const item of items) {
|
|
2448
|
+
const prev = tokenTotals.get(item.considerationToken) ?? 0n;
|
|
2449
|
+
tokenTotals.set(item.considerationToken, prev + BigInt(item.considerationAmount));
|
|
2450
|
+
}
|
|
2451
|
+
const approveCalls = Array.from(tokenTotals.entries()).map(([tokenAddr, totalWei]) => {
|
|
2452
|
+
const amount = starknet.cairo.uint256(totalWei.toString());
|
|
2453
|
+
return {
|
|
2454
|
+
contractAddress: tokenAddr,
|
|
2455
|
+
entrypoint: "approve",
|
|
2456
|
+
calldata: [
|
|
2457
|
+
config.marketplace1155Contract,
|
|
2458
|
+
amount.low.toString(),
|
|
2459
|
+
amount.high.toString()
|
|
2460
|
+
]
|
|
2461
|
+
};
|
|
2462
|
+
});
|
|
2463
|
+
const currentNonce = await contract.nonces(account.address);
|
|
2464
|
+
const baseNonce = BigInt(currentNonce.toString());
|
|
2465
|
+
const chainId = getChainId();
|
|
2466
|
+
const fulfillCalls = [];
|
|
2467
|
+
for (let i = 0; i < items.length; i++) {
|
|
2468
|
+
const item = items[i];
|
|
2469
|
+
const nonce = (baseNonce + BigInt(i)).toString();
|
|
2470
|
+
const quantity = item.quantity ?? "1";
|
|
2471
|
+
const fulfillmentParams = {
|
|
2472
|
+
order_hash: item.orderHash,
|
|
2473
|
+
fulfiller: account.address,
|
|
2474
|
+
quantity,
|
|
2475
|
+
nonce
|
|
2476
|
+
};
|
|
2477
|
+
const typedData = stringifyBigInts(
|
|
2478
|
+
build1155FulfillmentTypedData(fulfillmentParams, chainId)
|
|
2479
|
+
);
|
|
2480
|
+
const signature = await account.signMessage(typedData);
|
|
2481
|
+
const signatureArray = toSignatureArray(signature);
|
|
2482
|
+
const fulfillPayload = stringifyBigInts({
|
|
2483
|
+
fulfillment: fulfillmentParams,
|
|
2484
|
+
signature: signatureArray
|
|
2485
|
+
});
|
|
2486
|
+
fulfillCalls.push(contract.populate("fulfill_order", [fulfillPayload]));
|
|
2487
|
+
}
|
|
2488
|
+
try {
|
|
2489
|
+
const tx = await account.execute([...approveCalls, ...fulfillCalls]);
|
|
2490
|
+
await provider.waitForTransaction(tx.transaction_hash);
|
|
2491
|
+
return { txHash: tx.transaction_hash };
|
|
2492
|
+
} catch (err) {
|
|
2493
|
+
throw new MedialaneError("ERC-1155 cart checkout failed", "TRANSACTION_FAILED", err);
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
async function getOrderDetails1155(orderHash, config) {
|
|
2497
|
+
const contract = getContract(config);
|
|
2498
|
+
return contract.get_order_details(orderHash);
|
|
2499
|
+
}
|
|
2500
|
+
async function getNonce1155(address, config) {
|
|
2501
|
+
const contract = getContract(config);
|
|
2502
|
+
return BigInt((await contract.nonces(address)).toString());
|
|
2503
|
+
}
|
|
2334
2504
|
|
|
2335
2505
|
// src/marketplace1155/index.ts
|
|
2336
2506
|
var Medialane1155Module = class {
|
|
@@ -2345,6 +2515,13 @@ var Medialane1155Module = class {
|
|
|
2345
2515
|
createListing(account, params) {
|
|
2346
2516
|
return createListing1155(account, params, this.config);
|
|
2347
2517
|
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Make an offer (bid) on an ERC-1155 token.
|
|
2520
|
+
* Approves the ERC-20 spend then calls `register_order` atomically.
|
|
2521
|
+
*/
|
|
2522
|
+
makeOffer(account, params) {
|
|
2523
|
+
return makeOffer1155(account, params, this.config);
|
|
2524
|
+
}
|
|
2348
2525
|
/**
|
|
2349
2526
|
* Fulfill (buy) an ERC-1155 listing.
|
|
2350
2527
|
* Approves the payment token then calls `fulfill_order` atomically.
|
|
@@ -2358,6 +2535,20 @@ var Medialane1155Module = class {
|
|
|
2358
2535
|
cancelOrder(account, params) {
|
|
2359
2536
|
return cancelOrder1155(account, params, this.config);
|
|
2360
2537
|
}
|
|
2538
|
+
/**
|
|
2539
|
+
* Checkout a cart of ERC-1155 orders atomically.
|
|
2540
|
+
* Signs one fulfillment per item (with quantity), sums ERC-20 approvals by token.
|
|
2541
|
+
*/
|
|
2542
|
+
checkoutCart(account, items) {
|
|
2543
|
+
return checkoutCart1155(account, items, this.config);
|
|
2544
|
+
}
|
|
2545
|
+
// ─── View calls ───────────────────────────────────────────────────────────
|
|
2546
|
+
getOrderDetails(orderHash) {
|
|
2547
|
+
return getOrderDetails1155(orderHash, this.config);
|
|
2548
|
+
}
|
|
2549
|
+
getNonce(address) {
|
|
2550
|
+
return getNonce1155(address, this.config);
|
|
2551
|
+
}
|
|
2361
2552
|
// ─── Typed data builders (for ChipiPay / custom signing flows) ───────────
|
|
2362
2553
|
buildListingTypedData(params, chainId) {
|
|
2363
2554
|
return build1155OrderTypedData(params, chainId);
|
|
@@ -3065,44 +3256,6 @@ var DropService = class {
|
|
|
3065
3256
|
return { txHash: res.transaction_hash };
|
|
3066
3257
|
}
|
|
3067
3258
|
};
|
|
3068
|
-
|
|
3069
|
-
// src/client.ts
|
|
3070
|
-
var MedialaneClient = class {
|
|
3071
|
-
constructor(rawConfig = {}) {
|
|
3072
|
-
this.config = resolveConfig(rawConfig);
|
|
3073
|
-
this.marketplace = new MarketplaceModule(this.config);
|
|
3074
|
-
this.marketplace1155 = new Medialane1155Module(this.config);
|
|
3075
|
-
this.services = {
|
|
3076
|
-
pop: new PopService(this.config),
|
|
3077
|
-
drop: new DropService(this.config)
|
|
3078
|
-
};
|
|
3079
|
-
if (!this.config.backendUrl) {
|
|
3080
|
-
this.api = new Proxy({}, {
|
|
3081
|
-
get(_target, prop) {
|
|
3082
|
-
return () => {
|
|
3083
|
-
throw new Error(
|
|
3084
|
-
`backendUrl not configured. Pass backendUrl to MedialaneClient to use .api.${String(prop)}()`
|
|
3085
|
-
);
|
|
3086
|
-
};
|
|
3087
|
-
}
|
|
3088
|
-
});
|
|
3089
|
-
} else {
|
|
3090
|
-
this.api = new ApiClient(this.config.backendUrl, this.config.apiKey, this.config.retryOptions);
|
|
3091
|
-
}
|
|
3092
|
-
}
|
|
3093
|
-
get network() {
|
|
3094
|
-
return this.config.network;
|
|
3095
|
-
}
|
|
3096
|
-
get rpcUrl() {
|
|
3097
|
-
return this.config.rpcUrl;
|
|
3098
|
-
}
|
|
3099
|
-
get marketplaceContract() {
|
|
3100
|
-
return this.config.marketplaceContract;
|
|
3101
|
-
}
|
|
3102
|
-
};
|
|
3103
|
-
|
|
3104
|
-
// src/types/api.ts
|
|
3105
|
-
var OPEN_LICENSES = ["CC0", "CC BY", "CC BY-SA", "CC BY-NC"];
|
|
3106
3259
|
var ERC1155CollectionService = class {
|
|
3107
3260
|
constructor(config) {
|
|
3108
3261
|
this.factoryAddress = config.collection1155Contract ?? COLLECTION_1155_CONTRACT_MAINNET;
|
|
@@ -3211,6 +3364,45 @@ var ERC1155CollectionService = class {
|
|
|
3211
3364
|
}
|
|
3212
3365
|
};
|
|
3213
3366
|
|
|
3367
|
+
// src/client.ts
|
|
3368
|
+
var MedialaneClient = class {
|
|
3369
|
+
constructor(rawConfig = {}) {
|
|
3370
|
+
this.config = resolveConfig(rawConfig);
|
|
3371
|
+
this.marketplace = new MarketplaceModule(this.config);
|
|
3372
|
+
this.marketplace1155 = new Medialane1155Module(this.config);
|
|
3373
|
+
this.services = {
|
|
3374
|
+
pop: new PopService(this.config),
|
|
3375
|
+
drop: new DropService(this.config),
|
|
3376
|
+
erc1155Collection: new ERC1155CollectionService(this.config)
|
|
3377
|
+
};
|
|
3378
|
+
if (!this.config.backendUrl) {
|
|
3379
|
+
this.api = new Proxy({}, {
|
|
3380
|
+
get(_target, prop) {
|
|
3381
|
+
return () => {
|
|
3382
|
+
throw new Error(
|
|
3383
|
+
`backendUrl not configured. Pass backendUrl to MedialaneClient to use .api.${String(prop)}()`
|
|
3384
|
+
);
|
|
3385
|
+
};
|
|
3386
|
+
}
|
|
3387
|
+
});
|
|
3388
|
+
} else {
|
|
3389
|
+
this.api = new ApiClient(this.config.backendUrl, this.config.apiKey, this.config.retryOptions);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
get network() {
|
|
3393
|
+
return this.config.network;
|
|
3394
|
+
}
|
|
3395
|
+
get rpcUrl() {
|
|
3396
|
+
return this.config.rpcUrl;
|
|
3397
|
+
}
|
|
3398
|
+
get marketplaceContract() {
|
|
3399
|
+
return this.config.marketplaceContract;
|
|
3400
|
+
}
|
|
3401
|
+
};
|
|
3402
|
+
|
|
3403
|
+
// src/types/api.ts
|
|
3404
|
+
var OPEN_LICENSES = ["CC0", "CC BY", "CC BY-SA", "CC BY-NC"];
|
|
3405
|
+
|
|
3214
3406
|
exports.ApiClient = ApiClient;
|
|
3215
3407
|
exports.COLLECTION_1155_CLASS_HASH_MAINNET = COLLECTION_1155_CLASS_HASH_MAINNET;
|
|
3216
3408
|
exports.COLLECTION_1155_CONTRACT_MAINNET = COLLECTION_1155_CONTRACT_MAINNET;
|
|
@@ -3260,6 +3452,7 @@ exports.build1155OrderTypedData = build1155OrderTypedData;
|
|
|
3260
3452
|
exports.buildCancellationTypedData = buildCancellationTypedData;
|
|
3261
3453
|
exports.buildFulfillmentTypedData = buildFulfillmentTypedData;
|
|
3262
3454
|
exports.buildOrderTypedData = buildOrderTypedData;
|
|
3455
|
+
exports.encodeByteArray = encodeByteArray;
|
|
3263
3456
|
exports.formatAmount = formatAmount;
|
|
3264
3457
|
exports.getListableTokens = getListableTokens;
|
|
3265
3458
|
exports.getTokenByAddress = getTokenByAddress;
|