@medialane/sdk 0.70.0 → 0.71.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.
@@ -261,18 +261,26 @@ var ApiClient = class {
261
261
  addr(a) {
262
262
  return normalizeAddress(this.chain, a);
263
263
  }
264
- async request(path, init) {
264
+ /**
265
+ * The one HTTP path for the whole client: base headers (incl. x-api-key),
266
+ * JSON error unwrapping, and `withRetry` (5xx/network only — 4xx never
267
+ * retried). `allow404`/`allow403` turn those statuses into a `null` result
268
+ * instead of a throw, for "profile may not exist" / "not a holder" reads —
269
+ * so no method needs to hand-roll `fetch` to get that behavior.
270
+ */
271
+ async request(path, init, opts) {
265
272
  const url = `${this.baseUrl.replace(/\/$/, "")}${path}`;
266
273
  const headers = { ...this.baseHeaders };
267
274
  if (!(init?.body instanceof FormData)) {
268
275
  headers["Content-Type"] = "application/json";
269
276
  }
277
+ const allowed = (status) => opts?.allow404 === true && status === 404 || opts?.allow403 === true && status === 403;
270
278
  const res = await withRetry(async () => {
271
279
  const response = await fetch(url, {
272
280
  ...init,
273
281
  headers: { ...headers, ...init?.headers }
274
282
  });
275
- if (!response.ok) {
283
+ if (!response.ok && !allowed(response.status)) {
276
284
  const text = await response.text().catch(() => response.statusText);
277
285
  let message = text;
278
286
  try {
@@ -284,6 +292,7 @@ var ApiClient = class {
284
292
  }
285
293
  return response;
286
294
  }, this.retryOptions);
295
+ if (allowed(res.status)) return null;
287
296
  return res.json();
288
297
  }
289
298
  get(path) {
@@ -298,20 +307,9 @@ var ApiClient = class {
298
307
  del(path) {
299
308
  return this.request(path, { method: "DELETE" });
300
309
  }
301
- async checkResponse(res, options) {
302
- if (options?.allow404 && res.status === 404) return null;
303
- if (options?.allow403 && res.status === 403) return null;
304
- if (!res.ok) {
305
- const text = await res.text().catch(() => res.statusText);
306
- let message = text;
307
- try {
308
- const body = JSON.parse(text);
309
- if (body.error) message = body.error;
310
- } catch {
311
- }
312
- throw new MedialaneApiError(res.status, message);
313
- }
314
- return res.json();
310
+ /** Bearer header for Clerk-JWT-authenticated routes. */
311
+ bearer(clerkToken) {
312
+ return { Authorization: `Bearer ${clerkToken}` };
315
313
  }
316
314
  // ─── Orders ────────────────────────────────────────────────────────────────
317
315
  getOrders(query = {}) {
@@ -515,17 +513,11 @@ var ApiClient = class {
515
513
  * Authorization: Bearer (Clerk JWT) simultaneously.
516
514
  */
517
515
  async claimCollection(contractAddress, walletAddress, clerkToken) {
518
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collections/claim`;
519
- const res = await fetch(url, {
516
+ return this.request("/v1/collections/claim", {
520
517
  method: "POST",
521
- headers: {
522
- "x-api-key": this.baseHeaders["x-api-key"] ?? "",
523
- "Content-Type": "application/json",
524
- "Authorization": `Bearer ${clerkToken}`
525
- },
526
- body: JSON.stringify({ contractAddress, walletAddress })
518
+ body: JSON.stringify({ contractAddress, walletAddress }),
519
+ headers: this.bearer(clerkToken)
527
520
  });
528
- return this.checkResponse(res);
529
521
  }
530
522
  /**
531
523
  * Path 3: Manual off-chain claim request (email-based).
@@ -537,106 +529,92 @@ var ApiClient = class {
537
529
  });
538
530
  }
539
531
  // ─── Collection Profiles ────────────────────────────────────────────────────
540
- async getCollectionProfile(contractAddress) {
541
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collections/${this.addr(contractAddress)}/profile`;
542
- const res = await fetch(url, { headers: this.baseHeaders });
543
- return this.checkResponse(res, { allow404: true });
532
+ getCollectionProfile(contractAddress) {
533
+ return this.request(
534
+ `/v1/collections/${this.addr(contractAddress)}/profile`,
535
+ { method: "GET" },
536
+ { allow404: true }
537
+ );
544
538
  }
545
539
  /**
546
540
  * Update collection profile. Requires Clerk JWT for ownership check.
547
541
  */
548
- async updateCollectionProfile(contractAddress, data, clerkToken) {
549
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collections/${this.addr(contractAddress)}/profile`;
550
- const res = await fetch(url, {
551
- method: "PATCH",
552
- headers: {
553
- "x-api-key": this.baseHeaders["x-api-key"] ?? "",
554
- "Content-Type": "application/json",
555
- "Authorization": `Bearer ${clerkToken}`
556
- },
557
- body: JSON.stringify(data)
558
- });
559
- return this.checkResponse(res);
542
+ updateCollectionProfile(contractAddress, data, clerkToken) {
543
+ return this.request(
544
+ `/v1/collections/${this.addr(contractAddress)}/profile`,
545
+ { method: "PATCH", body: JSON.stringify(data), headers: this.bearer(clerkToken) }
546
+ );
560
547
  }
561
- async getGatedContent(contractAddress, clerkToken) {
562
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collections/${this.addr(contractAddress)}/gated-content`;
563
- const res = await fetch(url, {
564
- headers: { ...this.baseHeaders, "Authorization": `Bearer ${clerkToken}` }
565
- });
566
- return this.checkResponse(res, { allow404: true, allow403: true });
548
+ getGatedContent(contractAddress, clerkToken) {
549
+ return this.request(
550
+ `/v1/collections/${this.addr(contractAddress)}/gated-content`,
551
+ { method: "GET", headers: this.bearer(clerkToken) },
552
+ { allow404: true, allow403: true }
553
+ );
567
554
  }
568
555
  // ─── Creator Profiles ───────────────────────────────────────────────────────
569
556
  /** List all creators with an approved username. */
570
- async getCreators(opts = {}) {
557
+ getCreators(opts = {}) {
571
558
  const params = new URLSearchParams();
572
559
  if (opts.search) params.set("search", opts.search);
573
560
  if (opts.page) params.set("page", String(opts.page));
574
561
  if (opts.limit) params.set("limit", String(opts.limit));
575
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/creators?${params}`;
576
- const res = await fetch(url, { headers: this.baseHeaders });
577
- return this.checkResponse(res);
562
+ const qs = params.toString();
563
+ return this.get(`/v1/creators${qs ? `?${qs}` : ""}`);
578
564
  }
579
- async getCreatorProfile(walletAddress) {
580
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/creators/${this.addr(walletAddress)}/profile`;
581
- const res = await fetch(url, { headers: this.baseHeaders });
582
- return this.checkResponse(res, { allow404: true });
565
+ getCreatorProfile(walletAddress) {
566
+ return this.request(
567
+ `/v1/creators/${this.addr(walletAddress)}/profile`,
568
+ { method: "GET" },
569
+ { allow404: true }
570
+ );
583
571
  }
584
572
  /** Resolve a username slug to a creator profile (public). */
585
- async getCreatorByUsername(username) {
586
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/creators/by-username/${encodeURIComponent(username.toLowerCase().trim())}`;
587
- const res = await fetch(url, { headers: this.baseHeaders });
588
- return this.checkResponse(res, { allow404: true });
573
+ getCreatorByUsername(username) {
574
+ return this.request(
575
+ `/v1/creators/by-username/${encodeURIComponent(username.toLowerCase().trim())}`,
576
+ { method: "GET" },
577
+ { allow404: true }
578
+ );
589
579
  }
590
580
  /**
591
581
  * Update creator profile. Requires Clerk JWT; wallet must match authenticated user.
592
582
  */
593
- async updateCreatorProfile(walletAddress, data, clerkToken) {
594
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/creators/${this.addr(walletAddress)}/profile`;
595
- const res = await fetch(url, {
596
- method: "PATCH",
597
- headers: {
598
- "x-api-key": this.baseHeaders["x-api-key"] ?? "",
599
- "Content-Type": "application/json",
600
- "Authorization": `Bearer ${clerkToken}`
601
- },
602
- body: JSON.stringify(data)
603
- });
604
- return this.checkResponse(res);
583
+ updateCreatorProfile(walletAddress, data, clerkToken) {
584
+ return this.request(
585
+ `/v1/creators/${this.addr(walletAddress)}/profile`,
586
+ { method: "PATCH", body: JSON.stringify(data), headers: this.bearer(clerkToken) }
587
+ );
605
588
  }
606
589
  // ─── Collection Slug Claims ───────────────────────────────────────────────────
607
590
  /** Check if a collection slug is available (public, no auth). */
608
- async checkCollectionSlugAvailability(slug) {
609
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collection-slug-claims/check/${encodeURIComponent(slug.toLowerCase().trim())}`;
610
- const res = await fetch(url, { headers: this.baseHeaders });
611
- return this.checkResponse(res);
591
+ checkCollectionSlugAvailability(slug) {
592
+ return this.get(
593
+ `/v1/collection-slug-claims/check/${encodeURIComponent(slug.toLowerCase().trim())}`
594
+ );
612
595
  }
613
596
  /** Submit a slug claim for a collection. Requires Clerk JWT — caller must be the collection owner. */
614
- async submitCollectionSlugClaim(contractAddress, slug, clerkToken, notifyEmail) {
615
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collection-slug-claims`;
616
- const res = await fetch(url, {
597
+ submitCollectionSlugClaim(contractAddress, slug, clerkToken, notifyEmail) {
598
+ return this.request("/v1/collection-slug-claims", {
617
599
  method: "POST",
618
- headers: {
619
- "x-api-key": this.baseHeaders["x-api-key"] ?? "",
620
- "Content-Type": "application/json",
621
- Authorization: `Bearer ${clerkToken}`
622
- },
623
- body: JSON.stringify({ contractAddress, slug, notifyEmail })
600
+ body: JSON.stringify({ contractAddress, slug, notifyEmail }),
601
+ headers: this.bearer(clerkToken)
624
602
  });
625
- return this.checkResponse(res);
626
603
  }
627
604
  /** Returns all slug claims submitted by the authenticated wallet. Requires Clerk JWT. */
628
- async getMyCollectionSlugClaims(clerkToken) {
629
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collection-slug-claims/me`;
630
- const res = await fetch(url, {
631
- headers: { ...this.baseHeaders, Authorization: `Bearer ${clerkToken}` }
605
+ getMyCollectionSlugClaims(clerkToken) {
606
+ return this.request("/v1/collection-slug-claims/me", {
607
+ method: "GET",
608
+ headers: this.bearer(clerkToken)
632
609
  });
633
- return this.checkResponse(res);
634
610
  }
635
611
  /** Resolve a collection slug to a full collection. Returns null if not found. */
636
- async getCollectionBySlug(slug) {
637
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/collections/by-slug/${encodeURIComponent(slug.toLowerCase().trim())}`;
638
- const res = await fetch(url, { headers: this.baseHeaders });
639
- return this.checkResponse(res, { allow404: true });
612
+ getCollectionBySlug(slug) {
613
+ return this.request(
614
+ `/v1/collections/by-slug/${encodeURIComponent(slug.toLowerCase().trim())}`,
615
+ { method: "GET" },
616
+ { allow404: true }
617
+ );
640
618
  }
641
619
  // ─── User Wallet ─────────────────────────────────────────────────────────────
642
620
  /**
@@ -653,33 +631,28 @@ var ApiClient = class {
653
631
  return this.post("/v1/users/register", params);
654
632
  }
655
633
  async upsertMyWallet(clerkToken, options = {}) {
656
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/users/me`;
657
634
  const body = {
658
635
  walletType: options.walletType ?? "UNKNOWN",
659
636
  appSource: options.appSource ?? "MEDIALANE_SDK"
660
637
  };
661
638
  if (options.chain) body.chain = options.chain;
662
- const res = await fetch(url, {
639
+ return this.request("/v1/users/me", {
663
640
  method: "POST",
664
- headers: {
665
- "Content-Type": "application/json",
666
- "Authorization": `Bearer ${clerkToken}`
667
- },
668
- body: JSON.stringify(body)
641
+ body: JSON.stringify(body),
642
+ headers: this.bearer(clerkToken)
669
643
  });
670
- return this.checkResponse(res);
671
644
  }
672
645
  /**
673
646
  * Get the authenticated user's stored wallet address from the backend DB.
674
647
  * Returns null if the user has not completed onboarding yet.
675
648
  * Requires Clerk JWT; no tenant API key needed.
676
649
  */
677
- async getMyWallet(clerkToken) {
678
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/users/me`;
679
- const res = await fetch(url, {
680
- headers: { "Authorization": `Bearer ${clerkToken}` }
681
- });
682
- return this.checkResponse(res, { allow404: true });
650
+ getMyWallet(clerkToken) {
651
+ return this.request(
652
+ "/v1/users/me",
653
+ { method: "GET", headers: this.bearer(clerkToken) },
654
+ { allow404: true }
655
+ );
683
656
  }
684
657
  // ─── Remix Licensing ─────────────────────────────────────────────────────────
685
658
  /**
@@ -729,25 +702,23 @@ var ApiClient = class {
729
702
  * role="creator" — offers where you are the original creator.
730
703
  * role="requester" — offers you made.
731
704
  */
732
- async getRemixOffers(query, clerkToken) {
705
+ getRemixOffers(query, clerkToken) {
733
706
  const params = new URLSearchParams({ role: query.role });
734
707
  if (query.page !== void 0) params.set("page", String(query.page));
735
708
  if (query.limit !== void 0) params.set("limit", String(query.limit));
736
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/remix-offers?${params}`;
737
- const res = await fetch(url, {
738
- headers: { ...this.baseHeaders, "Authorization": `Bearer ${clerkToken}` }
709
+ return this.request(`/v1/remix-offers?${params}`, {
710
+ method: "GET",
711
+ headers: this.bearer(clerkToken)
739
712
  });
740
- return this.checkResponse(res);
741
713
  }
742
714
  /**
743
715
  * Get a single remix offer. Clerk JWT optional (price/currency hidden for non-participants).
744
716
  */
745
- async getRemixOffer(id, clerkToken) {
746
- const url = `${this.baseUrl.replace(/\/$/, "")}/v1/remix-offers/${id}`;
747
- const headers = { ...this.baseHeaders };
748
- if (clerkToken) headers["Authorization"] = `Bearer ${clerkToken}`;
749
- const res = await fetch(url, { headers });
750
- return this.checkResponse(res);
717
+ getRemixOffer(id, clerkToken) {
718
+ return this.request(`/v1/remix-offers/${id}`, {
719
+ method: "GET",
720
+ headers: clerkToken ? this.bearer(clerkToken) : void 0
721
+ });
751
722
  }
752
723
  /**
753
724
  * Creator approves a remix offer (authorises the requester to mint). Requires Clerk JWT.
@@ -10342,8 +10313,21 @@ var ERC1155CollectionService = class {
10342
10313
 
10343
10314
  // src/utils/token.ts
10344
10315
  function getTokenByAddress(address) {
10345
- const lower = address.toLowerCase();
10346
- return SUPPORTED_TOKENS.find((t) => t.address.toLowerCase() === lower);
10316
+ let target = null;
10317
+ try {
10318
+ target = BigInt(address);
10319
+ } catch {
10320
+ target = null;
10321
+ }
10322
+ return SUPPORTED_TOKENS.find((t) => {
10323
+ if (target !== null) {
10324
+ try {
10325
+ return BigInt(t.address) === target;
10326
+ } catch {
10327
+ }
10328
+ }
10329
+ return t.address.toLowerCase() === address.toLowerCase();
10330
+ });
10347
10331
  }
10348
10332
 
10349
10333
  // src/starknet/services/creatorCoin.ts