Monorepo for Aesthetic.Computer aesthetic.computer
at main 139 lines 4.9 kB view raw
1""" 2Deploy FA2 contract to Ghostnet using PyTezos (pure Python, no octez-client needed) 3""" 4 5import sys 6from pathlib import Path 7from pytezos import pytezos, Key 8 9# Load kidlisp wallet credentials 10vault_dir = Path(__file__).parent.parent / "aesthetic-computer-vault" / "tezos" / "kidlisp" 11env_file = vault_dir / ".env" 12 13KIDLISP_ADDRESS = None 14KIDLISP_KEY = None 15 16if env_file.exists(): 17 with open(env_file) as f: 18 for line in f: 19 if line.startswith('KIDLISP_ADDRESS='): 20 KIDLISP_ADDRESS = line.split('=')[1].strip().strip('"') 21 elif line.startswith('KIDLISP_KEY='): 22 KIDLISP_KEY = line.split('=')[1].strip().strip('"') 23 24if not KIDLISP_ADDRESS or not KIDLISP_KEY: 25 print("❌ Error: KIDLISP credentials not found in vault/tezos/kidlisp/.env") 26 sys.exit(1) 27 28# Ghostnet configuration 29GHOSTNET_RPC = "https://ghostnet.ecadinfra.com" 30 31 32def deploy_contract(): 33 print("=" * 70) 34 print("🚀 Deploying FA2 Contract to Ghostnet (PyTezos)") 35 print("=" * 70) 36 print() 37 38 # Connect to Ghostnet with kidlisp key 39 print("🔧 Connecting to Ghostnet...") 40 ptz = pytezos.using(shell=GHOSTNET_RPC, key=Key.from_encoded_key(KIDLISP_KEY)) 41 42 print(f" ✓ RPC: {GHOSTNET_RPC}") 43 print(f" ✓ Address: {ptz.key.public_key_hash()}") 44 45 # Check balance 46 print("\n💰 Checking balance...") 47 balance = ptz.balance() 48 balance_xtz = balance / 1_000_000 49 print(f" ✓ Balance: {balance_xtz:.6f} XTZ") 50 51 if balance_xtz < 1: 52 print(" ⚠️ Low balance! Get testnet tez from: https://faucet.ghostnet.teztnets.com/") 53 54 # Load contract 55 print("\n📄 Loading contract...") 56 contract_file = Path(__file__).parent / "michelson-lib" / "keeps-fa2-complete.tz" 57 58 if not contract_file.exists(): 59 print(f"❌ Contract file not found: {contract_file}") 60 sys.exit(1) 61 62 contract_code = contract_file.read_text() 63 print(f" ✓ Loaded: {contract_file.name}") 64 65 # Initial storage (Michelson format) 66 # Structure: (pair (pair address ledger) (pair next_token_id (pair operators token_metadata))) 67 admin_address = ptz.key.public_key_hash() 68 initial_storage = f'(Pair (Pair "{admin_address}" {{}}) (Pair 0 (Pair {{}} {{}})))' 69 70 print(f"\n💾 Initial storage:") 71 print(f" ✓ Administrator: {admin_address}") 72 print(f" ✓ Next token ID: 0") 73 74 # Deploy 75 print("\n📤 Deploying contract...") 76 print(" (This may take 1-2 minutes...)") 77 78 try: 79 # Originate 80 op = ptz.origination(script={ 81 'code': contract_code, 82 'storage': initial_storage 83 }).autofill().sign() 84 85 print(f" ⏳ Operation: {op.hash}") 86 print(" ⏳ Waiting for confirmation...") 87 88 # Inject and wait 89 result = op.inject(_async=False) 90 91 # Get contract address from result 92 contract_address = None 93 if hasattr(result, 'contents'): 94 for content in result.contents: 95 if hasattr(content, 'metadata') and content.metadata: 96 results = content.metadata.get('operation_result', {}).get('originated_contracts', []) 97 if results: 98 contract_address = results[0] 99 break 100 101 if not contract_address: 102 # Try to find from operation receipt 103 print("\n⚠️ Looking for contract address in operation receipt...") 104 op_result = ptz.shell.blocks['head'].operations[3][op.hash].get() 105 for content in op_result: 106 if 'metadata' in content: 107 results = content['metadata'].get('operation_result', {}).get('originated_contracts', []) 108 if results: 109 contract_address = results[0] 110 break 111 112 if contract_address: 113 print("\n" + "=" * 70) 114 print("✅ Contract Deployed Successfully!") 115 print("=" * 70) 116 print() 117 print(f"📍 Contract Address: {contract_address}") 118 print(f"🔍 View on TzKT: https://ghostnet.tzkt.io/{contract_address}") 119 print() 120 121 # Save contract address 122 address_file = Path(__file__).parent / "contract-address.txt" 123 address_file.write_text(contract_address) 124 print(f"💾 Saved to: {address_file}") 125 126 return contract_address 127 else: 128 print("\n⚠️ Deployment succeeded but couldn't extract contract address") 129 print(f" Check operation: https://ghostnet.tzkt.io/{op.hash}") 130 131 except Exception as e: 132 print(f"\n❌ Deployment failed: {e}") 133 import traceback 134 traceback.print_exc() 135 sys.exit(1) 136 137 138if __name__ == "__main__": 139 deploy_contract()