This is the process I used to create a meme coin on Solana. I used the command line and some JavaScript code to set the metadata.
The coins I have made are for fun only. They have no value and no one can mine any additional coins. I have not set up any liquidity pools.
Note: These instructions are for the Mac. There are Windows equivalents for all the commands, but I have not tested them.
- Solana CLI documentation
- SPL Token CLI documentation
- Claude Code (of course)
Node.js is required to run the metadata script. Install it with Homebrew:
brew install node
node --versionInstall npm (Node.js) packages:
npm installIf you need Homebrew, install it with:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Or see brew.sh for other installation options.
I installed this with Homebrew:
brew install solana
solana --versionThis is a Rust program that provides a command line interface for creating and managing SPL tokens on the Solana blockchain.
First I installed Rust with Homebrew:
brew install rustThen I installed spl-token-cli with Cargo:
cargo install spl-token-cli
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
spl-token --versionFor the most part, you can type all of the commands below into the terminal. The ones that require values from previous steps are marked with placeholders like <TOKEN_ID>. There are also some JavaScript scripts in this repo that you can run with node to automate some of the steps, such as uploading to Arweave and setting metadata. There are also some shell scripts that automate the whole process or verify the results. If you want to use the scripts, follow this procedure. You will need a github account.
This repo is a GitHub Template.
- Click Use this template (top-right on GitHub).
- Create a new repository under your GitHub account/org.
- Clone your new repo, then run
npm install.
Notes:
- Your repo will be independent (not a fork).
- Your
originremote will point to your repo, notbillbak/memecoin.- Nothing you do will push back here unless you intentionally open a PR.
solana config set --url https://api.mainnet-beta.solana.com
solana config getsolana-keygen new --outfile ~/.config/solana/id.jsonI skipped the pass phrase. The command will print the public address and the seed phrase you can use to recover the key. I saved the seed phrase in a secure location. DO NOT COMMIT THE FILE OR THE SEED PHRASE.
cp ~/.config/solana/id.json ~/solana-id.json ## Or anywhere you prefer
gpg --symmetric --cipher-algo AES256 ~/solana-id.json ## Encrypt the file with a passphrase
rm ~/solana-id.json ## Remove the unencrypted fileCopy the encrypted file (~/solana-id.json.gpg) to a secure location, such as an external drive or cloud storage.
solana-keygen pubkey ~/.config/solana/id.jsonYou need this for the next step.
Use some wallet that contains SOL to send 0.2 SOL to the new address. This is needed to pay for transaction fees and account creation. These fees are called "gas fees" on Ethereum, but Solana just calls them "fees". You can use any wallet that supports Solana, such as Phantom or Solflare.
solana balancespl-token create-token --decimals 0
Creating token <TOKEN_ID> under program <PROGRAM_ID>
Address: <TOKEN_ID>
Decimals: 0
Signature: wzYkn...vfM5QeThis command creates a new token with 0 decimals (i.e., indivisible) and returns the token address, which is needed for the next steps. The token address is also called the "mint address" because it represents the mint of the token.
You will need this address for subsequent commands. Write it down, or copy it somewhere you can copy/paste from.
spl-token create-account <TOKEN_ID>
Creating account <RECIPIENT_ID>
Signature: 4pLBv...x1AK8This command creates a new token account that can hold the tokens of the specified mint. The token account address is also needed for the next steps. The token account is associated with the wallet address, so only the owner of the wallet can access the tokens in that account.
spl-token mint <TOKEN_ID> 1000
Minting 1000 tokens
Token: <TOKEN_ID>
Recipient: <RECIPIENT_ID>
Signature: 5ztu...R6YoLThis command mints 1000 tokens of the specified mint to the specified recipient token account.
spl-token balance <TOKEN_ID>
1000This command checks the balance of the specified token account. It should return 1000, which is the amount of tokens that were minted to that account. You can also check the balance with a wallet that supports Solana, such as Phantom or Solflare, by adding the token to the wallet with the mint address.
Token icons should be stored on Arweave, which is permanent, decentralized storage. Wallets like Phantom and indexers like Solscan reliably display icons hosted on Arweave. GitHub-hosted images can break if the repo is renamed, moved, or made private.
Upload your 512x512 PNG icon with:
node upload-to-arweave.mjs --file ./mytoken/icon.pngThis prints an Arweave URL like https://gateway.irys.xyz/.... Update your metadata.json to use this URL for both the image field and properties.files[0].uri.
If you use mint-token.sh with the --icon flag, this upload and metadata update happens automatically (see below).
The metadata.json file is also uploaded to Arweave for permanence. This ensures the on-chain metadata URI points to permanent storage instead of a GitHub URL that could break if the repo is renamed, moved, or made private.
node upload-to-arweave.mjs --file ./mytoken/metadata.jsonThis prints an Arweave URL that you pass to create-metadata.mjs with --uri:
If you use mint-token.sh, in this repo, this upload happens automatically — the script uploads metadata.json to Arweave and uses the resulting URL when applying on-chain metadata.
Tokens have metadata: name, symbol, description, and icon. This is what makes the token recognizable in wallets and explorers. The metadata is stored on-chain as a URI pointing to a JSON file that follows the Metaplex standard. See any of the metadata.json files in this repo for an example.
There is a Metaplex command line tool that sets metadata, but it brought in packages with security vulnerabilities. Instead I wrote create-metadata.mjs to call the Metaplex libraries directly (well, Claude Code wrote it).
At this point you should have already uploaded both the icon and metadata.json to Arweave (see the two sections above). Run:
node create-metadata.mjs --mint <TOKEN_ID> --name <NAME> --symbol <SYMBOL> --uri <ARWEAVE_URL>The script works for both new tokens (creates metadata) and existing tokens (updates metadata). After running, you should see the token's name, symbol, and image in wallets like Phantom or Solflare.
Legacy option: You can use
--metadata <local-path>instead of--uri. This infers a raw GitHub URL from your git remote, which works if the repo is public but breaks if the repo is renamed, made private, or deleted. Arweave is recommended.
At this point, the token is fully functional and can be transferred, traded, or used in any way that other Solana tokens can be. Only the account that owns the mint can transfer tokens to other wallets.
spl-token authorize <TOKEN_ID> mint --disable
Updating <TOKEN_ID>
Current mint: <MINT_ADDRESS>
New mint: disabled
Signature: 34ypF...Nsxoespl-token account-info <TOKEN_ID>
SPL Token Account
Address: <ACCOUNT_ADDRESS>
Program: <PROGRAM_ADDRESS>
Balance: 1000
Decimals: 0
Mint: <MINT_ADDRESS>
Owner: <OWNER_ADDRESS>
State: Initialized
Delegation: (not set)
Close authority: (not set)You are done! You have created a new meme coin on Solana with custom metadata. You can share the mint address and the metadata URI with others so they can view the token in their wallets or trade it on decentralized exchanges that support Solana tokens.
A liquidity pool is what makes a token tradeable. Without one, people can only receive tokens via direct transfers — there's no way to buy or sell on the open market. We can create an AMM (automated market maker) liquidity pool for our token on Raydium, which is the most popular DEX on Solana. This will allow anyone to swap between our token and SOL, making it easily accessible to anyone with a Solana wallet.
A liquidity pool is a pair of tokens locked in a smart contract. For example, a BLLBK/SOL pool holds both BLLBK and SOL. When someone wants to buy BLLBK, they send SOL to the pool and receive BLLBK in return. The pool uses a constant product formula (x × y = k) to automatically set the price based on the ratio of the two tokens.
In this formula:
-
x = amount of BLLBK in the pool
-
y = amount of SOL in the pool
-
k = constant (the product of x and y)
-
More buyers → the pool's BLLBK supply decreases → price goes up
-
More sellers → the pool's BLLBK supply increases → price goes down
The initial price is set by the ratio of tokens you deposit. For example, depositing 500 BLLBK and 5 SOL impies an initial price of 0.01 SOL per BLLBK.
When you create a pool or add liquidity, you receive LP (liquidity provider) tokens in return. These represent your share of the pool. You can redeem them at any time to withdraw your portion of both tokens (at whatever the current ratio is). LP tokens are standard SPL tokens and show up in your wallet like any other token.
Every swap through the pool pays a small fee (typically 0.25%) that gets added back to the pool. This means your LP position grows over time as trades happen.
We use Raydium's CPMM (Constant Product Market Maker), which is the standard approach for meme coin liquidity on Solana. CPMM pools are standalone — they don't require creating an OpenBook market first (unlike Raydium's older AMM v4).
node create-pool.mjs --mint <TOKEN_ID> --token-amount 500 --sol-amount 5This will:
- Fetch token info and fee configs from the Raydium API
- Show a summary (amounts, initial price, protocol fee) and ask for confirmation
- Create the pool on-chain and print the pool ID and explorer links
The pool creation fee is ~0.15 SOL (Raydium protocol fee) plus rent.
Options:
| Flag | Description | Default |
|---|---|---|
--mint |
Token mint address to pair with SOL | (required) |
--token-amount |
Number of tokens to deposit | (required) |
--sol-amount |
Amount of SOL to deposit | (required) |
--keypair <path> |
Path to keypair JSON | ~/.config/solana/id.json |
--rpc <url> |
RPC endpoint | mainnet |
./pool-info.sh <POOL_ID>This queries the Raydium API and shows the pool composition, price, TVL, 24h volume, trade fees, and links to the explorer and Raydium UI.
Once the pool is live, your token is tradeable on Raydium and any aggregator that routes through Raydium (like Jupiter). Anyone with SOL can buy your token, and anyone holding your token can sell it.
You can swap BLLBK and SOL on Raydium's interface (select the CPMM pool) or with the CLI:
spl-token swap <AMOUNT_IN> <TOKEN_IN> <TOKEN_OUT> --pool <POOL_ID>This repo includes several shell and Node.js scripts that automate the token lifecycle.
End-to-end script that creates a new token, mints tokens, uploads the icon and metadata to Arweave, applies on-chain metadata, and optionally locks down the mint authority — all in one command.
./mint-token.sh --name "BillBak" --symbol "BLLBK" --amount 10000 --metadata ./bllbk/metadata.json --icon ./bllbk/icon.png| Flag | Description | Required |
|---|---|---|
--name |
Token name | Yes |
--symbol |
Token symbol/ticker | Yes |
--amount |
Number of tokens to mint | Yes |
--metadata |
Path to metadata JSON file | Yes |
--icon |
Path to icon PNG — uploads to Arweave and updates metadata | No |
The script runs pre-flight checks (tools installed, files exist, SOL balance), shows a summary, and asks for confirmation before proceeding. At the end it asks whether to permanently disable mint authority.
Queries the Raydium API and displays details for a CPMM liquidity pool: token pair, amounts, price, TVL, 24h volume, trade fees, LP mint, and links.
./pool-info.sh <POOL_ID>Verifies that each token's on-chain metadata URI and icon image URL point to Arweave (permanent storage) rather than GitHub or another host. Useful for confirming everything is on permanent storage before making the repo private.
./verify-tokens.sh --mint <TOKEN_MINT> --mint <TOKEN_MINT>Pass one or more --mint flags. The script fetches on-chain metadata, follows the URI to the metadata JSON, checks the image URL, and confirms each is reachable.
Lists all SPL token balances for a wallet, with token names looked up from on-chain metadata.
./wallet-balances.sh <WALLET_ADDRESS>Shows SOL balance plus all token holdings in a formatted table with name, balance, and mint address.