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