@misofm/platform 0.26.2 → 0.28.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.
- package/README.md +309 -204
- package/dist/Miso.d.ts +403 -0
- package/dist/Miso.d.ts.map +1 -0
- package/dist/Miso.js +455 -0
- package/dist/Miso.js.map +1 -0
- package/dist/auth.d.ts +11 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +16 -3
- package/dist/auth.js.map +1 -1
- package/dist/catalog.d.ts +8 -5
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +36 -19
- package/dist/catalog.js.map +1 -1
- package/dist/client.d.ts +52 -443
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +58 -775
- package/dist/client.js.map +1 -1
- package/dist/contracts/composition_credits/composition_credits.d.ts +38 -48
- package/dist/contracts/composition_credits/composition_credits.d.ts.map +1 -1
- package/dist/contracts/composition_credits/composition_credits.js +20 -4
- package/dist/contracts/composition_credits/composition_credits.js.map +1 -1
- package/dist/contracts/composition_routed_stake/composition_routed_stake.d.ts +64 -1
- package/dist/contracts/composition_routed_stake/composition_routed_stake.d.ts.map +1 -1
- package/dist/contracts/composition_routed_stake/composition_routed_stake.js +66 -1
- package/dist/contracts/composition_routed_stake/composition_routed_stake.js.map +1 -1
- package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts +52 -4
- package/dist/contracts/composition_royalty_pool/composition_royalty_pool.d.ts.map +1 -1
- package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js +52 -4
- package/dist/contracts/composition_royalty_pool/composition_royalty_pool.js.map +1 -1
- package/dist/contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.d.ts +63 -1
- package/dist/contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.d.ts.map +1 -1
- package/dist/contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.js +63 -1
- package/dist/contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.js.map +1 -1
- package/dist/contracts/genre/genre.d.ts +10 -1
- package/dist/contracts/genre/genre.d.ts.map +1 -1
- package/dist/contracts/genre/genre.js +8 -1
- package/dist/contracts/genre/genre.js.map +1 -1
- package/dist/contracts/miso_pay/deps/std/type_name.d.ts.map +1 -0
- package/dist/contracts/miso_pay/deps/std/type_name.js.map +1 -0
- package/dist/contracts/miso_pay/pay.d.ts +209 -0
- package/dist/contracts/miso_pay/pay.d.ts.map +1 -0
- package/dist/contracts/miso_pay/pay.js +195 -0
- package/dist/contracts/miso_pay/pay.js.map +1 -0
- package/dist/contracts/party_cta/party_cta.d.ts +49 -3
- package/dist/contracts/party_cta/party_cta.d.ts.map +1 -1
- package/dist/contracts/party_cta/party_cta.js +27 -5
- package/dist/contracts/party_cta/party_cta.js.map +1 -1
- package/dist/contracts/party_genre/party_genre.d.ts +25 -0
- package/dist/contracts/party_genre/party_genre.d.ts.map +1 -1
- package/dist/contracts/party_genre/party_genre.js +14 -3
- package/dist/contracts/party_genre/party_genre.js.map +1 -1
- package/dist/contracts/party_media/party_media.d.ts +19 -3
- package/dist/contracts/party_media/party_media.d.ts.map +1 -1
- package/dist/contracts/party_media/party_media.js +20 -4
- package/dist/contracts/party_media/party_media.js.map +1 -1
- package/dist/contracts/party_platform_link/party_platform_link.d.ts +15 -7
- package/dist/contracts/party_platform_link/party_platform_link.d.ts.map +1 -1
- package/dist/contracts/party_platform_link/party_platform_link.js +15 -7
- package/dist/contracts/party_platform_link/party_platform_link.js.map +1 -1
- package/dist/contracts/party_profile/party_profile.d.ts +63 -8
- package/dist/contracts/party_profile/party_profile.d.ts.map +1 -1
- package/dist/contracts/party_profile/party_profile.js +33 -8
- package/dist/contracts/party_profile/party_profile.js.map +1 -1
- package/dist/contracts/party_roles/party_roles.d.ts +28 -3
- package/dist/contracts/party_roles/party_roles.d.ts.map +1 -1
- package/dist/contracts/party_roles/party_roles.js +19 -4
- package/dist/contracts/party_roles/party_roles.js.map +1 -1
- package/dist/contracts/party_tags/party_tags.d.ts +23 -3
- package/dist/contracts/party_tags/party_tags.d.ts.map +1 -1
- package/dist/contracts/party_tags/party_tags.js +16 -4
- package/dist/contracts/party_tags/party_tags.js.map +1 -1
- package/dist/contracts/party_wallet/party_wallet.d.ts +4 -1
- package/dist/contracts/party_wallet/party_wallet.d.ts.map +1 -1
- package/dist/contracts/party_wallet/party_wallet.js +2 -1
- package/dist/contracts/party_wallet/party_wallet.js.map +1 -1
- package/dist/contracts/platform_link/platform_link.d.ts +207 -0
- package/dist/contracts/platform_link/platform_link.d.ts.map +1 -0
- package/dist/contracts/platform_link/platform_link.js +209 -0
- package/dist/contracts/platform_link/platform_link.js.map +1 -0
- package/dist/contracts/record/pressing.d.ts +53 -7
- package/dist/contracts/record/pressing.d.ts.map +1 -1
- package/dist/contracts/record/pressing.js +50 -4
- package/dist/contracts/record/pressing.js.map +1 -1
- package/dist/contracts/record/record.d.ts +14 -0
- package/dist/contracts/record/record.d.ts.map +1 -1
- package/dist/contracts/record/record.js +15 -1
- package/dist/contracts/record/record.js.map +1 -1
- package/dist/contracts/record_shop/listing.d.ts +80 -35
- package/dist/contracts/record_shop/listing.d.ts.map +1 -1
- package/dist/contracts/record_shop/listing.js +76 -13
- package/dist/contracts/record_shop/listing.js.map +1 -1
- package/dist/contracts/recording_advisory/recording_advisory.d.ts +15 -15
- package/dist/contracts/recording_advisory/recording_advisory.d.ts.map +1 -1
- package/dist/contracts/recording_advisory/recording_advisory.js +15 -8
- package/dist/contracts/recording_advisory/recording_advisory.js.map +1 -1
- package/dist/contracts/recording_credits/recording_credits.d.ts +95 -1350
- package/dist/contracts/recording_credits/recording_credits.d.ts.map +1 -1
- package/dist/contracts/recording_credits/recording_credits.js +63 -12
- package/dist/contracts/recording_credits/recording_credits.js.map +1 -1
- package/dist/contracts/recording_engine_session/recording_engine_session.d.ts +30 -49
- package/dist/contracts/recording_engine_session/recording_engine_session.d.ts.map +1 -1
- package/dist/contracts/recording_engine_session/recording_engine_session.js +19 -4
- package/dist/contracts/recording_engine_session/recording_engine_session.js.map +1 -1
- package/dist/contracts/recording_genre/recording_genre.d.ts +67 -9
- package/dist/contracts/recording_genre/recording_genre.d.ts.map +1 -1
- package/dist/contracts/recording_genre/recording_genre.js +53 -9
- package/dist/contracts/recording_genre/recording_genre.js.map +1 -1
- package/dist/contracts/recording_language/recording_language.d.ts +29 -5
- package/dist/contracts/recording_language/recording_language.d.ts.map +1 -1
- package/dist/contracts/recording_language/recording_language.js +18 -5
- package/dist/contracts/recording_language/recording_language.js.map +1 -1
- package/dist/contracts/recording_master_reference/recording_master_reference.d.ts +25 -15
- package/dist/contracts/recording_master_reference/recording_master_reference.d.ts.map +1 -1
- package/dist/contracts/recording_master_reference/recording_master_reference.js +18 -5
- package/dist/contracts/recording_master_reference/recording_master_reference.js.map +1 -1
- package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts +55 -4
- package/dist/contracts/recording_royalty_pool/recording_royalty_pool.d.ts.map +1 -1
- package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js +55 -4
- package/dist/contracts/recording_royalty_pool/recording_royalty_pool.js.map +1 -1
- package/dist/contracts/recording_royalty_pool_plugin/recording_royalty_pool_plugin.d.ts +66 -1
- package/dist/contracts/recording_royalty_pool_plugin/recording_royalty_pool_plugin.d.ts.map +1 -1
- package/dist/contracts/recording_royalty_pool_plugin/recording_royalty_pool_plugin.js +66 -1
- package/dist/contracts/recording_royalty_pool_plugin/recording_royalty_pool_plugin.js.map +1 -1
- package/dist/contracts/recording_streaming_transcode/recording_streaming_transcode.d.ts +12 -9
- package/dist/contracts/recording_streaming_transcode/recording_streaming_transcode.d.ts.map +1 -1
- package/dist/contracts/recording_streaming_transcode/recording_streaming_transcode.js +11 -4
- package/dist/contracts/recording_streaming_transcode/recording_streaming_transcode.js.map +1 -1
- package/dist/contracts/release_cover_art/release_cover_art.d.ts +168 -74
- package/dist/contracts/release_cover_art/release_cover_art.d.ts.map +1 -1
- package/dist/contracts/release_cover_art/release_cover_art.js +126 -10
- package/dist/contracts/release_cover_art/release_cover_art.js.map +1 -1
- package/dist/contracts/release_credits/release_credits.d.ts +24 -28
- package/dist/contracts/release_credits/release_credits.d.ts.map +1 -1
- package/dist/contracts/release_credits/release_credits.js +18 -4
- package/dist/contracts/release_credits/release_credits.js.map +1 -1
- package/dist/contracts/release_description/release_description.d.ts +16 -5
- package/dist/contracts/release_description/release_description.d.ts.map +1 -1
- package/dist/contracts/release_description/release_description.js +9 -4
- package/dist/contracts/release_description/release_description.js.map +1 -1
- package/dist/contracts/release_dsp_link/release_dsp_link.d.ts +130 -160
- package/dist/contracts/release_dsp_link/release_dsp_link.d.ts.map +1 -1
- package/dist/contracts/release_dsp_link/release_dsp_link.js +74 -19
- package/dist/contracts/release_dsp_link/release_dsp_link.js.map +1 -1
- package/dist/contracts/release_genre/release_genre.d.ts +66 -11
- package/dist/contracts/release_genre/release_genre.d.ts.map +1 -1
- package/dist/contracts/release_genre/release_genre.js +52 -11
- package/dist/contracts/release_genre/release_genre.js.map +1 -1
- package/dist/contracts/release_kind/release_kind.d.ts +28 -5
- package/dist/contracts/release_kind/release_kind.d.ts.map +1 -1
- package/dist/contracts/release_kind/release_kind.js +19 -4
- package/dist/contracts/release_kind/release_kind.js.map +1 -1
- package/dist/contracts/release_revenue_distributor/release_revenue_distributor.d.ts +17 -0
- package/dist/contracts/release_revenue_distributor/release_revenue_distributor.d.ts.map +1 -1
- package/dist/contracts/release_revenue_distributor/release_revenue_distributor.js +15 -0
- package/dist/contracts/release_revenue_distributor/release_revenue_distributor.js.map +1 -1
- package/dist/contracts/release_revenue_distributor_plugin/release_revenue_distributor_plugin.d.ts +37 -1
- package/dist/contracts/release_revenue_distributor_plugin/release_revenue_distributor_plugin.d.ts.map +1 -1
- package/dist/contracts/release_revenue_distributor_plugin/release_revenue_distributor_plugin.js +37 -1
- package/dist/contracts/release_revenue_distributor_plugin/release_revenue_distributor_plugin.js.map +1 -1
- package/dist/contracts/routed_stake/routed_stake.d.ts +78 -6
- package/dist/contracts/routed_stake/routed_stake.d.ts.map +1 -1
- package/dist/contracts/routed_stake/routed_stake.js +79 -7
- package/dist/contracts/routed_stake/routed_stake.js.map +1 -1
- package/dist/contracts/royalty_pool/pool.d.ts +117 -27
- package/dist/contracts/royalty_pool/pool.d.ts.map +1 -1
- package/dist/contracts/royalty_pool/pool.js +117 -28
- package/dist/contracts/royalty_pool/pool.js.map +1 -1
- package/dist/contracts/royalty_pool/stake.d.ts +3 -0
- package/dist/contracts/royalty_pool/stake.d.ts.map +1 -1
- package/dist/contracts/royalty_pool/stake.js +5 -2
- package/dist/contracts/royalty_pool/stake.js.map +1 -1
- package/dist/contracts/share/share.d.ts +80 -0
- package/dist/contracts/share/share.d.ts.map +1 -0
- package/dist/contracts/share/share.js +72 -0
- package/dist/contracts/share/share.js.map +1 -0
- package/dist/contracts/vault/vault.d.ts +51 -0
- package/dist/contracts/vault/vault.d.ts.map +1 -1
- package/dist/contracts/vault/vault.js +55 -4
- package/dist/contracts/vault/vault.js.map +1 -1
- package/dist/contracts.d.ts +60 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +17 -0
- package/dist/contracts.js.map +1 -1
- package/dist/cover.d.ts +5 -6
- package/dist/cover.d.ts.map +1 -1
- package/dist/cover.js +10 -10
- package/dist/cover.js.map +1 -1
- package/dist/credits.d.ts +12 -13
- package/dist/credits.d.ts.map +1 -1
- package/dist/credits.js +16 -10
- package/dist/credits.js.map +1 -1
- package/dist/deployments.d.ts +3 -3
- package/dist/deployments.d.ts.map +1 -1
- package/dist/deployments.js +2 -3
- package/dist/deployments.js.map +1 -1
- package/dist/errors.d.ts +32 -9
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +52 -16
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +1687 -835
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +258 -39
- package/dist/events.js.map +1 -1
- package/dist/genre.d.ts +11 -12
- package/dist/genre.d.ts.map +1 -1
- package/dist/genre.js +5 -3
- package/dist/genre.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/packages.d.ts +1047 -1695
- package/dist/packages.d.ts.map +1 -1
- package/dist/party/client.d.ts +113 -296
- package/dist/party/client.d.ts.map +1 -1
- package/dist/party/client.js +93 -178
- package/dist/party/client.js.map +1 -1
- package/dist/party/extensions/ctas.d.ts +3 -3
- package/dist/party/extensions/ctas.d.ts.map +1 -1
- package/dist/party/extensions/genres.d.ts +4 -4
- package/dist/party/extensions/genres.d.ts.map +1 -1
- package/dist/party/extensions/links.d.ts +5 -5
- package/dist/party/extensions/links.d.ts.map +1 -1
- package/dist/party/extensions/links.js.map +1 -1
- package/dist/party/extensions/media.d.ts +3 -3
- package/dist/party/extensions/media.d.ts.map +1 -1
- package/dist/party/extensions/profile.d.ts +3 -3
- package/dist/party/extensions/profile.d.ts.map +1 -1
- package/dist/party/extensions/roles.d.ts +4 -4
- package/dist/party/extensions/roles.d.ts.map +1 -1
- package/dist/party/extensions/roles.js.map +1 -1
- package/dist/party/extensions/tags.d.ts +4 -4
- package/dist/party/extensions/tags.d.ts.map +1 -1
- package/dist/party/index.d.ts +1 -1
- package/dist/party/index.d.ts.map +1 -1
- package/dist/party/index.js.map +1 -1
- package/dist/party/queries.d.ts +8 -8
- package/dist/party/queries.d.ts.map +1 -1
- package/dist/party/queries.js +83 -56
- package/dist/party/queries.js.map +1 -1
- package/dist/pressing.d.ts +13 -15
- package/dist/pressing.d.ts.map +1 -1
- package/dist/pressing.js +99 -29
- package/dist/pressing.js.map +1 -1
- package/dist/publication.d.ts +13 -6
- package/dist/publication.d.ts.map +1 -1
- package/dist/publication.js +26 -21
- package/dist/publication.js.map +1 -1
- package/dist/queries.js +3 -3
- package/dist/queries.js.map +1 -1
- package/dist/read/artist.d.ts +4 -3
- package/dist/read/artist.d.ts.map +1 -1
- package/dist/read/artist.js +24 -8
- package/dist/read/artist.js.map +1 -1
- package/dist/read/catalog.d.ts +17 -16
- package/dist/read/catalog.d.ts.map +1 -1
- package/dist/read/catalog.js +25 -11
- package/dist/read/catalog.js.map +1 -1
- package/dist/read/client.d.ts +41 -20
- package/dist/read/client.d.ts.map +1 -1
- package/dist/read/client.js +20 -12
- package/dist/read/client.js.map +1 -1
- package/dist/read/config.d.ts +27 -3
- package/dist/read/config.d.ts.map +1 -1
- package/dist/read/config.js +42 -24
- package/dist/read/config.js.map +1 -1
- package/dist/read/genres.d.ts +8 -3
- package/dist/read/genres.d.ts.map +1 -1
- package/dist/read/genres.js +23 -17
- package/dist/read/genres.js.map +1 -1
- package/dist/read/index.d.ts +3 -1
- package/dist/read/index.d.ts.map +1 -1
- package/dist/read/index.js +9 -6
- package/dist/read/index.js.map +1 -1
- package/dist/read/receipts.d.ts +5 -4
- package/dist/read/receipts.d.ts.map +1 -1
- package/dist/read/receipts.js +94 -46
- package/dist/read/receipts.js.map +1 -1
- package/dist/read/royalties.d.ts +25 -0
- package/dist/read/royalties.d.ts.map +1 -0
- package/dist/read/royalties.js +168 -0
- package/dist/read/royalties.js.map +1 -0
- package/dist/read/types.d.ts +27 -0
- package/dist/read/types.d.ts.map +1 -1
- package/dist/read/wallet.d.ts +23 -12
- package/dist/read/wallet.d.ts.map +1 -1
- package/dist/read/wallet.js +158 -177
- package/dist/read/wallet.js.map +1 -1
- package/dist/read/works.d.ts +6 -6
- package/dist/read/works.d.ts.map +1 -1
- package/dist/read/works.js +40 -26
- package/dist/read/works.js.map +1 -1
- package/dist/recording-extensions.d.ts +15 -16
- package/dist/recording-extensions.d.ts.map +1 -1
- package/dist/recording-extensions.js +12 -8
- package/dist/recording-extensions.js.map +1 -1
- package/dist/release-extensions.d.ts +5 -6
- package/dist/release-extensions.d.ts.map +1 -1
- package/dist/release-extensions.js +3 -2
- package/dist/release-extensions.js.map +1 -1
- package/dist/release-graph.d.ts +2 -2
- package/dist/release-graph.d.ts.map +1 -1
- package/dist/release-graph.js.map +1 -1
- package/dist/royalty.d.ts +4 -4
- package/dist/royalty.d.ts.map +1 -1
- package/dist/royalty.js +16 -7
- package/dist/royalty.js.map +1 -1
- package/dist/share.d.ts +58 -24
- package/dist/share.d.ts.map +1 -1
- package/dist/share.js +167 -92
- package/dist/share.js.map +1 -1
- package/dist/transactions.d.ts +15 -6
- package/dist/transactions.d.ts.map +1 -1
- package/dist/transactions.js +1 -0
- package/dist/transactions.js.map +1 -1
- package/dist/vault.d.ts +13 -3
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +22 -16
- package/dist/vault.js.map +1 -1
- package/package.json +9 -8
- package/src/Miso.ts +951 -0
- package/src/auth.ts +16 -3
- package/src/catalog.ts +58 -25
- package/src/client.ts +98 -1359
- package/src/contracts/composition_credits/composition_credits.ts +20 -4
- package/src/contracts/composition_routed_stake/composition_routed_stake.ts +67 -1
- package/src/contracts/composition_royalty_pool/composition_royalty_pool.ts +53 -4
- package/src/contracts/composition_royalty_pool_plugin/composition_royalty_pool_plugin.ts +64 -1
- package/src/contracts/genre/genre.ts +8 -1
- package/src/contracts/miso_pay/pay.ts +356 -0
- package/src/contracts/party_cta/party_cta.ts +27 -5
- package/src/contracts/party_genre/party_genre.ts +14 -3
- package/src/contracts/party_media/party_media.ts +20 -4
- package/src/contracts/party_platform_link/party_platform_link.ts +15 -7
- package/src/contracts/party_profile/party_profile.ts +33 -8
- package/src/contracts/party_roles/party_roles.ts +19 -4
- package/src/contracts/party_tags/party_tags.ts +16 -4
- package/src/contracts/party_wallet/party_wallet.ts +2 -1
- package/src/contracts/platform_link/platform_link.ts +322 -0
- package/src/contracts/record/pressing.ts +50 -4
- package/src/contracts/record/record.ts +15 -1
- package/src/contracts/record_shop/listing.ts +76 -13
- package/src/contracts/recording_advisory/recording_advisory.ts +15 -8
- package/src/contracts/recording_credits/recording_credits.ts +63 -12
- package/src/contracts/recording_engine_session/recording_engine_session.ts +19 -4
- package/src/contracts/recording_genre/recording_genre.ts +53 -9
- package/src/contracts/recording_language/recording_language.ts +18 -5
- package/src/contracts/recording_master_reference/recording_master_reference.ts +18 -5
- package/src/contracts/recording_royalty_pool/recording_royalty_pool.ts +56 -4
- package/src/contracts/recording_royalty_pool_plugin/recording_royalty_pool_plugin.ts +67 -1
- package/src/contracts/recording_streaming_transcode/recording_streaming_transcode.ts +11 -4
- package/src/contracts/release_cover_art/release_cover_art.ts +126 -10
- package/src/contracts/release_credits/release_credits.ts +18 -4
- package/src/contracts/release_description/release_description.ts +9 -4
- package/src/contracts/release_dsp_link/release_dsp_link.ts +74 -19
- package/src/contracts/release_genre/release_genre.ts +52 -11
- package/src/contracts/release_kind/release_kind.ts +19 -4
- package/src/contracts/release_revenue_distributor/release_revenue_distributor.ts +15 -0
- package/src/contracts/release_revenue_distributor_plugin/release_revenue_distributor_plugin.ts +38 -1
- package/src/contracts/routed_stake/routed_stake.ts +79 -7
- package/src/contracts/royalty_pool/pool.ts +140 -38
- package/src/contracts/royalty_pool/stake.ts +5 -2
- package/src/contracts/share/share.ts +97 -0
- package/src/contracts/vault/vault.ts +55 -4
- package/src/contracts.ts +18 -0
- package/src/cover.ts +14 -15
- package/src/credits.ts +27 -22
- package/src/deployments.ts +3 -4
- package/src/errors.ts +77 -34
- package/src/events.ts +260 -39
- package/src/genre.ts +15 -14
- package/src/index.ts +19 -10
- package/src/party/client.ts +217 -208
- package/src/party/extensions/ctas.ts +3 -3
- package/src/party/extensions/genres.ts +4 -4
- package/src/party/extensions/links.ts +7 -7
- package/src/party/extensions/media.ts +3 -3
- package/src/party/extensions/profile.ts +3 -3
- package/src/party/extensions/roles.ts +5 -5
- package/src/party/extensions/tags.ts +4 -4
- package/src/party/index.ts +0 -1
- package/src/party/queries.ts +90 -87
- package/src/pressing.ts +132 -89
- package/src/publication.ts +33 -32
- package/src/queries.ts +3 -3
- package/src/read/artist.ts +36 -17
- package/src/read/catalog.ts +68 -36
- package/src/read/client.ts +55 -30
- package/src/read/config.ts +57 -29
- package/src/read/genres.ts +22 -18
- package/src/read/index.ts +15 -6
- package/src/read/receipts.ts +130 -67
- package/src/read/royalties.ts +212 -0
- package/src/read/types.ts +30 -0
- package/src/read/wallet.ts +226 -216
- package/src/read/works.ts +51 -44
- package/src/recording-extensions.ts +27 -24
- package/src/release-extensions.ts +7 -7
- package/src/release-graph.ts +2 -1
- package/src/royalty.ts +19 -25
- package/src/share.ts +197 -128
- package/src/transactions.ts +15 -8
- package/src/vault.ts +24 -31
- package/dist/contracts/record_shop/deps/std/type_name.d.ts.map +0 -1
- package/dist/contracts/record_shop/deps/std/type_name.js.map +0 -1
- package/dist/contracts/recording_language/deps/language_code/language_code.d.ts +0 -6
- package/dist/contracts/recording_language/deps/language_code/language_code.d.ts.map +0 -1
- package/dist/contracts/recording_language/deps/language_code/language_code.js +0 -8
- package/dist/contracts/recording_language/deps/language_code/language_code.js.map +0 -1
- package/dist/contracts/recording_master_reference/deps/ori/confidentiality.d.ts +0 -24
- package/dist/contracts/recording_master_reference/deps/ori/confidentiality.d.ts.map +0 -1
- package/dist/contracts/recording_master_reference/deps/ori/confidentiality.js +0 -24
- package/dist/contracts/recording_master_reference/deps/ori/confidentiality.js.map +0 -1
- package/dist/contracts/recording_master_reference/deps/ori/data.d.ts +0 -16
- package/dist/contracts/recording_master_reference/deps/ori/data.d.ts.map +0 -1
- package/dist/contracts/recording_master_reference/deps/ori/data.js +0 -12
- package/dist/contracts/recording_master_reference/deps/ori/data.js.map +0 -1
- package/dist/execute.d.ts +0 -32
- package/dist/execute.d.ts.map +0 -1
- package/dist/execute.js +0 -36
- package/dist/execute.js.map +0 -1
- package/src/contracts/recording_language/deps/language_code/language_code.ts +0 -8
- package/src/contracts/recording_master_reference/deps/ori/confidentiality.ts +0 -24
- package/src/contracts/recording_master_reference/deps/ori/data.ts +0 -12
- package/src/execute.ts +0 -56
- /package/dist/contracts/{record_shop → miso_pay}/deps/std/type_name.d.ts +0 -0
- /package/dist/contracts/{record_shop → miso_pay}/deps/std/type_name.js +0 -0
- /package/src/contracts/{record_shop → miso_pay}/deps/std/type_name.ts +0 -0
package/src/read/receipts.ts
CHANGED
|
@@ -21,13 +21,19 @@
|
|
|
21
21
|
// math the chain does.
|
|
22
22
|
|
|
23
23
|
import * as listingContract from "../contracts/record_shop/listing.ts";
|
|
24
|
-
import {
|
|
25
|
-
extractTypeParams2,
|
|
26
|
-
getCompositionsByIds,
|
|
27
|
-
} from "@misofm/musicos";
|
|
24
|
+
import { extractTypeParams2, Musicos, type MusicosDeploymentInvalid, type MusicosService, type MusicosWorkNotFound } from "@misofm/musicos";
|
|
28
25
|
import { normalizeStructTag, normalizeSuiAddress } from "@mysten/sui/utils";
|
|
29
|
-
import { Effect } from "effect";
|
|
30
|
-
import {
|
|
26
|
+
import { Effect, Result } from "effect";
|
|
27
|
+
import {
|
|
28
|
+
GraphQLUnavailable,
|
|
29
|
+
ObjectId,
|
|
30
|
+
Sui,
|
|
31
|
+
SuiGraphQL,
|
|
32
|
+
TransportError,
|
|
33
|
+
type BatchItemError,
|
|
34
|
+
type DecodeError,
|
|
35
|
+
type TransactionNotFound,
|
|
36
|
+
} from "@unconfirmed/sui-effect";
|
|
31
37
|
import { getPressingDetail } from "./catalog.ts";
|
|
32
38
|
import { int } from "./internal/scalars.ts";
|
|
33
39
|
import { requireRecordSalesDeployment } from "../deployments.ts";
|
|
@@ -52,6 +58,29 @@ const FULLNODE_WAIT_MS = 5_000;
|
|
|
52
58
|
/** Composition royalty rate (bps) per recording id. Sparse — an unresolved parent has no entry. */
|
|
53
59
|
type CompositionRates = Record<string, number | undefined>;
|
|
54
60
|
|
|
61
|
+
/**
|
|
62
|
+
* `GraphQLUnavailable` lets through, not folded into `TransportError` — see
|
|
63
|
+
* `@misofm/musicos`'s own `queries.ts` (and `read/royalties.ts`) for the
|
|
64
|
+
* same idiom.
|
|
65
|
+
*/
|
|
66
|
+
const graphqlError = (method: string) => (cause: unknown): GraphQLUnavailable | TransportError =>
|
|
67
|
+
cause instanceof GraphQLUnavailable ? cause : TransportError.fromUnknown(method, cause);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Builds `Musicos.layer({ deployment: { packageId } })`, provides it, and
|
|
71
|
+
* hands back the effect it wraps — see `../catalog.ts`'s `withMusicos` for
|
|
72
|
+
* the same idiom (kept file-local; see `docs/CONVERSION-STATUS.md`).
|
|
73
|
+
*/
|
|
74
|
+
function withMusicos<A, E>(
|
|
75
|
+
packageId: string,
|
|
76
|
+
effect: (musicos: MusicosService) => Effect.Effect<A, E, Sui>,
|
|
77
|
+
): Effect.Effect<A, E | MusicosDeploymentInvalid, Sui> {
|
|
78
|
+
return Effect.gen(function* () {
|
|
79
|
+
const musicos = yield* Musicos;
|
|
80
|
+
return yield* effect(musicos);
|
|
81
|
+
}).pipe(Effect.provide(Musicos.layer({ deployment: { packageId } })));
|
|
82
|
+
}
|
|
83
|
+
|
|
55
84
|
function coerceU64(v: unknown): bigint | null {
|
|
56
85
|
const value = typeof v === "bigint"
|
|
57
86
|
? v
|
|
@@ -63,20 +92,46 @@ function coerceU64(v: unknown): bigint | null {
|
|
|
63
92
|
return value !== null && value >= 0n && value <= U64_MAX ? value : null;
|
|
64
93
|
}
|
|
65
94
|
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
73
|
-
const fixed = variants.$kind === "Fixed" || Object.hasOwn(variants, "Fixed");
|
|
74
|
-
const floor = variants.$kind === "Floor" || Object.hasOwn(variants, "Floor");
|
|
75
|
-
if (fixed === floor) return null;
|
|
76
|
-
const amount = coerceU64(fixed ? variants.Fixed : variants.Floor);
|
|
95
|
+
function priceFromRichFields(
|
|
96
|
+
pricingIsFixed: unknown,
|
|
97
|
+
priceValue: unknown,
|
|
98
|
+
): Price | null {
|
|
99
|
+
if (typeof pricingIsFixed !== "boolean") return null;
|
|
100
|
+
const amount = coerceU64(priceValue);
|
|
77
101
|
return amount == null || amount <= 0n
|
|
78
102
|
? null
|
|
79
|
-
: { kind:
|
|
103
|
+
: { kind: pricingIsFixed ? "fixed" : "floor", amount: amount.toString() };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Decode a Move `vector<u8>` containing a UTF-8 defining type name. */
|
|
107
|
+
function utf8ByteVector(value: unknown): string | null {
|
|
108
|
+
let bytes: number[];
|
|
109
|
+
if (typeof value === "string") {
|
|
110
|
+
// GraphQL's MoveValue JSON projects vector<u8> as standard padded Base64.
|
|
111
|
+
// Require the canonical spelling and round-trip it before accepting it;
|
|
112
|
+
// arbitrary strings are never interpreted as a type name.
|
|
113
|
+
if (value.length === 0 || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) return null;
|
|
114
|
+
try {
|
|
115
|
+
const binary = atob(value);
|
|
116
|
+
const canonical = btoa(binary);
|
|
117
|
+
if (canonical !== value) return null;
|
|
118
|
+
bytes = Array.from(binary, (char) => char.charCodeAt(0));
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
} else if (Array.isArray(value) || value instanceof Uint8Array) {
|
|
123
|
+
bytes = Array.from(value);
|
|
124
|
+
} else {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (!bytes.every((byte) => typeof byte === "number" && Number.isInteger(byte) && byte >= 0 && byte <= 255)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(Uint8Array.from(bytes));
|
|
132
|
+
} catch {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
80
135
|
}
|
|
81
136
|
|
|
82
137
|
function typeName(value: unknown): string | null {
|
|
@@ -121,8 +176,9 @@ function saleFromJson(
|
|
|
121
176
|
const purchasePrice = coerceU64(json.purchase_price);
|
|
122
177
|
const purchasedTimestampMs = coerceU64(json.purchased_timestamp_ms);
|
|
123
178
|
const recordId = json.record_id;
|
|
124
|
-
const pricing =
|
|
125
|
-
const
|
|
179
|
+
const pricing = priceFromRichFields(json.pricing_is_fixed, json.price);
|
|
180
|
+
const currencyText = utf8ByteVector(json.purchase_currency);
|
|
181
|
+
const embeddedCurrency = currencyText == null ? null : typeName(currencyText);
|
|
126
182
|
if (
|
|
127
183
|
edition == null ||
|
|
128
184
|
number == null ||
|
|
@@ -215,14 +271,17 @@ export function findRecordSales(
|
|
|
215
271
|
);
|
|
216
272
|
if (!currencyType) continue;
|
|
217
273
|
try {
|
|
218
|
-
// The generated struct decodes addresses to 0x-hex and
|
|
274
|
+
// The generated struct decodes addresses to 0x-hex and unsigned values
|
|
275
|
+
// to decimal strings. `purchase_currency` is the raw Move byte vector,
|
|
276
|
+
// so decode it before normalizing the defining type tag.
|
|
219
277
|
const s = listingContract.RecordSoldEvent.parse(e.bcs);
|
|
220
|
-
const pricing =
|
|
221
|
-
const
|
|
222
|
-
const
|
|
278
|
+
const pricing = priceFromRichFields(s.pricing_is_fixed, s.price);
|
|
279
|
+
const currencyText = utf8ByteVector(s.purchase_currency);
|
|
280
|
+
const embeddedCurrency = currencyText == null ? null : typeName(currencyText);
|
|
281
|
+
const purchasePrice = coerceU64(s.purchase_price);
|
|
223
282
|
if (
|
|
224
|
-
!pricing || embeddedCurrency !== currencyType ||
|
|
225
|
-
!validPricingRelationship(purchasePrice, pricing) ||
|
|
283
|
+
!pricing || embeddedCurrency !== currencyType || purchasePrice == null ||
|
|
284
|
+
purchasePrice <= 0n || !validPricingRelationship(purchasePrice, pricing) ||
|
|
226
285
|
s.edition <= 0 || s.number <= 0
|
|
227
286
|
) throw new MalformedRecordSoldEventError({ reason: "malformed canonical RecordSoldEvent" });
|
|
228
287
|
sales.push({
|
|
@@ -233,7 +292,7 @@ export function findRecordSales(
|
|
|
233
292
|
edition: s.edition,
|
|
234
293
|
number: s.number,
|
|
235
294
|
purchaseCurrency: embeddedCurrency,
|
|
236
|
-
purchasePrice:
|
|
295
|
+
purchasePrice: purchasePrice.toString(),
|
|
237
296
|
pricing,
|
|
238
297
|
currencyType,
|
|
239
298
|
purchasedBy: s.purchased_by,
|
|
@@ -274,19 +333,18 @@ const salesFromFullnode = Effect.fn("salesFromFullnode")(function* (
|
|
|
274
333
|
config: MisoConfig,
|
|
275
334
|
): Effect.fn.Return<
|
|
276
335
|
RecordSale[],
|
|
277
|
-
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError |
|
|
278
|
-
|
|
336
|
+
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError | TransactionNotFound | TransportError,
|
|
337
|
+
Sui
|
|
279
338
|
> {
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
catch: (cause) => new SuiRpcError({ operation: "waitForTransaction", cause }),
|
|
339
|
+
const sui = yield* Sui;
|
|
340
|
+
// The mechanical tier's raw `waitForTransaction`: `Sui`'s opinionated tier
|
|
341
|
+
// has no timeout-bearing wait convenience of its own, so this reaches
|
|
342
|
+
// `sui.core` directly, per sui-effect's docs/extensions.md ("reach for it
|
|
343
|
+
// directly only for a field or method Sui does not expose").
|
|
344
|
+
const result = yield* sui.core.waitForTransaction({
|
|
345
|
+
digest: txDigest,
|
|
346
|
+
include: { events: true },
|
|
347
|
+
timeout: FULLNODE_WAIT_MS,
|
|
290
348
|
});
|
|
291
349
|
if (result.$kind !== "Transaction" || !result.Transaction.status.success) {
|
|
292
350
|
return yield* new ReceiptNotFoundError({ digest: txDigest });
|
|
@@ -325,7 +383,7 @@ const salesFromIndexer = Effect.fn("salesFromIndexer")(function* (
|
|
|
325
383
|
config: MisoConfig,
|
|
326
384
|
): Effect.fn.Return<
|
|
327
385
|
RecordSale[],
|
|
328
|
-
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError |
|
|
386
|
+
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError | GraphQLUnavailable | TransportError,
|
|
329
387
|
SuiGraphQL
|
|
330
388
|
> {
|
|
331
389
|
const client = yield* SuiGraphQL;
|
|
@@ -335,13 +393,13 @@ const salesFromIndexer = Effect.fn("salesFromIndexer")(function* (
|
|
|
335
393
|
query: TX_EVENTS_QUERY,
|
|
336
394
|
variables: { digest: txDigest },
|
|
337
395
|
}),
|
|
338
|
-
catch: (
|
|
396
|
+
catch: graphqlError("transactionEvents"),
|
|
339
397
|
});
|
|
340
398
|
if (errors?.length) {
|
|
341
|
-
return yield*
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
399
|
+
return yield* TransportError.fromUnknown(
|
|
400
|
+
"transactionEvents",
|
|
401
|
+
new AggregateError(errors.map((e) => new Error(e.message)), "Transaction events query failed"),
|
|
402
|
+
);
|
|
345
403
|
}
|
|
346
404
|
|
|
347
405
|
const effects = data?.transaction?.effects;
|
|
@@ -374,12 +432,12 @@ const salesFromChain = Effect.fn("salesFromChain")(function* (
|
|
|
374
432
|
config: MisoConfig,
|
|
375
433
|
): Effect.fn.Return<
|
|
376
434
|
RecordSale[],
|
|
377
|
-
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError |
|
|
378
|
-
|
|
435
|
+
ReceiptNotFoundError | RecordPurchaseNotFoundError | MalformedRecordSoldEventError | GraphQLUnavailable | TransportError,
|
|
436
|
+
Sui | SuiGraphQL
|
|
379
437
|
> {
|
|
380
438
|
return yield* salesFromFullnode(txDigest, config).pipe(
|
|
381
439
|
Effect.catchIf(
|
|
382
|
-
(error): error is ReceiptNotFoundError | RecordPurchaseNotFoundError |
|
|
440
|
+
(error): error is ReceiptNotFoundError | RecordPurchaseNotFoundError | TransactionNotFound | TransportError =>
|
|
383
441
|
error._tag !== "MalformedRecordSoldEventError",
|
|
384
442
|
() => salesFromIndexer(txDigest, config),
|
|
385
443
|
),
|
|
@@ -400,20 +458,18 @@ const salesFromChain = Effect.fn("salesFromChain")(function* (
|
|
|
400
458
|
const compositionRatesByRecording = Effect.fn("compositionRatesByRecording")(function* (
|
|
401
459
|
recordingIds: string[],
|
|
402
460
|
config: MisoConfig,
|
|
403
|
-
): Effect.fn.Return<CompositionRates,
|
|
461
|
+
): Effect.fn.Return<CompositionRates, MusicosDeploymentInvalid | GraphQLUnavailable | TransportError, Sui | SuiGraphQL> {
|
|
404
462
|
if (recordingIds.length === 0) return {};
|
|
405
463
|
|
|
406
|
-
const
|
|
464
|
+
const sui = yield* Sui;
|
|
407
465
|
const shareTypeByRecording: Record<string, string> = {};
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
for (const obj of objects) {
|
|
413
|
-
if (obj instanceof Error || !obj.type) continue;
|
|
466
|
+
const results = yield* sui.getObjects([...new Set(recordingIds)].map((id) => ObjectId.make(id)));
|
|
467
|
+
for (const result of results) {
|
|
468
|
+
if (!Result.isSuccess(result)) continue;
|
|
469
|
+
const object = result.success;
|
|
414
470
|
try {
|
|
415
|
-
const [, compositionShareType] = extractTypeParams2(
|
|
416
|
-
shareTypeByRecording[
|
|
471
|
+
const [, compositionShareType] = extractTypeParams2(object.type);
|
|
472
|
+
shareTypeByRecording[object.id] = compositionShareType;
|
|
417
473
|
} catch {
|
|
418
474
|
// A recording type we can't read the parent off — skip this track.
|
|
419
475
|
}
|
|
@@ -427,12 +483,17 @@ const compositionRatesByRecording = Effect.fn("compositionRatesByRecording")(fun
|
|
|
427
483
|
config.deployment.musicos,
|
|
428
484
|
);
|
|
429
485
|
const compositionIds = Object.values(addresses.compositions).filter((id): id is string => !!id);
|
|
430
|
-
const
|
|
486
|
+
const compositionResults = yield* withMusicos(config.deployment.musicos, (musicos) =>
|
|
487
|
+
musicos.getCompositionsByIds(compositionIds.map((id) => ObjectId.make(id))),
|
|
488
|
+
);
|
|
489
|
+
const compositions = new Map(
|
|
490
|
+
compositionResults.flatMap((result, index) => (Result.isSuccess(result) ? [[compositionIds[index]!, result.success] as const] : [])),
|
|
491
|
+
);
|
|
431
492
|
|
|
432
493
|
const rates: CompositionRates = {};
|
|
433
494
|
for (const [recordingId, shareType] of Object.entries(shareTypeByRecording)) {
|
|
434
495
|
const compositionId = addresses.compositions[shareType];
|
|
435
|
-
const composition = compositionId ? compositions
|
|
496
|
+
const composition = compositionId ? compositions.get(compositionId) : undefined;
|
|
436
497
|
if (composition) rates[recordingId] = int(composition.royaltyRate.value);
|
|
437
498
|
}
|
|
438
499
|
return rates;
|
|
@@ -478,18 +539,20 @@ type ReceiptError =
|
|
|
478
539
|
| ReceiptNotFoundError
|
|
479
540
|
| RecordPurchaseNotFoundError
|
|
480
541
|
| MalformedRecordSoldEventError
|
|
481
|
-
|
|
|
542
|
+
| DecodeError
|
|
482
543
|
| ReleaseNotFoundError
|
|
483
|
-
|
|
|
484
|
-
|
|
|
544
|
+
| MusicosWorkNotFound
|
|
545
|
+
| BatchItemError
|
|
546
|
+
| GraphQLUnavailable
|
|
547
|
+
| TransportError;
|
|
485
548
|
|
|
486
549
|
const hydratePurchaseReceipt = Effect.fn("hydratePurchaseReceipt")(function* (
|
|
487
550
|
sale: RecordSale,
|
|
488
551
|
config: MisoConfig,
|
|
489
552
|
): Effect.fn.Return<
|
|
490
553
|
PurchaseReceipt | null,
|
|
491
|
-
|
|
492
|
-
|
|
554
|
+
DecodeError | ReleaseNotFoundError | MusicosWorkNotFound | BatchItemError | GraphQLUnavailable | TransportError,
|
|
555
|
+
Sui | SuiGraphQL
|
|
493
556
|
> {
|
|
494
557
|
const detail = yield* getPressingDetail(sale.pressingId, config);
|
|
495
558
|
if (!detail) return null;
|
|
@@ -512,7 +575,7 @@ const hydratePurchaseReceipt = Effect.fn("hydratePurchaseReceipt")(function* (
|
|
|
512
575
|
export const getPurchaseReceipts = Effect.fn("getPurchaseReceipts")(function* (
|
|
513
576
|
txDigest: string,
|
|
514
577
|
config: MisoConfig,
|
|
515
|
-
): Effect.fn.Return<PurchaseReceipt[], ReceiptError,
|
|
578
|
+
): Effect.fn.Return<PurchaseReceipt[], ReceiptError, Sui | SuiGraphQL> {
|
|
516
579
|
const sales = yield* salesFromChain(txDigest, config);
|
|
517
580
|
const hydrated = yield* Effect.forEach(sales, (sale) => hydratePurchaseReceipt(sale, config), {
|
|
518
581
|
concurrency: "unbounded",
|
|
@@ -529,7 +592,7 @@ export const getPurchaseReceipt = Effect.fn("getPurchaseReceipt")(function* (
|
|
|
529
592
|
txDigest: string,
|
|
530
593
|
recordId: string,
|
|
531
594
|
config: MisoConfig,
|
|
532
|
-
): Effect.fn.Return<PurchaseReceipt | null, ReceiptError,
|
|
595
|
+
): Effect.fn.Return<PurchaseReceipt | null, ReceiptError, Sui | SuiGraphQL> {
|
|
533
596
|
const sales = yield* salesFromChain(txDigest, config);
|
|
534
597
|
const wanted = normalizeSuiAddress(recordId);
|
|
535
598
|
const sale = sales.find((candidate) => normalizeSuiAddress(candidate.recordId) === wanted);
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// Copyright (c) Miso Labs, Inc.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
//
|
|
4
|
+
// Royalty claim history for one address, read from the GraphQL indexer's
|
|
5
|
+
// event index. A claim is one transaction that emitted
|
|
6
|
+
// `royalty_pool::pool::RoyaltyClaimedEvent` — one event per pool the
|
|
7
|
+
// transaction swept — filtered by the transaction's sender, which stays the
|
|
8
|
+
// wallet even when gas is sponsored, and which is the same whether the claim
|
|
9
|
+
// went through `pool::claim_rewards` directly or through a routed stake sweep.
|
|
10
|
+
//
|
|
11
|
+
// The index is paged by event, newest last, and a page boundary can fall
|
|
12
|
+
// inside a transaction. Each page returned here holds only complete claims:
|
|
13
|
+
// when older events remain, the oldest transaction on the page is withheld
|
|
14
|
+
// and the next cursor points just before the oldest kept one, so the next
|
|
15
|
+
// page starts with the withheld transaction whole.
|
|
16
|
+
//
|
|
17
|
+
// The public indexers retain events for a bounded window (about four weeks at
|
|
18
|
+
// the time of writing) while keeping transactions back to genesis, so a page
|
|
19
|
+
// also reports the earliest checkpoint the index still covers. A caller can
|
|
20
|
+
// tell "no older claims" from "no older index" with it.
|
|
21
|
+
|
|
22
|
+
import { normalizeStructTag, normalizeSuiAddress, parseStructTag } from "@mysten/sui/utils";
|
|
23
|
+
import { Effect } from "effect";
|
|
24
|
+
import { GraphQLUnavailable, SuiGraphQL, TransportError } from "@unconfirmed/sui-effect";
|
|
25
|
+
import { MalformedRoyaltyClaimedEventError } from "../errors.ts";
|
|
26
|
+
import type { MisoConfig } from "./config.ts";
|
|
27
|
+
import type { RoyaltyClaim, RoyaltyClaimEntry, RoyaltyClaimPage } from "./types.ts";
|
|
28
|
+
|
|
29
|
+
/** The indexer caps event pages at 50. */
|
|
30
|
+
export const ROYALTY_CLAIMS_PAGE_LIMIT = 50;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* `GraphQLUnavailable` lets through, not folded into `TransportError` — see
|
|
34
|
+
* `@misofm/musicos`'s own `queries.ts` for the same idiom: under
|
|
35
|
+
* `SuiGraphQL.layerUnavailable`, every call rejects with the same
|
|
36
|
+
* `GraphQLUnavailable` instance, and a caller that wants "no endpoint
|
|
37
|
+
* configured" distinguished from "the endpoint answered badly" needs the
|
|
38
|
+
* real tag rather than having it stand behind `cause`.
|
|
39
|
+
*/
|
|
40
|
+
const graphqlError = (method: string) => (cause: unknown): GraphQLUnavailable | TransportError =>
|
|
41
|
+
cause instanceof GraphQLUnavailable ? cause : TransportError.fromUnknown(method, cause);
|
|
42
|
+
|
|
43
|
+
const CLAIMS_QUERY = `query RoyaltyClaims($sender: SuiAddress!, $type: String!, $last: Int!, $before: String) {
|
|
44
|
+
events(last: $last, before: $before, filter: { sender: $sender, type: $type }) {
|
|
45
|
+
pageInfo { hasPreviousPage }
|
|
46
|
+
edges {
|
|
47
|
+
cursor
|
|
48
|
+
node { timestamp transaction { digest } contents { type { repr } json } }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
serviceConfig {
|
|
52
|
+
availableRange(type: "Query", field: "events") { first { timestamp } }
|
|
53
|
+
}
|
|
54
|
+
}`;
|
|
55
|
+
|
|
56
|
+
interface ClaimsQueryVariables {
|
|
57
|
+
sender: string;
|
|
58
|
+
type: string;
|
|
59
|
+
last: number;
|
|
60
|
+
before: string | null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface ClaimsQueryResult {
|
|
64
|
+
events: {
|
|
65
|
+
pageInfo: { hasPreviousPage: boolean };
|
|
66
|
+
edges: Array<{
|
|
67
|
+
cursor: string;
|
|
68
|
+
node: {
|
|
69
|
+
timestamp: string | null;
|
|
70
|
+
transaction: { digest: string } | null;
|
|
71
|
+
contents: { type: { repr: string }; json: unknown } | null;
|
|
72
|
+
};
|
|
73
|
+
}>;
|
|
74
|
+
} | null;
|
|
75
|
+
serviceConfig: {
|
|
76
|
+
availableRange: { first: { timestamp: string } | null } | null;
|
|
77
|
+
} | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ListRoyaltyClaimsOptions {
|
|
81
|
+
/** Opaque cursor from a previous page's `nextCursor`; omit for the newest page. */
|
|
82
|
+
before?: string | null;
|
|
83
|
+
/** Events per page, 1–50. Claims per page is at most this. */
|
|
84
|
+
limit?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** `pkg::pool::RoyaltyClaimedEvent` — the generic name matches every `<Share, Currency>`. */
|
|
88
|
+
export function royaltyClaimedEventType(config: MisoConfig): string {
|
|
89
|
+
return `${config.protocol.royaltyPool}::pool::RoyaltyClaimedEvent`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function u64String(value: unknown): string | null {
|
|
93
|
+
if (typeof value === "string" && /^\d+$/.test(value)) return value;
|
|
94
|
+
if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0) return String(value);
|
|
95
|
+
if (typeof value === "bigint" && value >= 0n) return value.toString();
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function entryFromEvent(repr: string, json: unknown, digest: string): RoyaltyClaimEntry {
|
|
100
|
+
const fail = (reason: string) => new MalformedRoyaltyClaimedEventError({ digest, reason });
|
|
101
|
+
let typeParams: (string | { address: string })[];
|
|
102
|
+
try {
|
|
103
|
+
typeParams = parseStructTag(repr).typeParams as (string | { address: string })[];
|
|
104
|
+
} catch {
|
|
105
|
+
throw fail(`unparseable event type ${repr}`);
|
|
106
|
+
}
|
|
107
|
+
const [share, currency] = typeParams;
|
|
108
|
+
if (!share || !currency) throw fail("RoyaltyClaimedEvent without <Share, Currency>");
|
|
109
|
+
if (!json || typeof json !== "object") throw fail("RoyaltyClaimedEvent without JSON contents");
|
|
110
|
+
const fields = json as Record<string, unknown>;
|
|
111
|
+
const amount = u64String(fields.reward_amount);
|
|
112
|
+
if (typeof fields.pool_id !== "string" || typeof fields.stake_id !== "string" || amount === null) {
|
|
113
|
+
throw fail("RoyaltyClaimedEvent missing pool_id, stake_id or reward_amount");
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
poolId: normalizeSuiAddress(fields.pool_id),
|
|
117
|
+
stakeId: normalizeSuiAddress(fields.stake_id),
|
|
118
|
+
shareType: normalizeStructTag(share as never),
|
|
119
|
+
currency: normalizeStructTag(currency as never),
|
|
120
|
+
amount,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* One page of an address's royalty claims, newest first.
|
|
126
|
+
*
|
|
127
|
+
* Fails with `GraphQLUnavailable` when no GraphQL endpoint is configured,
|
|
128
|
+
* `TransportError` when the indexer cannot be reached or rejects the query,
|
|
129
|
+
* and `MalformedRoyaltyClaimedEventError` when an event of the configured
|
|
130
|
+
* type does not carry the fields this package version expects.
|
|
131
|
+
*/
|
|
132
|
+
export const listRoyaltyClaims = Effect.fn("listRoyaltyClaims")(function* (
|
|
133
|
+
address: string,
|
|
134
|
+
config: MisoConfig,
|
|
135
|
+
options: ListRoyaltyClaimsOptions = {},
|
|
136
|
+
): Effect.fn.Return<RoyaltyClaimPage, GraphQLUnavailable | TransportError | MalformedRoyaltyClaimedEventError, SuiGraphQL> {
|
|
137
|
+
const client = yield* SuiGraphQL;
|
|
138
|
+
const limit = Math.min(Math.max(Math.trunc(options.limit ?? ROYALTY_CLAIMS_PAGE_LIMIT), 1), ROYALTY_CLAIMS_PAGE_LIMIT);
|
|
139
|
+
const { data, errors } = yield* Effect.tryPromise({
|
|
140
|
+
try: () =>
|
|
141
|
+
client.query<ClaimsQueryResult, ClaimsQueryVariables>({
|
|
142
|
+
query: CLAIMS_QUERY,
|
|
143
|
+
variables: {
|
|
144
|
+
sender: normalizeSuiAddress(address),
|
|
145
|
+
type: royaltyClaimedEventType(config),
|
|
146
|
+
last: limit,
|
|
147
|
+
before: options.before ?? null,
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
catch: graphqlError("royaltyClaims"),
|
|
151
|
+
});
|
|
152
|
+
if (errors?.length) {
|
|
153
|
+
return yield* TransportError.fromUnknown(
|
|
154
|
+
"royaltyClaims",
|
|
155
|
+
new AggregateError(errors.map((e) => new Error(e.message)), "Royalty claims query failed"),
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const edges = data?.events?.edges ?? [];
|
|
160
|
+
const hasOlder = data?.events?.pageInfo.hasPreviousPage ?? false;
|
|
161
|
+
const availableFrom = data?.serviceConfig?.availableRange?.first?.timestamp ?? null;
|
|
162
|
+
const availableFromMs = availableFrom === null ? null : Date.parse(availableFrom);
|
|
163
|
+
|
|
164
|
+
// Group in index order (oldest first); a transaction's events are contiguous.
|
|
165
|
+
const groups: Array<{ firstCursor: string; claim: RoyaltyClaim }> = [];
|
|
166
|
+
for (const { cursor, node } of edges) {
|
|
167
|
+
const digest = node.transaction?.digest;
|
|
168
|
+
const contents = node.contents;
|
|
169
|
+
if (!digest || !contents) {
|
|
170
|
+
return yield* new MalformedRoyaltyClaimedEventError({ digest: digest ?? "?", reason: "event without transaction or contents" });
|
|
171
|
+
}
|
|
172
|
+
let entry: RoyaltyClaimEntry;
|
|
173
|
+
try {
|
|
174
|
+
entry = entryFromEvent(contents.type.repr, contents.json, digest);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
return yield* (error as MalformedRoyaltyClaimedEventError);
|
|
177
|
+
}
|
|
178
|
+
const last = groups.at(-1);
|
|
179
|
+
if (last && last.claim.txDigest === digest) {
|
|
180
|
+
last.claim.entries.push(entry);
|
|
181
|
+
} else {
|
|
182
|
+
groups.push({
|
|
183
|
+
firstCursor: cursor,
|
|
184
|
+
claim: {
|
|
185
|
+
txDigest: digest,
|
|
186
|
+
timestampMs: node.timestamp ? Date.parse(node.timestamp) : 0,
|
|
187
|
+
entries: [entry],
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
let nextCursor: string | null = null;
|
|
194
|
+
let kept = groups;
|
|
195
|
+
if (hasOlder && groups.length > 0) {
|
|
196
|
+
if (groups.length > 1) {
|
|
197
|
+
// The oldest group may continue past the page start; hand it back whole
|
|
198
|
+
// on the next page by starting that page just before the oldest kept one.
|
|
199
|
+
kept = groups.slice(1);
|
|
200
|
+
nextCursor = kept[0]!.firstCursor;
|
|
201
|
+
} else {
|
|
202
|
+
// One transaction fills the whole page: continue before its first event.
|
|
203
|
+
nextCursor = groups[0]!.firstCursor;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
claims: kept.map((group) => group.claim).reverse(),
|
|
209
|
+
nextCursor,
|
|
210
|
+
availableFromMs: availableFromMs !== null && Number.isFinite(availableFromMs) ? availableFromMs : null,
|
|
211
|
+
};
|
|
212
|
+
});
|
package/src/read/types.ts
CHANGED
|
@@ -426,3 +426,33 @@ export interface PurchaseReceipt {
|
|
|
426
426
|
price: string;
|
|
427
427
|
tracks: TrackRoyalty[];
|
|
428
428
|
}
|
|
429
|
+
|
|
430
|
+
/** One pool swept by a royalty claim transaction. */
|
|
431
|
+
export interface RoyaltyClaimEntry {
|
|
432
|
+
poolId: string;
|
|
433
|
+
stakeId: string;
|
|
434
|
+
/** The pool's share type, e.g. `0x…::share::Share`. */
|
|
435
|
+
shareType: string;
|
|
436
|
+
/** The currency paid out, e.g. the network's stable coin type. */
|
|
437
|
+
currency: string;
|
|
438
|
+
/** Base units of `currency`, a u64 as a decimal string. */
|
|
439
|
+
amount: string;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/** One royalty claim transaction sent by the address. */
|
|
443
|
+
export interface RoyaltyClaim {
|
|
444
|
+
txDigest: string;
|
|
445
|
+
/** Checkpoint timestamp, milliseconds since the epoch; 0 if the index had none. */
|
|
446
|
+
timestampMs: number;
|
|
447
|
+
/** The pools swept, in event order. */
|
|
448
|
+
entries: RoyaltyClaimEntry[];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** A page of claims, newest first. */
|
|
452
|
+
export interface RoyaltyClaimPage {
|
|
453
|
+
claims: RoyaltyClaim[];
|
|
454
|
+
/** Pass as `before` for the next (older) page; null when none remain. */
|
|
455
|
+
nextCursor: string | null;
|
|
456
|
+
/** Earliest timestamp the event index still covers, or null if unknown. */
|
|
457
|
+
availableFromMs: number | null;
|
|
458
|
+
}
|