#!/usr/bin/env python3 """ Vector Zulu — KoreID Generator Generates KoreID display numbers per the KoreID Display Generation Specification. Format: /---- Example: 061925a1/b231f4e5-3487-0a1b-03e8-001540009abc S1 (8) = DDMMYY (6-digit UTC date) + CT (2-hex ID-type) S2 (8) = PT (2-hex parent ID-type) + T (1-hex parent treasury) + PNNNNN (5-hex parent network) S3 (4) = CCC (3-hex ISO currency) + CK (1-hex XOR checksum) S4 (4) = First 4 hex of current 8-hex network code S5 (4) = Last 4 hex of current 8-hex network code S6 (12) = PPPP (4-hex parent monthly seq) + T (1-hex current treasury) + CCCC (4-hex current monthly seq) + RRR (3-hex nonce) """ import os import uuid import hashlib import logging from datetime import datetime, timezone from functools import reduce log = logging.getLogger(__name__) # ── Lookup tables (placeholders — populate from Bryan's full spec) ──────────── # kore_id_type: maps event type names to 2-hex codes # TODO: replace with values from Bryan's kore_id_type SQL table ID_TYPES = { 'MINT': 'a1', # SV token mint event 'BURN': 'a2', # SV token burn/redemption event 'TRANSFER': 'a3', # SV token transfer event 'RESERVE': 'a4', # Reserve oracle update 'SWAP': 'a5', # Uniswap swap event 'ONRAMP': 'a6', # Fiat on-ramp 'OFFRAMP': 'a7', # Fiat off-ramp 'EXTERNAL': 'b1', # Generic external response } # kore_treasury: maps treasury names to 1-hex codes # TODO: replace with values from Bryan's kore_treasury SQL table TREASURIES = { 'VECTOR_ZULU': '1', 'SOVEREIGN_GLOBAL': '2', 'KORE_COLLECTIVE': '3', 'MERIDIAN': '4', } # kore_network: maps network names to 5-hex parent network codes # TODO: replace with values from Bryan's kore_network SQL table PARENT_NETWORKS = { 'KORECHAIN': 'f4e50', 'ETHEREUM': '0a1b0', 'AMITIS': '03e80', 'TRON': '00154', } # kore_network_current: maps network names to 8-hex current network codes # TODO: replace with values from Bryan's kore_network_current SQL table CURRENT_NETWORKS = { 'ETHEREUM': '0a1b03e8', 'AMITIS': '03e80015', 'KORECHAIN': 'f4e5b231', 'TRON': '001540ab', } # kore_currency: maps ISO currency codes to 3-hex values # TODO: replace with values from Bryan's kore_currency SQL table CURRENCIES = { 'USD': '001', 'GBP': '002', 'EUR': '003', 'CHF': '004', 'JPY': '005', 'SGD': '006', 'BTC': '010', 'ETH': '011', 'USDT': '012', 'USDC': '013', 'GPSC': '020', 'AMTS': '030', } # Parent ID type for VZ as a child of KoreChain PARENT_ID_TYPE = 'b2' # TODO: confirm with Bryan class KoreIDGenerator: """ Generates KoreID display numbers for events originating from Vector Zulu. Requires a sequence store (Postgres) for monthly sequence tracking. """ def __init__(self, pg_conn=None): self.pg = pg_conn def _xor_checksum(self, hex_string: str) -> str: """XOR all bytes of a hex string, return 1-hex result.""" bytes_list = [int(hex_string[i:i+2], 16) for i in range(0, len(hex_string), 2)] result = reduce(lambda a, b: a ^ b, bytes_list, 0) return format(result & 0xF, 'x') def _get_sequence(self, mmyy: str, id_type: str, treasury: str, network: str, currency: str) -> tuple[int, int]: """ Get or create monthly sequence entry. Returns (parent_seq, current_seq) — increments current_seq. Falls back to random if no DB connection. """ if not self.pg: import random return (random.randint(0, 0xFFFF), random.randint(0, 0xFFFF)) try: with self.pg.cursor() as cur: cur.execute(""" INSERT INTO kore_sequence (mmyy, ct, t, net, ccc, parent_seq, current_seq) VALUES (%s, %s, %s, %s, %s, 0, 1) ON CONFLICT (mmyy, ct, t, net, ccc) DO UPDATE SET current_seq = kore_sequence.current_seq + 1 RETURNING parent_seq, current_seq """, (mmyy, id_type, treasury, network, currency)) row = cur.fetchone() self.pg.commit() return (row[0], row[1]) except Exception as e: log.error(f"Sequence DB error: {e}") import random return (random.randint(0, 0xFFFF), random.randint(0, 0xFFFF)) def generate( self, event_type: str, currency: str, current_network: str = 'ETHEREUM', parent_network: str = 'KORECHAIN', treasury: str = 'VECTOR_ZULU', parent_treasury: str = 'KORE_COLLECTIVE', nonce: str = None, ) -> dict: """ Generate a KoreID for a Vector Zulu event. Returns dict with: - koreid: the display ID string - guid: UUIDv4 for internal storage - metadata: all components for traceability """ now = datetime.now(timezone.utc) mmyy = now.strftime('%m%y') ddmmyy = now.strftime('%d%m%y') # Resolve codes ct = ID_TYPES.get(event_type.upper(), 'ff') pt = PARENT_ID_TYPE t = TREASURIES.get(treasury.upper(), '0') pt_val = TREASURIES.get(parent_treasury.upper(), '0') pnnnnn = PARENT_NETWORKS.get(parent_network.upper(), '00000') ccc = CURRENCIES.get(currency.upper(), '000') net8 = CURRENT_NETWORKS.get(current_network.upper(), '00000000') # S1: DDMMYY + CT s1 = ddmmyy + ct # 8 chars # S2: PT + T(parent) + PNNNNN s2 = pt + pt_val + pnnnnn # 8 chars # S3: CCC + checksum ck = self._xor_checksum(ccc + '0') # XOR of currency bytes s3 = ccc + ck # 4 chars # S4 / S5: split current network code s4 = net8[:4] # 4 chars s5 = net8[4:] # 4 chars # S6: PPPP + T(current) + CCCC + RRR parent_seq, current_seq = self._get_sequence(mmyy, ct, t, pnnnnn, ccc) pppp = format(parent_seq & 0xFFFF, '04x') cccc = format(current_seq & 0xFFFF, '04x') if nonce is None: import random nonce = format(random.randint(0, 0xFFF), '03x') s6 = pppp + t + cccc + nonce # 12 chars koreid = f"{s1}/{s2}-{s3}-{s4}-{s5}-{s6}" guid = str(uuid.uuid4()) return { 'koreid': koreid, 'guid': guid, 'components': { 's1': s1, 's2': s2, 's3': s3, 's4': s4, 's5': s5, 's6': s6, }, 'metadata': { 'event_type': event_type, 'currency': currency, 'current_network': current_network, 'parent_network': parent_network, 'treasury': treasury, 'generated_at': now.isoformat(), 'id_type_code': ct, 'parent_seq': parent_seq, 'current_seq': current_seq, } } def wrap_ethereum_event( event_type: str, amount: float, currency: str, tx_hash: str, block_number: int, from_address: str, to_address: str, token_symbol: str, koreid_generator: KoreIDGenerator, linked_koreid: str = None, ) -> dict: """ Convert an Ethereum event into a KoreID-formatted payload for posting back to KoreChain via KoreOracle. Preserves full traceability per Bryan's spec: - KoreID reference - hash (TX hash) - signature (block + tx proof) - chain linkage """ kid = koreid_generator.generate( event_type=event_type, currency=currency, current_network='ETHEREUM', parent_network='KORECHAIN', ) payload = { 'koreid': kid['koreid'], 'guid': kid['guid'], 'value': amount, 'proof': { 'hash': tx_hash, 'block_number': block_number, 'chain_reference': kid['koreid'], 'network': 'ETHEREUM', 'network_code': CURRENT_NETWORKS.get('ETHEREUM'), }, 'source': { 'type': 'ETHEREUM_EVENT', 'event_type': event_type, 'token': token_symbol, 'from_address': from_address, 'to_address': to_address, 'tx_hash': tx_hash, }, 'linked_to': linked_koreid, 'generated_at': datetime.now(timezone.utc).isoformat(), } return payload if __name__ == '__main__': # Test generation gen = KoreIDGenerator() result = gen.generate('MINT', 'GBP', 'ETHEREUM', 'KORECHAIN', 'VECTOR_ZULU') print("Generated KoreID:", result['koreid']) print("GUID:", result['guid']) print("Components:", result['components']) # Test event wrapping payload = wrap_ethereum_event( event_type='MINT', amount=1000000.00, currency='GBP', tx_hash='0xabc123def456', block_number=25375588, from_address='0x0000000000000000000000000000000000000000', to_address='0x8B59352944134D6c2e175d92Bb07b25443163A53', token_symbol='SVGBP', koreid_generator=gen, ) import json print("\nWrapped payload:") print(json.dumps(payload, indent=2))