@gala-chain/launchpad-sdk 8.1.0 → 9.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +837 -0
- package/EXAMPLES.md +95 -681
- package/MIGRATING-TO-9.0.md +343 -0
- package/README.md +46 -17
- package/dist/LaunchpadSDK.d.ts +536 -616
- package/dist/LaunchpadSDK.d.ts.map +1 -1
- package/dist/api/LaunchpadAPI.d.ts +6 -176
- package/dist/api/LaunchpadAPI.d.ts.map +1 -1
- package/dist/auth/SessionAuthService.d.ts +32 -2
- package/dist/auth/SessionAuthService.d.ts.map +1 -1
- package/dist/auth/SignatureAuth.d.ts +2 -2
- package/dist/auth/SignatureAuth.d.ts.map +1 -1
- package/dist/auth/session.d.ts +59 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/types.d.ts +7 -2
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/config/environments.d.ts +7 -2
- package/dist/config/environments.d.ts.map +1 -1
- package/dist/constants/decimals.d.ts +0 -23
- package/dist/constants/decimals.d.ts.map +1 -1
- package/dist/constants/endpoints.d.ts +19 -8
- package/dist/constants/endpoints.d.ts.map +1 -1
- package/dist/constants/enums.d.ts +19 -0
- package/dist/constants/enums.d.ts.map +1 -1
- package/dist/constants/version.generated.d.ts +1 -1
- package/dist/constants/version.generated.d.ts.map +1 -1
- package/dist/errors/LaunchpadSDKError.d.ts +18 -0
- package/dist/errors/LaunchpadSDKError.d.ts.map +1 -1
- package/dist/helpers/sdk.d.ts.map +1 -1
- package/dist/index.browser.d.ts +40 -45
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.esm.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.node.d.ts +4 -5
- package/dist/index.node.d.ts.map +1 -1
- package/dist/launchpad/bundle-submission.d.ts +57 -10
- package/dist/launchpad/bundle-submission.d.ts.map +1 -1
- package/dist/launchpad/create-sale-validation.d.ts +19 -0
- package/dist/launchpad/create-sale-validation.d.ts.map +1 -0
- package/dist/launchpad/transport.d.ts +33 -2
- package/dist/launchpad/transport.d.ts.map +1 -1
- package/dist/launchpad/writes.d.ts +37 -11
- package/dist/launchpad/writes.d.ts.map +1 -1
- package/dist/native.cjs +1 -1
- package/dist/native.d.ts +4 -5
- package/dist/native.d.ts.map +1 -1
- package/dist/native.esm.js +1 -1
- package/dist/schemas/launchpad.d.ts +3 -2
- package/dist/schemas/launchpad.d.ts.map +1 -1
- package/dist/schemas/primitives.d.ts +12 -2
- package/dist/schemas/primitives.d.ts.map +1 -1
- package/dist/schemas/user.d.ts +3 -18
- package/dist/schemas/user.d.ts.map +1 -1
- package/dist/schemas/validators.d.ts +3 -3
- package/dist/services/AbstractCacheService.d.ts +2 -2
- package/dist/services/ApiKeyService.d.ts +1 -1
- package/dist/services/BanService.d.ts +1 -1
- package/dist/services/ChartService.d.ts.map +1 -1
- package/dist/services/ContentReactionService.d.ts +6 -18
- package/dist/services/ContentReactionService.d.ts.map +1 -1
- package/dist/services/EventsQueryService.d.ts +47 -0
- package/dist/services/EventsQueryService.d.ts.map +1 -0
- package/dist/services/GalaChainBalanceService.d.ts +17 -89
- package/dist/services/GalaChainBalanceService.d.ts.map +1 -1
- package/dist/services/GalaChainLockService.d.ts +19 -20
- package/dist/services/GalaChainLockService.d.ts.map +1 -1
- package/dist/services/GalaChainService.d.ts +28 -15
- package/dist/services/GalaChainService.d.ts.map +1 -1
- package/dist/services/GalaChainTokenService.d.ts +25 -53
- package/dist/services/GalaChainTokenService.d.ts.map +1 -1
- package/dist/services/GalaChainTransferService.d.ts +42 -41
- package/dist/services/GalaChainTransferService.d.ts.map +1 -1
- package/dist/services/HealthService.d.ts +33 -0
- package/dist/services/HealthService.d.ts.map +1 -0
- package/dist/services/ImageService.d.ts +3 -3
- package/dist/services/ImageService.d.ts.map +1 -1
- package/dist/services/LaunchpadPriceService.d.ts +66 -0
- package/dist/services/LaunchpadPriceService.d.ts.map +1 -0
- package/dist/services/LaunchpadService.d.ts +34 -42
- package/dist/services/LaunchpadService.d.ts.map +1 -1
- package/dist/services/MessagesService.d.ts +12 -44
- package/dist/services/MessagesService.d.ts.map +1 -1
- package/dist/services/ModeratorService.d.ts +2 -2
- package/dist/services/ModeratorService.d.ts.map +1 -1
- package/dist/services/NftCollectionService.d.ts +22 -6
- package/dist/services/NftCollectionService.d.ts.map +1 -1
- package/dist/services/OverseerService.d.ts +3 -3
- package/dist/services/OverseerService.d.ts.map +1 -1
- package/dist/services/PlatformStatsService.d.ts +1 -2
- package/dist/services/PlatformStatsService.d.ts.map +1 -1
- package/dist/services/PoolService.d.ts +28 -65
- package/dist/services/PoolService.d.ts.map +1 -1
- package/dist/services/RestrictedNamesService.d.ts +1 -1
- package/dist/services/RestrictedNamesService.d.ts.map +1 -1
- package/dist/services/StreamChatService.d.ts +8 -19
- package/dist/services/StreamChatService.d.ts.map +1 -1
- package/dist/services/StreamTokenServiceBase.d.ts +2 -1
- package/dist/services/StreamTokenServiceBase.d.ts.map +1 -1
- package/dist/services/StreamWebSocketService.d.ts +423 -451
- package/dist/services/StreamWebSocketService.d.ts.map +1 -1
- package/dist/services/StreamingService.d.ts +14 -15
- package/dist/services/StreamingService.d.ts.map +1 -1
- package/dist/services/TokenBanService.d.ts +1 -1
- package/dist/services/TokenResolverService.d.ts +5 -5
- package/dist/services/TokenResolverService.d.ts.map +1 -1
- package/dist/services/TradeService.d.ts +13 -9
- package/dist/services/TradeService.d.ts.map +1 -1
- package/dist/services/TradingQuotesService.d.ts.map +1 -1
- package/dist/services/UserService.d.ts +64 -20
- package/dist/services/UserService.d.ts.map +1 -1
- package/dist/services/gateway-transport.d.ts +32 -0
- package/dist/services/gateway-transport.d.ts.map +1 -0
- package/dist/services/gateway-writes.d.ts +83 -0
- package/dist/services/gateway-writes.d.ts.map +1 -0
- package/dist/services/realtime/event-catalog.d.ts +456 -0
- package/dist/services/realtime/event-catalog.d.ts.map +1 -0
- package/dist/services/shared/pagination-helpers.d.ts +22 -5
- package/dist/services/shared/pagination-helpers.d.ts.map +1 -1
- package/dist/services/shared/service-validators.d.ts.map +1 -1
- package/dist/signing/index.d.ts +2 -3
- package/dist/signing/index.d.ts.map +1 -1
- package/dist/signing/signers.d.ts +64 -9
- package/dist/signing/signers.d.ts.map +1 -1
- package/dist/signing/types.d.ts +7 -10
- package/dist/signing/types.d.ts.map +1 -1
- package/dist/types/api-key.dto.d.ts +1 -1
- package/dist/types/ban.dto.d.ts +21 -16
- package/dist/types/ban.dto.d.ts.map +1 -1
- package/dist/types/burn.dto.d.ts +4 -2
- package/dist/types/burn.dto.d.ts.map +1 -1
- package/dist/types/chat-messages.dto.d.ts +10 -72
- package/dist/types/chat-messages.dto.d.ts.map +1 -1
- package/dist/types/comments.dto.d.ts +8 -78
- package/dist/types/comments.dto.d.ts.map +1 -1
- package/dist/types/common.d.ts +42 -85
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/constraints.d.ts +47 -23
- package/dist/types/constraints.d.ts.map +1 -1
- package/dist/types/content-flag.dto.d.ts +5 -1
- package/dist/types/content-flag.dto.d.ts.map +1 -1
- package/dist/types/content-reactions.dto.d.ts +0 -4
- package/dist/types/content-reactions.dto.d.ts.map +1 -1
- package/dist/types/dto.d.ts +0 -5
- package/dist/types/dto.d.ts.map +1 -1
- package/dist/types/engagement-stats.dto.d.ts +16 -27
- package/dist/types/engagement-stats.dto.d.ts.map +1 -1
- package/dist/types/events.dto.d.ts +89 -0
- package/dist/types/events.dto.d.ts.map +1 -1
- package/dist/types/global-feed.dto.d.ts +23 -164
- package/dist/types/global-feed.dto.d.ts.map +1 -1
- package/dist/types/health.dto.d.ts +32 -0
- package/dist/types/health.dto.d.ts.map +1 -0
- package/dist/types/launchpad.dto.d.ts +77 -323
- package/dist/types/launchpad.dto.d.ts.map +1 -1
- package/dist/types/lock.dto.d.ts +12 -7
- package/dist/types/lock.dto.d.ts.map +1 -1
- package/dist/types/messages.dto.d.ts +168 -118
- package/dist/types/messages.dto.d.ts.map +1 -1
- package/dist/types/moderator.dto.d.ts +1 -1
- package/dist/types/options.dto.d.ts +8 -36
- package/dist/types/options.dto.d.ts.map +1 -1
- package/dist/types/overseer.dto.d.ts +2 -1
- package/dist/types/overseer.dto.d.ts.map +1 -1
- package/dist/types/platform-stats.dto.d.ts +3 -3
- package/dist/types/realtime-events.dto.d.ts +340 -0
- package/dist/types/realtime-events.dto.d.ts.map +1 -0
- package/dist/types/restricted-names.dto.d.ts +2 -2
- package/dist/types/restricted-names.dto.d.ts.map +1 -1
- package/dist/types/stream-chat.dto.d.ts +15 -14
- package/dist/types/stream-chat.dto.d.ts.map +1 -1
- package/dist/types/streaming.dto.d.ts +73 -104
- package/dist/types/streaming.dto.d.ts.map +1 -1
- package/dist/types/token-ban.dto.d.ts.map +1 -1
- package/dist/types/token-config.dto.d.ts +34 -19
- package/dist/types/token-config.dto.d.ts.map +1 -1
- package/dist/types/trades-query.dto.d.ts +8 -24
- package/dist/types/trades-query.dto.d.ts.map +1 -1
- package/dist/types/user.dto.d.ts +133 -112
- package/dist/types/user.dto.d.ts.map +1 -1
- package/dist/types/websocket-events.dto.d.ts +5 -5
- package/dist/types/websocket-events.dto.d.ts.map +1 -1
- package/dist/utils/address-formatter.d.ts +25 -2
- package/dist/utils/address-formatter.d.ts.map +1 -1
- package/dist/utils/agent-config.d.ts +9 -4
- package/dist/utils/agent-config.d.ts.map +1 -1
- package/dist/utils/auto-pagination.d.ts +7 -240
- package/dist/utils/auto-pagination.d.ts.map +1 -1
- package/dist/utils/bignumber-helpers.d.ts +3 -2
- package/dist/utils/bignumber-helpers.d.ts.map +1 -1
- package/dist/utils/delimiter-parser.d.ts +0 -13
- package/dist/utils/delimiter-parser.d.ts.map +1 -1
- package/dist/utils/error-factories.d.ts +4 -3
- package/dist/utils/error-factories.d.ts.map +1 -1
- package/dist/utils/error-patterns.d.ts +0 -47
- package/dist/utils/error-patterns.d.ts.map +1 -1
- package/dist/utils/error-wrapper.d.ts +5 -5
- package/dist/utils/errors.d.ts +53 -318
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/http.d.ts +36 -3
- package/dist/utils/http.d.ts.map +1 -1
- package/dist/utils/message-validators.d.ts.map +1 -1
- package/dist/utils/pagination-helpers.d.ts +17 -0
- package/dist/utils/pagination-helpers.d.ts.map +1 -1
- package/dist/utils/pagination-validation.d.ts +2 -2
- package/dist/utils/response-handlers.d.ts.map +1 -1
- package/dist/utils/service-validators.d.ts +6 -6
- package/dist/utils/service-validators.d.ts.map +1 -1
- package/dist/utils/token-format-converter.d.ts +1 -1
- package/dist/utils/token-parser.d.ts +6 -127
- package/dist/utils/token-parser.d.ts.map +1 -1
- package/dist/utils/token-stringification.d.ts +7 -7
- package/dist/utils/token-stringification.d.ts.map +1 -1
- package/dist/utils/tokenNameNormalizer.d.ts +2 -2
- package/dist/utils/tokenNormalizer.d.ts +5 -29
- package/dist/utils/tokenNormalizer.d.ts.map +1 -1
- package/dist/utils/unique-key-generator.d.ts +7 -134
- package/dist/utils/unique-key-generator.d.ts.map +1 -1
- package/dist/utils/validation-helpers.d.ts +21 -64
- package/dist/utils/validation-helpers.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +4 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/package.json +47 -87
- package/dist/api/dto/BurnTokensDto.d.ts +0 -77
- package/dist/api/dto/BurnTokensDto.d.ts.map +0 -1
- package/dist/api/dto/LockTokenDto.d.ts +0 -85
- package/dist/api/dto/LockTokenDto.d.ts.map +0 -1
- package/dist/api/dto/TransferTokenDto.d.ts +0 -64
- package/dist/api/dto/TransferTokenDto.d.ts.map +0 -1
- package/dist/api/dto/UnlockTokenDto.d.ts +0 -74
- package/dist/api/dto/UnlockTokenDto.d.ts.map +0 -1
- package/dist/bridge/BridgeService.d.ts +0 -484
- package/dist/bridge/BridgeService.d.ts.map +0 -1
- package/dist/bridge/GalaConnectClient.d.ts +0 -170
- package/dist/bridge/GalaConnectClient.d.ts.map +0 -1
- package/dist/bridge/constants/index.d.ts +0 -7
- package/dist/bridge/constants/index.d.ts.map +0 -1
- package/dist/bridge/constants/tokens.d.ts +0 -212
- package/dist/bridge/constants/tokens.d.ts.map +0 -1
- package/dist/bridge/index.d.ts +0 -24
- package/dist/bridge/index.d.ts.map +0 -1
- package/dist/bridge/public-types.d.ts +0 -2
- package/dist/bridge/public-types.d.ts.map +0 -1
- package/dist/bridge/strategies/BridgeStrategy.d.ts +0 -204
- package/dist/bridge/strategies/BridgeStrategy.d.ts.map +0 -1
- package/dist/bridge/strategies/EthereumBridgeStrategy.d.ts +0 -178
- package/dist/bridge/strategies/EthereumBridgeStrategy.d.ts.map +0 -1
- package/dist/bridge/strategies/SolanaBridgeStrategy.d.ts +0 -236
- package/dist/bridge/strategies/SolanaBridgeStrategy.d.ts.map +0 -1
- package/dist/bridge/types/bridge.dto.d.ts +0 -772
- package/dist/bridge/types/bridge.dto.d.ts.map +0 -1
- package/dist/bridge/types/bridgeable-token.dto.d.ts +0 -209
- package/dist/bridge/types/bridgeable-token.dto.d.ts.map +0 -1
- package/dist/bridge/types/eip712.d.ts +0 -66
- package/dist/bridge/types/eip712.d.ts.map +0 -1
- package/dist/bridge/types/index.d.ts +0 -8
- package/dist/bridge/types/index.d.ts.map +0 -1
- package/dist/bridge/utils/RateLimiter.d.ts +0 -34
- package/dist/bridge/utils/RateLimiter.d.ts.map +0 -1
- package/dist/bridge/utils/address-formatter.d.ts +0 -25
- package/dist/bridge/utils/address-formatter.d.ts.map +0 -1
- package/dist/bridge/utils/addressValidation.d.ts +0 -200
- package/dist/bridge/utils/addressValidation.d.ts.map +0 -1
- package/dist/bridge/utils/balanceHelpers.d.ts +0 -215
- package/dist/bridge/utils/balanceHelpers.d.ts.map +0 -1
- package/dist/bridge/utils/bridgeErrors.d.ts +0 -98
- package/dist/bridge/utils/bridgeErrors.d.ts.map +0 -1
- package/dist/bridge/utils/bridgeOutHelpers.d.ts +0 -68
- package/dist/bridge/utils/bridgeOutHelpers.d.ts.map +0 -1
- package/dist/bridge/utils/bridgePayload.d.ts +0 -98
- package/dist/bridge/utils/bridgePayload.d.ts.map +0 -1
- package/dist/bridge/utils/bridgeStatusParser.d.ts +0 -76
- package/dist/bridge/utils/bridgeStatusParser.d.ts.map +0 -1
- package/dist/bridge/utils/eip712Helpers.d.ts +0 -66
- package/dist/bridge/utils/eip712Helpers.d.ts.map +0 -1
- package/dist/bridge/utils/index.d.ts +0 -19
- package/dist/bridge/utils/index.d.ts.map +0 -1
- package/dist/bridge/utils/retry.d.ts +0 -112
- package/dist/bridge/utils/retry.d.ts.map +0 -1
- package/dist/bridge/utils/strategyDelegation.d.ts +0 -126
- package/dist/bridge/utils/strategyDelegation.d.ts.map +0 -1
- package/dist/bridge/utils/tokenIdUtils.d.ts +0 -86
- package/dist/bridge/utils/tokenIdUtils.d.ts.map +0 -1
- package/dist/bridge/utils/tokenMath.d.ts +0 -39
- package/dist/bridge/utils/tokenMath.d.ts.map +0 -1
- package/dist/bridge/utils/tokenMetadataResolver.d.ts +0 -97
- package/dist/bridge/utils/tokenMetadataResolver.d.ts.map +0 -1
- package/dist/helpers/wallet.d.ts +0 -151
- package/dist/helpers/wallet.d.ts.map +0 -1
- package/dist/react/WalletContext.d.ts +0 -60
- package/dist/react/WalletContext.d.ts.map +0 -1
- package/dist/react/index.d.ts +0 -65
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/types.d.ts +0 -76
- package/dist/react/types.d.ts.map +0 -1
- package/dist/react/useWallet.d.ts +0 -123
- package/dist/react/useWallet.d.ts.map +0 -1
- package/dist/react/useWalletConnection.d.ts +0 -89
- package/dist/react/useWalletConnection.d.ts.map +0 -1
- package/dist/react/useWalletDetection.d.ts +0 -81
- package/dist/react/useWalletDetection.d.ts.map +0 -1
- package/dist/react.cjs +0 -1
- package/dist/react.esm.js +0 -1
- package/dist/services/AbstractTokenFetchService.d.ts +0 -150
- package/dist/services/AbstractTokenFetchService.d.ts.map +0 -1
- package/dist/services/BatchedCacheService.d.ts +0 -133
- package/dist/services/BatchedCacheService.d.ts.map +0 -1
- package/dist/services/BridgeableTokenCache.d.ts +0 -120
- package/dist/services/BridgeableTokenCache.d.ts.map +0 -1
- package/dist/services/BridgeableTokenService.d.ts +0 -218
- package/dist/services/BridgeableTokenService.d.ts.map +0 -1
- package/dist/services/DexService.d.ts +0 -440
- package/dist/services/DexService.d.ts.map +0 -1
- package/dist/services/NetworkKeyedCacheService.d.ts +0 -185
- package/dist/services/NetworkKeyedCacheService.d.ts.map +0 -1
- package/dist/services/PriceHistoryService.d.ts +0 -209
- package/dist/services/PriceHistoryService.d.ts.map +0 -1
- package/dist/services/StreamingEventService.d.ts +0 -441
- package/dist/services/StreamingEventService.d.ts.map +0 -1
- package/dist/services/WrapService.d.ts +0 -171
- package/dist/services/WrapService.d.ts.map +0 -1
- package/dist/services/WrappableTokenCache.d.ts +0 -100
- package/dist/services/WrappableTokenCache.d.ts.map +0 -1
- package/dist/services/WrappableTokenService.d.ts +0 -130
- package/dist/services/WrappableTokenService.d.ts.map +0 -1
- package/dist/setup.d.ts +0 -8
- package/dist/setup.d.ts.map +0 -1
- package/dist/tokens/transfers.d.ts +0 -95
- package/dist/tokens/transfers.d.ts.map +0 -1
- package/dist/types/comment.dto.d.ts +0 -176
- package/dist/types/comment.dto.d.ts.map +0 -1
- package/dist/types/galachain-api.types.d.ts +0 -297
- package/dist/types/galachain-api.types.d.ts.map +0 -1
- package/dist/types/priceHistory.dto.d.ts +0 -134
- package/dist/types/priceHistory.dto.d.ts.map +0 -1
- package/dist/types/streaming-events.dto.d.ts +0 -605
- package/dist/types/streaming-events.dto.d.ts.map +0 -1
- package/dist/types/token.types.d.ts +0 -359
- package/dist/types/token.types.d.ts.map +0 -1
- package/dist/types/wrappable-token.dto.d.ts +0 -305
- package/dist/types/wrappable-token.dto.d.ts.map +0 -1
- package/dist/utils/crypto-compat.d.ts +0 -40
- package/dist/utils/crypto-compat.d.ts.map +0 -1
- package/dist/utils/load-env.d.ts +0 -31
- package/dist/utils/load-env.d.ts.map +0 -1
- package/dist/utils/token-instance-key.d.ts +0 -57
- package/dist/utils/token-instance-key.d.ts.map +0 -1
- package/dist/utils/wallet.d.ts +0 -166
- package/dist/utils/wallet.d.ts.map +0 -1
- package/dist/wallet/ExternalWalletProvider.d.ts +0 -90
- package/dist/wallet/ExternalWalletProvider.d.ts.map +0 -1
- package/dist/wallet/GalaWalletProvider.d.ts +0 -122
- package/dist/wallet/GalaWalletProvider.d.ts.map +0 -1
- package/dist/wallet/PrivateKeyProvider.d.ts +0 -90
- package/dist/wallet/PrivateKeyProvider.d.ts.map +0 -1
- package/dist/wallet/detection.d.ts +0 -107
- package/dist/wallet/detection.d.ts.map +0 -1
- package/dist/wallet/event-handlers.d.ts +0 -50
- package/dist/wallet/event-handlers.d.ts.map +0 -1
- package/dist/wallet/index.d.ts +0 -51
- package/dist/wallet/index.d.ts.map +0 -1
- package/dist/wallet/signing-operation.d.ts +0 -19
- package/dist/wallet/signing-operation.d.ts.map +0 -1
- package/dist/wallet/typed-data-helpers.d.ts +0 -68
- package/dist/wallet/typed-data-helpers.d.ts.map +0 -1
- package/dist/wallet/types.d.ts +0 -267
- package/dist/wallet/types.d.ts.map +0 -1
- package/dist/wallet/utils.d.ts +0 -117
- package/dist/wallet/utils.d.ts.map +0 -1
- package/dist/wallet.cjs +0 -1
- package/dist/wallet.esm.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,842 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.0.0-rc.1
|
|
4
|
+
|
|
5
|
+
Since 9.0.0-rc.0 (published): the sections "App-owned session" through "The stream socket" below
|
|
6
|
+
(the app-session, browser-wallet, bundle-confirmation, error-answer, path-parameter, `PageInfo`,
|
|
7
|
+
`fetchPools`, admin/overseer, trades/tokens/users/streaming and stream-socket contracts) and the
|
|
8
|
+
later entries of "BREAKING CHANGES" and "Fixes" are new in rc.1; everything else in this section is
|
|
9
|
+
rc.0's. Core peer floor is `>=1.0.0-rc.6 <2`.
|
|
10
|
+
|
|
11
|
+
launchpad-sdk is launchpad-only. Everything that speaks to the GalaChain gateway generically is
|
|
12
|
+
`@gala-chain/gala-core-sdk`'s (a peer dependency: install it beside launchpad-sdk); everything that
|
|
13
|
+
speaks to the swap backend (dex-backend) is `@gala-chain/gswap-sdk`'s, and launchpad-sdk no longer
|
|
14
|
+
depends on it in any way. **[MIGRATING-TO-9.0.md](./MIGRATING-TO-9.0.md)** lists every export and
|
|
15
|
+
`LaunchpadSDK` member 8.1.0 had that 9.0.0 does not, with its new home; it is generated from the
|
|
16
|
+
built declarations of both versions (`pnpm docs:migration`).
|
|
17
|
+
|
|
18
|
+
### BREAKING CHANGES (9.0 cut)
|
|
19
|
+
|
|
20
|
+
- **The `Sign` header goes to the launchpad backend only.** The clients for the GalaChain gateway,
|
|
21
|
+
dex-api (referrals, bridgeable and wrappable token lists), the swap backend (prices) and the
|
|
22
|
+
bundler no longer send it: none of those hosts reads it (the gateway's own signature is in each
|
|
23
|
+
write's body; dex-api reads `x-wallet-address`), and every header cost a wallet signature per
|
|
24
|
+
request, a prompt for browser wallets. The clients keep the wallet identity (`getAddress`,
|
|
25
|
+
`signTypedData`) services read from them. `HttpClient` takes `{ signRequests }` as its third
|
|
26
|
+
constructor argument (default true: the launchpad backend client). Gateway read goldens
|
|
27
|
+
(`gateway-reads`, `token-discovery`) lost exactly their recorded `Sign` header and nothing else;
|
|
28
|
+
`tests/http-client-sign-header.test.ts` pins both behaviours.
|
|
29
|
+
- **No DEX at all, not even as a devDependency.** The 46 DEX demos and their npm scripts (`demo:dex*`,
|
|
30
|
+
`demo:liquidity*`, `demo:fees*`, the pool watchers, `test:demos:dex`, `test:demos:fees`) moved to
|
|
31
|
+
`packages/gswap-sdk/examples/demos` (on gswap-sdk's own client, type-checked by its
|
|
32
|
+
`check:examples`), and the stage live test's DEX checks to gswap-sdk's live test.
|
|
33
|
+
`tests/product-boundary.test.ts` scans `src`, `tests`, `examples` and `scripts` with the TypeScript
|
|
34
|
+
scanner, refuses gswap-sdk in every dependency field and resolves it from the package with plain
|
|
35
|
+
Node (MODULE_NOT_FOUND); the CI dist check refuses it in every bundle.
|
|
36
|
+
- **Prices: launchpad tokens only.** Of the two swap-backend price readers launchpad-sdk had, only the
|
|
37
|
+
launchpad-token one stays: `fetchTokenPrice({ tokenName })` (the bonding-curve price, or the
|
|
38
|
+
token's swap-backend price once it graduated; GALA's USD price and a graduated token's price are
|
|
39
|
+
read with a thin `GET /market/price` documented as launchpad-backend-adjacent). REMOVED, as
|
|
40
|
+
generic swap-backend reads that gswap-sdk's `market` already makes:
|
|
41
|
+
`fetchTokenPrice({ tokenId })` (a `tokenId` is now refused with a `ValidationError` before
|
|
42
|
+
anything is sent) and its 400/404 "launchpad fallback" (the recorded golden vector shows it never
|
|
43
|
+
fired: the 404 was wrapped before the check), `fetchGalaPrice()`, `fetchPriceHistory()`,
|
|
44
|
+
`fetchAllPriceHistory()` and their types (`FetchPriceHistoryOptions`, `PriceHistoryResult`,
|
|
45
|
+
`PriceSnapshot`, `PriceSortOrder`). Use `gSwap.market.getPrice(tokenId)` and
|
|
46
|
+
`gSwap.market.getPriceSeries(await sdk.resolveTokenClassKey(name), timeframe)`.
|
|
47
|
+
Decision and evidence (callers grepped in mcp-server, the apps, examples and docs): the only
|
|
48
|
+
callers of the removed reads were the MCP price tools, the examples and the docs. The MCP tools
|
|
49
|
+
(`gala_launchpad_fetch_token_spot_price` with `tokenId`, `..._fetch_gala_spot_price`,
|
|
50
|
+
`..._fetch_price_history`, `..._fetch_all_price_history`) keep their names, inputs and outputs on
|
|
51
|
+
the MCP server's own GSwap client, and replay the 13 recorded 8.1 vectors of these reads (same
|
|
52
|
+
endpoint and query, same outputs). What differs on the wire: no launchpad `Sign` header on these
|
|
53
|
+
public reads, the `$` of a class key sent as `%24`, and a backend failure's inner text (gswap-sdk's).
|
|
54
|
+
- **Dependencies are the source's import graph** (`tests/dependency-graph.test.ts`): `@gala-chain/api`,
|
|
55
|
+
`axios`, `bignumber.js`, `ethers`, `socket.io-client`, `uuid`, `web-file-polyfill`; peers
|
|
56
|
+
`@gala-chain/gala-core-sdk` (`>=1.0.0-rc.3 <2`), `zod` (now `^4.3.6`: the peer said `^3` while the
|
|
57
|
+
schemas are zod 4, and it is no longer also a dependency) and the shared libraries. No longer
|
|
58
|
+
dependencies: `@solana/web3.js`, `@solana/spl-token`, `dotenv`, `@modelcontextprotocol/sdk` (and,
|
|
59
|
+
since the bridge move, `bs58` and `json-stringify-deterministic`).
|
|
60
|
+
- **Bridging is explicit: the `bridge` loader.** The bridge, balance-on-chain, token-list and wrap
|
|
61
|
+
methods run on `@gala-chain/gala-core-sdk/bridge` (the one core entry that loads `ethers`,
|
|
62
|
+
`@solana/web3.js` and `@solana/spl-token`, core's optional peers), which the app hands over:
|
|
63
|
+
`new LaunchpadSDK({ ..., bridge: () => import('@gala-chain/gala-core-sdk/bridge') })` (type
|
|
64
|
+
`CoreBridgeLoader`; a page without a bundler passes a function resolving to the module it loaded
|
|
65
|
+
itself). The UMD bundle no longer looks for a `GalaCoreSDKBridge` global. launchpad-sdk
|
|
66
|
+
names neither that module nor Solana in any built bundle: a bundler (Vite, webpack, Metro)
|
|
67
|
+
resolves every load it sees, a lazy `import()` included, so the earlier `import()` inside the SDK
|
|
68
|
+
made every app's build need Solana (an app's Vite build failed with 13 `MISSING_EXPORT` errors on
|
|
69
|
+
`@solana/web3.js` / `@solana/spl-token`). Without the loader a bridge or wrap call is a
|
|
70
|
+
`ConfigurationError` (`field: 'bridge'`) naming it; with it, the module is loaded once per SDK at
|
|
71
|
+
the first such call, and a failed load (the peers are not installed) is a `ConfigurationError`
|
|
72
|
+
naming them, tried again at the next call. `check:pack` scans every built bundle of the packed
|
|
73
|
+
package for a `@gala-chain/gala-core-sdk/bridge` or `@solana/*` load (`scripts/runtime-specifiers.ts`).
|
|
74
|
+
A bridge or wrap call made with one wallet is refused (`ConfigurationError`, nothing sent) if
|
|
75
|
+
`setWallet` / `setWalletProvider` runs while `/bridge` loads, rather than running as the next
|
|
76
|
+
wallet. `getSupportedBridgeTokens()` is `async`.
|
|
77
|
+
- **The public surface re-exports nothing** (`tests/public-surface.test.ts` pins both entries' export
|
|
78
|
+
lists and fails on any export declared outside `src/`). Removed from the main and `/native`
|
|
79
|
+
entries: `generateEIP712Types` and `GalaChainSigner` (core's), the duplicate EIP-712 types
|
|
80
|
+
`EIP712Types`, `EIP712TypeField`, `EIP712Domain` (core's `EIP712Types`, `EIP712DomainValue`),
|
|
81
|
+
`HttpRequestor` (the bundler transport takes core's `HttpRequestor` type), `GALA_TOKEN_CLASS_KEY`
|
|
82
|
+
(core's), `generateUniqueKey` (core's `createUniqueKey`), and the demo `.env` loaders `getEnv`,
|
|
83
|
+
`getEnvOrThrow`, `loadEnvWithFallback`.
|
|
84
|
+
|
|
85
|
+
### App-owned session (a browser app's httpOnly-cookie JWT session)
|
|
86
|
+
|
|
87
|
+
- **`session` in `LaunchpadSDKConfig`.** A browser app (launchpad-frontend-v3) keeps its own JWT
|
|
88
|
+
session: the refresh token is an httpOnly cookie the backend sets for `cookieSession: true`
|
|
89
|
+
logins, and the app is the one token authority. With `session: { accessToken, onUnauthorized,
|
|
90
|
+
credentials? }` every launchpad-backend request takes its bearer from `accessToken()` (awaited per
|
|
91
|
+
request), a 401 goes to `onUnauthorized(rejectedToken)` and is retried once with the token it
|
|
92
|
+
returns (`null`: the 401 stands), the launchpad-backend client sends credentials (unless
|
|
93
|
+
`credentials: 'omit'`), and the SDK stores no token (services that attach "the JWT" attach
|
|
94
|
+
nothing; the client adds the session's bearer). No other host (gateway, bundler, dex-api, swap
|
|
95
|
+
backend) ever sees the session or credentials. Exclusive with `accessToken`. Pair it with
|
|
96
|
+
`signer` + `walletAddress`: `wallet` / `walletProvider` sign every launchpad request (`Sign`).
|
|
97
|
+
- **`loginWithSignature({ address, message, signature, publicKey? })`**: `POST /auth/login` with a
|
|
98
|
+
signature the caller made (a browser wallet signs `Sign in to Launchpad t:<ms>` itself); with a
|
|
99
|
+
session it asks for the cookie session and stores nothing. **`loginWithDevBypass(address)`**: the
|
|
100
|
+
backend's non-production signature bypass.
|
|
101
|
+
- With a session, `refreshToken()` is `POST /auth/refresh` with `{}`, no bearer and the cookie;
|
|
102
|
+
`logout({ allDevices, accessToken })` always revokes on the server (bearer as handed over, never
|
|
103
|
+
refreshed); `ensureValidToken()` is the session's current token. Auth-endpoint failures are an
|
|
104
|
+
`AuthError` with the backend's `statusCode` (401/403: the session was rejected; 429/5xx/none:
|
|
105
|
+
transient). `tests/app-session.test.ts` drives each through a real axios instance.
|
|
106
|
+
|
|
107
|
+
### Browser-app wallet signing
|
|
108
|
+
|
|
109
|
+
- **`BrowserWalletSigner.fromEip1193(provider, keyAddress, options?)`**: a browser app holds the
|
|
110
|
+
wallet's raw EIP-1193 provider, not an ethers one. The factory builds the ethers `BrowserProvider`
|
|
111
|
+
the typed-data path reads the network and the selected account from, keeps the raw `request` for
|
|
112
|
+
`signObject`, and takes the key as `0x` or `eth|` (a `client|` alias is refused: it names no key).
|
|
113
|
+
The bytes are those of the constructor path (bundler-typed-data and wallet-providers goldens
|
|
114
|
+
unchanged; `tests/wallet-signers-app.test.ts` compares both paths over a real `BrowserProvider`).
|
|
115
|
+
- **`WALLET_ACCOUNT_CHANGED`** (`LaunchpadSDKError`, `details.walletAccount` / `signerAccount`):
|
|
116
|
+
`BrowserWalletSigner` refuses to sign when the wallet's selected account is not its key. Same
|
|
117
|
+
message as before; it was a plain `Error`, which the bundler transport rewrapped as
|
|
118
|
+
`LAUNCHPAD_SIGNING_FAILED`.
|
|
119
|
+
- **`WALLET_USER_REJECTED`**: the bundler transport tells a decline in the wallet (gala-core-sdk's
|
|
120
|
+
`isWalletUserRejection`: `4001`, `ACTION_REJECTED`, Gala Wallet's decline, core's
|
|
121
|
+
`SIGNING_FAILED`/`user_rejected`) apart from other signing failures, with the wallet's code in
|
|
122
|
+
`details.walletCode`. Other failures stay `LAUNCHPAD_SIGNING_FAILED`; an SDK error passes through.
|
|
123
|
+
- **Gala Wallet typed data selects the account.** `GalaWalletSigner.signTypedData` switches the
|
|
124
|
+
extension (`setAddress`, where it offers it) to `selectAddress`, else the Ethereum account the
|
|
125
|
+
request names, inside gala-core-sdk's per-wallet select-then-sign queue
|
|
126
|
+
(`withGalaWalletIdentity`), and signs through the `wallet` option when one is given (it read
|
|
127
|
+
`window.gala` even then, while `signObject` used the option).
|
|
128
|
+
- **`GalaWalletSigner` option `verifyActiveAccount` (default `false`)**: the app's check before a Gala
|
|
129
|
+
Wallet signature. On, the signer reads the wallet's active account (`wallet.address`, else
|
|
130
|
+
`eth_accounts` when the wallet has not reported one since the page loaded) and refuses with
|
|
131
|
+
`WALLET_ACCOUNT_CHANGED` (`details.walletAccount` null when none was reported) unless it is the
|
|
132
|
+
signer's key; the RPC order is that check, `setAddress`, `eth_signTypedData`. Off by default so the
|
|
133
|
+
six recorded `galaWalletEthAddress` vectors of `bundler-typed-data.golden.json` are unchanged (the
|
|
134
|
+
check adds an `eth_accounts` request); the opt-in sequences are pinned by the new
|
|
135
|
+
`tests/golden/gala-wallet-verify-account.golden.json`. A signer that names no Ethereum key
|
|
136
|
+
(`client|` alias without an Ethereum `selectAddress`) is refused at construction
|
|
137
|
+
(`INVALID_SIGNER_OPTIONS`). `BrowserWalletSigner` needs no option: it always compares the wallet's
|
|
138
|
+
selected account with its key.
|
|
139
|
+
|
|
140
|
+
### Bundle confirmation for a browser app
|
|
141
|
+
|
|
142
|
+
- **`bundleSocketFactory` in `LaunchpadSDKConfig`** (passed to `BundlerTransport`): the app's own
|
|
143
|
+
bundler socket, with its reconnect settings. Each `wait()` adds its listener for the bundle's
|
|
144
|
+
event on the socket the factory returns and removes it when the wait ends; that socket is never
|
|
145
|
+
disconnected (a socket the transport opens itself still is).
|
|
146
|
+
- **`sdk.launchpad.attach({ bundleId, method, uniqueKey, tokenName? })`** (and
|
|
147
|
+
`BundlerTransport.attach`): a `BundleSubmission` for a bundle sent before a reload, whose `wait()`
|
|
148
|
+
confirms exactly as the original's (socket event raced against the REST confirmation, which also
|
|
149
|
+
answers for a bundle that settled while nobody listened). Nothing is signed or sent until
|
|
150
|
+
`wait()`. Refused with `INVALID_BUNDLE_ATTACHMENT` (`details.field`): empty `bundleId` /
|
|
151
|
+
`uniqueKey`, a method the bundler does not accept, a `CreateSale` without `tokenName`. New exports:
|
|
152
|
+
`LAUNCHPAD_WRITE_METHODS` (`LaunchpadWriteMethod` is now derived from it), types
|
|
153
|
+
`BundleAttachment`, `BundleSocket`, `SocketFactory`. `LaunchpadWriteTransport` gains `attach`.
|
|
154
|
+
- The bundler (bundler-backend origin/main, `src/socket/socket.gateway.ts`) emits only
|
|
155
|
+
`{ status, data }` (lowercase; `PENDING` / `PROCESSED` / `FAILED`), never `{ Status, Data }`, so
|
|
156
|
+
`parseBundleResult` is unchanged.
|
|
157
|
+
|
|
158
|
+
### The backend's error answer on `NetworkError`
|
|
159
|
+
|
|
160
|
+
- **`serverMessage`, `serverError`, `details`, `body`** (type `NetworkErrorServerAnswer`) beside
|
|
161
|
+
`statusCode`. Before, an HTTP failure was `NetworkError("HTTP <M> <url>: Request failed with status
|
|
162
|
+
code N")` and the backend's body survived only on `originalError.launchpadError`. The launchpad
|
|
163
|
+
backend (origin/main `GlobalExceptionFilter`) answers `{ status, error: true, message }`
|
|
164
|
+
(HttpException: validation pipe, `sendResult`, guards) or `{ statusCode, message }` (CustomError,
|
|
165
|
+
413, unhandled 500): `serverMessage` is that `message` (an array is joined with `,`, as
|
|
166
|
+
`String(array)` shows it), `serverError` is a string `error` only (`true` is not one), `body` the
|
|
167
|
+
whole body (or the text of a non-JSON answer). Messages are unchanged.
|
|
168
|
+
- **A wrapped NetworkError keeps them**: `new NetworkError(msg, status?, originalError?, answer?)`
|
|
169
|
+
takes the answer of `originalError` (an axios error's response, or another NetworkError) when
|
|
170
|
+
not given, and `handleNetworkError` (the `error-wrapper` `withErrorHandling` wrap services put
|
|
171
|
+
around the client's error) also takes the wrapped NetworkError's status: it was `undefined`
|
|
172
|
+
there. (A bare `createNetworkError(msg, undefined, inner)` does not take the status: the
|
|
173
|
+
gateway-reads golden pins `statusCode` absent on the GalaChain balance read's wrapped 400.)
|
|
174
|
+
`createNetworkError` takes the answer as an optional fourth argument;
|
|
175
|
+
`response-handlers.assertResponseSuccess` puts a 2xx error envelope's body on it.
|
|
176
|
+
- Paths that turned the client's NetworkError into another error now keep it a NetworkError, same
|
|
177
|
+
message: `PoolService.fetchToken`'s 404 "Token not found: <name>" (was a plain `Error`),
|
|
178
|
+
`UserService.uploadProfileImage`'s "Profile image upload failed: ..." for an HTTP refusal (was a
|
|
179
|
+
`ValidationError` `UPLOAD_FAILED`; other failures still are), and `LaunchpadPriceService`'s spot
|
|
180
|
+
price failure now wraps the original.
|
|
181
|
+
- The response interceptor's `launchpadError.error` is set only when the body's `error` is a string
|
|
182
|
+
(it cast the backend's `true` to a string).
|
|
183
|
+
|
|
184
|
+
### Path parameters are spelled as the backend compares them
|
|
185
|
+
|
|
186
|
+
- `buildEndpoint` (every `StreamTokenServiceBase` service) lowercased EVERY path value. It now
|
|
187
|
+
follows `PATH_PARAM_CASING`, decided per parameter from launchpad-backend origin/main's routes:
|
|
188
|
+
`tokenName` (the pool lookup's `normalizeTokenName`), `address` and `userAddress`
|
|
189
|
+
(`normalizeAddress`) stay lowercased; `assetId` and `targetId` (Mux ids, mixed-case, compared
|
|
190
|
+
exactly), `id` (numeric invite ids) and `code` (invite codes, matched exactly) are sent as given.
|
|
191
|
+
A parameter the table does not name is refused. Changed on the wire: `getRecordingDownload` /
|
|
192
|
+
`deleteRecording` (`/v1/tokens/:tokenName/recordings/:assetId[/download]`) and
|
|
193
|
+
`removeSimulcastTarget` (`/v1/tokens/:tokenName/simulcasts/:targetId`): a mixed-case Mux id was
|
|
194
|
+
lowercased into one the backend does not have; the moderator and overseer `getInviteByCode`
|
|
195
|
+
(`/v1/{moderator,overseer}-invites/code/:code`) send the code as given (generated codes are
|
|
196
|
+
lowercase hex, so only a code typed in another case differs); the invite `:id` routes are
|
|
197
|
+
unchanged in effect (digits).
|
|
198
|
+
|
|
199
|
+
### `PageInfo` is the backend's `pageInfo`
|
|
200
|
+
|
|
201
|
+
- **`PageInfo` = `{ hasNextPage, endCursor?, hasPreviousPage?, startCursor?, totalCount? }`**, the
|
|
202
|
+
backend's own keys (launchpad-backend origin/main `buildPageInfo`: `endCursor` / `startCursor`
|
|
203
|
+
are `string | null`). It declared `nextCursor` / `prevCursor` / `hasPrevPage`, while every list
|
|
204
|
+
but two passed the backend's `pageInfo` through unchanged (so at run time it was `endCursor`), and
|
|
205
|
+
`PoolService` / `UserService` renamed the backend's keys to the declared ones. Now no list renames:
|
|
206
|
+
pools and user token lists return the backend's `pageInfo` (`pageInfoOf`, which drops a field of
|
|
207
|
+
the wrong type), and the cursor walkers (`autoPaginateWithCursor`, `fetchAllPools`, the vault
|
|
208
|
+
token-name lookup) follow `endCursor` (`nextCursorOf`): `autoPaginateWithCursor` stopped after
|
|
209
|
+
the first page of every passed-through list. They also stop when the backend repeats the cursor
|
|
210
|
+
just used (`fetchAllPools` went back to page 1 on a missing cursor).
|
|
211
|
+
- `totalCount` is set only on results the SDK assembles from every page (`fetchAll...`): the
|
|
212
|
+
backend sends no count. Removed with it: `UserTokenListResult.total` (always undefined), the
|
|
213
|
+
dead `InternalFetchUserBalancesResponse` type, and the top-level `count` / `total` / `nextCursor`
|
|
214
|
+
/ `prevCursor` / `hasNextPage` / `hasPrevPage` fields of the internal pool and user-list response
|
|
215
|
+
types (the backend answers `{ tokens | token | launches, pageInfo }`). Migration: read
|
|
216
|
+
`pageInfo.endCursor` (`?? undefined` for a `cursor` option) where you read `nextCursor`.
|
|
217
|
+
|
|
218
|
+
### `fetchPools` matches `GET /v1/tokens` (launchpad-backend origin/main `FetchPoolDto`)
|
|
219
|
+
|
|
220
|
+
- **`type` and `streamStatus` in the backend's spelling, any case.** `type` RECENT / POPULAR /
|
|
221
|
+
RECORDINGS / SECONDS_STREAMED (`POOL_FETCH_TYPES`; the backend compares case-sensitively, so it is
|
|
222
|
+
sent uppercase), `streamStatus` IDLE / ACTIVE / DISABLED (`POOL_STREAM_STATUSES`). The lookup
|
|
223
|
+
tables were lowercase-keyed and DROPPED the app's `'POPULAR'` / `'ACTIVE'` without a word; lowercase
|
|
224
|
+
still works. A value the backend does not accept is a `ValidationError`, never dropped.
|
|
225
|
+
- **`pageSize` 1 to 100** (`POOL_LIST_MAX_PAGE_SIZE`, the backend's `MediumListQueryDto` maximum):
|
|
226
|
+
it was silently clamped to 20. Larger, zero or fractional is a `ValidationError`. `fetchAllPools`
|
|
227
|
+
reads pages of 100 (was 20). Default still 10.
|
|
228
|
+
- `recentlyStreamed` (integer 1 to 720), `language` (ISO 639-1) and `search` (at most 255) are
|
|
229
|
+
checked before sending, as the backend would refuse them.
|
|
230
|
+
- **`hasUpcomingShows` / `hasRecordings`: only `true` is sent.** The backend's boolean conversion
|
|
231
|
+
(`@Type(() => Boolean)` with implicit conversion) reads `"false"` as true, so `false` used to turn
|
|
232
|
+
the filter ON; it now sends nothing (no filter).
|
|
233
|
+
- `isGraduated` / `creatorAddress` are NOT added: origin/main's `FetchPoolDto` has neither and the
|
|
234
|
+
pipe forbids unknown properties (a 400).
|
|
235
|
+
- One pool-list reader: the private `LaunchpadAPI.fetchPools` / `fetchPoolsFromAPI` copy (used to
|
|
236
|
+
find a vault's token name for a sell-fee quote) is removed; that lookup reads `PoolService`. The
|
|
237
|
+
copy read `hasNextPage` / `nextCursor` at the top of `data`, where the backend never puts them,
|
|
238
|
+
so it never got past page 1. `LaunchpadService` / `fetchAllPools` take `FetchPoolsOptions` (their
|
|
239
|
+
inline option types still named `offset` / `limit`). The zod `poolFetchTypeSchema` takes all four
|
|
240
|
+
types; the public `PoolFetchType` is the one type (`'RECENT' | 'POPULAR' | 'RECORDINGS' |
|
|
241
|
+
'SECONDS_STREAMED'`, it was the schema's two).
|
|
242
|
+
|
|
243
|
+
### Admin and overseer contracts (launchpad-backend origin/main)
|
|
244
|
+
|
|
245
|
+
- **`revokeOverseerInvite` and `revokeOverseer` sent no Authorization.** The auth headers were passed
|
|
246
|
+
in the query-params slot of `HttpClient.delete`: the request went out unauthenticated and the
|
|
247
|
+
header names became query parameters. They are headers now (`tests/g3-admin-wire.test.ts`).
|
|
248
|
+
- **Restricted token names carry the session bearer.** `getRestrictedNames` / `updateRestrictedNames`
|
|
249
|
+
(Overseer-only routes) sent no Authorization. An empty `content` is accepted (the backend takes any
|
|
250
|
+
string; it clears the list); `UpdateRestrictedNamesResponse` is `{ content }` (the backend echoes the
|
|
251
|
+
stored content), it was typed `{ success: true }`.
|
|
252
|
+
- **Invite codes are validated like the backend**: any non-empty string up to 64 characters
|
|
253
|
+
(`INVITE_CODE_CONSTRAINT.MAX_LENGTH`, was 100 for overseer codes and "64 hex" for moderator codes).
|
|
254
|
+
An unknown code is the backend's 404, which a claim page relies on to fall through from the overseer
|
|
255
|
+
lookup to the moderator one; it used to be a client-side `ValidationError`.
|
|
256
|
+
- **`sdk.getHealth()`** (`GET /health`, public): `HealthCheckResponse` (`status` plus database, redis,
|
|
257
|
+
mux, rabbitmq, galachain_query, galachain_launchpad). A critical dependency down is HTTP 503 and
|
|
258
|
+
throws a `NetworkError`.
|
|
259
|
+
- **`sdk.getEventStats()`, `sdk.queryEvents(options)`** (`GET /v1/events/stats`, `GET /v1/events`,
|
|
260
|
+
Admin API key or Overseer): the routes answer BARE bodies, which the service reads and shape-checks.
|
|
261
|
+
`queryEvents` pages by `page` / `limit` (1..100). `eventTypes` / `categories` are sent as a
|
|
262
|
+
REPEATED key (one value is sent twice): the backend validates them with `@IsArray` behind Express 5's
|
|
263
|
+
simple query parser, where a comma list or `key[]=` is refused.
|
|
264
|
+
- **`getMessageStats` reads the bare object** `GET /v1/messages/stats` answers (it required a
|
|
265
|
+
`{ data }` envelope and could never succeed against the backend).
|
|
266
|
+
|
|
267
|
+
- **The flag filters validate what `GetFlagsQueryDto` takes**: the token filter is 1-50 letters and digits
|
|
268
|
+
(a 1-character filter threw; see the token name rules below) and the addresses
|
|
269
|
+
(`reporterAddress`, `reportedUserAddress`, also `createFlag`'s) are the forms `@GalaChainAddressField()`
|
|
270
|
+
takes after its normalisation: `eth|<40 hex>`, `0x<40 hex>`, 40 hex, `client|<24 hex>` or 24 hex
|
|
271
|
+
(`isBackendUserAddress` / `assertBackendUserAddress`). A bare client id is accepted now; a partial
|
|
272
|
+
address and `client|<name>` stay refused, because the backend answers 400 for them.
|
|
273
|
+
- **`updateModeratorInvite({ inviteId, description: '' })` is a valid update**: the backend's `UpdateModeratorInviteDto.description` has no minimum and its service updates on
|
|
274
|
+
`description !== undefined`, so `''` alone clears the label (the SDK refused it with "At least one of
|
|
275
|
+
role or description"). An update with neither field is still refused.
|
|
276
|
+
|
|
277
|
+
### Trades, tokens, users and streaming contracts (launchpad-backend origin/main)
|
|
278
|
+
|
|
279
|
+
- **`fetchTrades` reaches its route.** It sent the literal `/v1/tokens/:tokenName/trades` with the
|
|
280
|
+
name in a query parameter; the token is now in the path (lowercased, as the backend compares it).
|
|
281
|
+
`TradeQueryItem` types `tokenSymbol`, which `GET /v1/trades` returns. `getTrades` already unwrapped
|
|
282
|
+
the `{ data }` body (verified on the wire, `tests/g3-trades-wire.test.ts`).
|
|
283
|
+
- **`fetchTokenStats` returns what the backend sends**: `{ holdersCount, chatMessageCount, commentCount,
|
|
284
|
+
roomCount }` (`TokenStatsData`, was `EngagementStatsData`). It required a `stats` wrapper the backend
|
|
285
|
+
has none of, and so could never succeed; `totalEngagement`, participants and activity fields were
|
|
286
|
+
never sent.
|
|
287
|
+
- **`updateTokenConfig` takes `chatEnabled`** (was `messagesEnabled`, which the backend refuses with 400:
|
|
288
|
+
its `UpdateTokenConfigDto` has `chatEnabled`).
|
|
289
|
+
- **`fetchLaunchpadFee()` returns the number** (`data.feeAmount`); it returned the `{ feeAmount }` object
|
|
290
|
+
typed as a number.
|
|
291
|
+
- **Images reach their routes.** `uploadImageByTokenName` posts to `/v1/tokens/:tokenName/image` (the
|
|
292
|
+
placeholder went out literally, the name in a query parameter) and `uploadProfileImage` to
|
|
293
|
+
`POST /v1/users/me/image` (it used the token route); the profile upload needs no address or wallet.
|
|
294
|
+
- **`updateProfile` sends what is given.** `address` is optional (validated, not sent), `fullName` and
|
|
295
|
+
`profileImage` are optional (at least one), `profileImage: ''` clears the image, and the profile is no
|
|
296
|
+
longer fetched first to send the old image back. `fullName` is validated like the backend's
|
|
297
|
+
`UpdateProfileDto` (a trimmed 2..20 letters, one optional second word) and no wallet is required, only
|
|
298
|
+
a JWT.
|
|
299
|
+
- **User token lists take pages up to 100** (`USER_PAGINATION_CONSTRAINT.MAX_LIMIT` 20 -> 100; the
|
|
300
|
+
backend takes up to 1000, default 50); `getManagedTokens` sends no `pageSize` unless asked, so the
|
|
301
|
+
backend's 50 applies (the SDK's default 10 cut a longer list off).
|
|
302
|
+
- **`fetchVolumeData` returns the chart**: `{ dataPoints, isPreviousData, nextTime? }` with the candles
|
|
303
|
+
typed as the backend sends them (`startTime`, `openPrice`, `highPrice`, `lowPrice`, `closePrice`,
|
|
304
|
+
`volume`); `dataPoints` held the whole `{ data, isPreviousData }` object typed as `{ timestamp, value }[]`.
|
|
305
|
+
- **`getTradeQuote` takes an `AbortSignal`** (`TradeQuoteParams.signal`); `PlatformStatsData` volumes are
|
|
306
|
+
numbers (typed as strings); `listOverseerUsers` accepts `ASC` / `DESC` (the backend reads the order
|
|
307
|
+
case-insensitively).
|
|
308
|
+
- **Recordings match `GET /v1/tokens/:tokenName/recordings`**: a bare array with no paging.
|
|
309
|
+
`getStreamRecordings({ tokenName })` returns `{ recordings, tokenName }` (the fabricated `page`, `limit`,
|
|
310
|
+
`total`, `hasNext` are gone; the old code read `data.recordings` and could never succeed). A recording is
|
|
311
|
+
`{ id, playbackId, status, duration, createdAt, masterAccess, aspectRatio?, assets? }` (was `assetId`,
|
|
312
|
+
`tokenName`, `downloadable`, `fileSize`, `thumbnailUrl`); `RECORDING_STATUS` is Mux's `preparing` /
|
|
313
|
+
`ready` / `errored`. An unknown token is a `NetworkError` with `statusCode` 404.
|
|
314
|
+
- **Simulcasts match `/v1/tokens/:tokenName/simulcasts`**: the list is a bare array behind the owner's
|
|
315
|
+
session bearer (it was sent without Authorization); a target is `{ id, url, status, passthrough? }`;
|
|
316
|
+
`addSimulcastTarget` sends `{ platform, url, streamKey, passthrough? }` with the platform in lowercase
|
|
317
|
+
(`'youtube' | 'twitch' | 'facebook' | 'custom'`, `SIMULCAST_PLATFORM`), as the backend's
|
|
318
|
+
`CreateSimulcastTargetDto` requires (it refused `rtmpUrl`, `name` and uppercase platforms), and the
|
|
319
|
+
URL is RTMP or RTMPS only (the SDK allowed SRT, which the backend refuses).
|
|
320
|
+
- **`sdk.getChatStatus(tokenName)`** (`GET /live/:tokenName/chat`, public): `{ enabled, tokenName,
|
|
321
|
+
reason?, slowModeSeconds?, status? }`. `ChatStatusResponse` gains `tokenName` and `slowModeSeconds`.
|
|
322
|
+
- **The pinned message is the backend's `PinnedMessageData`** (`messageId`, `content`, `userAddress`,
|
|
323
|
+
`pinnedBy`, `pinnedAt`, `user?`, `holderTier?`): `getPinnedMessage` returned a type with `id` and
|
|
324
|
+
`createdAt` the backend never sends, and threw when nothing was pinned (`{ data: null }`); it returns
|
|
325
|
+
`{ message: null }` now. `getPinnedChatMessage` / `pinChatMessage` return that message as it is, and
|
|
326
|
+
`unpinChatMessage` takes its `messageId`.
|
|
327
|
+
- **`UpdateMessageOptions.type`**: a chat edit is capped at 500 characters before it is sent when the
|
|
328
|
+
type is known (`updateChatMessage` passes it).
|
|
329
|
+
- **`PoolData` names the streaming fields the backend sends**: `muxPlaybackId`, `muxStreamAspectRatio`,
|
|
330
|
+
`streamLanguage` (typed `playbackId`, `aspectRatio`, `language`, which the backend does not send, so
|
|
331
|
+
they were always undefined); `streamEnabled`, `messagesEnabled`, `commentsEnabled` are not on a pool.
|
|
332
|
+
- **New `sdk.getUserGalaBalance(address)`** (`GET /v1/users/:address/gala-balance`, public: the GALA
|
|
333
|
+
balance and USD value the backend reads) and **`sdk.fetchReferralCode()`**
|
|
334
|
+
(`GET /v1/connect/users/referrals/code`, JWT: `{ code, username? }`).
|
|
335
|
+
- **`TradesQueryResult` is the one trades result type, and it is not deprecated.** `getTrades`,
|
|
336
|
+
`getRecentTrades` and `getHolderHistory` return the backend's `{ trades, pageInfo }`; the
|
|
337
|
+
`@deprecated` marker (it pointed at `TradesListResult`, an `items`/`meta` type no method returns) and
|
|
338
|
+
`TradesListResult` are gone, and the `getTrades` examples read `pageInfo` (they destructured a `meta`
|
|
339
|
+
the result never had).
|
|
340
|
+
- **`UpdateTokenConfigOptions` is one type.** The package root exported a `token-config.dto` interface
|
|
341
|
+
(social links `string` only) while `updateTokenConfig` took a second one declared beside the message
|
|
342
|
+
types (`string | null`). The backend's `UpdateTokenConfigDto` takes `null` to clear a social link, so
|
|
343
|
+
the one type is the `string | null` form, declared in `token-config.dto` with
|
|
344
|
+
`validateUpdateTokenConfigOptions` (moved with it), and the dead duplicate
|
|
345
|
+
`InternalUpdateTokenConfigResponse` of `messages.dto` is gone.
|
|
346
|
+
- **The pin and invite result types are exported, one meaning per name.** `pinMessage` / `unpinMessage`
|
|
347
|
+
return `PinMessageResult` (`{ success }`) and `getPinnedMessage` returns `PinnedMessageResult`
|
|
348
|
+
(`{ message }`), both now exported from the root; the root's old `PinMessageResult`
|
|
349
|
+
(`{ tokenName, pinnedMessage }`, the shape of a removed REST route) is gone and
|
|
350
|
+
`getPinnedChatMessage` / `pinChatMessage` return `GetPinnedMessageResult`
|
|
351
|
+
(`pinnedMessage` is `null` when another moderator unpinned between the pin and the read back; it was
|
|
352
|
+
cast to non-null). `InviteScope`, `UpdateInviteRoleOptions` and `UpdateInviteRoleResult` are exported;
|
|
353
|
+
the identical `InviteScope` of `streaming.dto` and `ModeratedTokenInviteScope` are the one
|
|
354
|
+
`InviteScope`.
|
|
355
|
+
- **`fetchProfile` is typed and unwrapped.** `fetchProfile(address)` returned the whole
|
|
356
|
+
`{ status, error, message, data }` envelope typed `unknown`; it returns `PublicUserProfile` (the
|
|
357
|
+
backend's `ProfileResponse`: `address`, nullable `fullName` / `profileImage` / `bio`, `stats`
|
|
358
|
+
(`ProfileStats`), the four `BadgeStatus[]` ladders, `isLiveStreaming`, `liveStreamToken`) and a body
|
|
359
|
+
that is not that shape is a `NetworkError` (`Malformed profile response`). The service's no-address
|
|
360
|
+
form (`GET /v1/users/me/profile`, JWT) returns `CurrentUserProfile`. `BadgeStatus`, `ProfileStats`,
|
|
361
|
+
`PublicUserProfile` and `CurrentUserProfile` are exported.
|
|
362
|
+
- **`PoolData` types `badges`** (`PoolBadges`: the `volume` and `engagement` `BadgeStatus[]` ladders the
|
|
363
|
+
backend builds for `GET /v1/tokens` and `/:tokenName`) and the stored `volumeBadge` / `engagementBadge`
|
|
364
|
+
columns. The pool route sends no `chatEnabled`, `streamingEnabled` or `tokenSymbol` (they are not in
|
|
365
|
+
its attribute list), so `PoolData` does not declare them.
|
|
366
|
+
- **Message, comment and chat types are the backend's five shapes** (`GET /v1/messages` and the four write
|
|
367
|
+
answers differ; the SDK typed one invented `BaseContentItem` for all of them). `Message` is the list
|
|
368
|
+
item of `fetchMessages`, `getComments` and `getChatMessages`: `id` and `messageId` (the same string),
|
|
369
|
+
`user` / `userProfile` (the same non-null `{ fullName, profileImage }`), `updatedAt` `string | null`,
|
|
370
|
+
`reactions: { counts, userReacted? }` (was a plain `Record<string, number>`), and no `type`,
|
|
371
|
+
`holderTier` or `isPinned` (the backend sends none of them on a list item). Writes: `sendChatMessage`
|
|
372
|
+
returns `SentChatMessage` (no database id, `holderTier?`), `createComment` / `updateComment` return
|
|
373
|
+
`WrittenComment` (numeric `id` AND `messageId`, no `tokenName`), `updateChatMessage` returns
|
|
374
|
+
`EditedChatMessage` (numeric `id`, `reactions?` as `ReactionData`); `createMessage` / `updateMessage`
|
|
375
|
+
infer the result from `options.type`. `BaseContentItem`, `CommentItem`, `ChatMessageItem`,
|
|
376
|
+
`isChatMessageItem` and the dead `/v1/comments` result types (`CommentData`, `FetchCommentsResult`,
|
|
377
|
+
`PostCommentResult`, `FetchCommentsOptions`, `PostCommentOptions`, `DeleteCommentOptions`, file
|
|
378
|
+
`comment.dto.ts`) are gone; `isMessage` checks the real shape (it needed a `type` no item has, so it
|
|
379
|
+
was false for every item). Each id the examples took from a write (`result.comment.id`, a number, or
|
|
380
|
+
`result.message.id`, undefined) is the `messageId`.
|
|
381
|
+
- **Each method validates the token name of ITS backend route** (launchpad-backend origin/main). The SDK
|
|
382
|
+
refused names the routes take (3-20 everywhere, 2-20 on messages, 50 on trades) and sent names a route
|
|
383
|
+
refuses. Five rules, exported as `TOKEN_NAME_*_CONSTRAINT` (and `TokenNameConstraint`), replace
|
|
384
|
+
`LAUNCHPAD_TOKEN_NAME_CONSTRAINT`, `RELAXED_TOKEN_NAME_CONSTRAINT`, `EXTENDED_TOKEN_NAME_CONSTRAINT`
|
|
385
|
+
and the helpers' silent 3-20 default (`validateTokenName(name, field, constraint)`,
|
|
386
|
+
`isValidTokenName(name, constraint)`, `validateOptionalTokenName(...)` now take the route's rule):
|
|
387
|
+
`DTO` 1-20 letters and digits (`@TokenNameField()` request fields: `fetchPools` filter, `fetchVolumeData`,
|
|
388
|
+
`fetchTokenDistribution`, `fetchUserHolderContext`, `fetchMessages`, `createMessage`, `getTrades`,
|
|
389
|
+
flag create, moderator invites, `banToken`), `FILTER` 1-50 (the flag lists), `PATH` letters and digits
|
|
390
|
+
1-255 (a raw `:tokenName` the pool lookup resolves, no format check: `fetchToken`, `fetchTokenStats`,
|
|
391
|
+
`updateTokenConfig`, `getTokenConfig`, image upload, every stream, recording, simulcast, ban and chat
|
|
392
|
+
method, `getPinnedMessage`, the user token list filter), `AVAILABILITY` 1-50 characters, any
|
|
393
|
+
(`validateToken`, `checkPool`: `ValidateTokenDto`), `EVENT` 1-100 characters without HTML (the
|
|
394
|
+
`WebSocketAdminService` emits). The root helpers `validateTokenName(name, field, constraint)`,
|
|
395
|
+
`isValidTokenName(name, constraint)` and `validateOptionalTokenName(name, field, constraint)` take the
|
|
396
|
+
rule of the route you name (they had a silent 3-20 default). The chain's launch rule (letters and
|
|
397
|
+
digits, 1+, no cap; what the launch form and `createSale` take) is `tokenNameSchema`,
|
|
398
|
+
`launchTokenDataSchema` and `imageUploadOptionsSchema`; `graphDataOptionsSchema` and
|
|
399
|
+
`graduateTokenOptionsSchema` use the DTO rule (`dtoTokenNameSchema`) and `checkPoolOptionsSchema` the
|
|
400
|
+
availability rule (`availabilityTokenNameSchema`). `TRADES_QUERY_CONSTRAINTS` (a deprecated
|
|
401
|
+
composite) is gone.
|
|
402
|
+
- **The reaction routes take no token name.** `AddReactionDto` is `{ messageId, reactionType }` and the
|
|
403
|
+
backend refuses any other property (whitelist + forbidNonWhitelisted), so `addContentReaction` with a
|
|
404
|
+
`tokenName` answered 400; `AddContentReactionOptions` / `RemoveContentReactionOptions` lose
|
|
405
|
+
`tokenName` and nothing is validated or sent for it.
|
|
406
|
+
- **`uploadTokenImage` and `uploadProfileImage` work on a signer-plus-address SDK.** The facade threw
|
|
407
|
+
"Wallet is required" (and `uploadProfileImage` defaulted the address from the wallet) though
|
|
408
|
+
`POST /v1/tokens/:tokenName/image` and `POST /v1/users/me/image` read the user from the session JWT and
|
|
409
|
+
need nothing else; an app configured with `{ signer, walletAddress, session }` and no `wallet` uploads
|
|
410
|
+
with the session bearer (`tests/g7-uploads-wire.test.ts`). `uploadProfileImage` no longer invents an
|
|
411
|
+
address: one that is given is validated and left out of the request. Their JSDoc described
|
|
412
|
+
`imagePath` options and a Node-only API that do not exist (the options are `{ file }`).
|
|
413
|
+
- **Image uploads send multipart, not JSON.** Both uploads put the `FormData` through an axios instance
|
|
414
|
+
that carries `Content-Type: application/json` as an instance default; the request-level header was only
|
|
415
|
+
left out, so the default survived the merge and axios serialised the body as JSON
|
|
416
|
+
(`{"image":{}}`, the file lost; the 400 the backend answers was the only sign). `HttpClient` now
|
|
417
|
+
clears the Content-Type for a `FormData` body per request (an explicit `undefined`), so the transport
|
|
418
|
+
sets `multipart/form-data` with its boundary (axios' Node adapter, the browser's XHR). The existing
|
|
419
|
+
wire tests swapped the whole instance for one without the default and could not see it;
|
|
420
|
+
`tests/image-upload-multipart-wire.test.ts` (Node, real server) and
|
|
421
|
+
`tests/image-upload-multipart-browser-wire.test.ts` (jsdom XHR, real server, plus the FormData as it
|
|
422
|
+
leaves axios) run the real `createHttpExecutor` instance and read the bytes sent. These are the only
|
|
423
|
+
two multipart paths in the SDK.
|
|
424
|
+
- **One name for an image upload.** `UploadImageByTokenNameOptions.options.tokenName` (a second name that
|
|
425
|
+
went into the URL without being validated) is gone; the path takes the validated `tokenName`. The dead
|
|
426
|
+
`LaunchpadAPI.uploadImageByTokenName` (`POST /launchpad/upload-image`) and
|
|
427
|
+
`LaunchpadAPI.fetchTokenDistribution` (`GET /holders/:tokenName`), routes the backend does not have, are
|
|
428
|
+
removed with their tests (`ImageService` and `PoolService` are the working ones).
|
|
429
|
+
|
|
430
|
+
### The stream socket: one registry of subscribers (launchpad-backend origin/main)
|
|
431
|
+
|
|
432
|
+
`StreamWebSocketService` keeps ONE registry. `sdk.realtime` is the service of an SDK (built with
|
|
433
|
+
`streamWebSocketUrl`, the reconnect settings and the session's token). Every event the backend emits has a
|
|
434
|
+
typed entry on it (`RealtimeEventPayloads`, read from the emit sites, not from the backend's docs).
|
|
435
|
+
|
|
436
|
+
- **Any number of subscribers per event, per token, per room.** Every `subscribe*` method is synchronous,
|
|
437
|
+
returns that subscriber's OWN unsubscribe (a second call is harmless) and replaces nobody. The old
|
|
438
|
+
single callback slots (`globalCallbacks`, `roomCallbacks`, `globalFeedCallbacks`) are gone: a second
|
|
439
|
+
subscriber used to replace the first and the first's cleanup deleted the second's callback, and
|
|
440
|
+
`subscribeToStream` on a joined token wiped every other subscriber's callbacks. A subscriber that
|
|
441
|
+
throws or rejects is logged and skipped; the others are served. `LaunchpadSDK.watch*` are plain
|
|
442
|
+
subscribers (the fan-out, refcount and room bookkeeping `watchTokenRoomEvent` kept is deleted).
|
|
443
|
+
- **Rooms are refcounted.** A token room, a comment room, the global feed and the events firehose are
|
|
444
|
+
joined on the FIRST subscriber and left on the LAST; never two server subscriptions for one room. A
|
|
445
|
+
leave waits for the join's acknowledgement (a subscribe followed at once by an unsubscribe cannot strand
|
|
446
|
+
the room on the server). A subscribe before the socket is connected registers and joins on connect; with
|
|
447
|
+
`autoConnect` (default) it also opens the socket. It never throws `NOT_CONNECTED`.
|
|
448
|
+
- **Listeners are registered once per socket**, when it is created (they used to be registered again on
|
|
449
|
+
every `connect`, so every reconnect doubled every callback), and removed when it is closed.
|
|
450
|
+
- **Reconnect.** The service acts on the Socket's `connect` (the Manager's `reconnect` fires before the
|
|
451
|
+
socket is connected and used to run `authenticate()` too early). On every connection after the first:
|
|
452
|
+
re-authenticate FIRST with the token current at that moment (`tokenProvider`, never a remembered
|
|
453
|
+
one) if the socket was authenticated, THEN re-join every room that still has a subscriber, THEN call the
|
|
454
|
+
new `onReconnect(listener)` listeners (the app's version never fired, `reconnect` is a Manager event).
|
|
455
|
+
`onConnectionStateChange(listener)` is new. A server-side `io server disconnect` reconnects (socket.io
|
|
456
|
+
does not), and so do `connect()` and a new subscribe after socket.io ran out of reconnection attempts
|
|
457
|
+
(`socket.active` stays true then). `LaunchpadSDKConfig.streamReconnectAttempts` / `streamReconnectDelay` /
|
|
458
|
+
`streamReconnectDelayMax` reach socket.io (a browser app wants `Infinity`, 1000, 10000); defaults stay
|
|
459
|
+
5 / 2000.
|
|
460
|
+
- **`authenticate(token?)` returns `Promise<boolean>`** (it returned `void` and threw `NOT_CONNECTED`
|
|
461
|
+
when not connected): `true` on `authenticated`; `false` on `exception`, `stream_chat_auth_error`, the
|
|
462
|
+
10 s timeout, a dropped connection, no token, or a newer `authenticate` / `deauthenticate`. The same
|
|
463
|
+
token on the same connection sends nothing; a different token replaces the pending one and is sent after
|
|
464
|
+
the server answered the one in flight. `LaunchpadSDK.authenticateStreamWebSocket(token?)` takes the
|
|
465
|
+
app's token (or the session's) and returns the boolean. The handshake carries no token any more
|
|
466
|
+
(`StreamWebSocketConfig.authToken` is gone; a static token was presented, expired, on every reconnect).
|
|
467
|
+
- **`deauthenticate()`** (`sdk.deauthenticateStreamWebSocket()`): the server has no message that drops a
|
|
468
|
+
socket's identity, so an authenticated socket is closed and opened again (subscriptions stay registered;
|
|
469
|
+
`onReconnect` fires). `setWallet` / `setWalletProvider` call it.
|
|
470
|
+
- **`joinTokenRoom(token)`** holds a token's room with no listener (the room stays joined while its
|
|
471
|
+
listeners come and go); it returns its own release.
|
|
472
|
+
- **The overseers' firehose** (`subscribeEventsFirehose(listener, filters?)`): one server subscription
|
|
473
|
+
for all subscribers, joined once the socket is authenticated (it is overseer-only) and again after every
|
|
474
|
+
re-authentication. The backend's firehose takes no filters, so each subscriber's
|
|
475
|
+
`{ eventTypes, tokenName, userAddress }` filters are applied client-side.
|
|
476
|
+
- **The comment room.** `COMMENT_*` events are sent to the comment room only; `subscribeCommentCreated`
|
|
477
|
+
(and the new `Updated` / `Deleted`) now emit `subscribe_comment` (it never did, so it received nothing).
|
|
478
|
+
- **User-room and overseer events are delivered to global subscribers** (`subscribeGlobalModeratorAdded`
|
|
479
|
+
/ `Removed` / `RoleUpdated` / `InviteCreated`, `subscribeGlobalTokenBanned` / `Unbanned`,
|
|
480
|
+
`subscribeContentFlagged`, `subscribeFlagResolved`, `subscribeAIModerationComplete` / `Failed`,
|
|
481
|
+
`subscribeUserBanned` / `Unbanned`, `subscribeBanEnforcement`, `subscribeTradeUpdateNotify`,
|
|
482
|
+
`subscribeBalanceUpdated(token)`, ...), not only to a token room's subscribers.
|
|
483
|
+
- **Feed subscribers are served whether or not the token room is joined.** The backend sends a client in
|
|
484
|
+
both rooms one copy of an event; the service delivers it to the token subscribers and to the feed
|
|
485
|
+
subscribers (it used to deliver it to the token room only, never to the feed).
|
|
486
|
+
- **New events with typed payloads**: `STREAM_CHAT_UPDATED`, `STREAM_CHAT_DELETED`, `SLOW_MODE_CHANGED`,
|
|
487
|
+
`RECORDING_STATUS`, `RECORDINGS_COUNT_UPDATED`, `SIMULCAST_STATUS`, `DOWNLOAD_READY`,
|
|
488
|
+
`STREAM_CONTROL_STATUS_CHANGED`, `CONTENT_REACTION_ADDED` / `REMOVED`, `COMMENT_UPDATED` / `DELETED`,
|
|
489
|
+
`CONTENT_FLAGGED`, `FLAG_RESOLVED`, `AI_MODERATION_COMPLETE` / `FAILED`, `POOL_CREATED`,
|
|
490
|
+
`TRADE_UPDATE_NOTIFY`, `AI_MODERATION_GLOBAL_STATUS`, `EVENT` (firehose), `exception`.
|
|
491
|
+
`STREAM_COUNTDOWN_UPDATED` / `STREAM_LANGUAGE_UPDATED` are fed from `TOKEN_CONFIG_UPDATED` (the backend no
|
|
492
|
+
longer emits them separately). `getSiteConfigState()` returns the latest site-wide switches.
|
|
493
|
+
`subscribeFeedTokenEvents(cb)` hands every feed token event over named (`{ event, data }`).
|
|
494
|
+
- **A second copy of one occurrence is dropped** for the events the backend sends through two rooms a
|
|
495
|
+
client can be in (`CONTENT_FLAGGED`, `FLAG_RESOLVED`, `AI_MODERATION_*`, `POOL_CREATED`, `OVERSEER_*`):
|
|
496
|
+
within 5 seconds, by id.
|
|
497
|
+
- **A payload with no usable `tokenName` no longer throws inside the socket listener** (`data.tokenName.trim()`,
|
|
498
|
+
`data.content.slice`); it reaches the subscribers of the event for every token and none of a token.
|
|
499
|
+
- **The 30-second replay buffer is removed.** It replayed stale events (trade deltas, candles) to a
|
|
500
|
+
late subscriber as if they were new, and started a timer per event per token; registration now precedes
|
|
501
|
+
the join, so there is no join race left for it to cover.
|
|
502
|
+
- **Replaced APIs (9.0.0 is unpublished: no shims).** `setGlobalCallbacks` -> `addCallbacks(callbacks)`
|
|
503
|
+
(adds, returns the remover); `setGlobalFeedCallbacks`, `unsubscribeFromGlobalFeed` and the Promise form
|
|
504
|
+
of `subscribeToGlobalFeed` -> `subscribeToGlobalFeed(callbacks)` returns an unsubscribe;
|
|
505
|
+
`connectStreamWebSocket(callbacks)` adds subscribers; `subscribeToStream(token, callbacks)` adds, and
|
|
506
|
+
`unsubscribeFromStream(token)` removes only what `subscribeToStream` added. `subscribeEngagementStatsUpdated`
|
|
507
|
+
takes a token. `StreamingEventService` and its `streaming-events` types are deleted: the
|
|
508
|
+
`LaunchpadSDK.on*` methods they backed never fired (nothing fed them); they are now subscribers of the same
|
|
509
|
+
registry (`onStreamChatMessage`, `onViewerCountChanged`, `onUserBanned`, ...: every occurrence the socket
|
|
510
|
+
receives, for any token; join rooms with the `subscribe*` methods or `subscribeToStream`).
|
|
511
|
+
`disconnect()` releases every subscriber, listener and timer and rejects what is pending; the service can be
|
|
512
|
+
used again; `dispose()` (called by `sdk.cleanup()`) is final.
|
|
513
|
+
- **Payload types follow the backend**: `UserBannedEvent` / `UserUnbannedEvent` / `BanEnforcementEvent`
|
|
514
|
+
(`isGlobal`, `isPermanent`, optional `reason` / `expiresAt` / `userAddress`; `tokenName` is `null` for a
|
|
515
|
+
global ban; the type guards accept the banned user's own copy, which has no address),
|
|
516
|
+
`TradeExecutedEvent` (+ `symbol`, `icon`), `BalanceUpdatedEvent` (the backend sends no balances),
|
|
517
|
+
`StreamGlobalStatusEvent` / `StreamChatGlobalStatusEvent` (`updatedAt` optional: `{ enabled }`), and the
|
|
518
|
+
global-feed token types are the token-room types (the feed copies named other fields). `COMMENT_DELETED`
|
|
519
|
+
carries `commentId`, not `messageId`.
|
|
520
|
+
|
|
521
|
+
### Fixes
|
|
522
|
+
|
|
523
|
+
- `createSale`'s pre-flight refused launches the launch form and the deployed bundler accept (a
|
|
524
|
+
scheme-less link such as `t.me/x`, a lower-case symbol, a name of 2 or 21-25 characters, a
|
|
525
|
+
pre-buy of `5.`). It now refuses only what the bundler (fee window, bad words) or the chain
|
|
526
|
+
(`CreateTokenSaleDTO`, `TokenClass`) refuses: a name of letters and digits (any length), a symbol
|
|
527
|
+
of letters and digits in any case (the chain upper-cases it; the wire carries it as typed), no
|
|
528
|
+
link rules, a non-empty description (at most 1000) and image (at most 500), an integer
|
|
529
|
+
`saleStartTime`, and a plain-decimal pre-buy and curve portions, which are SIGNED in their
|
|
530
|
+
canonical spelling (`5.` -> `5`, `1.50` -> `1.5`: the chain keeps any other spelling a string
|
|
531
|
+
and refuses it). Bad words are still refused by the bundler after signing (it fetches the list).
|
|
532
|
+
`LaunchpadTradeInput`, `LaunchpadExtraFees` and `CreateSaleInput` are exported by name
|
|
533
|
+
(`@since 9.0.0`), and `LaunchpadTradeInput.extraFees` documents what is sent on a buy.
|
|
534
|
+
- `BundleSubmission.wait()` takes `{ signal?: AbortSignal }` beside `timeoutMs` / `pollIntervalMs`
|
|
535
|
+
(`@since 9.0.0`). An aborted wait rejects with `LaunchpadSDKError` `BUNDLE_WAIT_ABORTED`
|
|
536
|
+
(`details.method`, `details.bundleId`; an already aborted signal rejects before a socket is opened
|
|
537
|
+
or a read sent) and stops what it started: the in-flight read (the requestor gets the wait's
|
|
538
|
+
`AbortSignal` as `init.signal`), the pause between reads, the deadline timer, its socket listener
|
|
539
|
+
(an own socket is disconnected, a borrowed `bundleSocketFactory` socket never). Aborting stops
|
|
540
|
+
watching only; `attach` resumes the bundle. A wait that ends for any reason now stops its reads too
|
|
541
|
+
(they used to run on until the deadline, up to 10 minutes). Also: one failed confirmation read (an
|
|
542
|
+
HTTP error, a network error, an unreadable body) no longer rejects the wait with
|
|
543
|
+
`BUNDLE_REQUEST_FAILED` while the socket can still deliver: reads are repeated every
|
|
544
|
+
`pollIntervalMs` until the deadline, and only a verdict (PROCESSED / FAILED), the deadline or an
|
|
545
|
+
abort ends the wait. At the deadline after failing reads the error is `BUNDLE_CONFIRMATION_TIMEOUT`
|
|
546
|
+
with the last failed read in `details.lastReadFailure` (`{ message, status? }`); the deadline
|
|
547
|
+
also holds for a read that never answers.
|
|
548
|
+
- `graduateToken` bought `calculateBuyAmountForGraduation`'s `amount` (the GALA cost of the
|
|
549
|
+
remaining tokens) as the exact-buy token quantity. It buys `remainingTokens`, with the GALA cost
|
|
550
|
+
as `expectedAmount` (the slippage cap).
|
|
551
|
+
- `subscribeToTokenCreations`: an event field that is missing or not a string is its fallback
|
|
552
|
+
(`''`, `preBuyQuantity` `'0'`), never `undefined`; `isFinalized` is `true` only for `true`.
|
|
553
|
+
- Demo tooling: `demo:run` ran every selection interactively and counted failed demos as
|
|
554
|
+
successes (booleans tested with `!= null`); the registry maps each demo's SDK methods, leaves
|
|
555
|
+
the tooling out (130 demos) and `demo:run:method` / `demo:run:endpoint` exist. 131 more boolean
|
|
556
|
+
`!= null` tests in the demos and tests (write demos ran their transfer, wrap and unwrap whatever
|
|
557
|
+
their `EXECUTE_*` flag said) are plain boolean tests, and `tests/constant-boolean-null-check.test.ts`
|
|
558
|
+
refuses the shape.
|
|
559
|
+
|
|
560
|
+
### The `/bundle` signing schemes (unchanged bytes; for Andy)
|
|
561
|
+
|
|
562
|
+
Two schemes post to the bundler's `/bundle`, and both have callers, so both stay:
|
|
563
|
+
`sdk.launchpad.buyWithNative / buyExactToken / sellWithNative / sellExactToken / createSale`
|
|
564
|
+
(`BundlerTransport`) signs EIP-712 typed data (`signTypedData`, the GalaChain domain; pinned by
|
|
565
|
+
`tests/golden/bundler-typed-data.golden.json`): what the live launchpad frontend
|
|
566
|
+
(launchpad-frontend-v3, `signTypedData` / `eth_signTypedData`) and the MCP trading tools send.
|
|
567
|
+
`sdk.buy()` / `sdk.sell()` (`BundleService.buyToken / sellToken`) sign with the signer's
|
|
568
|
+
`signObject` (native for a private key, personal-sign for a browser wallet): the native app calls
|
|
569
|
+
these (`src/sdk/facades/trade.ts`), as do the examples. Retiring `BundleService`'s trade methods
|
|
570
|
+
needs the native app moved to `sdk.launchpad.*` first (which changes the bytes it sends).
|
|
571
|
+
|
|
572
|
+
### What moved to gala-core-sdk (the extraction steps, from the 8.1.0 baseline)
|
|
573
|
+
|
|
574
|
+
The gateway token writes (transfer GALA, transfer a token, burn, lock, unlock) moved to
|
|
575
|
+
`@gala-chain/gala-core-sdk` 1.0.0-rc.1 (`GatewayWrites`). `transferGala`, `transferToken`,
|
|
576
|
+
`burnTokens`, `lockTokens` and `unlockTokens` keep their names, signatures, input checks, result
|
|
577
|
+
shapes and error classes and delegate to it; their requests are byte-identical (golden vectors)
|
|
578
|
+
and still go through the SDK's gateway `HttpClient` (the `Sign` header included).
|
|
579
|
+
|
|
580
|
+
The gateway token READS moved to `@gala-chain/gala-core-sdk` 1.0.0-rc.2 (`GatewayReads`):
|
|
581
|
+
`fetchGalaBalance`, `fetchTokenBalance` (tokenId and MUSIC/GMUSIC routes), `fetchTokenDetails`,
|
|
582
|
+
`fetchTokenClassesWithSupply` and the NFT reads keep their names and signatures and delegate to it,
|
|
583
|
+
through the same clients as before (balances and NFT reads through the gateway `HttpClient` with
|
|
584
|
+
its `Sign` header, token classes through the unauthenticated gateway axios instance). The core peer
|
|
585
|
+
range is now `>=1.0.0-rc.3 <2`.
|
|
586
|
+
|
|
587
|
+
The wallet providers and the React hooks moved to `@gala-chain/gala-core-sdk` 1.0.0-rc.3
|
|
588
|
+
(`/providers`, `/react`). `LaunchpadSDKConfig.walletProvider`, `setWalletProvider` and
|
|
589
|
+
`SignatureAuth` take core's `WalletProvider`; a core `PrivateKeyProvider` still gives the SDK's
|
|
590
|
+
services their key.
|
|
591
|
+
|
|
592
|
+
The bridge moved to `@gala-chain/gala-core-sdk` 1.0.0-rc.3 (`/bridge`): `BridgeService`, the
|
|
593
|
+
Ethereum and Solana strategies, `GalaConnectClient`, the bridgeable and wrappable token services
|
|
594
|
+
(with their caches and the offset pagination), `WrapService`, the bridge constants and types, and
|
|
595
|
+
`createSolanaWallet`. `src/bridge/` and those services are gone from launchpad-sdk; the SDK's
|
|
596
|
+
bridge, balance, token-list and wrap methods build core's services (from the SDK's wallet, its
|
|
597
|
+
native signer and its DEX API client) and keep their names. The bridge-out signed payloads are
|
|
598
|
+
byte-identical (golden vectors, unchanged); every GalaConnect request, Ethereum and Solana
|
|
599
|
+
transaction, token-list read and wrap request replays the recorded vectors, and
|
|
600
|
+
`LaunchpadSDK.wrapToken` sends exactly the recorded wrap. `/native` is 337,915 bytes (was 403,450).
|
|
601
|
+
|
|
602
|
+
#### Breaking (the moves)
|
|
603
|
+
|
|
604
|
+
- **The bridge is gala-core-sdk's.** Every bridge export of the browser and node entries is
|
|
605
|
+
REMOVED; import it from `@gala-chain/gala-core-sdk/bridge` (same name unless listed):
|
|
606
|
+
|
|
607
|
+
| Was (launchpad-sdk) | Now (`@gala-chain/gala-core-sdk/bridge`) |
|
|
608
|
+
| --- | --- |
|
|
609
|
+
| `BaseBridgeStrategy`, `EthereumBridgeStrategy`, `SolanaBridgeStrategy`, `GalaConnectClient`, `BridgeStatusCode`, the constants (`CHAIN_IDS`, `GALACHAIN_CHANNELS`, `ETHEREUM_TOKENS_PROD` / `_STAGE`, `DEFAULT_SOLANA_TOKENS`, `ERC20_ABI`, `BRIDGE_CONTRACT_ABI`, ...), the EIP-712 constants, the token math (`toBaseUnits`, `fromBaseUnits`, `formatTokenAmount`, `compareAmounts`), `stripHexPrefix`, and every bridge, bridgeable-token and wrappable-token type | the same name |
|
|
610
|
+
| `BRIDGE_TOKEN_METADATA` | `STATIC_TOKEN_METADATA` |
|
|
611
|
+
| `BridgeRateLimiter` | `RateLimiter` |
|
|
612
|
+
| `DEFAULT_ETHEREUM_TOKENS` (deprecated alias) | `ETHEREUM_TOKENS_PROD` |
|
|
613
|
+
| `GalaConnectHttpError` | `GalaSDKError` with code `GALACONNECT_HTTP_ERROR` (`error.status`, `params.serverMessage`) |
|
|
614
|
+
| `createSolanaWallet`, `GeneratedSolanaWallet` | the same name (it was in the browser and node entries) |
|
|
615
|
+
| `WrapUnwrapStatus`, `WrapUnwrapStatusResult` | removed: a wrap resolves only once completed |
|
|
616
|
+
|
|
617
|
+
`BridgeService`, `BridgeableTokenService`, `WrappableTokenService` and `WrapService`, which
|
|
618
|
+
launchpad-sdk did not export, are exported there too.
|
|
619
|
+
- **Bridge and wrap failures are typed `GalaSDKError`s** (`isGalaError(error, code)`), not
|
|
620
|
+
`ValidationError` / `NetworkError` / `TransactionError` / `GalaConnectHttpError` or a text:
|
|
621
|
+
`INVALID_BRIDGE_AMOUNT`, `INVALID_WALLET_ADDRESS`, `INVALID_TOKEN_REFERENCE`,
|
|
622
|
+
`UNSUPPORTED_BRIDGE_TOKEN`, `BRIDGE_NOT_CONFIGURED`, `INVALID_BRIDGE_OPTION`,
|
|
623
|
+
`INSUFFICIENT_BRIDGE_BALANCE`, `GALACONNECT_HTTP_ERROR`, `BRIDGE_REQUEST_REJECTED`,
|
|
624
|
+
`BRIDGE_RESPONSE_INVALID`, `BRIDGE_READ_RESPONSE_INVALID`, `BRIDGE_TOKEN_NOT_FOUND`,
|
|
625
|
+
`TOKEN_NOT_WRAPPABLE`, `INVALID_WRAP_DIRECTION`, `BRIDGE_CHAIN_READ_FAILED`, and, once something
|
|
626
|
+
may have moved (never repeat it), `BRIDGE_WRITE_OUTCOME_UNKNOWN`, `BRIDGE_OUT_OUTCOME_UNKNOWN`
|
|
627
|
+
(with the bridge request id and the `uniqueKey`), `BRIDGE_DEPOSIT_OUTCOME_UNKNOWN`,
|
|
628
|
+
`BRIDGE_STATUS_TIMEOUT`.
|
|
629
|
+
- **`wrapToken` / `unwrapToken` throw instead of returning `success: false`**: `WrapUnwrapResult`
|
|
630
|
+
is the completed result (`success: true`, `transactionId` and `completedAt` always set; `error`
|
|
631
|
+
and `fee` removed). Their options have no `memo` (it was never sent). **`getWrapStatus` is
|
|
632
|
+
REMOVED** (it always answered "completed" for any id).
|
|
633
|
+
- **`getBridgeStatus(hash)`** takes no chain hint (one GalaConnect read answers for either chain);
|
|
634
|
+
**`estimateBridgeFee`** takes no `amount` (the fee never depended on it).
|
|
635
|
+
- Behaviour on the way: a GalaConnect write is sent again only after a 429 (a 5xx or a failure in
|
|
636
|
+
transit may have been applied: outcome unknown); an `eth|0x...` recipient is accepted; the
|
|
637
|
+
caller's own input (token id, amount, recipient, an unconfigured chain) is refused before any
|
|
638
|
+
read; a malformed RPC URL, contract, wallet address or program id option is refused when the
|
|
639
|
+
service is built.
|
|
640
|
+
- `bs58` and `json-stringify-deterministic` are no longer dependencies (nor, with the 9.0 cut above,
|
|
641
|
+
`@solana/web3.js` and `@solana/spl-token`: core's `/bridge` loads them, at the first bridge
|
|
642
|
+
call). `LaunchpadSDK`'s own
|
|
643
|
+
declarations need no Node types (a consumer of it compiles with TypeScript 6 and 7 without
|
|
644
|
+
them); an app that imports `/bridge` types naming `@solana/web3.js` (e.g. `BridgeServiceConfig`)
|
|
645
|
+
needs Node's types, since `@solana/web3.js`'s declarations import `http` / `https`.
|
|
646
|
+
|
|
647
|
+
- **`@gala-chain/launchpad-sdk/wallet` and `@gala-chain/launchpad-sdk/react` are REMOVED**, and so
|
|
648
|
+
are the wallet exports of the browser entry. Import from core instead (same names unless listed):
|
|
649
|
+
|
|
650
|
+
| Was (launchpad-sdk) | Now (gala-core-sdk) |
|
|
651
|
+
| --- | --- |
|
|
652
|
+
| `/wallet` and the browser entry: `PrivateKeyProvider`, `ExternalWalletProvider`, `GalaWalletProvider`, `detectWallets`, `getWalletByRdns`, `hasAnyWallet`, `isWalletAvailable`, `subscribeToWalletChanges`, `getInjectedEip1193Provider`, `KNOWN_WALLET_RDNS`, `createWalletProvider`, `createProviderFromEip1193`, `ensureConnected`, `getPrivateKeyIfAvailable`, `isPrivateKeyProvider`, `isExternalProvider`, `isEip1193Provider` and the types (`WalletProvider`, `Eip1193Provider`, `DetectedWallet`, ...) | `@gala-chain/gala-core-sdk/providers` |
|
|
653
|
+
| `WalletProviderError`, `WalletProviderErrorCode` | `GalaSDKError` from `@gala-chain/gala-core-sdk`, branched with `isGalaError(error, 'WALLET_CONNECTION_FAILED' \| 'WALLET_NOT_CONNECTED' \| 'SIGNING_FAILED' \| ...)` |
|
|
654
|
+
| `createProviderFromWallet(wallet)`, `walletToProvider(wallet)` | `PrivateKeyProvider.fromWallet(wallet)` |
|
|
655
|
+
| `providerToWallet(provider)` | `isPrivateKeyProvider(p) ? new Wallet(p.exportPrivateKey()) : undefined` (ethers stays the app's) |
|
|
656
|
+
| `/react`: `WalletProvider`, `WalletContext`, `useWallet`, `useWalletContext`, `useWalletConnection`, `useWalletDetection`, `useWalletAddress`, `useGalaAddress`, `useWalletProvider`, `useIsWalletConnected` and their types | `@gala-chain/gala-core-sdk/react` |
|
|
657
|
+
| `/react`'s re-exports `detectWallets`, `ExternalWalletProvider`, `KNOWN_WALLET_RDNS`, `PrivateKeyProvider`, type `WalletProviderInterface` | `@gala-chain/gala-core-sdk/providers` (`WalletProviderInterface` is `WalletProvider`) |
|
|
658
|
+
|
|
659
|
+
A custom `WalletProvider` now needs `getSigner()` (core's interface). `react` is no longer a peer
|
|
660
|
+
of launchpad-sdk (it is an optional peer of core's `/react`).
|
|
661
|
+
- **The Ethereum wallet helpers are gala-core-sdk's.** `createWallet`, `getPublicKeyFromPrivateKey`,
|
|
662
|
+
`getEthereumAddressFromPrivateKey` and the type `PublicKeyResult` are REMOVED from launchpad-sdk
|
|
663
|
+
(browser, node and `/native` entries): import them from `@gala-chain/gala-core-sdk`. Core's
|
|
664
|
+
`createWallet` returns `{ privateKey, address, galaAddress, mnemonic }` without the ethers
|
|
665
|
+
`.wallet`: `new Wallet(createWallet(input).privateKey)`. Refusals are core `GalaSDKError`s
|
|
666
|
+
(`INVALID_WALLET_INPUT`, `INVALID_PRIVATE_KEY`) instead of `ValidationError` / ethers errors; the
|
|
667
|
+
test-mode fake key (`NODE_ENV=test`) is gone. `createSolanaWallet` moved with the bridge (above).
|
|
668
|
+
`AgentConfig` builds its wallets with core's `createWallet`; its wallet type is exported as
|
|
669
|
+
`AgentWallet` (core's wallet plus the ethers `wallet`). The internal `WalletUtils` is gone.
|
|
670
|
+
|
|
671
|
+
- **The token-class and hold types are gala-core-sdk's.** `fetchTokenClassesWithSupply` returns
|
|
672
|
+
`GalaChainTokenClass[]` (was `TokenClassWithSupply`, whose `authorities` were typed as objects:
|
|
673
|
+
GalaChain sends user refs, strings) and `fetchTokenDetails` returns `GalaChainTokenDetails` (was
|
|
674
|
+
launchpad's `GalaChainTokenDetails`, whose `chatEnabled` was never set: a token's chat status is
|
|
675
|
+
`getTokenConfig(tokenName).chatEnabled`). A hold in `TokenBalanceResult` / `LockedBalanceResult`
|
|
676
|
+
is `GalaChainTokenHold` (`name` and `vestingPeriodStart` are optional, as GalaChain stores them).
|
|
677
|
+
Removed exports: `TokenClassWithSupply`, `TokenHold`, the zod `tokenHoldSchema`; import the types
|
|
678
|
+
from `@gala-chain/gala-core-sdk`. A token class carries GalaChain's documented fields only (an
|
|
679
|
+
undocumented field is no longer passed on).
|
|
680
|
+
- **`TokenClassKey` and `TokenInstanceKey` REMOVED**: every signature uses gala-core-sdk's
|
|
681
|
+
`GalaChainTokenClassKey` / `GalaChainTokenInstanceKey` (same four fields, plus `instance`), so
|
|
682
|
+
import those from `@gala-chain/gala-core-sdk`. `TokenId` stays (`string | GalaChainTokenClassKey
|
|
683
|
+
| GalaChainTokenInstanceKey`). The bridge's `isTokenClassKey` export is removed: use core's
|
|
684
|
+
`isTokenClassKey` (the same check: four non-empty strings).
|
|
685
|
+
- `ENVIRONMENT_URLS` takes `gatewayBaseUrl` and `dexApiBaseUrl` from core's
|
|
686
|
+
`GALA_CHAIN_ENVIRONMENTS` (same URLs); `Environment` is core's `GalaChainEnv` (`'prod' | 'stage'`).
|
|
687
|
+
- **The DEX is gswap-sdk's, not launchpad-sdk's.** launchpad-sdk no longer depends on
|
|
688
|
+
`@gala-chain/gswap-sdk` (product SDKs never import each other). Removed: `sdk.dex` (the `GSwap`
|
|
689
|
+
client) and the `GSwap` re-export; the swap-backend reads `fetchAllDexSeasons`,
|
|
690
|
+
`fetchCurrentDexSeason`, `fetchDexLeaderboardBySeasonId`, `fetchCurrentDexLeaderboard`,
|
|
691
|
+
`fetchDexAggregatedVolumeSummary` and the pool poller `onDexPoolCreation`; the types `DexSeason`,
|
|
692
|
+
`LeaderboardEntry`, `LeaderboardResult`, `MasteryTitle`, `DexAggregatedVolumeSummary`. Migration:
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
import { PrivateKeySigner } from '@gala-chain/gala-core-sdk';
|
|
696
|
+
import { GSwap } from '@gala-chain/gswap-sdk';
|
|
697
|
+
|
|
698
|
+
const gSwap = new GSwap({ env, signer: new PrivateKeySigner(key), walletAddress: sdk.getAddress() });
|
|
699
|
+
// sdk.dex.quoting / swaps / pools / positions / symbols / assets -> gSwap.quoting / swaps / ...
|
|
700
|
+
// sdk.fetchAllDexSeasons() -> gSwap.leaderboard.getSeasons()
|
|
701
|
+
// sdk.fetchCurrentDexSeason() -> gSwap.leaderboard.getCurrentSeason()
|
|
702
|
+
// sdk.fetchDexLeaderboardBySeasonId(id) -> gSwap.leaderboard.getLeaderboard(id) ({ seasonId, entries })
|
|
703
|
+
// sdk.fetchCurrentDexLeaderboard() -> gSwap.leaderboard.getCurrentLeaderboard()
|
|
704
|
+
// sdk.fetchDexAggregatedVolumeSummary() -> gSwap.market.getVolumeSummary() (8 fields)
|
|
705
|
+
// sdk.onDexPoolCreation(cb, { minTVL }) -> gSwap.pools.watchNewPools(cb, { minTvl })
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
The gswap reads follow the backend's real answers: an answer of another shape is an error, not
|
|
709
|
+
`[]`; an unusable row is skipped (reported to `onInvalidEntry`), not filled with `''` / `0`; a
|
|
710
|
+
leaderboard has no `totalEntries` (`entries.length`) and a wallet without an XP breakdown has
|
|
711
|
+
`totalXp: null` (was `'0'`). `sdk.dex` was also never rebuilt by `setWallet` (it kept the first
|
|
712
|
+
wallet's signer): an app's own `GSwap` is built from the signer it means.
|
|
713
|
+
(The price reads went with the 9.0 cut above: only `fetchTokenPrice({ tokenName })` stays.)
|
|
714
|
+
|
|
715
|
+
- **`sdk.tokens` and `TokenWrites` REMOVED**, with the types `ChainResult`, `TransferInput`,
|
|
716
|
+
`LockInput`, `TokenAmountInput` and `TokenIdentifier`. They were a second implementation of the
|
|
717
|
+
same writes. Migration:
|
|
718
|
+
|
|
719
|
+
```typescript
|
|
720
|
+
// Removed
|
|
721
|
+
const result = await sdk.tokens.transfer({ to, tokenClassKey: 'GALA|Unit|none|none', quantity: '1' });
|
|
722
|
+
|
|
723
|
+
// Now (the SDK's wallet, or a { signer, walletAddress } SDK)
|
|
724
|
+
const { transactionId, blockNumber } = await sdk.transferToken({ to, tokenId: 'GALA|Unit|none|none', amount: '1' });
|
|
725
|
+
// sdk.tokens.burn / lock / unlock -> sdk.burnTokens / lockTokens / unlockTokens({ tokens: [...] })
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
What the services do not take that `sdk.tokens` did: a `client|` or `eth|0x...` recipient (spell
|
|
729
|
+
an Ethereum recipient `eth|<40 hex>` or `0x<40 hex>`), any `uniqueKey` (transfer keys keep the
|
|
730
|
+
`galaswap-operation-` / `galaconnect-operation-` prefix rule), a `$`-joined `tokenId`. For
|
|
731
|
+
those, use `GatewayWrites` from `@gala-chain/gala-core-sdk` directly.
|
|
732
|
+
|
|
733
|
+
#### Added
|
|
734
|
+
|
|
735
|
+
- An SDK configured with `{ signer, walletAddress }` (no `wallet`) can make token writes through
|
|
736
|
+
the five methods: signed by that signer and made as the declared identity (an `eth|` account or
|
|
737
|
+
a `client|` alias). With a `wallet` nothing changed.
|
|
738
|
+
- `LockTokensResult`, `UnlockTokensResult` and `BurnTokensResult` carry the gateway's
|
|
739
|
+
`x-transaction-id` as `transactionId` (preferred over a `Data` item's id) and `blockNumber`
|
|
740
|
+
from `x-block-number`, like the transfer receipts.
|
|
741
|
+
|
|
742
|
+
#### Changed
|
|
743
|
+
|
|
744
|
+
- Auto-generated `uniqueKey`s are `galaconnect-operation-<uuid v4>` (58 characters, CSPRNG) instead
|
|
745
|
+
of `galaconnect-operation-<ms>_<26 hex>` (62). An empty `uniqueKey` means "none" (a key is
|
|
746
|
+
minted); it used to be signed as `""` and refused by the chain.
|
|
747
|
+
- A caller's `uniqueKey` on `lockTokens` / `unlockTokens` / `burnTokens` (never checked before), and
|
|
748
|
+
one with characters outside `A-Za-z0-9._:-` on a transfer, is refused before signing.
|
|
749
|
+
- Quantities must be plain decimal strings (no exponent, hex or spaces); they are still signed as
|
|
750
|
+
written, never scaled.
|
|
751
|
+
- A pipe `tokenId` with a non-decimal fifth part (`Token|Unit|X|client|launchpad`, read as instance
|
|
752
|
+
`launchpad`) or a `TokenInstanceKey` with a non-decimal `instance` is refused before signing
|
|
753
|
+
instead of being signed as a different token.
|
|
754
|
+
- Token writes go through the SDK's gateway `HttpClient` (axios, the `Sign` header) as the five
|
|
755
|
+
methods always did; `config.httpRequestor`, which `sdk.tokens` used, is not used for them (it
|
|
756
|
+
still serves the bundler path). An app that must send token writes through its own
|
|
757
|
+
requestor uses core's `GatewayWrites` (`httpRequestor` option).
|
|
758
|
+
- `setWallet` / `setWalletProvider` now rebuild the token-write services, so a transfer, burn,
|
|
759
|
+
lock or unlock signs as the new wallet (before, the services kept signing as the wallet the SDK
|
|
760
|
+
was constructed with); a declared `{ signer, walletAddress }` identity no longer applies once the
|
|
761
|
+
wallet changes.
|
|
762
|
+
- A refusal of the core write before anything is sent maps to the service's error class
|
|
763
|
+
(`SIGNING_FAILED` -> `SIGNATURE_FAILED`, a token reference -> `TOKEN_NOT_FOUND`, a quantity ->
|
|
764
|
+
`INVALID_AMOUNT`, others -> the validation type).
|
|
765
|
+
|
|
766
|
+
#### Fixed (wallet changes)
|
|
767
|
+
|
|
768
|
+
- After `setWallet` / `setWalletProvider` nothing signs as, or sends from, the previous wallet:
|
|
769
|
+
the bundle trades (`buyTokens`, `sellTokens`) are rebuilt for the new wallet (they kept the
|
|
770
|
+
construction wallet, so an SDK started read-only could never trade), and the bridge service, the
|
|
771
|
+
wrap service and the GalaConnect client (built at first use with that wallet's address and key,
|
|
772
|
+
then kept forever) are dropped and rebuilt for the new wallet at their next use.
|
|
773
|
+
- An identity declared at construction (`walletAddress`, `galaChainAddress`, e.g. a `client|`
|
|
774
|
+
alias) named the construction key and is dropped on a wallet change: `getAddress()` was still
|
|
775
|
+
the old one, so the rebuilt services would have paired the new key with the old identity.
|
|
776
|
+
- `SignatureAuth.setWalletProvider` with a key-holding provider (`PrivateKeyProvider`) knows the
|
|
777
|
+
address at once, as `setWallet` does (the synchronous getters threw until `cacheAddress()`); a
|
|
778
|
+
wallet-backed provider still needs `cacheAddress()` and never reports the previous account.
|
|
779
|
+
|
|
780
|
+
#### Fixed (gateway reads)
|
|
781
|
+
|
|
782
|
+
- `fetchGalaBalance` and `fetchTokenBalance` (tokenId and MUSIC/GMUSIC routes) work against the
|
|
783
|
+
real gateway again: their `FetchBalances` body carried `instance: "0"`, which mainnet and testnet
|
|
784
|
+
refuse with HTTP 400 ("whitelistValidation: property instance should not exist", recorded
|
|
785
|
+
2026-10-13), so every such call threw a `NetworkError`. The body is now the chain DTO
|
|
786
|
+
(`owner, collection, category, type, additionalKey`).
|
|
787
|
+
- A balance record of another owner than the one asked for is never reported as theirs (the read
|
|
788
|
+
answers `null`); a missing owner is refused instead of reading every owner's balances.
|
|
789
|
+
- `availableQuantity` / `lockedQuantity` / `inUseQuantity` are never in exponent form
|
|
790
|
+
(`0.00000001`, not `1e-8`).
|
|
791
|
+
- `fetchNftCollections`, `isNftCollectionAvailable`, `fetchNftTokenClasses` and `fetchNftBalances`
|
|
792
|
+
read GalaChain (`FetchNftCollectionAuthorizationsWithPagination`,
|
|
793
|
+
`FetchTokenClassesWithPagination`, `FetchBalances`, page by page and bounded); they were
|
|
794
|
+
placeholders that always answered `[]` / `true`. `isNftCollectionAvailable` throws when the read
|
|
795
|
+
fails (never "available"), so `claimNftCollection` refuses a name that is already claimed. The
|
|
796
|
+
NFT writes (`claimNftCollection`, `createNftTokenClass`, `mintNft`) still do not reach GalaChain:
|
|
797
|
+
they return a locally made transaction id with status `pending`.
|
|
798
|
+
|
|
799
|
+
#### Fixed (price history; these reads are now the MCP server's, on gswap-sdk, which keeps the fixes)
|
|
800
|
+
|
|
801
|
+
- `fetchAllPriceHistory` reads the series once. It paged it through `fetchPriceHistory` with the
|
|
802
|
+
page NUMBER as the offset (0, 1, 2, ... with 50 per page), so a series over 50 points was
|
|
803
|
+
refetched in full per page (a 120-point series: about 100 requests) and came back with
|
|
804
|
+
overlapping, repeated snapshots; a series that changed between two requests shifted the pages.
|
|
805
|
+
A caller's `offset` / `limit` do not apply to it.
|
|
806
|
+
- `fetchPriceHistory` refuses a `limit` or `pageSize` outside 1-50 and a negative or fractional
|
|
807
|
+
`offset` before any request (`ValidationError`). A `limit` of 0 used to answer `page: NaN`,
|
|
808
|
+
`totalPages: Infinity` (JSON `null`).
|
|
809
|
+
|
|
810
|
+
#### Changed (gateway reads)
|
|
811
|
+
|
|
812
|
+
- A `FetchBalances` / `FetchTokenClasses` answer that is not GalaChain's (a numeric quantity, a hold
|
|
813
|
+
or class missing its fields) is refused whole: a balance is then `null` (as for any unusable
|
|
814
|
+
answer), a token class a `NetworkError`. A token-class answer without the class asked for is a
|
|
815
|
+
`NetworkError` ("Token not found on GalaChain", 404) instead of returning another class.
|
|
816
|
+
`fetchTokenClassesWithSupply` answers one class per key in the order asked (1 to 1000 keys).
|
|
817
|
+
|
|
818
|
+
#### Removed (internal)
|
|
819
|
+
|
|
820
|
+
- `api/dto/{TransferTokenDto,BurnTokensDto,LockTokenDto,UnlockTokenDto}` (and with them
|
|
821
|
+
`@gala-chain/api`'s `ChainCallDTO` on these paths), `utils/token-instance-key.ts`.
|
|
822
|
+
- `GalaChainBalanceService`'s `sumHoldQuantities` / `filterHolds` / `calculateAvailableQuantity`
|
|
823
|
+
(core totals the holds), the `GalaChainTokenBalance` / `InternalGalaChainFetchBalancesResponse` /
|
|
824
|
+
`InternalFetchTokenClassesWithSupplyResponse` types, `BalanceQueryParams.instance`, and
|
|
825
|
+
`@gala-chain/api`'s `TokenClass` on the token-class paths.
|
|
826
|
+
- Dead code: `utils/token-parser` `parseToken` (no caller), `isDelimited`, `isValidTokenFormat`,
|
|
827
|
+
`isPlainTokenSymbol` and its `isTokenClassKey`; `delimiter-parser` `validateTokenObject` (only
|
|
828
|
+
`parseToken` used it); `tokenNormalizer`'s `isTokenClassKeyStrict` re-export, `isTokenInstanceKey`
|
|
829
|
+
and `isTokenIdString`; `unique-key-generator` `generateOperationKey` (no caller; its keys held a
|
|
830
|
+
`|` and exceeded 64 characters); the unimported modules `types/token.types.ts` and
|
|
831
|
+
`types/galachain-api.types.ts` (a third and fourth `TokenClassKey` / `isTokenClassKey`).
|
|
832
|
+
- The GSwap error wrappers `GSwapQuoteError`, `GSwapSwapError`, `GSwapPoolError`,
|
|
833
|
+
`GSwapAssetError`, `GSwapPositionError`, `DexQuoteError`, `DexPoolNotFoundError` and
|
|
834
|
+
`handleGSwapErrorGeneric` (not exported, never thrown: gswap-sdk's `GSwapSDKError` is the DEX
|
|
835
|
+
error); `DexService`'s season, leaderboard and volume reads; `scripts/stage-verify-dex-reads.ts`
|
|
836
|
+
(`verify:stage-dex-reads`, which checked `sdk.dex`).
|
|
837
|
+
- `@gala-chain/gswap-sdk` was then a devDependency only (the examples and the live stage test); with
|
|
838
|
+
the 9.0 cut above it is no dependency of any kind.
|
|
839
|
+
|
|
3
840
|
## 6.0.0
|
|
4
841
|
|
|
5
842
|
### BREAKING CHANGES
|