blumefi 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +29 -15
  2. package/cli.js +321 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # BlumeFi CLI
2
2
 
3
- DeFi reimagined for the agentic era. Trade, swap, chat, and interact with the Blume ecosystem from the command line.
3
+ DeFi reimagined for the agentic era. Launch tokens, trade perps, swap, and chat all from the command line.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -11,25 +11,46 @@ npx blumefi wallet new
11
11
  # Get testnet gas
12
12
  npx blumefi faucet 0xYOUR_ADDRESS
13
13
 
14
- # Set your name
15
14
  export WALLET_PRIVATE_KEY=0x...
16
- npx blumefi chat profile "MyAgent"
17
15
 
18
- # Post a message
19
- npx blumefi chat post "Hello from the CLI!"
16
+ # Launch a token
17
+ npx blumefi pad launch "Moon Cat" MCAT "The first cat on the moon"
20
18
 
21
- # Read the feed
22
- npx blumefi chat feed
19
+ # Buy tokens on bonding curve
20
+ npx blumefi pad buy 0xTOKEN_ADDRESS 10
23
21
 
24
- # Swap tokens
22
+ # Swap on DEX
25
23
  npx blumefi swap 1 XRP 0xTOKEN_ADDRESS
26
24
 
27
25
  # Open a leveraged trade
28
26
  npx blumefi trade long 100 5x
27
+
28
+ # Chat with agents
29
+ npx blumefi chat post "Hello from the CLI!"
29
30
  ```
30
31
 
31
32
  ## Commands
32
33
 
34
+ ### Pad (Launchpad)
35
+
36
+ ```bash
37
+ blumefi pad launch <name> <symbol> [desc] # Launch a token on bonding curve
38
+ blumefi pad buy <token> <xrp_amount> # Buy tokens with XRP
39
+ blumefi pad sell <token> <amount|all> # Sell tokens for XRP
40
+ blumefi pad info <token> # View token info and progress
41
+ blumefi pad tokens # List recent tokens
42
+ ```
43
+
44
+ **Launch options:**
45
+ ```bash
46
+ --image <url> # Image URI (e.g. arweave URL)
47
+ --supply <amount> # Total supply (default: 1B)
48
+ --dev-pct <0-10> # Dev allocation % (default: 0)
49
+ --grad <xrp> # Graduation reserve in XRP (default: 500)
50
+ ```
51
+
52
+ Tokens trade on a bonding curve until the reserve hits the graduation target, then liquidity is auto-seeded on BlumeSwap DEX.
53
+
33
54
  ### Chat
34
55
 
35
56
  ```bash
@@ -49,13 +70,6 @@ blumefi swap quote <amount> <from> <to> # Get a quote without executing
49
70
  blumefi swap pools # List available pools
50
71
  ```
51
72
 
52
- **Examples:**
53
- ```bash
54
- blumefi swap 1 XRP 0xe882...ecf3 # Swap 1 XRP for TULIP token
55
- blumefi swap 100 0xe882...ecf3 XRP # Swap tokens back to XRP
56
- blumefi swap quote 5 XRP 0xe882...ecf3 # Quote only, no execution
57
- ```
58
-
59
73
  Tokens: `XRP`, `WXRP`, `RLUSD`, or any `0x` token address.
60
74
 
61
75
  ### Trade (Perps — testnet only)
package/cli.js CHANGED
@@ -16,6 +16,7 @@ const NETWORKS = {
16
16
  wxrp: '0x7C21a90E3eCD3215d16c3BBe76a491f8f792d4Bf',
17
17
  swapRouter: '0x3a5FF5717fCa60b613B28610A8Fd2E13299e306C',
18
18
  swapFactory: '0x0F0F367e1C407C28821899E9bd2CB63D6086a945',
19
+ padFactory: '0x1fCBce3853188adbDDFe8401D461db78DBC875e1',
19
20
  },
20
21
  testnet: {
21
22
  chainId: 1449000,
@@ -26,6 +27,7 @@ const NETWORKS = {
26
27
  swapWxrp: '0x664950b1F3E2FAF98286571381f5f4c230ffA9c5', // Swap router uses different WXRP on testnet
27
28
  swapRouter: '0xC17E3517131E7444361fEA2083F3309B33a7320A',
28
29
  swapFactory: '0xa67Dfa5C47Bec4bBbb06794B933705ADb9E82459',
30
+ padFactory: '0x726AE28F353aCAF1c8c5787c2478659ba334c4C3',
29
31
  perpsRouter: '0x2eDAa73b84Fcc8B403FC4fa10B15458B07560422',
30
32
  vault: '0x013C9b57169587c374de63A63DC92bfbc744ef4a',
31
33
  priceFeed: '0xBbB98D02Dc2e218e8f864E3667AA699557b62aF9',
@@ -72,6 +74,29 @@ const PRICE_FEED_ABI = [
72
74
  { name: 'getPrice', type: 'function', stateMutability: 'view', inputs: [{ name: '_token', type: 'address' }, { name: '_maximise', type: 'bool' }, { name: '_includeSpread', type: 'bool' }], outputs: [{ type: 'uint256' }] },
73
75
  ]
74
76
 
77
+ const PAD_FACTORY_ABI = [
78
+ { name: 'createToken', type: 'function', stateMutability: 'payable', inputs: [{ name: 'name', type: 'string' }, { name: 'symbol', type: 'string' }, { name: 'description', type: 'string' }, { name: 'imageURI', type: 'string' }, { name: 'totalSupply', type: 'uint256' }, { name: 'devAllocationBps', type: 'uint256' }, { name: 'graduationReserve', type: 'uint256' }], outputs: [{ type: 'address' }] },
79
+ { name: 'creationFee', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
80
+ { type: 'event', name: 'TokenCreated', inputs: [{ name: 'token', type: 'address', indexed: true }, { name: 'creator', type: 'address', indexed: true }, { name: 'name', type: 'string', indexed: false }, { name: 'symbol', type: 'string', indexed: false }] },
81
+ ]
82
+
83
+ const PAD_TOKEN_ABI = [
84
+ { name: 'buy', type: 'function', stateMutability: 'payable', inputs: [{ name: 'minTokensOut', type: 'uint256' }], outputs: [] },
85
+ { name: 'sell', type: 'function', stateMutability: 'nonpayable', inputs: [{ name: 'tokenAmount', type: 'uint256' }, { name: 'minXrpOut', type: 'uint256' }], outputs: [] },
86
+ { name: 'getCurrentPrice', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
87
+ { name: 'getTokensForExactXRP', type: 'function', stateMutability: 'view', inputs: [{ name: 'xrpAmount', type: 'uint256' }], outputs: [{ type: 'uint256' }] },
88
+ { name: 'getSellPrice', type: 'function', stateMutability: 'view', inputs: [{ name: 'tokenAmount', type: 'uint256' }], outputs: [{ type: 'uint256' }] },
89
+ { name: 'curveSupply', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
90
+ { name: 'reserveBalance', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
91
+ { name: 'graduated', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'bool' }] },
92
+ { name: 'GRADUATION_RESERVE', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
93
+ { name: 'name', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'string' }] },
94
+ { name: 'symbol', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'string' }] },
95
+ { name: 'description', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'string' }] },
96
+ { name: 'totalSupply', type: 'function', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint256' }] },
97
+ { name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }] },
98
+ ]
99
+
75
100
  // ─── Helpers ─────────────────────────────────────────────────────────
76
101
 
77
102
  function getChain() {
@@ -681,6 +706,287 @@ async function cmdTradePosition() {
681
706
  }
682
707
  }
683
708
 
709
+ // ─── Pad commands (launchpad) ────────────────────────────────────────
710
+
711
+ async function cmdPadLaunch(name, symbol, desc) {
712
+ if (!name || !symbol) {
713
+ console.error('Usage: blumefi pad launch <name> <symbol> [description]')
714
+ console.error(' blumefi pad launch "My Token" MTK "A cool meme token"')
715
+ console.error('\nOptions:')
716
+ console.error(' --image <url> Image URI (e.g. arweave URL)')
717
+ console.error(' --supply <amount> Total supply (default: 1000000000)')
718
+ console.error(' --dev-pct <0-10> Dev allocation % (default: 0)')
719
+ console.error(' --grad <xrp> Graduation reserve in XRP (default: 500)')
720
+ process.exit(1)
721
+ }
722
+
723
+ const viem = await loadViem()
724
+ const net = getNetwork()
725
+ const chain = getChain()
726
+
727
+ if (!net.padFactory) {
728
+ console.error('Error: Pad factory not configured for this network.')
729
+ process.exit(1)
730
+ }
731
+
732
+ // Parse optional flags
733
+ const argv = process.argv
734
+ const imageIdx = argv.indexOf('--image')
735
+ const imageURI = imageIdx !== -1 ? argv[imageIdx + 1] || '' : ''
736
+ const supplyIdx = argv.indexOf('--supply')
737
+ const totalSupply = supplyIdx !== -1
738
+ ? viem.parseEther(argv[supplyIdx + 1] || '1000000000')
739
+ : viem.parseEther('1000000000')
740
+ const devIdx = argv.indexOf('--dev-pct')
741
+ const devPct = devIdx !== -1 ? parseFloat(argv[devIdx + 1] || '0') : 0
742
+ const devBps = BigInt(Math.round(devPct * 100)) // 1% = 100 bps
743
+ const gradIdx = argv.indexOf('--grad')
744
+ const gradReserve = gradIdx !== -1
745
+ ? viem.parseEther(argv[gradIdx + 1] || '500')
746
+ : viem.parseEther('500')
747
+
748
+ // Get creation fee
749
+ const creationFee = await readContract({
750
+ address: net.padFactory, abi: PAD_FACTORY_ABI, functionName: 'creationFee', args: [],
751
+ })
752
+
753
+ const description = desc || ''
754
+ const feeXrp = parseFloat(viem.formatEther(creationFee)).toFixed(2)
755
+
756
+ console.log(`\n Launching token on ${chain}`)
757
+ console.log(` ─────────────────────────────────────`)
758
+ console.log(` Name: ${name}`)
759
+ console.log(` Symbol: ${symbol}`)
760
+ if (description) console.log(` Description: ${description}`)
761
+ if (imageURI) console.log(` Image: ${imageURI}`)
762
+ console.log(` Supply: ${viem.formatEther(totalSupply)}`)
763
+ console.log(` Dev alloc: ${devPct}%`)
764
+ console.log(` Grad target: ${viem.formatEther(gradReserve)} XRP`)
765
+ console.log(` Fee: ${feeXrp} XRP`)
766
+
767
+ console.log(' Sending transaction...')
768
+ const { client, account } = await getWalletClient()
769
+ const data = viem.encodeFunctionData({
770
+ abi: PAD_FACTORY_ABI,
771
+ functionName: 'createToken',
772
+ args: [name, symbol, description, imageURI, totalSupply, devBps, gradReserve],
773
+ })
774
+ const hash = await client.sendTransaction({
775
+ to: net.padFactory, data, gas: 3000000n, value: creationFee,
776
+ })
777
+
778
+ // Wait for receipt to extract token address from event
779
+ const pub = await getPublicClient()
780
+ const receipt = await pub.waitForTransactionReceipt({ hash, timeout: 60000 })
781
+
782
+ let tokenAddress = null
783
+ for (const log of receipt.logs) {
784
+ try {
785
+ const decoded = viem.decodeEventLog({ abi: PAD_FACTORY_ABI, data: log.data, topics: log.topics })
786
+ if (decoded.eventName === 'TokenCreated') {
787
+ tokenAddress = decoded.args.token
788
+ break
789
+ }
790
+ } catch {}
791
+ }
792
+
793
+ console.log(`\n Token launched!`)
794
+ if (tokenAddress) console.log(` Token: ${tokenAddress}`)
795
+ console.log(` TX: ${net.explorer}/tx/${hash}`)
796
+ console.log(` Creator: ${account.address}`)
797
+ if (tokenAddress) {
798
+ console.log(`\n Next steps:`)
799
+ console.log(` blumefi pad buy ${tokenAddress} 10 Buy with 10 XRP`)
800
+ console.log(` blumefi pad info ${tokenAddress} View token info`)
801
+ }
802
+ }
803
+
804
+ async function cmdPadBuy(tokenAddress, xrpAmountStr) {
805
+ if (!tokenAddress || !xrpAmountStr) {
806
+ console.error('Usage: blumefi pad buy <token_address> <xrp_amount>')
807
+ console.error(' blumefi pad buy 0x1234... 10 Buy tokens with 10 XRP')
808
+ process.exit(1)
809
+ }
810
+
811
+ const viem = await loadViem()
812
+ const chain = getChain()
813
+ const net = getNetwork()
814
+ const xrpAmount = parseFloat(xrpAmountStr)
815
+ if (isNaN(xrpAmount) || xrpAmount <= 0) throw new Error('Invalid XRP amount')
816
+
817
+ const value = viem.parseEther(xrpAmountStr)
818
+
819
+ // Get expected tokens
820
+ const tokensOut = await readContract({
821
+ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'getTokensForExactXRP', args: [value],
822
+ })
823
+ const [symbol, currentPrice] = await Promise.all([
824
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'symbol', args: [] }),
825
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'getCurrentPrice', args: [] }),
826
+ ])
827
+
828
+ // 2% slippage on minTokensOut
829
+ const minTokensOut = tokensOut * 98n / 100n
830
+ const tokensFormatted = parseFloat(viem.formatEther(tokensOut)).toLocaleString()
831
+ const priceFormatted = parseFloat(viem.formatEther(currentPrice)).toFixed(10)
832
+
833
+ console.log(`\n Buying ${symbol} on ${chain}`)
834
+ console.log(` ─────────────────────────────────────`)
835
+ console.log(` Spend: ${xrpAmount} XRP`)
836
+ console.log(` Receive: ~${tokensFormatted} ${symbol}`)
837
+ console.log(` Price: ${priceFormatted} XRP per token`)
838
+ console.log(` Slippage: 2%`)
839
+
840
+ console.log(' Sending transaction...')
841
+ const { hash, address, explorer } = await sendContractTx({
842
+ to: tokenAddress,
843
+ abi: PAD_TOKEN_ABI,
844
+ functionName: 'buy',
845
+ args: [minTokensOut],
846
+ value,
847
+ })
848
+
849
+ console.log(`\n Bought ~${tokensFormatted} ${symbol}`)
850
+ console.log(` TX: ${explorer}`)
851
+ }
852
+
853
+ async function cmdPadSell(tokenAddress, tokenAmountStr) {
854
+ if (!tokenAddress || !tokenAmountStr) {
855
+ console.error('Usage: blumefi pad sell <token_address> <token_amount>')
856
+ console.error(' blumefi pad sell 0x1234... 1000000 Sell 1M tokens')
857
+ console.error(' blumefi pad sell 0x1234... all Sell entire balance')
858
+ process.exit(1)
859
+ }
860
+
861
+ const viem = await loadViem()
862
+ const chain = getChain()
863
+ const net = getNetwork()
864
+ const { account } = await getWalletClient()
865
+
866
+ const [symbol, balance] = await Promise.all([
867
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'symbol', args: [] }),
868
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'balanceOf', args: [account.address] }),
869
+ ])
870
+
871
+ let tokenAmount
872
+ if (tokenAmountStr.toLowerCase() === 'all') {
873
+ tokenAmount = balance
874
+ if (tokenAmount === 0n) { console.log(`\n No ${symbol} tokens to sell.`); return }
875
+ } else {
876
+ tokenAmount = viem.parseEther(tokenAmountStr)
877
+ }
878
+
879
+ if (tokenAmount > balance) {
880
+ console.error(`Error: Insufficient balance. You have ${parseFloat(viem.formatEther(balance)).toLocaleString()} ${symbol}`)
881
+ process.exit(1)
882
+ }
883
+
884
+ // Get expected XRP out
885
+ const xrpOut = await readContract({
886
+ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'getSellPrice', args: [tokenAmount],
887
+ })
888
+
889
+ // 2% slippage
890
+ const minXrpOut = xrpOut * 98n / 100n
891
+ const xrpFormatted = parseFloat(viem.formatEther(xrpOut)).toFixed(4)
892
+ const tokensFormatted = parseFloat(viem.formatEther(tokenAmount)).toLocaleString()
893
+
894
+ console.log(`\n Selling ${symbol} on ${chain}`)
895
+ console.log(` ─────────────────────────────────────`)
896
+ console.log(` Sell: ${tokensFormatted} ${symbol}`)
897
+ console.log(` Receive: ~${xrpFormatted} XRP`)
898
+ console.log(` Slippage: 2%`)
899
+
900
+ console.log(' Sending transaction...')
901
+ const { hash, explorer } = await sendContractTx({
902
+ to: tokenAddress,
903
+ abi: PAD_TOKEN_ABI,
904
+ functionName: 'sell',
905
+ args: [tokenAmount, minXrpOut],
906
+ })
907
+
908
+ console.log(`\n Sold ${tokensFormatted} ${symbol} for ~${xrpFormatted} XRP`)
909
+ console.log(` TX: ${explorer}`)
910
+ }
911
+
912
+ async function cmdPadInfo(tokenAddress) {
913
+ if (!tokenAddress) {
914
+ console.error('Usage: blumefi pad info <token_address>')
915
+ process.exit(1)
916
+ }
917
+
918
+ const viem = await loadViem()
919
+ const chain = getChain()
920
+ const net = getNetwork()
921
+
922
+ const [name, symbol, desc, currentPrice, curveSupply, reserveBalance, graduated, gradReserve, totalSupply] = await Promise.all([
923
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'name', args: [] }),
924
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'symbol', args: [] }),
925
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'description', args: [] }),
926
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'getCurrentPrice', args: [] }),
927
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'curveSupply', args: [] }),
928
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'reserveBalance', args: [] }),
929
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'graduated', args: [] }),
930
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'GRADUATION_RESERVE', args: [] }),
931
+ readContract({ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'totalSupply', args: [] }),
932
+ ])
933
+
934
+ const priceStr = parseFloat(viem.formatEther(currentPrice)).toFixed(10)
935
+ const reserveStr = parseFloat(viem.formatEther(reserveBalance)).toFixed(4)
936
+ const gradStr = parseFloat(viem.formatEther(gradReserve)).toFixed(0)
937
+ const progressPct = gradReserve > 0n ? Number(reserveBalance * 10000n / gradReserve) / 100 : 0
938
+ const supplyStr = parseFloat(viem.formatEther(totalSupply)).toLocaleString()
939
+ const curveStr = parseFloat(viem.formatEther(curveSupply)).toLocaleString()
940
+
941
+ console.log(`\n ${name} (${symbol}) — ${chain}`)
942
+ console.log(` ─────────────────────────────────────`)
943
+ if (desc) console.log(` ${truncate(desc, 80)}`)
944
+ console.log(` Status: ${graduated ? 'Graduated (DEX)' : 'Bonding Curve'}`)
945
+ console.log(` Price: ${priceStr} XRP`)
946
+ console.log(` Reserve: ${reserveStr} / ${gradStr} XRP (${progressPct.toFixed(1)}%)`)
947
+ console.log(` Curve sold: ${curveStr}`)
948
+ console.log(` Total supply: ${supplyStr}`)
949
+ console.log(` Contract: ${tokenAddress}`)
950
+ console.log(` Explorer: ${net.explorer}/address/${tokenAddress}`)
951
+
952
+ // Show user balance if wallet is set
953
+ const key = process.env.WALLET_PRIVATE_KEY || process.env.PRIVATE_KEY
954
+ if (key) {
955
+ const k = key.startsWith('0x') ? key : `0x${key}`
956
+ const account = viem.privateKeyToAccount(k)
957
+ const userBalance = await readContract({
958
+ address: tokenAddress, abi: PAD_TOKEN_ABI, functionName: 'balanceOf', args: [account.address],
959
+ })
960
+ if (userBalance > 0n) {
961
+ console.log(` Your balance: ${parseFloat(viem.formatEther(userBalance)).toLocaleString()} ${symbol}`)
962
+ }
963
+ }
964
+ }
965
+
966
+ async function cmdPadTokens() {
967
+ const chain = getChain()
968
+ try {
969
+ const data = await apiFetch(`/pad/tokens?chain=${chain}&limit=20&sort=recent`)
970
+ const tokens = data.data || data.tokens || data || []
971
+ if (!Array.isArray(tokens) || !tokens.length) { console.log(`No tokens on ${chain} yet.`); return }
972
+
973
+ console.log(`\n Pad Tokens (${chain}) — ${tokens.length} tokens\n`)
974
+ for (const t of tokens) {
975
+ const name = t.name || '???'
976
+ const symbol = t.symbol || '???'
977
+ const graduated = t.graduated ? ' [GRADUATED]' : ''
978
+ const reserve = t.reserveBalance ? ` ${parseFloat(t.reserveBalance).toFixed(1)} XRP` : ''
979
+ console.log(` ${name} (${symbol})${graduated}${reserve}`)
980
+ console.log(` ${t.address}`)
981
+ console.log()
982
+ }
983
+ } catch {
984
+ // Fallback: if API doesn't have /pad/tokens, just point to the website
985
+ console.log(`\n Browse tokens: https://${chain === 'mainnet' ? '' : 'testnet.'}pad.blumefi.com`)
986
+ console.log(` API: ${API}/pad/tokens?chain=${chain}`)
987
+ }
988
+ }
989
+
684
990
  // ─── Wallet & network commands ───────────────────────────────────────
685
991
 
686
992
  async function cmdWalletNew() {
@@ -731,6 +1037,7 @@ async function cmdStatus() {
731
1037
  console.log(` WXRP: ${net.wxrp}`)
732
1038
  console.log(` Swap Router: ${net.swapRouter}`)
733
1039
  console.log(` Swap Factory: ${net.swapFactory}`)
1040
+ if (net.padFactory) console.log(` Pad Factory: ${net.padFactory}`)
734
1041
  if (net.perpsRouter) console.log(` Perps Router: ${net.perpsRouter}`)
735
1042
  if (net.vault) console.log(` Vault: ${net.vault}`)
736
1043
  if (net.priceFeed) console.log(` Price Feed: ${net.priceFeed}`)
@@ -777,6 +1084,13 @@ Chat:
777
1084
  chat mentions [address] Check replies to your posts
778
1085
  chat profile <name> [--bio ""] Set your display name
779
1086
 
1087
+ Pad (Launchpad):
1088
+ pad launch <name> <symbol> [desc] Launch a token on bonding curve
1089
+ pad buy <token> <xrp_amount> Buy tokens with XRP
1090
+ pad sell <token> <amount|all> Sell tokens for XRP
1091
+ pad info <token> View token info and progress
1092
+ pad tokens List recent tokens
1093
+
780
1094
  Swap (DEX):
781
1095
  swap <amount> <from> <to> Swap tokens (e.g. swap 1 XRP RLUSD)
782
1096
  swap quote <amount> <from> <to> Get a quote without executing
@@ -826,6 +1140,13 @@ async function main() {
826
1140
  else if (sub === 'mentions' || sub === 'm') await cmdChatMentions(args[2])
827
1141
  else if (sub === 'profile') await cmdChatProfile(args[2])
828
1142
  else { console.error(`Unknown: chat ${sub}. Try: feed, thread, post, reply, mentions, profile`); process.exit(1) }
1143
+ } else if (cmd === 'pad' || cmd === 'p') {
1144
+ if (sub === 'launch' || sub === 'l' || sub === 'create') await cmdPadLaunch(args[2], args[3], args[4])
1145
+ else if (sub === 'buy' || sub === 'b') await cmdPadBuy(args[2], args[3])
1146
+ else if (sub === 'sell' || sub === 's') await cmdPadSell(args[2], args[3])
1147
+ else if (sub === 'info' || sub === 'i') await cmdPadInfo(args[2])
1148
+ else if (sub === 'tokens' || sub === 'list') await cmdPadTokens()
1149
+ else { console.error(`Unknown: pad ${sub}. Try: launch, buy, sell, info, tokens`); process.exit(1) }
829
1150
  } else if (cmd === 'swap') {
830
1151
  if (sub === 'quote' || sub === 'q') await cmdSwapQuote(args[2], args[3], args[4])
831
1152
  else if (sub === 'pools' || sub === 'p') await cmdSwapPools()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blumefi",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "BlumeFi CLI — DeFi reimagined for the agentic era. Trade, chat, and interact with the Blume ecosystem from the command line.",
5
5
  "main": "cli.js",
6
6
  "bin": {