From 61779511fc033050dddbbb3e942eb84813e485d5 Mon Sep 17 00:00:00 2001 From: JD Francis Date: Wed, 1 Oct 2025 11:16:56 -0500 Subject: [PATCH 1/9] wip --- .../common/src/api/tan-query/queryKeys.ts | 3 +- .../src/messages/coinDetailsMessages.ts | 2 + .../pedalboard/apps/solana-relay/src/index.ts | 2 + .../src/routes/launchpad/claim_fee.ts | 65 +++++++++++++ .../src/sdk/services/Solana/SolanaRelay.ts | 35 ++++++- packages/sdk/src/sdk/services/Solana/types.ts | 10 ++ packages/web/src/hooks/useClaimFee.ts | 74 +++++++++++++++ .../LaunchpadPage.tsx | 10 +- .../components/LaunchpadBuyModal.tsx | 4 +- .../pages/BuyCoinPage.tsx | 4 +- .../artist-coins-launchpad-page/utils.ts | 4 +- .../artist-coins-launchpad-page/validation.ts | 4 +- .../components/AssetInfoSection.tsx | 94 ++++++++++++++++++- packages/web/src/services/env/env.prod.ts | 2 +- 14 files changed, 294 insertions(+), 19 deletions(-) create mode 100644 packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts create mode 100644 packages/web/src/hooks/useClaimFee.ts diff --git a/packages/common/src/api/tan-query/queryKeys.ts b/packages/common/src/api/tan-query/queryKeys.ts index 6957c68c7a8..584a04b57f8 100644 --- a/packages/common/src/api/tan-query/queryKeys.ts +++ b/packages/common/src/api/tan-query/queryKeys.ts @@ -124,5 +124,6 @@ export const QUERY_KEYS = { firstBuyQuote: 'firstBuyQuote', walletSolBalance: 'walletSolBalance', launchpadConfig: 'launchpadConfig', - externalWalletBalance: 'externalWalletBalance' + externalWalletBalance: 'externalWalletBalance', + claimFee: 'claimFee' } as const diff --git a/packages/common/src/messages/coinDetailsMessages.ts b/packages/common/src/messages/coinDetailsMessages.ts index ed52f899706..2201035ccc8 100644 --- a/packages/common/src/messages/coinDetailsMessages.ts +++ b/packages/common/src/messages/coinDetailsMessages.ts @@ -65,6 +65,8 @@ export const coinDetailsMessages = { }, overflowMenu: { copyCoinAddress: 'Copy Coin Address', + unclaimedFees: 'Unclaimed Fees', + claim: 'Claim', openDexscreener: 'Open Dexscreener', details: 'Details', copiedToClipboard: 'Copied Coin Address To Clipboard!', diff --git a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts index 31f16b1dba2..fbb847feb12 100644 --- a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts +++ b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts @@ -18,6 +18,7 @@ import { cache } from './routes/cache' import { feePayer } from './routes/feePayer' import { health } from './routes/health/health' import { location } from './routes/instruction/location' +import { claimFee } from './routes/launchpad/claim_fee' import { firstBuyQuote, getLaunchpadConfigRoute @@ -45,6 +46,7 @@ const main = async () => { }) // launchpad endpoints don't need user/discovery validation, so register them before middleware app.post('/solana/launchpad/launch_coin', upload.single('image'), launchCoin) + app.get('/solana/launchpad/claim_fee', claimFee) app.get('/solana/launchpad/first_buy_quote', firstBuyQuote) app.get('/solana/launchpad/config', getLaunchpadConfigRoute) diff --git a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts new file mode 100644 index 00000000000..575e1c4e05f --- /dev/null +++ b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts @@ -0,0 +1,65 @@ +import { DynamicBondingCurveClient } from '@meteora-ag/dynamic-bonding-curve-sdk' +import { PublicKey } from '@solana/web3.js' +import { Request, Response } from 'express' + +import { logger } from '../../logger' +import { getConnection } from '../../utils/connections' + +interface ClaimFeeRequestBody { + tokenMint: string + ownerWalletAddress: string + receiverWalletAddress: string +} + +export const claimFee = async ( + req: Request, + res: Response +) => { + try { + const { tokenMint, ownerWalletAddress, receiverWalletAddress } = req.query + + // Validate required parameters + if (!tokenMint || !ownerWalletAddress || !receiverWalletAddress) { + throw new Error( + 'Invalid request parameters. tokenMint, ownerWalletAddress, and receiverWalletAddress are required.' + ) + } + + const connection = getConnection() + const dbcClient = new DynamicBondingCurveClient(connection, 'confirmed') + + const tokenPool = await dbcClient.state.getPoolByBaseMint( + new PublicKey(tokenMint) + ) + if (!tokenPool) { + throw new Error(`No DBC pool found for base mint: ${tokenMint}.`) + } + + const poolAddress = tokenPool.publicKey + const poolData = tokenPool.account + + const claimFeeTx = await dbcClient.creator.claimCreatorTradingFee({ + pool: poolAddress, + payer: new PublicKey(ownerWalletAddress), + creator: new PublicKey(ownerWalletAddress), + maxBaseAmount: poolData.creatorBaseFee, // Match max amount to the claimable amount (effectively no limit) + maxQuoteAmount: poolData.creatorQuoteFee, // Match max amount to the claimable amount (effectively no limit) + receiver: new PublicKey(receiverWalletAddress) + }) + + claimFeeTx.recentBlockhash = ( + await connection.getLatestBlockhash() + ).blockhash + claimFeeTx.feePayer = new PublicKey(ownerWalletAddress) + + return res.status(200).send({ + claimFeeTx: claimFeeTx.serialize({ requireAllSignatures: false }) + }) + } catch (e) { + logger.error( + 'Error in claim_fee - unable to create creator claim fee transaction' + ) + logger.error(e) + res.status(500).send() + } +} diff --git a/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts b/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts index 8b1f50a9974..40203844b4e 100644 --- a/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts +++ b/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts @@ -17,7 +17,9 @@ import { LaunchCoinSchema, FirstBuyQuoteResponse, FirstBuyQuoteRequest, - LaunchpadConfigResponse + LaunchpadConfigResponse, + ClaimFeeRequest, + ClaimFeeResponse } from './types' /** @@ -302,4 +304,35 @@ export class SolanaRelay extends BaseAPI { return json as LaunchpadConfigResponse }).value() } + + /** + * Claims creator trading fees from a dynamic bonding curve pool. + */ + public async claimFee( + params: ClaimFeeRequest, + initOverrides?: RequestInit | runtime.InitOverrideFunction + ): Promise { + const headerParameters: runtime.HTTPHeaders = { + 'Content-Type': 'application/json' + } + const queryParameters: runtime.HTTPQuery = { + tokenMint: params.tokenMint, + ownerWalletAddress: params.ownerWalletAddress, + receiverWalletAddress: params.receiverWalletAddress + } + + const response = await this.request( + { + path: '/launchpad/claim_fee', + method: 'GET', + headers: headerParameters, + query: queryParameters + }, + initOverrides + ) + + return await new runtime.JSONApiResponse(response, (json) => { + return json as ClaimFeeResponse + }).value() + } } diff --git a/packages/sdk/src/sdk/services/Solana/types.ts b/packages/sdk/src/sdk/services/Solana/types.ts index 4cd960e9398..b8f46e3083d 100644 --- a/packages/sdk/src/sdk/services/Solana/types.ts +++ b/packages/sdk/src/sdk/services/Solana/types.ts @@ -157,3 +157,13 @@ export type LaunchpadConfigResponse = { maxTokenOutputAmount: string startingPrice: string } + +export type ClaimFeeRequest = { + tokenMint: string + ownerWalletAddress: string + receiverWalletAddress: string +} + +export type ClaimFeeResponse = { + claimFeeTx: string +} diff --git a/packages/web/src/hooks/useClaimFee.ts b/packages/web/src/hooks/useClaimFee.ts new file mode 100644 index 00000000000..1aaea809aca --- /dev/null +++ b/packages/web/src/hooks/useClaimFee.ts @@ -0,0 +1,74 @@ +import { useQueryContext } from '@audius/common/api' +import type { Provider as SolanaProvider } from '@reown/appkit-adapter-solana/react' +import { VersionedTransaction } from '@solana/web3.js' +import { useMutation, UseMutationOptions } from '@tanstack/react-query' + +import { appkitModal } from 'app/ReownAppKitModal' + +export type UseClaimFeeParams = { + tokenMint: string + ownerWalletAddress: string + receiverWalletAddress: string +} + +export type ClaimFeeResponse = { + claimFeeTx: string + signature: string +} + +/** + * Hook for claiming creator trading fees from a dynamic bonding curve pool. + * This creates, signs, and sends the claim fee transaction. + */ +export const useClaimFee = ( + options?: UseMutationOptions +) => { + const { audiusSdk } = useQueryContext() + + return useMutation({ + mutationFn: async ({ + tokenMint, + ownerWalletAddress, + receiverWalletAddress + }: UseClaimFeeParams): Promise => { + const sdk = await audiusSdk() + const solanaProvider = appkitModal.getProvider('solana') + if (!solanaProvider) { + throw new Error('Missing SolanaProvider') + } + if (!ownerWalletAddress) { + throw new Error('Missing owner wallet address') + } + + // Get the claim fee transaction from the relay + const claimFeeResponse = await sdk.services.solanaRelay.claimFee({ + tokenMint, + ownerWalletAddress, + receiverWalletAddress + }) + + const { claimFeeTx: claimFeeTxSerialized } = claimFeeResponse + + // Transaction is sent from the backend as a serialized base64 string + const deserializedTx = VersionedTransaction.deserialize( + Buffer.from(claimFeeTxSerialized, 'base64') + ) + + // Triggers 3rd party wallet to sign and send the transaction + const signature = + await solanaProvider.signAndSendTransaction(deserializedTx) + + // Confirm the transaction + await sdk.services.solanaClient.connection.confirmTransaction( + signature, + 'confirmed' + ) + + return { + claimFeeTx: claimFeeTxSerialized, + signature + } + }, + ...options + }) +} diff --git a/packages/web/src/pages/artist-coins-launchpad-page/LaunchpadPage.tsx b/packages/web/src/pages/artist-coins-launchpad-page/LaunchpadPage.tsx index 3b7037a121d..e230e94c433 100644 --- a/packages/web/src/pages/artist-coins-launchpad-page/LaunchpadPage.tsx +++ b/packages/web/src/pages/artist-coins-launchpad-page/LaunchpadPage.tsx @@ -41,7 +41,7 @@ import { } from './components/LaunchpadModals' import { LAUNCHPAD_COIN_DESCRIPTION, MIN_SOL_BALANCE, Phase } from './constants' import { BuyCoinPage, ReviewPage, SetupPage, SplashPage } from './pages' -import { getLatestConnectedWallet, useLaunchpadAnalytics } from './utils' +import { getLastConnectedSolWallet, useLaunchpadAnalytics } from './utils' import { useLaunchpadFormSchema } from './validation' const messages = { @@ -71,7 +71,7 @@ const LaunchpadPageContent = ({ const { data: connectedWallets } = useConnectedWallets() const { toast } = useContext(ToastContext) const connectedWallet = useMemo( - () => getLatestConnectedWallet(connectedWallets), + () => getLastConnectedSolWallet(connectedWallets), [connectedWallets] ) const { @@ -174,7 +174,7 @@ const LaunchpadPageContent = ({ async (error: unknown) => { // If wallet is already linked, continue with the flow if (error instanceof AlreadyAssociatedError) { - const lastConnectedWallet = getLatestConnectedWallet(connectedWallets) + const lastConnectedWallet = getLastConnectedSolWallet(connectedWallets) if (lastConnectedWallet) { const { isValid: isValidWalletBalance, walletBalanceLamports } = await getIsValidWalletBalance(lastConnectedWallet?.address) @@ -326,7 +326,7 @@ export const LaunchpadPage = () => { const navigate = useNavigate() const connectedWallet = useMemo( - () => getLatestConnectedWallet(connectedWallets), + () => getLastConnectedSolWallet(connectedWallets), [connectedWallets] ) const { @@ -480,7 +480,7 @@ export const LaunchpadPage = () => { // Get the most recent connected Solana wallet (last in the array) const connectedWallet: ConnectedWallet | undefined = - getLatestConnectedWallet(connectedWallets) + getLastConnectedSolWallet(connectedWallets) if (!user || !connectedWallet) { toast(messages.errors.unknownError) diff --git a/packages/web/src/pages/artist-coins-launchpad-page/components/LaunchpadBuyModal.tsx b/packages/web/src/pages/artist-coins-launchpad-page/components/LaunchpadBuyModal.tsx index 0a5e2f6a053..54fda927649 100644 --- a/packages/web/src/pages/artist-coins-launchpad-page/components/LaunchpadBuyModal.tsx +++ b/packages/web/src/pages/artist-coins-launchpad-page/components/LaunchpadBuyModal.tsx @@ -37,7 +37,7 @@ import { useExternalWalletSwap } from 'hooks/useExternalWalletSwap' import { make, track } from 'services/analytics' import zIndex from 'utils/zIndex' -import { getLatestConnectedWallet } from '../utils' +import { getLastConnectedSolWallet } from '../utils' const INPUT_TOKEN_MAP: Record = { @@ -401,7 +401,7 @@ export const LaunchpadBuyModal = ({ } const { data: connectedWallets } = useConnectedWallets() const externalWalletAddress = useMemo( - () => getLatestConnectedWallet(connectedWallets)?.address, + () => getLastConnectedSolWallet(connectedWallets)?.address, [connectedWallets] ) const { diff --git a/packages/web/src/pages/artist-coins-launchpad-page/pages/BuyCoinPage.tsx b/packages/web/src/pages/artist-coins-launchpad-page/pages/BuyCoinPage.tsx index 3648260abdd..89180d188c5 100644 --- a/packages/web/src/pages/artist-coins-launchpad-page/pages/BuyCoinPage.tsx +++ b/packages/web/src/pages/artist-coins-launchpad-page/pages/BuyCoinPage.tsx @@ -34,7 +34,7 @@ import { ArtistCoinsSubmitRow } from '../components/ArtistCoinsSubmitRow' import { LaunchpadBuyModal } from '../components/LaunchpadBuyModal' import type { PhasePageProps } from '../components/types' import { AMOUNT_OF_STEPS } from '../constants' -import { getLatestConnectedWallet, useLaunchpadAnalytics } from '../utils' +import { getLastConnectedSolWallet, useLaunchpadAnalytics } from '../utils' import { FIELDS } from '../validation' const messages = { @@ -92,7 +92,7 @@ export const BuyCoinPage = ({ const [isReceiveAmountChanging, setIsReceiveAmountChanging] = useState(false) const { data: connectedWallets } = useConnectedWallets() const connectedWallet = useMemo( - () => getLatestConnectedWallet(connectedWallets), + () => getLastConnectedSolWallet(connectedWallets), [connectedWallets] ) diff --git a/packages/web/src/pages/artist-coins-launchpad-page/utils.ts b/packages/web/src/pages/artist-coins-launchpad-page/utils.ts index adae9bf0a3a..1b37f87c8a2 100644 --- a/packages/web/src/pages/artist-coins-launchpad-page/utils.ts +++ b/packages/web/src/pages/artist-coins-launchpad-page/utils.ts @@ -10,9 +10,9 @@ import { omit } from 'lodash' import { make } from 'services/analytics' /** - * Gets the most recently added connected wallet + * Gets the last connected Solana wallet in the connected wallets array */ -export const getLatestConnectedWallet = ( +export const getLastConnectedSolWallet = ( connectedWallets: ConnectedWallet[] | undefined ) => { return connectedWallets?.filter( diff --git a/packages/web/src/pages/artist-coins-launchpad-page/validation.ts b/packages/web/src/pages/artist-coins-launchpad-page/validation.ts index 5d62d5e8fc6..1e83209ca5a 100644 --- a/packages/web/src/pages/artist-coins-launchpad-page/validation.ts +++ b/packages/web/src/pages/artist-coins-launchpad-page/validation.ts @@ -18,7 +18,7 @@ import { toFormikValidationSchema } from 'zod-formik-adapter' import { useLaunchpadConfig } from 'hooks/useLaunchpadConfig' import { reportToSentry } from 'store/errors/reportToSentry' -import { getLatestConnectedWallet } from './utils' +import { getLastConnectedSolWallet } from './utils' export const FIELDS = { coinName: 'coinName', @@ -215,7 +215,7 @@ export const useLaunchpadFormSchema = () => { }, [firstBuyQuoteData]) const connectedWallet = useMemo( - () => getLatestConnectedWallet(connectedWallets), + () => getLastConnectedSolWallet(connectedWallets), [connectedWallets] ) const { data: audioBalance } = useWalletAudioBalance({ diff --git a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx index a52fe3d9623..16a654016b7 100644 --- a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx +++ b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx @@ -4,21 +4,27 @@ import { useArtistCoin, useCurrentUserId, useUser, - useUserCoins + useUserCoins, + useConnectedWallets, + useWalletAddresses, + useCurrentAccountUser } from '@audius/common/api' import { useDiscordOAuthLink } from '@audius/common/hooks' import { coinDetailsMessages } from '@audius/common/messages' import { WidthSizes } from '@audius/common/models' import { route, shortenSPLAddress } from '@audius/common/utils' import { + Button, Flex, IconCopy, IconDiscord, IconExternalLink, IconGift, + IconInfo, Paper, PlainButton, Text, + TextLink, useTheme } from '@audius/harmony' import { HashId } from '@audius/sdk' @@ -28,7 +34,9 @@ import Skeleton from 'components/skeleton/Skeleton' import { ToastContext } from 'components/toast/ToastContext' import Tooltip from 'components/tooltip/Tooltip' import { UserTokenBadge } from 'components/user-token-badge/UserTokenBadge' +import { useClaimFee } from 'hooks/useClaimFee' import { useCoverPhoto } from 'hooks/useCoverPhoto' +import { getLastConnectedSolWallet } from 'pages/artist-coins-launchpad-page/utils' import { env } from 'services/env' import { copyToClipboard } from 'utils/clipboardUtil' import { push } from 'utils/navigation' @@ -184,15 +192,36 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { const { data: coin, isLoading } = useArtistCoin(mint) - const { data: currentUserId } = useCurrentUserId() - const { data: userCoins } = useUserCoins({ userId: currentUserId }) + const { data: currentUser } = useCurrentAccountUser() + const { data: userCoins } = useUserCoins({ userId: currentUser?.user_id }) const userToken = useMemo( () => userCoins?.find((coin) => coin.mint === mint), [userCoins, mint] ) + const isCoinCreator = coin?.ownerId === currentUser?.user_id const discordOAuthLink = useDiscordOAuthLink(userToken?.ticker) const { balance: userTokenBalance } = userToken ?? {} + // Get wallet addresses for claim fee + const { data: connectedWallets } = useConnectedWallets() + const externalSolWallet = useMemo( + () => getLastConnectedSolWallet(connectedWallets), + [connectedWallets] + ) + + // Claim fee hook + const { mutate: claimFee, isPending: isClaimFeePending } = useClaimFee({ + onSuccess: (data) => { + toast('Fees claimed successfully!') + // eslint-disable-next-line no-console + console.log('Claim fee transaction signature:', data.signature) + }, + onError: (error) => { + toast(`Failed to claim fees: ${error.message}`) + } + }) + const unclaimedFees = coin?.unclaimedFees ?? 0.01 // TODO: get this working on api side + const descriptionParagraphs = coin?.description?.split('\n') ?? [] const openDiscord = () => { @@ -212,6 +241,29 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { toast(overflowMessages.copiedToClipboard) }, [mint, toast]) + const handleClaimFees = useCallback(() => { + if (!externalSolWallet) { + toast('Please connect your wallet to claim fees') + return + } + + if (!mint) { + toast('Invalid token mint address') + return + } + + if (!currentUser?.spl_wallet) { + toast('Something went wrong') + return + } + + claimFee({ + tokenMint: mint, + ownerWalletAddress: externalSolWallet.address, + receiverWalletAddress: currentUser.spl_wallet // Using same wallet for owner and receiver + }) + }, [externalSolWallet, mint, claimFee, currentUser?.spl_wallet, toast]) + if (isLoading || !coin) { return } @@ -330,6 +382,42 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { {shortenSPLAddress(mint)} + {isCoinCreator ? ( + + + + {overflowMessages.unclaimedFees} + + + + + + + {unclaimedFees > 0 ? ( + + {overflowMessages.claim} + + ) : null} + + ${unclaimedFees} + + + + ) : null} ) } diff --git a/packages/web/src/services/env/env.prod.ts b/packages/web/src/services/env/env.prod.ts index e82d0ddcafe..f20466aceac 100644 --- a/packages/web/src/services/env/env.prod.ts +++ b/packages/web/src/services/env/env.prod.ts @@ -71,7 +71,7 @@ export const env: Env = { SOL_TOKEN_BRIDGE_ADDRESS: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb', SOLANA_CLUSTER_ENDPOINT: 'https://audius-fe.rpcpool.com', SOLANA_FEE_PAYER_ADDRESS: 'pqx3fvvh6b2eZBfLhTtQ5KxzU3CginmgGTmDCjk8TPP', - SOLANA_RELAY_ENDPOINT: 'https://discoveryprovider.audius.co', + SOLANA_RELAY_ENDPOINT: 'http://localhost:6002', SOLANA_TOKEN_PROGRAM_ADDRESS: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', SOLANA_WEB3_CLUSTER: 'mainnet-beta', STRIPE_CLIENT_PUBLISHABLE_KEY: From 94944d549dcb4307a3330bd3ca46a9b6acf214bd Mon Sep 17 00:00:00 2001 From: JD Francis Date: Wed, 1 Oct 2025 15:34:33 -0500 Subject: [PATCH 2/9] run gen:stage --- .../default/.openapi-generator/FILES | 2 + .../api/generated/default/apis/CoinsApi.ts | 58 ++++ .../sdk/api/generated/default/models/Coin.ts | 32 ++ .../default/models/CoinDynamicBondingCurve.ts | 16 + .../default/models/UpdateCoinRequest.ts | 98 ++++++ .../default/models/UpdateCoinResponse.ts | 66 ++++ .../sdk/api/generated/default/models/index.ts | 2 + .../generated/full/.openapi-generator/FILES | 9 + .../sdk/api/generated/full/apis/CoinsApi.ts | 305 ++++++++++++++++++ .../sdk/api/generated/full/apis/UsersApi.ts | 2 + .../src/sdk/api/generated/full/apis/index.ts | 1 + .../src/sdk/api/generated/full/models/Coin.ts | 207 ++++++++++++ .../api/generated/full/models/CoinResponse.ts | 73 +++++ .../generated/full/models/CoinsResponse.ts | 74 +++++ .../full/models/CreateCoinRequest.ts | 110 +++++++ .../full/models/CreateCoinResponse.ts | 73 +++++ .../full/models/CreateCoinResponseData.ts | 120 +++++++ .../full/models/UpdateCoinRequest.ts | 98 ++++++ .../full/models/UpdateCoinResponse.ts | 66 ++++ .../sdk/api/generated/full/models/index.ts | 8 + 20 files changed, 1420 insertions(+) create mode 100644 packages/sdk/src/sdk/api/generated/default/models/UpdateCoinRequest.ts create mode 100644 packages/sdk/src/sdk/api/generated/default/models/UpdateCoinResponse.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/apis/CoinsApi.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/Coin.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/CoinResponse.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/CoinsResponse.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/CreateCoinRequest.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponse.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponseData.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/UpdateCoinRequest.ts create mode 100644 packages/sdk/src/sdk/api/generated/full/models/UpdateCoinResponse.ts diff --git a/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES b/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES index b8931aae062..3a983e61826 100644 --- a/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES +++ b/packages/sdk/src/sdk/api/generated/default/.openapi-generator/FILES @@ -129,6 +129,8 @@ models/TrendingPlaylistsResponse.ts models/UnclaimedIdResponse.ts models/UndisbursedChallenge.ts models/UndisbursedChallenges.ts +models/UpdateCoinRequest.ts +models/UpdateCoinResponse.ts models/User.ts models/UserCoin.ts models/UserCoinAccount.ts diff --git a/packages/sdk/src/sdk/api/generated/default/apis/CoinsApi.ts b/packages/sdk/src/sdk/api/generated/default/apis/CoinsApi.ts index cd9359c3e40..1a76611a06f 100644 --- a/packages/sdk/src/sdk/api/generated/default/apis/CoinsApi.ts +++ b/packages/sdk/src/sdk/api/generated/default/apis/CoinsApi.ts @@ -22,6 +22,8 @@ import type { CoinsResponse, CreateCoinRequest, CreateCoinResponse, + UpdateCoinRequest, + UpdateCoinResponse, } from '../models'; import { CoinInsightsResponseFromJSON, @@ -36,6 +38,10 @@ import { CreateCoinRequestToJSON, CreateCoinResponseFromJSON, CreateCoinResponseToJSON, + UpdateCoinRequestFromJSON, + UpdateCoinRequestToJSON, + UpdateCoinResponseFromJSON, + UpdateCoinResponseToJSON, } from '../models'; export interface CreateCoinOperationRequest { @@ -73,6 +79,12 @@ export interface GetCoinsRequest { sortDirection?: GetCoinsSortDirectionEnum; } +export interface UpdateCoinOperationRequest { + mint: string; + userId: string; + updateCoinRequest: UpdateCoinRequest; +} + /** * */ @@ -315,6 +327,52 @@ export class CoinsApi extends runtime.BaseAPI { return await response.value(); } + /** + * @hidden + * Updates information about a specific coin by its mint address + */ + async updateCoinRaw(params: UpdateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.mint === null || params.mint === undefined) { + throw new runtime.RequiredError('mint','Required parameter params.mint was null or undefined when calling updateCoin.'); + } + + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling updateCoin.'); + } + + if (params.updateCoinRequest === null || params.updateCoinRequest === undefined) { + throw new runtime.RequiredError('updateCoinRequest','Required parameter params.updateCoinRequest was null or undefined when calling updateCoin.'); + } + + const queryParameters: any = {}; + + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/coins/{mint}`.replace(`{${"mint"}}`, encodeURIComponent(String(params.mint))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: UpdateCoinRequestToJSON(params.updateCoinRequest), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UpdateCoinResponseFromJSON(jsonValue)); + } + + /** + * Updates information about a specific coin by its mint address + */ + async updateCoin(params: UpdateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateCoinRaw(params, initOverrides); + return await response.value(); + } + } /** diff --git a/packages/sdk/src/sdk/api/generated/default/models/Coin.ts b/packages/sdk/src/sdk/api/generated/default/models/Coin.ts index bb974a315e7..ffc2bfdf29c 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/Coin.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/Coin.ts @@ -81,6 +81,30 @@ export interface Coin { * @memberof Coin */ website?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link1?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link2?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link3?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link4?: string; /** * Whether the coin has a Discord server * @type {boolean} @@ -413,6 +437,10 @@ export function CoinFromJSONTyped(json: any, ignoreDiscriminator: boolean): Coin 'logoUri': !exists(json, 'logo_uri') ? undefined : json['logo_uri'], 'description': !exists(json, 'description') ? undefined : json['description'], 'website': !exists(json, 'website') ? undefined : json['website'], + 'link1': !exists(json, 'link_1') ? undefined : json['link_1'], + 'link2': !exists(json, 'link_2') ? undefined : json['link_2'], + 'link3': !exists(json, 'link_3') ? undefined : json['link_3'], + 'link4': !exists(json, 'link_4') ? undefined : json['link_4'], 'hasDiscord': json['has_discord'], 'createdAt': json['created_at'], 'address': !exists(json, 'address') ? undefined : json['address'], @@ -478,6 +506,10 @@ export function CoinToJSON(value?: Coin | null): any { 'logo_uri': value.logoUri, 'description': value.description, 'website': value.website, + 'link_1': value.link1, + 'link_2': value.link2, + 'link_3': value.link3, + 'link_4': value.link4, 'has_discord': value.hasDiscord, 'created_at': value.createdAt, 'address': value.address, diff --git a/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts b/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts index 27afc8bf235..8f55ec7b7c3 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts @@ -44,6 +44,18 @@ export interface CoinDynamicBondingCurve { * @memberof CoinDynamicBondingCurve */ curveProgress: number; + /** + * Whether the bonding curve has been migrated + * @type {boolean} + * @memberof CoinDynamicBondingCurve + */ + isMigrated?: boolean; + /** + * Creator quote fee for the bonding curve + * @type {number} + * @memberof CoinDynamicBondingCurve + */ + creatorQuoteFee?: number; } /** @@ -73,6 +85,8 @@ export function CoinDynamicBondingCurveFromJSONTyped(json: any, ignoreDiscrimina 'price': json['price'], 'priceUSD': json['priceUSD'], 'curveProgress': json['curveProgress'], + 'isMigrated': !exists(json, 'isMigrated') ? undefined : json['isMigrated'], + 'creatorQuoteFee': !exists(json, 'creatorQuoteFee') ? undefined : json['creatorQuoteFee'], }; } @@ -89,6 +103,8 @@ export function CoinDynamicBondingCurveToJSON(value?: CoinDynamicBondingCurve | 'price': value.price, 'priceUSD': value.priceUSD, 'curveProgress': value.curveProgress, + 'isMigrated': value.isMigrated, + 'creatorQuoteFee': value.creatorQuoteFee, }; } diff --git a/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinRequest.ts b/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinRequest.ts new file mode 100644 index 00000000000..632b4cf285e --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinRequest.ts @@ -0,0 +1,98 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * Request body for updating coin information + * @export + * @interface UpdateCoinRequest + */ +export interface UpdateCoinRequest { + /** + * The description of the coin (max 2500 characters) + * @type {string} + * @memberof UpdateCoinRequest + */ + description?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link1?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link2?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link3?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link4?: string; +} + +/** + * Check if a given object implements the UpdateCoinRequest interface. + */ +export function instanceOfUpdateCoinRequest(value: object): value is UpdateCoinRequest { + let isInstance = true; + + return isInstance; +} + +export function UpdateCoinRequestFromJSON(json: any): UpdateCoinRequest { + return UpdateCoinRequestFromJSONTyped(json, false); +} + +export function UpdateCoinRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCoinRequest { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'description': !exists(json, 'description') ? undefined : json['description'], + 'link1': !exists(json, 'link_1') ? undefined : json['link_1'], + 'link2': !exists(json, 'link_2') ? undefined : json['link_2'], + 'link3': !exists(json, 'link_3') ? undefined : json['link_3'], + 'link4': !exists(json, 'link_4') ? undefined : json['link_4'], + }; +} + +export function UpdateCoinRequestToJSON(value?: UpdateCoinRequest | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'description': value.description, + 'link_1': value.link1, + 'link_2': value.link2, + 'link_3': value.link3, + 'link_4': value.link4, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinResponse.ts b/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinResponse.ts new file mode 100644 index 00000000000..ea682941036 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/default/models/UpdateCoinResponse.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * Audius V1 API + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateCoinResponse + */ +export interface UpdateCoinResponse { + /** + * Indicates if the update was successful + * @type {boolean} + * @memberof UpdateCoinResponse + */ + success?: boolean; +} + +/** + * Check if a given object implements the UpdateCoinResponse interface. + */ +export function instanceOfUpdateCoinResponse(value: object): value is UpdateCoinResponse { + let isInstance = true; + + return isInstance; +} + +export function UpdateCoinResponseFromJSON(json: any): UpdateCoinResponse { + return UpdateCoinResponseFromJSONTyped(json, false); +} + +export function UpdateCoinResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCoinResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'success': !exists(json, 'success') ? undefined : json['success'], + }; +} + +export function UpdateCoinResponseToJSON(value?: UpdateCoinResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'success': value.success, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/default/models/index.ts b/packages/sdk/src/sdk/api/generated/default/models/index.ts index 69c86bba328..48a0eefafea 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/index.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/index.ts @@ -115,6 +115,8 @@ export * from './TrendingPlaylistsResponse'; export * from './UnclaimedIdResponse'; export * from './UndisbursedChallenge'; export * from './UndisbursedChallenges'; +export * from './UpdateCoinRequest'; +export * from './UpdateCoinResponse'; export * from './User'; export * from './UserCoin'; export * from './UserCoinAccount'; diff --git a/packages/sdk/src/sdk/api/generated/full/.openapi-generator/FILES b/packages/sdk/src/sdk/api/generated/full/.openapi-generator/FILES index 9f76cea0708..7a0095c20db 100644 --- a/packages/sdk/src/sdk/api/generated/full/.openapi-generator/FILES +++ b/packages/sdk/src/sdk/api/generated/full/.openapi-generator/FILES @@ -1,6 +1,7 @@ .openapi-generator-ignore apis/ChallengesApi.ts apis/CidDataApi.ts +apis/CoinsApi.ts apis/CommentsApi.ts apis/ExploreApi.ts apis/NotificationsApi.ts @@ -48,6 +49,9 @@ models/CidDataResponse.ts models/ClaimableRewardNotification.ts models/ClaimableRewardNotificationAction.ts models/ClaimableRewardNotificationActionData.ts +models/Coin.ts +models/CoinResponse.ts +models/CoinsResponse.ts models/CollectionActivityFull.ts models/CollectionActivityFullWithoutTracks.ts models/CollectionLibraryResponseFull.ts @@ -73,6 +77,9 @@ models/CosignNotificationActionData.ts models/CoverArt.ts models/CoverPhoto.ts models/CoverPhotoFull.ts +models/CreateCoinRequest.ts +models/CreateCoinResponse.ts +models/CreateCoinResponseData.ts models/CreateNotification.ts models/CreateNotificationAction.ts models/CreateNotificationActionData.ts @@ -255,6 +262,8 @@ models/TrendingTimesIds.ts models/TrendingUndergroundNotification.ts models/TrendingUndergroundNotificationAction.ts models/TrendingUndergroundNotificationActionData.ts +models/UpdateCoinRequest.ts +models/UpdateCoinResponse.ts models/UrlWithMirrors.ts models/UsdcGate.ts models/UsdcPurchaseBuyerNotification.ts diff --git a/packages/sdk/src/sdk/api/generated/full/apis/CoinsApi.ts b/packages/sdk/src/sdk/api/generated/full/apis/CoinsApi.ts new file mode 100644 index 00000000000..ad8a3de9d58 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/apis/CoinsApi.ts @@ -0,0 +1,305 @@ +/* tslint:disable */ +// @ts-nocheck +/* eslint-disable */ +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + CoinResponse, + CoinsResponse, + CreateCoinRequest, + CreateCoinResponse, + UpdateCoinRequest, + UpdateCoinResponse, +} from '../models'; +import { + CoinResponseFromJSON, + CoinResponseToJSON, + CoinsResponseFromJSON, + CoinsResponseToJSON, + CreateCoinRequestFromJSON, + CreateCoinRequestToJSON, + CreateCoinResponseFromJSON, + CreateCoinResponseToJSON, + UpdateCoinRequestFromJSON, + UpdateCoinRequestToJSON, + UpdateCoinResponseFromJSON, + UpdateCoinResponseToJSON, +} from '../models'; + +export interface CreateCoinOperationRequest { + userId: string; + createCoinRequest: CreateCoinRequest; +} + +export interface GetCoinRequest { + mint: string; +} + +export interface GetCoinByTickerRequest { + ticker: string; +} + +export interface GetCoinsRequest { + ticker?: Array; + mint?: Array; + ownerId?: Array; + limit?: number; + offset?: number; + query?: string; + sortMethod?: GetCoinsSortMethodEnum; + sortDirection?: GetCoinsSortDirectionEnum; +} + +export interface UpdateCoinOperationRequest { + mint: string; + userId: string; + updateCoinRequest: UpdateCoinRequest; +} + +/** + * + */ +export class CoinsApi extends runtime.BaseAPI { + + /** + * @hidden + * Creates a new artist coin + */ + async createCoinRaw(params: CreateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling createCoin.'); + } + + if (params.createCoinRequest === null || params.createCoinRequest === undefined) { + throw new runtime.RequiredError('createCoinRequest','Required parameter params.createCoinRequest was null or undefined when calling createCoin.'); + } + + const queryParameters: any = {}; + + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/coins`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: CreateCoinRequestToJSON(params.createCoinRequest), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CreateCoinResponseFromJSON(jsonValue)); + } + + /** + * Creates a new artist coin + */ + async createCoin(params: CreateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createCoinRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Gets information about a specific coin by its mint address + */ + async getCoinRaw(params: GetCoinRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.mint === null || params.mint === undefined) { + throw new runtime.RequiredError('mint','Required parameter params.mint was null or undefined when calling getCoin.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/coins/{mint}`.replace(`{${"mint"}}`, encodeURIComponent(String(params.mint))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CoinResponseFromJSON(jsonValue)); + } + + /** + * Gets information about a specific coin by its mint address + */ + async getCoin(params: GetCoinRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getCoinRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Gets information about a specific coin by its ticker + */ + async getCoinByTickerRaw(params: GetCoinByTickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.ticker === null || params.ticker === undefined) { + throw new runtime.RequiredError('ticker','Required parameter params.ticker was null or undefined when calling getCoinByTicker.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/coins/ticker/{ticker}`.replace(`{${"ticker"}}`, encodeURIComponent(String(params.ticker))), + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CoinResponseFromJSON(jsonValue)); + } + + /** + * Gets information about a specific coin by its ticker + */ + async getCoinByTicker(params: GetCoinByTickerRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getCoinByTickerRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Gets a list of coins with optional filtering + */ + async getCoinsRaw(params: GetCoinsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (params.ticker) { + queryParameters['ticker'] = params.ticker; + } + + if (params.mint) { + queryParameters['mint'] = params.mint; + } + + if (params.ownerId) { + queryParameters['owner_id'] = params.ownerId; + } + + if (params.limit !== undefined) { + queryParameters['limit'] = params.limit; + } + + if (params.offset !== undefined) { + queryParameters['offset'] = params.offset; + } + + if (params.query !== undefined) { + queryParameters['query'] = params.query; + } + + if (params.sortMethod !== undefined) { + queryParameters['sort_method'] = params.sortMethod; + } + + if (params.sortDirection !== undefined) { + queryParameters['sort_direction'] = params.sortDirection; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/coins`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => CoinsResponseFromJSON(jsonValue)); + } + + /** + * Gets a list of coins with optional filtering + */ + async getCoins(params: GetCoinsRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getCoinsRaw(params, initOverrides); + return await response.value(); + } + + /** + * @hidden + * Updates information about a specific coin by its mint address + */ + async updateCoinRaw(params: UpdateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (params.mint === null || params.mint === undefined) { + throw new runtime.RequiredError('mint','Required parameter params.mint was null or undefined when calling updateCoin.'); + } + + if (params.userId === null || params.userId === undefined) { + throw new runtime.RequiredError('userId','Required parameter params.userId was null or undefined when calling updateCoin.'); + } + + if (params.updateCoinRequest === null || params.updateCoinRequest === undefined) { + throw new runtime.RequiredError('updateCoinRequest','Required parameter params.updateCoinRequest was null or undefined when calling updateCoin.'); + } + + const queryParameters: any = {}; + + if (params.userId !== undefined) { + queryParameters['user_id'] = params.userId; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + const response = await this.request({ + path: `/coins/{mint}`.replace(`{${"mint"}}`, encodeURIComponent(String(params.mint))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: UpdateCoinRequestToJSON(params.updateCoinRequest), + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => UpdateCoinResponseFromJSON(jsonValue)); + } + + /** + * Updates information about a specific coin by its mint address + */ + async updateCoin(params: UpdateCoinOperationRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updateCoinRaw(params, initOverrides); + return await response.value(); + } + +} + +/** + * @export + */ +export const GetCoinsSortMethodEnum = { + MarketCap: 'market_cap', + Price: 'price', + Volume: 'volume', + CreatedAt: 'created_at', + Holder: 'holder' +} as const; +export type GetCoinsSortMethodEnum = typeof GetCoinsSortMethodEnum[keyof typeof GetCoinsSortMethodEnum]; +/** + * @export + */ +export const GetCoinsSortDirectionEnum = { + Asc: 'asc', + Desc: 'desc' +} as const; +export type GetCoinsSortDirectionEnum = typeof GetCoinsSortDirectionEnum[keyof typeof GetCoinsSortDirectionEnum]; diff --git a/packages/sdk/src/sdk/api/generated/full/apis/UsersApi.ts b/packages/sdk/src/sdk/api/generated/full/apis/UsersApi.ts index b437e900ba1..c933dc1a034 100644 --- a/packages/sdk/src/sdk/api/generated/full/apis/UsersApi.ts +++ b/packages/sdk/src/sdk/api/generated/full/apis/UsersApi.ts @@ -3072,6 +3072,7 @@ export type GetTracksByUserHandleFilterTracksEnum = typeof GetTracksByUserHandle export const GetUSDCTransactionCountTypeEnum = { PurchaseContent: 'purchase_content', Transfer: 'transfer', + InternalTransfer: 'internal_transfer', PrepareWithdrawal: 'prepare_withdrawal', RecoverWithdrawal: 'recover_withdrawal', Withdrawal: 'withdrawal', @@ -3108,6 +3109,7 @@ export type GetUSDCTransactionsSortDirectionEnum = typeof GetUSDCTransactionsSor export const GetUSDCTransactionsTypeEnum = { PurchaseContent: 'purchase_content', Transfer: 'transfer', + InternalTransfer: 'internal_transfer', PrepareWithdrawal: 'prepare_withdrawal', RecoverWithdrawal: 'recover_withdrawal', Withdrawal: 'withdrawal', diff --git a/packages/sdk/src/sdk/api/generated/full/apis/index.ts b/packages/sdk/src/sdk/api/generated/full/apis/index.ts index edf0361fd99..ca532bc5d5b 100644 --- a/packages/sdk/src/sdk/api/generated/full/apis/index.ts +++ b/packages/sdk/src/sdk/api/generated/full/apis/index.ts @@ -2,6 +2,7 @@ /* eslint-disable */ export * from './ChallengesApi'; export * from './CidDataApi'; +export * from './CoinsApi'; export * from './CommentsApi'; export * from './ExploreApi'; export * from './NotificationsApi'; diff --git a/packages/sdk/src/sdk/api/generated/full/models/Coin.ts b/packages/sdk/src/sdk/api/generated/full/models/Coin.ts new file mode 100644 index 00000000000..c0b07edfb6b --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/Coin.ts @@ -0,0 +1,207 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * A coin object + * @export + * @interface Coin + */ +export interface Coin { + /** + * The mint address of the coin + * @type {string} + * @memberof Coin + */ + mint: string; + /** + * The coin symbol/ticker + * @type {string} + * @memberof Coin + */ + ticker: string; + /** + * The number of decimals for the coin + * @type {number} + * @memberof Coin + */ + decimals: number; + /** + * The coin name + * @type {string} + * @memberof Coin + */ + name: string; + /** + * The URI for the coin's logo image + * @type {string} + * @memberof Coin + */ + logoUri?: string; + /** + * The description of the coin + * @type {string} + * @memberof Coin + */ + description?: string; + /** + * X (Twitter) handle for the coin + * @type {string} + * @memberof Coin + */ + xHandle?: string; + /** + * Instagram handle for the coin + * @type {string} + * @memberof Coin + */ + instagramHandle?: string; + /** + * TikTok handle for the coin + * @type {string} + * @memberof Coin + */ + tiktokHandle?: string; + /** + * Website URL for the coin + * @type {string} + * @memberof Coin + */ + website?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link1?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link2?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link3?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof Coin + */ + link4?: string; + /** + * Whether the coin has a Discord server + * @type {boolean} + * @memberof Coin + */ + hasDiscord?: boolean; + /** + * The date and time when the coin was created + * @type {Date} + * @memberof Coin + */ + createdAt: Date; + /** + * The date and time when the coin was last updated + * @type {Date} + * @memberof Coin + */ + updatedAt?: Date; + /** + * The user ID of the coin owner + * @type {string} + * @memberof Coin + */ + ownerId?: string; +} + +/** + * Check if a given object implements the Coin interface. + */ +export function instanceOfCoin(value: object): value is Coin { + let isInstance = true; + isInstance = isInstance && "mint" in value && value["mint"] !== undefined; + isInstance = isInstance && "ticker" in value && value["ticker"] !== undefined; + isInstance = isInstance && "decimals" in value && value["decimals"] !== undefined; + isInstance = isInstance && "name" in value && value["name"] !== undefined; + isInstance = isInstance && "createdAt" in value && value["createdAt"] !== undefined; + + return isInstance; +} + +export function CoinFromJSON(json: any): Coin { + return CoinFromJSONTyped(json, false); +} + +export function CoinFromJSONTyped(json: any, ignoreDiscriminator: boolean): Coin { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'mint': json['mint'], + 'ticker': json['ticker'], + 'decimals': json['decimals'], + 'name': json['name'], + 'logoUri': !exists(json, 'logo_uri') ? undefined : json['logo_uri'], + 'description': !exists(json, 'description') ? undefined : json['description'], + 'xHandle': !exists(json, 'x_handle') ? undefined : json['x_handle'], + 'instagramHandle': !exists(json, 'instagram_handle') ? undefined : json['instagram_handle'], + 'tiktokHandle': !exists(json, 'tiktok_handle') ? undefined : json['tiktok_handle'], + 'website': !exists(json, 'website') ? undefined : json['website'], + 'link1': !exists(json, 'link_1') ? undefined : json['link_1'], + 'link2': !exists(json, 'link_2') ? undefined : json['link_2'], + 'link3': !exists(json, 'link_3') ? undefined : json['link_3'], + 'link4': !exists(json, 'link_4') ? undefined : json['link_4'], + 'hasDiscord': !exists(json, 'has_discord') ? undefined : json['has_discord'], + 'createdAt': (new Date(json['created_at'])), + 'updatedAt': !exists(json, 'updated_at') ? undefined : (new Date(json['updated_at'])), + 'ownerId': !exists(json, 'owner_id') ? undefined : json['owner_id'], + }; +} + +export function CoinToJSON(value?: Coin | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'mint': value.mint, + 'ticker': value.ticker, + 'decimals': value.decimals, + 'name': value.name, + 'logo_uri': value.logoUri, + 'description': value.description, + 'x_handle': value.xHandle, + 'instagram_handle': value.instagramHandle, + 'tiktok_handle': value.tiktokHandle, + 'website': value.website, + 'link_1': value.link1, + 'link_2': value.link2, + 'link_3': value.link3, + 'link_4': value.link4, + 'has_discord': value.hasDiscord, + 'created_at': (value.createdAt.toISOString()), + 'updated_at': value.updatedAt === undefined ? undefined : (value.updatedAt.toISOString()), + 'owner_id': value.ownerId, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/CoinResponse.ts b/packages/sdk/src/sdk/api/generated/full/models/CoinResponse.ts new file mode 100644 index 00000000000..5c3f4824e53 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/CoinResponse.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { Coin } from './Coin'; +import { + CoinFromJSON, + CoinFromJSONTyped, + CoinToJSON, +} from './Coin'; + +/** + * + * @export + * @interface CoinResponse + */ +export interface CoinResponse { + /** + * + * @type {Coin} + * @memberof CoinResponse + */ + data?: Coin; +} + +/** + * Check if a given object implements the CoinResponse interface. + */ +export function instanceOfCoinResponse(value: object): value is CoinResponse { + let isInstance = true; + + return isInstance; +} + +export function CoinResponseFromJSON(json: any): CoinResponse { + return CoinResponseFromJSONTyped(json, false); +} + +export function CoinResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CoinResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'data': !exists(json, 'data') ? undefined : CoinFromJSON(json['data']), + }; +} + +export function CoinResponseToJSON(value?: CoinResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'data': CoinToJSON(value.data), + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/CoinsResponse.ts b/packages/sdk/src/sdk/api/generated/full/models/CoinsResponse.ts new file mode 100644 index 00000000000..d0864d0db28 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/CoinsResponse.ts @@ -0,0 +1,74 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { Coin } from './Coin'; +import { + CoinFromJSON, + CoinFromJSONTyped, + CoinToJSON, +} from './Coin'; + +/** + * + * @export + * @interface CoinsResponse + */ +export interface CoinsResponse { + /** + * + * @type {Array} + * @memberof CoinsResponse + */ + data: Array; +} + +/** + * Check if a given object implements the CoinsResponse interface. + */ +export function instanceOfCoinsResponse(value: object): value is CoinsResponse { + let isInstance = true; + isInstance = isInstance && "data" in value && value["data"] !== undefined; + + return isInstance; +} + +export function CoinsResponseFromJSON(json: any): CoinsResponse { + return CoinsResponseFromJSONTyped(json, false); +} + +export function CoinsResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CoinsResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'data': ((json['data'] as Array).map(CoinFromJSON)), + }; +} + +export function CoinsResponseToJSON(value?: CoinsResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'data': ((value.data as Array).map(CoinToJSON)), + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/CreateCoinRequest.ts b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinRequest.ts new file mode 100644 index 00000000000..0baa25b96b8 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinRequest.ts @@ -0,0 +1,110 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateCoinRequest + */ +export interface CreateCoinRequest { + /** + * The mint address of the coin + * @type {string} + * @memberof CreateCoinRequest + */ + mint: string; + /** + * The coin symbol/ticker + * @type {string} + * @memberof CreateCoinRequest + */ + ticker: string; + /** + * The number of decimals for the coin (0-18) + * @type {number} + * @memberof CreateCoinRequest + */ + decimals: number; + /** + * The coin name + * @type {string} + * @memberof CreateCoinRequest + */ + name: string; + /** + * The URI for the coin's logo image + * @type {string} + * @memberof CreateCoinRequest + */ + logoUri?: string; + /** + * The description of the coin + * @type {string} + * @memberof CreateCoinRequest + */ + description?: string; +} + +/** + * Check if a given object implements the CreateCoinRequest interface. + */ +export function instanceOfCreateCoinRequest(value: object): value is CreateCoinRequest { + let isInstance = true; + isInstance = isInstance && "mint" in value && value["mint"] !== undefined; + isInstance = isInstance && "ticker" in value && value["ticker"] !== undefined; + isInstance = isInstance && "decimals" in value && value["decimals"] !== undefined; + isInstance = isInstance && "name" in value && value["name"] !== undefined; + + return isInstance; +} + +export function CreateCoinRequestFromJSON(json: any): CreateCoinRequest { + return CreateCoinRequestFromJSONTyped(json, false); +} + +export function CreateCoinRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCoinRequest { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'mint': json['mint'], + 'ticker': json['ticker'], + 'decimals': json['decimals'], + 'name': json['name'], + 'logoUri': !exists(json, 'logo_uri') ? undefined : json['logo_uri'], + 'description': !exists(json, 'description') ? undefined : json['description'], + }; +} + +export function CreateCoinRequestToJSON(value?: CreateCoinRequest | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'mint': value.mint, + 'ticker': value.ticker, + 'decimals': value.decimals, + 'name': value.name, + 'logo_uri': value.logoUri, + 'description': value.description, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponse.ts b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponse.ts new file mode 100644 index 00000000000..b06df2e5948 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponse.ts @@ -0,0 +1,73 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +import type { CreateCoinResponseData } from './CreateCoinResponseData'; +import { + CreateCoinResponseDataFromJSON, + CreateCoinResponseDataFromJSONTyped, + CreateCoinResponseDataToJSON, +} from './CreateCoinResponseData'; + +/** + * + * @export + * @interface CreateCoinResponse + */ +export interface CreateCoinResponse { + /** + * + * @type {CreateCoinResponseData} + * @memberof CreateCoinResponse + */ + data?: CreateCoinResponseData; +} + +/** + * Check if a given object implements the CreateCoinResponse interface. + */ +export function instanceOfCreateCoinResponse(value: object): value is CreateCoinResponse { + let isInstance = true; + + return isInstance; +} + +export function CreateCoinResponseFromJSON(json: any): CreateCoinResponse { + return CreateCoinResponseFromJSONTyped(json, false); +} + +export function CreateCoinResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCoinResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'data': !exists(json, 'data') ? undefined : CreateCoinResponseDataFromJSON(json['data']), + }; +} + +export function CreateCoinResponseToJSON(value?: CreateCoinResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'data': CreateCoinResponseDataToJSON(value.data), + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponseData.ts b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponseData.ts new file mode 100644 index 00000000000..e55b43e1ce4 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/CreateCoinResponseData.ts @@ -0,0 +1,120 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface CreateCoinResponseData + */ +export interface CreateCoinResponseData { + /** + * The mint address of the coin + * @type {string} + * @memberof CreateCoinResponseData + */ + mint: string; + /** + * The coin symbol/ticker + * @type {string} + * @memberof CreateCoinResponseData + */ + ticker: string; + /** + * The user ID who created the coin + * @type {number} + * @memberof CreateCoinResponseData + */ + userId: number; + /** + * The number of decimals for the coin + * @type {number} + * @memberof CreateCoinResponseData + */ + decimals: number; + /** + * The coin name + * @type {string} + * @memberof CreateCoinResponseData + */ + name: string; + /** + * The URI for the coin's logo image + * @type {string} + * @memberof CreateCoinResponseData + */ + logoUri?: string; + /** + * The date and time when the coin was created + * @type {Date} + * @memberof CreateCoinResponseData + */ + createdAt: Date; +} + +/** + * Check if a given object implements the CreateCoinResponseData interface. + */ +export function instanceOfCreateCoinResponseData(value: object): value is CreateCoinResponseData { + let isInstance = true; + isInstance = isInstance && "mint" in value && value["mint"] !== undefined; + isInstance = isInstance && "ticker" in value && value["ticker"] !== undefined; + isInstance = isInstance && "userId" in value && value["userId"] !== undefined; + isInstance = isInstance && "decimals" in value && value["decimals"] !== undefined; + isInstance = isInstance && "name" in value && value["name"] !== undefined; + isInstance = isInstance && "createdAt" in value && value["createdAt"] !== undefined; + + return isInstance; +} + +export function CreateCoinResponseDataFromJSON(json: any): CreateCoinResponseData { + return CreateCoinResponseDataFromJSONTyped(json, false); +} + +export function CreateCoinResponseDataFromJSONTyped(json: any, ignoreDiscriminator: boolean): CreateCoinResponseData { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'mint': json['mint'], + 'ticker': json['ticker'], + 'userId': json['user_id'], + 'decimals': json['decimals'], + 'name': json['name'], + 'logoUri': !exists(json, 'logo_uri') ? undefined : json['logo_uri'], + 'createdAt': (new Date(json['created_at'])), + }; +} + +export function CreateCoinResponseDataToJSON(value?: CreateCoinResponseData | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'mint': value.mint, + 'ticker': value.ticker, + 'user_id': value.userId, + 'decimals': value.decimals, + 'name': value.name, + 'logo_uri': value.logoUri, + 'created_at': (value.createdAt.toISOString()), + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinRequest.ts b/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinRequest.ts new file mode 100644 index 00000000000..b068ced41c8 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinRequest.ts @@ -0,0 +1,98 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * Request body for updating coin information + * @export + * @interface UpdateCoinRequest + */ +export interface UpdateCoinRequest { + /** + * The description of the coin (max 2500 characters) + * @type {string} + * @memberof UpdateCoinRequest + */ + description?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link1?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link2?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link3?: string; + /** + * Generic link URL for the coin + * @type {string} + * @memberof UpdateCoinRequest + */ + link4?: string; +} + +/** + * Check if a given object implements the UpdateCoinRequest interface. + */ +export function instanceOfUpdateCoinRequest(value: object): value is UpdateCoinRequest { + let isInstance = true; + + return isInstance; +} + +export function UpdateCoinRequestFromJSON(json: any): UpdateCoinRequest { + return UpdateCoinRequestFromJSONTyped(json, false); +} + +export function UpdateCoinRequestFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCoinRequest { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'description': !exists(json, 'description') ? undefined : json['description'], + 'link1': !exists(json, 'link_1') ? undefined : json['link_1'], + 'link2': !exists(json, 'link_2') ? undefined : json['link_2'], + 'link3': !exists(json, 'link_3') ? undefined : json['link_3'], + 'link4': !exists(json, 'link_4') ? undefined : json['link_4'], + }; +} + +export function UpdateCoinRequestToJSON(value?: UpdateCoinRequest | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'description': value.description, + 'link_1': value.link1, + 'link_2': value.link2, + 'link_3': value.link3, + 'link_4': value.link4, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinResponse.ts b/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinResponse.ts new file mode 100644 index 00000000000..1aedb480689 --- /dev/null +++ b/packages/sdk/src/sdk/api/generated/full/models/UpdateCoinResponse.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck +/** + * API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { exists, mapValues } from '../runtime'; +/** + * + * @export + * @interface UpdateCoinResponse + */ +export interface UpdateCoinResponse { + /** + * Indicates if the update was successful + * @type {boolean} + * @memberof UpdateCoinResponse + */ + success?: boolean; +} + +/** + * Check if a given object implements the UpdateCoinResponse interface. + */ +export function instanceOfUpdateCoinResponse(value: object): value is UpdateCoinResponse { + let isInstance = true; + + return isInstance; +} + +export function UpdateCoinResponseFromJSON(json: any): UpdateCoinResponse { + return UpdateCoinResponseFromJSONTyped(json, false); +} + +export function UpdateCoinResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): UpdateCoinResponse { + if ((json === undefined) || (json === null)) { + return json; + } + return { + + 'success': !exists(json, 'success') ? undefined : json['success'], + }; +} + +export function UpdateCoinResponseToJSON(value?: UpdateCoinResponse | null): any { + if (value === undefined) { + return undefined; + } + if (value === null) { + return null; + } + return { + + 'success': value.success, + }; +} + diff --git a/packages/sdk/src/sdk/api/generated/full/models/index.ts b/packages/sdk/src/sdk/api/generated/full/models/index.ts index 92a9ff30b04..a8daf3c8094 100644 --- a/packages/sdk/src/sdk/api/generated/full/models/index.ts +++ b/packages/sdk/src/sdk/api/generated/full/models/index.ts @@ -35,6 +35,9 @@ export * from './CidDataResponse'; export * from './ClaimableRewardNotification'; export * from './ClaimableRewardNotificationAction'; export * from './ClaimableRewardNotificationActionData'; +export * from './Coin'; +export * from './CoinResponse'; +export * from './CoinsResponse'; export * from './CollectionActivityFull'; export * from './CollectionActivityFullWithoutTracks'; export * from './CollectionLibraryResponseFull'; @@ -60,6 +63,9 @@ export * from './CosignNotificationActionData'; export * from './CoverArt'; export * from './CoverPhoto'; export * from './CoverPhotoFull'; +export * from './CreateCoinRequest'; +export * from './CreateCoinResponse'; +export * from './CreateCoinResponseData'; export * from './CreateNotification'; export * from './CreateNotificationAction'; export * from './CreateNotificationActionData'; @@ -242,6 +248,8 @@ export * from './TrendingTimesIds'; export * from './TrendingUndergroundNotification'; export * from './TrendingUndergroundNotificationAction'; export * from './TrendingUndergroundNotificationActionData'; +export * from './UpdateCoinRequest'; +export * from './UpdateCoinResponse'; export * from './UrlWithMirrors'; export * from './UsdcGate'; export * from './UsdcPurchaseBuyerNotification'; From 2f75ef3b746592891140e33e4566041ea85a2f63 Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 11:34:52 -0500 Subject: [PATCH 3/9] finish fee logic --- .../src/messages/coinDetailsMessages.ts | 8 + .../default/models/CoinDynamicBondingCurve.ts | 14 +- packages/web/src/hooks/useClaimFee.ts | 29 +++- .../components/AssetInfoSection.tsx | 156 +++++++++++++----- 4 files changed, 158 insertions(+), 49 deletions(-) diff --git a/packages/common/src/messages/coinDetailsMessages.ts b/packages/common/src/messages/coinDetailsMessages.ts index 2201035ccc8..c77a91747da 100644 --- a/packages/common/src/messages/coinDetailsMessages.ts +++ b/packages/common/src/messages/coinDetailsMessages.ts @@ -66,6 +66,10 @@ export const coinDetailsMessages = { overflowMenu: { copyCoinAddress: 'Copy Coin Address', unclaimedFees: 'Unclaimed Fees', + artistEarnings: 'Artist Earnings', + vestingSchedule: 'Vesting Schedule', + vestingScheduleValue: '5 years (post-graduation)', + $audio: '$AUDIO', claim: 'Claim', openDexscreener: 'Open Dexscreener', details: 'Details', @@ -103,5 +107,9 @@ export const coinDetailsMessages = { circulatingSupply: 'The number of artist coins currently available for trading, excluding any tokens that are locked or reserved.' } + }, + toasts: { + feesClaimed: 'Fees claimed successfully!', + feesClaimFailed: 'Unable to claim fees. Please try again.' } } diff --git a/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts b/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts index 8f55ec7b7c3..5bf9e649260 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/CoinDynamicBondingCurve.ts @@ -55,7 +55,13 @@ export interface CoinDynamicBondingCurve { * @type {number} * @memberof CoinDynamicBondingCurve */ - creatorQuoteFee?: number; + creatorQuoteFee: number; + /** + * Total trading quote fee accumulated + * @type {number} + * @memberof CoinDynamicBondingCurve + */ + totalTradingQuoteFee: number; } /** @@ -67,6 +73,8 @@ export function instanceOfCoinDynamicBondingCurve(value: object): value is CoinD isInstance = isInstance && "price" in value && value["price"] !== undefined; isInstance = isInstance && "priceUSD" in value && value["priceUSD"] !== undefined; isInstance = isInstance && "curveProgress" in value && value["curveProgress"] !== undefined; + isInstance = isInstance && "creatorQuoteFee" in value && value["creatorQuoteFee"] !== undefined; + isInstance = isInstance && "totalTradingQuoteFee" in value && value["totalTradingQuoteFee"] !== undefined; return isInstance; } @@ -86,7 +94,8 @@ export function CoinDynamicBondingCurveFromJSONTyped(json: any, ignoreDiscrimina 'priceUSD': json['priceUSD'], 'curveProgress': json['curveProgress'], 'isMigrated': !exists(json, 'isMigrated') ? undefined : json['isMigrated'], - 'creatorQuoteFee': !exists(json, 'creatorQuoteFee') ? undefined : json['creatorQuoteFee'], + 'creatorQuoteFee': json['creatorQuoteFee'], + 'totalTradingQuoteFee': json['totalTradingQuoteFee'], }; } @@ -105,6 +114,7 @@ export function CoinDynamicBondingCurveToJSON(value?: CoinDynamicBondingCurve | 'curveProgress': value.curveProgress, 'isMigrated': value.isMigrated, 'creatorQuoteFee': value.creatorQuoteFee, + 'totalTradingQuoteFee': value.totalTradingQuoteFee, }; } diff --git a/packages/web/src/hooks/useClaimFee.ts b/packages/web/src/hooks/useClaimFee.ts index 1aaea809aca..71750773c34 100644 --- a/packages/web/src/hooks/useClaimFee.ts +++ b/packages/web/src/hooks/useClaimFee.ts @@ -1,7 +1,12 @@ -import { useQueryContext } from '@audius/common/api' +import { type Coin } from '@audius/common/adapters' +import { getArtistCoinQueryKey, useQueryContext } from '@audius/common/api' import type { Provider as SolanaProvider } from '@reown/appkit-adapter-solana/react' import { VersionedTransaction } from '@solana/web3.js' -import { useMutation, UseMutationOptions } from '@tanstack/react-query' +import { + useMutation, + UseMutationOptions, + useQueryClient +} from '@tanstack/react-query' import { appkitModal } from 'app/ReownAppKitModal' @@ -24,6 +29,7 @@ export const useClaimFee = ( options?: UseMutationOptions ) => { const { audiusSdk } = useQueryContext() + const queryClient = useQueryClient() return useMutation({ mutationFn: async ({ @@ -69,6 +75,23 @@ export const useClaimFee = ( signature } }, - ...options + ...options, + onSuccess: (data, variables, context) => { + // Optimistically update the unclaimed fees data + const queryKey = getArtistCoinQueryKey(variables.tokenMint) + queryClient.setQueryData(queryKey, (existingCoin) => { + if (!existingCoin) return existingCoin + return { + ...existingCoin, + dynamicBondingCurve: { + ...existingCoin?.dynamicBondingCurve, + creatorQuoteFee: 0 + } + } + }) + + // Call the original onSuccess if provided + options?.onSuccess?.(data, variables, context) + } }) } diff --git a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx index 16a654016b7..fdb581021b5 100644 --- a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx +++ b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx @@ -2,25 +2,24 @@ import { useCallback, useContext, useMemo } from 'react' import { useArtistCoin, - useCurrentUserId, useUser, useUserCoins, useConnectedWallets, - useWalletAddresses, useCurrentAccountUser } from '@audius/common/api' import { useDiscordOAuthLink } from '@audius/common/hooks' import { coinDetailsMessages } from '@audius/common/messages' -import { WidthSizes } from '@audius/common/models' +import { Feature, WidthSizes } from '@audius/common/models' import { route, shortenSPLAddress } from '@audius/common/utils' +import { wAUDIO } from '@audius/fixed-decimal' import { - Button, Flex, IconCopy, IconDiscord, IconExternalLink, IconGift, IconInfo, + LoadingSpinner, Paper, PlainButton, Text, @@ -38,11 +37,13 @@ import { useClaimFee } from 'hooks/useClaimFee' import { useCoverPhoto } from 'hooks/useCoverPhoto' import { getLastConnectedSolWallet } from 'pages/artist-coins-launchpad-page/utils' import { env } from 'services/env' +import { reportToSentry } from 'store/errors/reportToSentry' import { copyToClipboard } from 'utils/clipboardUtil' import { push } from 'utils/navigation' const messages = coinDetailsMessages.coinInfo const overflowMessages = coinDetailsMessages.overflowMenu +const toastMessages = coinDetailsMessages.toasts const BANNER_HEIGHT = 120 @@ -211,17 +212,35 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { // Claim fee hook const { mutate: claimFee, isPending: isClaimFeePending } = useClaimFee({ - onSuccess: (data) => { - toast('Fees claimed successfully!') - // eslint-disable-next-line no-console - console.log('Claim fee transaction signature:', data.signature) + onSuccess: () => { + toast(toastMessages.feesClaimed) }, onError: (error) => { - toast(`Failed to claim fees: ${error.message}`) + reportToSentry({ + error, + feature: Feature.ArtistCoins, + name: 'Failed to claim artist coin fees', + additionalInfo: { + coin, + tokenMint: mint, + unclaimedFees, + totalArtistEarnings + } + }) + toast(toastMessages.feesClaimFailed) } }) - const unclaimedFees = coin?.unclaimedFees ?? 0.01 // TODO: get this working on api side + const unclaimedFees = coin?.dynamicBondingCurve?.creatorQuoteFee ?? 0 + const formattedUnclaimedFees = useMemo(() => { + return wAUDIO(BigInt(unclaimedFees)).toShorthand() + }, [unclaimedFees]) + const totalArtistEarnings = + coin?.dynamicBondingCurve?.totalTradingQuoteFee ?? 0 + const formattedTotalArtistEarnings = useMemo(() => { + // Here we divide by 2 because the artist only gets half of the fees (this value includes the AUDIO network fees) + return wAUDIO(BigInt(Math.trunc(totalArtistEarnings / 2))).toShorthand() + }, [totalArtistEarnings]) const descriptionParagraphs = coin?.description?.split('\n') ?? [] const openDiscord = () => { @@ -242,18 +261,19 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { }, [mint, toast]) const handleClaimFees = useCallback(() => { - if (!externalSolWallet) { - toast('Please connect your wallet to claim fees') - return - } - - if (!mint) { - toast('Invalid token mint address') - return - } - - if (!currentUser?.spl_wallet) { - toast('Something went wrong') + if (!externalSolWallet || !mint || !currentUser?.spl_wallet) { + toast(toastMessages.feesClaimFailed) + reportToSentry({ + error: new Error('Unknown error while claiming fees'), + feature: Feature.ArtistCoins, + name: 'No external Solana wallet connected', + additionalInfo: { + coin, + mint, + externalSolWallet, + currentUser + } + }) return } @@ -262,7 +282,7 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { ownerWalletAddress: externalSolWallet.address, receiverWalletAddress: currentUser.spl_wallet // Using same wallet for owner and receiver }) - }, [externalSolWallet, mint, claimFee, currentUser?.spl_wallet, toast]) + }, [externalSolWallet, mint, currentUser, claimFee, toast, coin]) if (isLoading || !coin) { return @@ -382,42 +402,90 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { {shortenSPLAddress(mint)} - {isCoinCreator ? ( + - {overflowMessages.unclaimedFees} + {overflowMessages.vestingSchedule} - + + + {overflowMessages.vestingScheduleValue} + + + - {unclaimedFees > 0 ? ( - - {overflowMessages.claim} - - ) : null} - - ${unclaimedFees} + + {overflowMessages.artistEarnings} + + + + + {formattedTotalArtistEarnings} {overflowMessages.$audio} + - ) : null} + {isCoinCreator ? ( + + + + {overflowMessages.unclaimedFees} + + + + + + + {unclaimedFees > 0 ? ( + + + {overflowMessages.claim} + + {isClaimFeePending ? ( + + ) : null} + + ) : null} + + + {formattedUnclaimedFees} {overflowMessages.$audio} + + + + ) : null} + ) } From cafa0e691b8747ed04caab44a1f8a1a82d1508ba Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 11:43:12 -0500 Subject: [PATCH 4/9] env --- packages/web/src/services/env/env.prod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/services/env/env.prod.ts b/packages/web/src/services/env/env.prod.ts index f20466aceac..e82d0ddcafe 100644 --- a/packages/web/src/services/env/env.prod.ts +++ b/packages/web/src/services/env/env.prod.ts @@ -71,7 +71,7 @@ export const env: Env = { SOL_TOKEN_BRIDGE_ADDRESS: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb', SOLANA_CLUSTER_ENDPOINT: 'https://audius-fe.rpcpool.com', SOLANA_FEE_PAYER_ADDRESS: 'pqx3fvvh6b2eZBfLhTtQ5KxzU3CginmgGTmDCjk8TPP', - SOLANA_RELAY_ENDPOINT: 'http://localhost:6002', + SOLANA_RELAY_ENDPOINT: 'https://discoveryprovider.audius.co', SOLANA_TOKEN_PROGRAM_ADDRESS: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', SOLANA_WEB3_CLUSTER: 'mainnet-beta', STRIPE_CLIENT_PUBLISHABLE_KEY: From 7d98f812d62c521d84380e51e01e2f70d89175eb Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 11:52:19 -0500 Subject: [PATCH 5/9] rename to claimFees plural - add reportToSentry to the mutation --- .../pedalboard/apps/solana-relay/src/index.ts | 4 +- .../launchpad/{claim_fee.ts => claim_fees.ts} | 23 +++++------ .../hooks/{useClaimFee.ts => useClaimFees.ts} | 38 +++++++++++++------ 3 files changed, 40 insertions(+), 25 deletions(-) rename packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/{claim_fee.ts => claim_fees.ts} (74%) rename packages/web/src/hooks/{useClaimFee.ts => useClaimFees.ts} (66%) diff --git a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts index fbb847feb12..31f983a55d8 100644 --- a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts +++ b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/index.ts @@ -18,7 +18,7 @@ import { cache } from './routes/cache' import { feePayer } from './routes/feePayer' import { health } from './routes/health/health' import { location } from './routes/instruction/location' -import { claimFee } from './routes/launchpad/claim_fee' +import { claimFees } from './routes/launchpad/claim_fees' import { firstBuyQuote, getLaunchpadConfigRoute @@ -46,7 +46,7 @@ const main = async () => { }) // launchpad endpoints don't need user/discovery validation, so register them before middleware app.post('/solana/launchpad/launch_coin', upload.single('image'), launchCoin) - app.get('/solana/launchpad/claim_fee', claimFee) + app.get('/solana/launchpad/claim_fees', claimFees) app.get('/solana/launchpad/first_buy_quote', firstBuyQuote) app.get('/solana/launchpad/config', getLaunchpadConfigRoute) diff --git a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts similarity index 74% rename from packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts rename to packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts index 575e1c4e05f..3d182f40c4b 100644 --- a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fee.ts +++ b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts @@ -5,14 +5,14 @@ import { Request, Response } from 'express' import { logger } from '../../logger' import { getConnection } from '../../utils/connections' -interface ClaimFeeRequestBody { +interface ClaimFeesRequestBody { tokenMint: string ownerWalletAddress: string receiverWalletAddress: string } -export const claimFee = async ( - req: Request, +export const claimFees = async ( + req: Request, res: Response ) => { try { @@ -37,29 +37,30 @@ export const claimFee = async ( const poolAddress = tokenPool.publicKey const poolData = tokenPool.account + const ownerWallet = new PublicKey(ownerWalletAddress) + const receiverWallet = new PublicKey(receiverWalletAddress) - const claimFeeTx = await dbcClient.creator.claimCreatorTradingFee({ + const claimFeesTx = await dbcClient.creator.claimCreatorTradingFee({ pool: poolAddress, - payer: new PublicKey(ownerWalletAddress), - creator: new PublicKey(ownerWalletAddress), + payer: ownerWallet, + creator: ownerWallet, maxBaseAmount: poolData.creatorBaseFee, // Match max amount to the claimable amount (effectively no limit) maxQuoteAmount: poolData.creatorQuoteFee, // Match max amount to the claimable amount (effectively no limit) - receiver: new PublicKey(receiverWalletAddress) + receiver: receiverWallet }) - claimFeeTx.recentBlockhash = ( + claimFeesTx.recentBlockhash = ( await connection.getLatestBlockhash() ).blockhash - claimFeeTx.feePayer = new PublicKey(ownerWalletAddress) + claimFeesTx.feePayer = ownerWallet return res.status(200).send({ - claimFeeTx: claimFeeTx.serialize({ requireAllSignatures: false }) + claimFeesTx: claimFeesTx.serialize({ requireAllSignatures: false }) }) } catch (e) { logger.error( 'Error in claim_fee - unable to create creator claim fee transaction' ) - logger.error(e) res.status(500).send() } } diff --git a/packages/web/src/hooks/useClaimFee.ts b/packages/web/src/hooks/useClaimFees.ts similarity index 66% rename from packages/web/src/hooks/useClaimFee.ts rename to packages/web/src/hooks/useClaimFees.ts index 71750773c34..e423c5aaa32 100644 --- a/packages/web/src/hooks/useClaimFee.ts +++ b/packages/web/src/hooks/useClaimFees.ts @@ -1,5 +1,6 @@ import { type Coin } from '@audius/common/adapters' import { getArtistCoinQueryKey, useQueryContext } from '@audius/common/api' +import { Feature } from '@audius/common/models' import type { Provider as SolanaProvider } from '@reown/appkit-adapter-solana/react' import { VersionedTransaction } from '@solana/web3.js' import { @@ -9,34 +10,36 @@ import { } from '@tanstack/react-query' import { appkitModal } from 'app/ReownAppKitModal' +import { reportToSentry } from 'store/errors/reportToSentry' -export type UseClaimFeeParams = { +export type UseClaimFeesParams = { tokenMint: string ownerWalletAddress: string receiverWalletAddress: string } -export type ClaimFeeResponse = { - claimFeeTx: string +export type ClaimFeesResponse = { + claimFeessTx: string signature: string } /** * Hook for claiming creator trading fees from a dynamic bonding curve pool. - * This creates, signs, and sends the claim fee transaction. + * This gets the TX from solana relay, then signs and sends the claim fees transaction. + * NOTE: This is a web feature only because the user must sign with the same external wallet they used to launch the coin (wallet connect wallet). */ -export const useClaimFee = ( - options?: UseMutationOptions +export const useClaimFees = ( + options?: UseMutationOptions ) => { const { audiusSdk } = useQueryContext() const queryClient = useQueryClient() - return useMutation({ + return useMutation({ mutationFn: async ({ tokenMint, ownerWalletAddress, receiverWalletAddress - }: UseClaimFeeParams): Promise => { + }: UseClaimFeesParams): Promise => { const sdk = await audiusSdk() const solanaProvider = appkitModal.getProvider('solana') if (!solanaProvider) { @@ -47,17 +50,17 @@ export const useClaimFee = ( } // Get the claim fee transaction from the relay - const claimFeeResponse = await sdk.services.solanaRelay.claimFee({ + const claimFeesResponse = await sdk.services.solanaRelay.claimFees({ tokenMint, ownerWalletAddress, receiverWalletAddress }) - const { claimFeeTx: claimFeeTxSerialized } = claimFeeResponse + const { claimFeessTx: claimFeessTxSerialized } = claimFeesResponse // Transaction is sent from the backend as a serialized base64 string const deserializedTx = VersionedTransaction.deserialize( - Buffer.from(claimFeeTxSerialized, 'base64') + Buffer.from(claimFeessTxSerialized, 'base64') ) // Triggers 3rd party wallet to sign and send the transaction @@ -71,11 +74,22 @@ export const useClaimFee = ( ) return { - claimFeeTx: claimFeeTxSerialized, + claimFeessTx: claimFeessTxSerialized, signature } }, ...options, + onError: (error, params) => { + // Call the original onError if provided + reportToSentry({ + error, + feature: Feature.ArtistCoins, + name: 'Artist coin fees claim error', + additionalInfo: { + ...params + } + }) + }, onSuccess: (data, variables, context) => { // Optimistically update the unclaimed fees data const queryKey = getArtistCoinQueryKey(variables.tokenMint) From 9e0866e055773481780c48d7a2d7380e429392ff Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 11:53:07 -0500 Subject: [PATCH 6/9] more pluralization --- .../components/AssetInfoSection.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx index d22c0cc162f..42288d60c41 100644 --- a/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx +++ b/packages/web/src/pages/asset-detail-page/components/AssetInfoSection.tsx @@ -39,7 +39,7 @@ import Skeleton from 'components/skeleton/Skeleton' import { ToastContext } from 'components/toast/ToastContext' import Tooltip from 'components/tooltip/Tooltip' import { UserTokenBadge } from 'components/user-token-badge/UserTokenBadge' -import { useClaimFee } from 'hooks/useClaimFee' +import { useClaimFees } from 'hooks/useClaimFees' import { useCoverPhoto } from 'hooks/useCoverPhoto' import { getLastConnectedSolWallet } from 'pages/artist-coins-launchpad-page/utils' import { env } from 'services/env' @@ -279,7 +279,7 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { ) // Claim fee hook - const { mutate: claimFee, isPending: isClaimFeePending } = useClaimFee({ + const { mutate: claimFees, isPending: isClaimFeesPending } = useClaimFees({ onSuccess: () => { toast(toastMessages.feesClaimed) }, @@ -345,12 +345,12 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { return } - claimFee({ + claimFees({ tokenMint: mint, ownerWalletAddress: externalSolWallet.address, receiverWalletAddress: currentUser.spl_wallet // Using same wallet for owner and receiver }) - }, [externalSolWallet, mint, currentUser, claimFee, toast, coin]) + }, [externalSolWallet, mint, currentUser, claimFees, toast, coin]) if (isLoading || !coin) { return @@ -540,16 +540,16 @@ export const AssetInfoSection = ({ mint }: AssetInfoSectionProps) => { {overflowMessages.claim} - {isClaimFeePending ? ( + {isClaimFeesPending ? ( ) : null} From 74acbf950eca9d2f17f3fd87ebc250dfd91de53c Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 12:00:49 -0500 Subject: [PATCH 7/9] more pluralization --- .../src/routes/launchpad/claim_fees.ts | 2 +- .../sdk/src/sdk/services/Solana/SolanaRelay.ts | 14 +++++++------- packages/sdk/src/sdk/services/Solana/types.ts | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts index 3d182f40c4b..fe9c6fdf9cb 100644 --- a/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts +++ b/packages/discovery-provider/plugins/pedalboard/apps/solana-relay/src/routes/launchpad/claim_fees.ts @@ -59,7 +59,7 @@ export const claimFees = async ( }) } catch (e) { logger.error( - 'Error in claim_fee - unable to create creator claim fee transaction' + 'Error in claim_fees - unable to create creator claim fee transaction' ) res.status(500).send() } diff --git a/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts b/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts index 40203844b4e..d5d5881fb35 100644 --- a/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts +++ b/packages/sdk/src/sdk/services/Solana/SolanaRelay.ts @@ -18,8 +18,8 @@ import { FirstBuyQuoteResponse, FirstBuyQuoteRequest, LaunchpadConfigResponse, - ClaimFeeRequest, - ClaimFeeResponse + ClaimFeesRequest, + ClaimFeesResponse } from './types' /** @@ -308,10 +308,10 @@ export class SolanaRelay extends BaseAPI { /** * Claims creator trading fees from a dynamic bonding curve pool. */ - public async claimFee( - params: ClaimFeeRequest, + public async claimFees( + params: ClaimFeesRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction - ): Promise { + ): Promise { const headerParameters: runtime.HTTPHeaders = { 'Content-Type': 'application/json' } @@ -323,7 +323,7 @@ export class SolanaRelay extends BaseAPI { const response = await this.request( { - path: '/launchpad/claim_fee', + path: '/launchpad/claim_fees', method: 'GET', headers: headerParameters, query: queryParameters @@ -332,7 +332,7 @@ export class SolanaRelay extends BaseAPI { ) return await new runtime.JSONApiResponse(response, (json) => { - return json as ClaimFeeResponse + return json as ClaimFeesResponse }).value() } } diff --git a/packages/sdk/src/sdk/services/Solana/types.ts b/packages/sdk/src/sdk/services/Solana/types.ts index b8f46e3083d..26fda06e592 100644 --- a/packages/sdk/src/sdk/services/Solana/types.ts +++ b/packages/sdk/src/sdk/services/Solana/types.ts @@ -158,12 +158,12 @@ export type LaunchpadConfigResponse = { startingPrice: string } -export type ClaimFeeRequest = { +export type ClaimFeesRequest = { tokenMint: string ownerWalletAddress: string receiverWalletAddress: string } -export type ClaimFeeResponse = { - claimFeeTx: string +export type ClaimFeesResponse = { + claimFeesTx: string } From a8f044aaeeec660ce0aa351bbb8f7e7491ccf6a4 Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 12:31:41 -0500 Subject: [PATCH 8/9] find replace bug --- packages/web/src/hooks/useClaimFees.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web/src/hooks/useClaimFees.ts b/packages/web/src/hooks/useClaimFees.ts index e423c5aaa32..062276f896a 100644 --- a/packages/web/src/hooks/useClaimFees.ts +++ b/packages/web/src/hooks/useClaimFees.ts @@ -19,7 +19,7 @@ export type UseClaimFeesParams = { } export type ClaimFeesResponse = { - claimFeessTx: string + claimfeesTx: string signature: string } @@ -56,11 +56,11 @@ export const useClaimFees = ( receiverWalletAddress }) - const { claimFeessTx: claimFeessTxSerialized } = claimFeesResponse + const { claimfeesTx: claimfeesTxSerialized } = claimFeesResponse // Transaction is sent from the backend as a serialized base64 string const deserializedTx = VersionedTransaction.deserialize( - Buffer.from(claimFeessTxSerialized, 'base64') + Buffer.from(claimfeesTxSerialized, 'base64') ) // Triggers 3rd party wallet to sign and send the transaction @@ -74,7 +74,7 @@ export const useClaimFees = ( ) return { - claimFeessTx: claimFeessTxSerialized, + claimfeesTx: claimfeesTxSerialized, signature } }, From cf23cf40837f77b830eea62307aaba67f3b8e9c1 Mon Sep 17 00:00:00 2001 From: JD Francis Date: Thu, 2 Oct 2025 12:41:01 -0500 Subject: [PATCH 9/9] caps issuee --- packages/web/src/hooks/useClaimFees.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web/src/hooks/useClaimFees.ts b/packages/web/src/hooks/useClaimFees.ts index 062276f896a..a116648f6cb 100644 --- a/packages/web/src/hooks/useClaimFees.ts +++ b/packages/web/src/hooks/useClaimFees.ts @@ -19,7 +19,7 @@ export type UseClaimFeesParams = { } export type ClaimFeesResponse = { - claimfeesTx: string + claimFeesTx: string signature: string } @@ -56,11 +56,11 @@ export const useClaimFees = ( receiverWalletAddress }) - const { claimfeesTx: claimfeesTxSerialized } = claimFeesResponse + const { claimFeesTx: claimFeesTxSerialized } = claimFeesResponse // Transaction is sent from the backend as a serialized base64 string const deserializedTx = VersionedTransaction.deserialize( - Buffer.from(claimfeesTxSerialized, 'base64') + Buffer.from(claimFeesTxSerialized, 'base64') ) // Triggers 3rd party wallet to sign and send the transaction @@ -74,7 +74,7 @@ export const useClaimFees = ( ) return { - claimfeesTx: claimfeesTxSerialized, + claimFeesTx: claimFeesTxSerialized, signature } },