repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources15d ago| #1 | #!/usr/bin/env python3 |
| #2 | """Create and manage Solana accounts using CDP (Coinbase Developer Platform)""" |
| #3 | |
| #4 | import sys |
| #5 | import argparse |
| #6 | |
| #7 | |
| #8 | def parse_args(): |
| #9 | """Parse command line arguments before importing CDP (which uses nest_asyncio).""" |
| #10 | parser = argparse.ArgumentParser( |
| #11 | description="Create and manage Solana accounts using CDP", |
| #12 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| #13 | epilog=""" |
| #14 | Examples: |
| #15 | # Create a new account |
| #16 | python create_solana_account.py create |
| #17 | |
| #18 | # Create a named account |
| #19 | python create_solana_account.py create --name my-trading-wallet |
| #20 | |
| #21 | # List all accounts |
| #22 | python create_solana_account.py list |
| #23 | |
| #24 | # Get balance |
| #25 | python create_solana_account.py balance <address> |
| #26 | |
| #27 | # Request devnet faucet (devnet only) |
| #28 | python create_solana_account.py faucet <address> |
| #29 | |
| #30 | # Send SOL |
| #31 | python create_solana_account.py send <from> <to> --lamports 1000 |
| #32 | |
| #33 | Environment Variables (in .env.local): |
| #34 | CDP_API_KEY_ID - Your CDP API Key ID |
| #35 | CDP_API_KEY_SECRET - Your CDP API Key Secret (Ed25519 base64) |
| #36 | CDP_WALLET_SECRET - Optional wallet secret for signing |
| #37 | CDP_NETWORK - "solana-mainnet" (default) or "solana-devnet" |
| #38 | CDP_RPC_URL - Custom RPC URL (optional) |
| #39 | |
| #40 | Get credentials at: https://portal.cdp.coinbase.com/projects/api-keys |
| #41 | """ |
| #42 | ) |
| #43 | |
| #44 | subparsers = parser.add_subparsers(dest="command", help="Command to run") |
| #45 | |
| #46 | # Create command |
| #47 | create_parser = subparsers.add_parser("create", help="Create a new Solana account") |
| #48 | create_parser.add_argument("--name", "-n", help="Optional name for the account (2-36 chars)") |
| #49 | |
| #50 | # List command |
| #51 | subparsers.add_parser("list", help="List all CDP Solana accounts") |
| #52 | |
| #53 | # Balance command |
| #54 | balance_parser = subparsers.add_parser("balance", help="Get SOL balance for an address") |
| #55 | balance_parser.add_argument("address", help="Solana address") |
| #56 | |
| #57 | # Faucet command |
| #58 | faucet_parser = subparsers.add_parser("faucet", help="Request devnet faucet funds") |
| #59 | faucet_parser.add_argument("address", help="Solana address to fund") |
| #60 | |
| #61 | # Send command |
| #62 | send_parser = subparsers.add_parser("send", help="Send SOL to another address") |
| #63 | send_parser.add_argument("from_address", help="Sender address (CDP-managed)") |
| #64 | send_parser.add_argument("to_address", help="Recipient address") |
| #65 | send_parser.add_argument("--lamports", "-l", type=int, default=1000, help="Amount in lamports (default: 1000)") |
| #66 | |
| #67 | return parser.parse_args(), parser |
| #68 | |
| #69 | |
| #70 | # Parse args BEFORE importing CDP (which imports nest_asyncio) |
| #71 | args, parser = parse_args() |
| #72 | |
| #73 | if not args.command: |
| #74 | parser.print_help() |
| #75 | sys.exit(0) |
| #76 | |
| #77 | # Now import the rest (CDP imports nest_asyncio) |
| #78 | import asyncio |
| #79 | from config import load_config |
| #80 | from clients.cdp_client import CDPSolanaClient, CDP_AVAILABLE |
| #81 | |
| #82 | |
| #83 | async def create_account(client: CDPSolanaClient, name: str = None): |
| #84 | """Create a new Solana account.""" |
| #85 | print("\n📦 Creating new Solana account...") |
| #86 | |
| #87 | account = await client.create_account(name=name) |
| #88 | |
| #89 | print(f"\n✅ Account created successfully!") |
| #90 | print(f" Address: {account['address']}") |
| #91 | if account.get('name'): |
| #92 | print(f" Name: {account['name']}") |
| #93 | |
| #94 | return account |
| #95 | |
| #96 | |
| #97 | async def list_accounts(client: CDPSolanaClient): |
| #98 | """List all CDP Solana accounts.""" |
| #99 | print("\n📋 Listing all CDP Solana accounts...") |
| #100 | |
| #101 | accounts = await client.list_accounts() |
| #102 | |
| #103 | if not accounts: |
| #104 | print(" No accounts found.") |
| #105 | return |
| #106 | |
| #107 | print(f"\n Found {len(accounts)} account(s):") |
| #108 | for acc in accounts: |
| #109 | name = acc.get('name') or '(unnamed)' |
| #110 | print(f" • {acc['address']} - {name}") |
| #111 | |
| #112 | return accounts |
| #113 | |
| #114 | |
| #115 | async def get_balance(client: CDPSolanaClient, address: str): |
| #116 | """Get balance for an address.""" |
| #117 | print(f"\n💰 Getting balance for {address}...") |
| #118 | |
| #119 | balance = await client.get_balance(address) |
| #120 | |
| #121 | print(f" Balance: {balance['balance_sol']:.9f} SOL ({balance['balance_lamports']} lamports)") |
| #122 | |
| #123 | return balance |
| #124 | |
| #125 | |
| #126 | async def request_faucet(client: CDPSolanaClient, address: str): |
| #127 | """Request devnet faucet funds.""" |
| #128 | print(f"\n🚰 Requesting faucet funds for {address}...") |
| #129 | |
| #130 | result = await client.request_faucet(address) |
| #131 | |
| #132 | print(f" ✅ Faucet request successful!") |
| #133 | print(f" Transaction: {result['explorer_url']}") |
| #134 | |
| #135 | # Wait for balance |
| #136 | print(" Waiting for funds to arrive...") |
| #137 | balance = await client.wait_for_balance(address) |
| #138 | print(f" Balance: {balance['balance_sol']:.9f} SOL") |
| #139 | |
| #140 | return result |
| #141 | |
| #142 | |
| #143 | async def send_sol(client: CDPSolanaClient, from_address: str, to_address: str, lamports: int): |
| #144 | """Send SOL from one address to another.""" |
| #145 | print(f"\n📤 Sending {lamports} lamports ({lamports/1e9:.9f} SOL)...") |
| #146 | print(f" From: {from_address}") |
| #147 | print(f" To: {to_address}") |
| #148 | |
| #149 | result = await client.send_sol(from_address, to_address, lamports) |
| #150 | |
| #151 | print(f"\n ✅ Transaction successful!") |
| #152 | print(f" Signature: {result['signature']}") |
| #153 | print(f" Explorer: {result['explorer_url']}") |
| #154 | |
| #155 | return result |
| #156 | |
| #157 | |
| #158 | async def main(): |
| #159 | # Check CDP availability |
| #160 | if not CDP_AVAILABLE: |
| #161 | print("❌ CDP SDK not installed. Run: pip install cdp-sdk") |
| #162 | return |
| #163 | |
| #164 | # Load config |
| #165 | try: |
| #166 | config = load_config() |
| #167 | except ValueError as e: |
| #168 | print(f"❌ Config error: {e}") |
| #169 | return |
| #170 | |
| #171 | # Check CDP credentials |
| #172 | if not config.cdp_api_key_id or not config.cdp_api_key_secret: |
| #173 | print("❌ CDP credentials not configured.") |
| #174 | print(" Add to .env.local:") |
| #175 | print(" CDP_API_KEY_ID=your_key_id") |
| #176 | print(" CDP_API_KEY_SECRET=your_secret") |
| #177 | print("\n Get credentials at: https://portal.cdp.coinbase.com/projects/api-keys") |
| #178 | return |
| #179 | |
| #180 | # Initialize client |
| #181 | print(f"🔗 Connecting to {config.cdp_network}...") |
| #182 | |
| #183 | client = CDPSolanaClient( |
| #184 | api_key_id=config.cdp_api_key_id, |
| #185 | api_key_secret=config.cdp_api_key_secret, |
| #186 | wallet_secret=config.cdp_wallet_secret, |
| #187 | rpc_url=config.cdp_rpc_url, |
| #188 | network=config.cdp_network, |
| #189 | ) |
| #190 | |
| #191 | try: |
| #192 | if args.command == "create": |
| #193 | account = await create_account(client, name=args.name) |
| #194 | |
| #195 | if config.cdp_network == "solana-mainnet": |
| #196 | print(f"\n⚠️ This is a MAINNET account.") |
| #197 | print(f" Send SOL to {account['address']} to fund it.") |
| #198 | print(f" Faucet is NOT available on mainnet.") |
| #199 | else: |
| #200 | print(f"\n💡 This is a DEVNET account.") |
| #201 | print(f" Use 'python create_solana_account.py faucet {account['address']}' to get test SOL.") |
| #202 | |
| #203 | elif args.command == "list": |
| #204 | await list_accounts(client) |
| #205 | |
| #206 | elif args.command == "balance": |
| #207 | await get_balance(client, args.address) |
| #208 | |
| #209 | elif args.command == "faucet": |
| #210 | await request_faucet(client, args.address) |
| #211 | |
| #212 | elif args.command == "send": |
| #213 | await send_sol(client, args.from_address, args.to_address, args.lamports) |
| #214 | |
| #215 | finally: |
| #216 | await client.close() |
| #217 | |
| #218 | |
| #219 | if __name__ == "__main__": |
| #220 | asyncio.run(main()) |
| #221 |