@medialane/sdk 0.85.5 → 0.85.6

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 CHANGED
@@ -44,11 +44,6 @@ var COORDINATES = {
44
44
  ipClubFactoryClassHash: "0x05d9d431bd3532b1fa4d5bab572f49c5ad8034ee3cc83951aa41ae82c9cad266",
45
45
  ipClubCollectionClassHash: "0x05b8477c72e6bf0cf64967d71155021fd4d77d9a57e8805c6b40709121c002c5",
46
46
  ipClubFactoryStartBlock: 11928775,
47
- // v3 redesign (deployed 2026-07-15): single contract is both the
48
- // offer/bid/proposal registry and the license collection (embeds
49
- // ERC721Component directly) — no separate receipt contract, no
50
- // set_minter bootstrap. Supersedes the 2026-07-02 v2 address, which had
51
- // zero offers/licenses ever issued (clean cutover, no reclassification).
52
47
  ipSponsorship: "0x03729ebe0fedf29ec97fca34db09174772af7f870af26a26e024a61040143e5c",
53
48
  ipSponsorshipClassHash: "0x0626daac2ed7e2bf630ef5b10104b3202db1559216c0c1a504c0e99be2fbfec3",
54
49
  ipSponsorshipStartBlock: 11896456,
@@ -87,13 +82,10 @@ function resolveFeeConfig(raw) {
87
82
 
88
83
  // src/config.ts
89
84
  var MedialaneConfigSchema = zod.z.object({
90
- // Chain-scoped client (spec 2026-06-13 Decision B): one client per chain,
91
- // coordinates resolved from the registry. Replaces the removed `network` axis.
92
85
  chain: zod.z.enum(CHAINS).default(DEFAULT_CHAIN),
93
86
  rpcUrl: zod.z.string().url().optional(),
94
87
  backendUrl: zod.z.string().url().optional(),
95
88
  apiKey: zod.z.string().optional(),
96
- // Per-contract overrides remain for tests/forks; default from the registry.
97
89
  marketplace721Contract: zod.z.string().optional(),
98
90
  marketplaceContract: zod.z.string().optional(),
99
91
  marketplace1155Contract: zod.z.string().optional(),
@@ -283,17 +275,9 @@ var ApiClient = class {
283
275
  this.baseHeaders = apiKey ? { "x-api-key": apiKey } : {};
284
276
  this.retryOptions = retryOptions;
285
277
  }
286
- /** Normalize an address for this client's chain (chain-scoped — Decision B). */
287
278
  addr(a) {
288
279
  return normalizeAddress(this.chain, a);
289
280
  }
290
- /**
291
- * The one HTTP path for the whole client: base headers (incl. x-api-key),
292
- * JSON error unwrapping, and `withRetry` (5xx/network only — 4xx never
293
- * retried). `allow404`/`allow403` turn those statuses into a `null` result
294
- * instead of a throw, for "profile may not exist" / "not a holder" reads —
295
- * so no method needs to hand-roll `fetch` to get that behavior.
296
- */
297
281
  async request(path, init, opts) {
298
282
  const url = `${this.baseUrl.replace(/\/$/, "")}${path}`;
299
283
  const headers = { ...this.baseHeaders };
@@ -333,11 +317,9 @@ var ApiClient = class {
333
317
  del(path) {
334
318
  return this.request(path, { method: "DELETE" });
335
319
  }
336
- /** Bearer header for SIWS-token-authenticated routes. */
337
320
  bearer(siwsToken) {
338
321
  return { Authorization: `Bearer ${siwsToken}` };
339
322
  }
340
- // ─── Orders ────────────────────────────────────────────────────────────────
341
323
  getOrders(query = {}) {
342
324
  const params = new URLSearchParams();
343
325
  if (query.status) params.set("status", query.status);
@@ -364,7 +346,6 @@ var ApiClient = class {
364
346
  `/v1/orders/user/${this.addr(address)}?page=${page}&limit=${limit}`
365
347
  );
366
348
  }
367
- // ─── Tokens ────────────────────────────────────────────────────────────────
368
349
  getToken(contract, tokenId, wait = false) {
369
350
  return this.get(
370
351
  `/v1/tokens/${contract}/${tokenId}${wait ? "?wait=true" : ""}`
@@ -380,7 +361,6 @@ var ApiClient = class {
380
361
  `/v1/tokens/${contract}/${tokenId}/history?page=${page}&limit=${limit}`
381
362
  );
382
363
  }
383
- // ─── Collections ───────────────────────────────────────────────────────────
384
364
  getCollections(page = 1, limit = 20, isKnown, sort, service, chain, standard) {
385
365
  const params = new URLSearchParams({ page: String(page), limit: String(limit) });
386
366
  if (isKnown !== void 0) params.set("isKnown", String(isKnown));
@@ -402,7 +382,6 @@ var ApiClient = class {
402
382
  `/v1/collections/${this.addr(contract)}/tokens?page=${page}&limit=${limit}&sort=${sort}`
403
383
  );
404
384
  }
405
- // ─── Activities ────────────────────────────────────────────────────────────
406
385
  getActivities(query = {}) {
407
386
  const params = new URLSearchParams();
408
387
  if (query.type) params.set("type", query.type);
@@ -418,7 +397,6 @@ var ApiClient = class {
418
397
  `/v1/activities/${this.addr(address)}?page=${page}&limit=${limit}`
419
398
  );
420
399
  }
421
- // ─── Comments ──────────────────────────────────────────────────────────────
422
400
  getTokenComments(contract, tokenId, opts = {}) {
423
401
  const params = new URLSearchParams();
424
402
  if (opts.page !== void 0) params.set("page", String(opts.page));
@@ -428,7 +406,6 @@ var ApiClient = class {
428
406
  `/v1/tokens/${this.addr(contract)}/${tokenId}/comments${qs ? `?${qs}` : ""}`
429
407
  );
430
408
  }
431
- // ─── Search ────────────────────────────────────────────────────────────────
432
409
  search(q, limit = 10, chain) {
433
410
  const params = new URLSearchParams({ q, limit: String(limit) });
434
411
  if (chain) params.set("chain", chain);
@@ -436,7 +413,6 @@ var ApiClient = class {
436
413
  `/v1/search?${params.toString()}`
437
414
  );
438
415
  }
439
- // ─── Intents ───────────────────────────────────────────────────────────────
440
416
  createListingIntent(params) {
441
417
  return this.post("/v1/intents/listing", params);
442
418
  }
@@ -503,11 +479,6 @@ var ApiClient = class {
503
479
  rejectSponsorshipProposalIntent(params) {
504
480
  return this.post("/v1/intents/sponsorship-proposal-reject", params);
505
481
  }
506
- /**
507
- * Create a counter-offer intent. The seller proposes a new price in response
508
- * to a buyer's active bid. siwsToken is optional — the endpoint authenticates
509
- * via the tenant API key; pass a SIWS token only if your backend requires it.
510
- */
511
482
  createCounterOfferIntent(params, siwsToken) {
512
483
  const extraHeaders = siwsToken ? { "Authorization": `Bearer ${siwsToken}` } : {};
513
484
  return this.request("/v1/intents/counter-offer", {
@@ -516,10 +487,6 @@ var ApiClient = class {
516
487
  headers: extraHeaders
517
488
  });
518
489
  }
519
- /**
520
- * Fetch counter-offers. Pass `originalOrderHash` (buyer view) or
521
- * `sellerAddress` (seller view) — at least one is required.
522
- */
523
490
  getCounterOffers(query) {
524
491
  const params = new URLSearchParams();
525
492
  if (query.originalOrderHash) params.set("originalOrderHash", query.originalOrderHash);
@@ -528,7 +495,6 @@ var ApiClient = class {
528
495
  if (query.limit !== void 0) params.set("limit", String(query.limit));
529
496
  return this.get(`/v1/orders/counter-offers?${params}`);
530
497
  }
531
- // ─── Metadata ──────────────────────────────────────────────────────────────
532
498
  getMetadataSignedUrl() {
533
499
  return this.get("/v1/metadata/signed-url");
534
500
  }
@@ -547,7 +513,6 @@ var ApiClient = class {
547
513
  body: formData
548
514
  });
549
515
  }
550
- // ─── Portal (tenant self-service) ──────────────────────────────────────────
551
516
  getMe() {
552
517
  return this.get("/v1/portal/me");
553
518
  }
@@ -574,11 +539,6 @@ var ApiClient = class {
574
539
  `/v1/portal/webhooks/${id}`
575
540
  );
576
541
  }
577
- // ─── Collection Claims ──────────────────────────────────────────────────────
578
- /**
579
- * Path 1: On-chain auto claim. Sends both x-api-key (tenant auth) and
580
- * Authorization: Bearer (SIWS token) simultaneously.
581
- */
582
542
  async claimCollection(contractAddress, walletAddress, siwsToken) {
583
543
  return this.request("/v1/collections/claim", {
584
544
  method: "POST",
@@ -586,23 +546,18 @@ var ApiClient = class {
586
546
  headers: this.bearer(siwsToken)
587
547
  });
588
548
  }
589
- /**
590
- * Path 3: Manual off-chain claim request (email-based).
591
- */
592
549
  requestCollectionClaim(params) {
593
550
  return this.request("/v1/collections/claim/request", {
594
551
  method: "POST",
595
552
  body: JSON.stringify(params)
596
553
  });
597
554
  }
598
- // ─── Business Provisioning ──────────────────────────────────────────────────
599
555
  registerBusinessProvisioning(params) {
600
556
  return this.post("/v1/business/provisioning", params);
601
557
  }
602
558
  completeBusinessProvisioning(id) {
603
559
  return this.post(`/v1/business/provisioning/${id}/complete`, {});
604
560
  }
605
- // ─── Collection Profiles ────────────────────────────────────────────────────
606
561
  getCollectionProfile(contractAddress) {
607
562
  return this.request(
608
563
  `/v1/collections/${this.addr(contractAddress)}/profile`,
@@ -610,16 +565,12 @@ var ApiClient = class {
610
565
  { allow404: true }
611
566
  );
612
567
  }
613
- /**
614
- * Update collection profile. Requires SIWS token for ownership check.
615
- */
616
568
  updateCollectionProfile(contractAddress, data, siwsToken) {
617
569
  return this.request(
618
570
  `/v1/collections/${this.addr(contractAddress)}/profile`,
619
571
  { method: "PATCH", body: JSON.stringify(data), headers: this.bearer(siwsToken) }
620
572
  );
621
573
  }
622
- /** No signature required — wallet activity is public on-chain data, read like any other /v1 GET. */
623
574
  getWalletActivity(address, chain = "STARKNET") {
624
575
  return this.get(
625
576
  `/v1/wallet-activity?address=${this.addr(address)}&chain=${chain}`
@@ -632,8 +583,6 @@ var ApiClient = class {
632
583
  { allow404: true, allow403: true }
633
584
  );
634
585
  }
635
- // ─── Creator Profiles ───────────────────────────────────────────────────────
636
- /** List all creators with an approved username. */
637
586
  getCreators(opts = {}) {
638
587
  const params = new URLSearchParams();
639
588
  if (opts.search) params.set("search", opts.search);
@@ -649,7 +598,6 @@ var ApiClient = class {
649
598
  { allow404: true }
650
599
  );
651
600
  }
652
- /** Resolve a username slug to a creator profile (public). */
653
601
  getCreatorByUsername(username) {
654
602
  return this.request(
655
603
  `/v1/creators/by-username/${encodeURIComponent(username.toLowerCase().trim())}`,
@@ -657,23 +605,17 @@ var ApiClient = class {
657
605
  { allow404: true }
658
606
  );
659
607
  }
660
- /**
661
- * Update creator profile. Requires SIWS token; wallet must match authenticated user.
662
- */
663
608
  updateCreatorProfile(walletAddress, data, siwsToken) {
664
609
  return this.request(
665
610
  `/v1/creators/${this.addr(walletAddress)}/profile`,
666
611
  { method: "PATCH", body: JSON.stringify(data), headers: this.bearer(siwsToken) }
667
612
  );
668
613
  }
669
- // ─── Collection Slug Claims ───────────────────────────────────────────────────
670
- /** Check if a collection slug is available (public, no auth). */
671
614
  checkCollectionSlugAvailability(slug) {
672
615
  return this.get(
673
616
  `/v1/collection-slug-claims/check/${encodeURIComponent(slug.toLowerCase().trim())}`
674
617
  );
675
618
  }
676
- /** Submit a slug claim for a collection. Requires SIWS token — caller must be the collection owner. */
677
619
  submitCollectionSlugClaim(contractAddress, slug, siwsToken, notifyEmail) {
678
620
  return this.request("/v1/collection-slug-claims", {
679
621
  method: "POST",
@@ -681,14 +623,12 @@ var ApiClient = class {
681
623
  headers: this.bearer(siwsToken)
682
624
  });
683
625
  }
684
- /** Returns all slug claims submitted by the authenticated wallet. Requires SIWS token. */
685
626
  getMyCollectionSlugClaims(siwsToken) {
686
627
  return this.request("/v1/collection-slug-claims/me", {
687
628
  method: "GET",
688
629
  headers: this.bearer(siwsToken)
689
630
  });
690
631
  }
691
- /** Resolve a collection slug to a full collection. Returns null if not found. */
692
632
  getCollectionBySlug(slug) {
693
633
  return this.request(
694
634
  `/v1/collections/by-slug/${encodeURIComponent(slug.toLowerCase().trim())}`,
@@ -696,12 +636,6 @@ var ApiClient = class {
696
636
  { allow404: true }
697
637
  );
698
638
  }
699
- // ─── User Wallet ─────────────────────────────────────────────────────────────
700
- /**
701
- * Frictionless wallet registration. Tenant API key only (no SIWS token required).
702
- * Idempotent — backend's ensureAccountForWallet upserts and upgrades existing
703
- * UNKNOWN walletType rows when a more specific value is supplied.
704
- */
705
639
  async registerUser(params) {
706
640
  return this.post("/v1/users/register", params);
707
641
  }
@@ -720,18 +654,12 @@ var ApiClient = class {
720
654
  headers: this.bearer(siwsToken)
721
655
  });
722
656
  }
723
- /** Whether an email already has an account attached — used by io's onboarding to branch into an "already exists" message instead of creating a duplicate account. */
724
657
  async checkEmailExists(email) {
725
658
  const { exists } = await this.get(
726
659
  `/v1/auth/email/exists?email=${encodeURIComponent(email)}`
727
660
  );
728
661
  return exists;
729
662
  }
730
- /**
731
- * Get the authenticated user's stored wallet address from the backend DB.
732
- * Returns null if the user has not completed onboarding yet.
733
- * Requires SIWS token; no tenant API key needed.
734
- */
735
663
  getMyWallet(siwsToken) {
736
664
  return this.request(
737
665
  "/v1/users/me",
@@ -739,10 +667,6 @@ var ApiClient = class {
739
667
  { allow404: true }
740
668
  );
741
669
  }
742
- // ─── Remix Licensing ─────────────────────────────────────────────────────────
743
- /**
744
- * Get public remixes of a token (open to everyone).
745
- */
746
670
  getTokenRemixes(contract, tokenId, opts = {}) {
747
671
  const params = new URLSearchParams();
748
672
  if (opts.page !== void 0) params.set("page", String(opts.page));
@@ -752,9 +676,6 @@ var ApiClient = class {
752
676
  `/v1/tokens/${this.addr(contract)}/${tokenId}/remixes${qs ? `?${qs}` : ""}`
753
677
  );
754
678
  }
755
- /**
756
- * Submit a custom remix offer for a token. Requires SIWS token.
757
- */
758
679
  submitRemixOffer(params, siwsToken) {
759
680
  return this.request("/v1/remix-offers", {
760
681
  method: "POST",
@@ -762,9 +683,6 @@ var ApiClient = class {
762
683
  headers: { "Authorization": `Bearer ${siwsToken}` }
763
684
  });
764
685
  }
765
- /**
766
- * Submit an auto remix offer for a token with an open license. Requires SIWS token.
767
- */
768
686
  submitAutoRemixOffer(params, siwsToken) {
769
687
  return this.request("/v1/remix-offers/auto", {
770
688
  method: "POST",
@@ -772,9 +690,6 @@ var ApiClient = class {
772
690
  headers: { "Authorization": `Bearer ${siwsToken}` }
773
691
  });
774
692
  }
775
- /**
776
- * Record a self-remix (owner remixing their own token). Requires SIWS token.
777
- */
778
693
  confirmSelfRemix(params, siwsToken) {
779
694
  return this.request("/v1/remix-offers/self/confirm", {
780
695
  method: "POST",
@@ -782,11 +697,6 @@ var ApiClient = class {
782
697
  headers: { "Authorization": `Bearer ${siwsToken}` }
783
698
  });
784
699
  }
785
- /**
786
- * List remix offers by role. Requires SIWS token.
787
- * role="creator" — offers where you are the original creator.
788
- * role="requester" — offers you made.
789
- */
790
700
  getRemixOffers(query, siwsToken) {
791
701
  const params = new URLSearchParams({ role: query.role });
792
702
  if (query.page !== void 0) params.set("page", String(query.page));
@@ -796,18 +706,12 @@ var ApiClient = class {
796
706
  headers: this.bearer(siwsToken)
797
707
  });
798
708
  }
799
- /**
800
- * Get a single remix offer. SIWS token optional (price/currency hidden for non-participants).
801
- */
802
709
  getRemixOffer(id, siwsToken) {
803
710
  return this.request(`/v1/remix-offers/${id}`, {
804
711
  method: "GET",
805
712
  headers: siwsToken ? this.bearer(siwsToken) : void 0
806
713
  });
807
714
  }
808
- /**
809
- * Creator approves a remix offer (authorises the requester to mint). Requires SIWS token.
810
- */
811
715
  confirmRemixOffer(id, params, siwsToken) {
812
716
  return this.request(`/v1/remix-offers/${id}/confirm`, {
813
717
  method: "POST",
@@ -815,9 +719,6 @@ var ApiClient = class {
815
719
  headers: { "Authorization": `Bearer ${siwsToken}` }
816
720
  });
817
721
  }
818
- /**
819
- * Creator rejects a remix offer. Requires SIWS token.
820
- */
821
722
  rejectRemixOffer(id, siwsToken) {
822
723
  return this.request(`/v1/remix-offers/${id}/reject`, {
823
724
  method: "POST",
@@ -825,10 +726,6 @@ var ApiClient = class {
825
726
  headers: { "Authorization": `Bearer ${siwsToken}` }
826
727
  });
827
728
  }
828
- /**
829
- * Requester extends the expiry of a pending remix offer by 1–30 days.
830
- * Requires SIWS token.
831
- */
832
729
  extendRemixOffer(id, days, siwsToken) {
833
730
  return this.request(`/v1/remix-offers/${id}/extend`, {
834
731
  method: "POST",
@@ -836,7 +733,6 @@ var ApiClient = class {
836
733
  headers: { "Authorization": `Bearer ${siwsToken}` }
837
734
  });
838
735
  }
839
- // ─── POP Protocol ──────────────────────────────────────────────────────────
840
736
  getPopCollections(opts = {}) {
841
737
  return this.getCollections(opts.page ?? 1, opts.limit ?? 20, void 0, opts.sort, "POP_PROTOCOL");
842
738
  }
@@ -853,9 +749,6 @@ var ApiClient = class {
853
749
  );
854
750
  return res.data;
855
751
  }
856
- // ─── Coins (fungible — ERC-20 etc.) ───────────────────────────────────────────
857
- // Coins are a separate model from Collections (spec 2026-06-14). Price/liquidity
858
- // is read live from Ekubo (CreatorCoinService.getPrice), never from these.
859
752
  getCoins(opts = {}) {
860
753
  const params = new URLSearchParams();
861
754
  if (opts.page) params.set("page", String(opts.page));
@@ -868,11 +761,6 @@ var ApiClient = class {
868
761
  getCoin(contract) {
869
762
  return this.get(`/v1/coins/${this.addr(contract)}`);
870
763
  }
871
- /**
872
- * Creator-authed coin profile edit (image/description). Backend authorizes
873
- * via `coin.creator` (trustless — from the factory event), not a body param;
874
- * `siwsToken` is the caller's SIWS bearer token for `identityAuth`.
875
- */
876
764
  updateCoinProfile(contract, data, siwsToken) {
877
765
  return this.request(`/v1/coins/${this.addr(contract)}`, {
878
766
  method: "PATCH",
@@ -880,7 +768,6 @@ var ApiClient = class {
880
768
  headers: this.bearer(siwsToken)
881
769
  });
882
770
  }
883
- // ─── Collection Drop ────────────────────────────────────────────────────────
884
771
  getDropCollections(opts = {}) {
885
772
  return this.getCollections(opts.page ?? 1, opts.limit ?? 20, void 0, opts.sort, "COLLECTION_DROP");
886
773
  }
@@ -890,29 +777,22 @@ var ApiClient = class {
890
777
  );
891
778
  return res.data;
892
779
  }
893
- // ─── Rewards (v0.49.0) ─────────────────────────────────────────────────────
894
- // Scores are recomputed on a schedule by the backend (~15 min) — reads only.
895
- /** Score + level + progress + badges for one address (zeroed for unknown). */
896
780
  async getRewards(address) {
897
781
  const res = await this.get(`/v1/rewards/${this.addr(address)}`);
898
782
  return res.data;
899
783
  }
900
- /** Paginated XP leaderboard. */
901
784
  getRewardsLeaderboard(page = 1, limit = 50) {
902
785
  return this.get(`/v1/rewards?page=${page}&limit=${limit}`);
903
786
  }
904
- /** Point-event history for an address. */
905
787
  getRewardsEvents(address, page = 1, limit = 20) {
906
788
  return this.get(
907
789
  `/v1/rewards/${this.addr(address)}/events?page=${page}&limit=${limit}`
908
790
  );
909
791
  }
910
- /** Reward configuration: level ladder, enabled action XP values, badge catalog. */
911
792
  async getRewardsConfig() {
912
793
  const res = await this.get(`/v1/rewards/config`);
913
794
  return res.data;
914
795
  }
915
- /** Minimal level info for up to 50 addresses — one call per list page. */
916
796
  async getRewardsBatch(addresses) {
917
797
  if (addresses.length === 0) return [];
918
798
  const params = new URLSearchParams({ addresses: addresses.map((a) => this.addr(a)).join(",") });
@@ -960,7 +840,6 @@ var STARKNET_CREATOR_COIN_START_BLOCK = SN.creatorCoinStartBlock;
960
840
  var STARKNET_EKUBO_CORE = SN.ekuboCore;
961
841
  var SUPPORTED_TOKENS = [
962
842
  {
963
- // Circle-native USDC on Starknet (canonical)
964
843
  symbol: "USDC",
965
844
  address: "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
966
845
  decimals: 6,
@@ -1032,10 +911,6 @@ var SERVICES = {
1032
911
  capabilities: ["list", "buy", "make_offer", "cancel", "transfer", "mint", "remix", "license"],
1033
912
  events: [
1034
913
  { name: "CollectionCreated", emittedBy: "factory" }
1035
- // Per-instance ERC-721 Transfer emitted by each deployed collection; not
1036
- // yet declared here because the indexer polls discovered instances on a
1037
- // slow schedule. Plan 2026-05-24-data-driven-event-registry.md covers
1038
- // the migration.
1039
914
  ],
1040
915
  metadataSchema: { licenseDefault: "CC BY-SA" }
1041
916
  },
@@ -1047,8 +922,6 @@ var SERVICES = {
1047
922
  provenance: "MEDIALANE",
1048
923
  uiVariant: "standard",
1049
924
  capabilities: ["list", "buy", "make_offer", "cancel", "transfer", "mint", "remix", "license"],
1050
- // No factory — single shared contract. Events declared when the genesis
1051
- // contract address is wired into onchain.STARKNET.factoryAddress here.
1052
925
  metadataSchema: { licenseDefault: "CC BY-SA" }
1053
926
  },
1054
927
  "mip-erc1155": {
@@ -1165,14 +1038,6 @@ var SERVICES = {
1165
1038
  }
1166
1039
  },
1167
1040
  uiVariant: "standard",
1168
- // v3: one contract is both the offer/bid/proposal registry and the
1169
- // issued license collection (a real, standard ERC-721 minted internally
1170
- // — no separate receipt contract). `transfer` reflects that a license is
1171
- // freely transferable at the protocol layer; transferable/expiry intent
1172
- // is declarative (carried in metadata + LicenseMinted), never
1173
- // contract-enforced. Supersedes the 2026-07-02 v2 `ip-sponsorship`
1174
- // (registry-only) + `ip-sponsorship-license` (non-authoritative receipt
1175
- // via a dedicated ip-erc721 instance) pair — retired as of this redesign.
1176
1041
  capabilities: ["sponsor", "transfer"],
1177
1042
  events: [
1178
1043
  { name: "OfferCreated", emittedBy: "factory" },
@@ -1195,10 +1060,6 @@ var SERVICES = {
1195
1060
  }
1196
1061
  },
1197
1062
  uiVariant: "coin",
1198
- // `swap` is a UI affordance (05 §III): the marketplace renders an embedded
1199
- // Ekubo swap (via StarkZapp) for the coin. Settlement is Ekubo — Medialane
1200
- // operates NO trading venue and custodies nothing. No venue service exists
1201
- // for coins (unlike NFTs, whose Medialane marketplace contract settles them).
1202
1063
  capabilities: ["launch", "swap", "transfer"],
1203
1064
  events: [
1204
1065
  { name: "CreatorCoinCreated", emittedBy: "factory" },