Source code for agora.webhook.events

import base64
import json
from typing import Optional

from agoraapi.common.v3 import model_pb2
from google.protobuf.json_format import Parse

from agora import solana
from agora.error import Error, InvalidSignatureError, BadNonceError, InsufficientBalanceError, AccountNotFoundError
from agora.model.invoice import InvoiceList


[docs]class SolanaEvent: """Solana event data related to a transaction. :param transaction: The :class:`Transaction <agora.solana.transaction.Transaction>` object. :param tx_error: (optional) The :class:`Error <agora.error.Error` indicating why the transaction failed. :param tx_error_raw: (optional) The raw transaction error. """ def __init__( self, transaction: solana.Transaction, tx_error: Optional[Error] = None, tx_error_raw: Optional[str] = None ): self.transaction = transaction self.tx_error = tx_error self.tx_error_raw = tx_error_raw
[docs] @classmethod def from_json(cls, data: dict) -> 'SolanaEvent': tx_string = data.get('transaction', "") if not tx_string: raise ValueError('`transaction` is required in Solana transaction events') return cls( solana.Transaction.unmarshal(base64.b64decode(tx_string)), tx_error=cls._convert_error(data.get('transaction_error', '')), tx_error_raw=data.get('transaction_error_raw', None), )
@staticmethod def _convert_error(e: str): if len(e) == 0 or e == 'none': return None if e == 'unknown': return Error(f'unknown error') if e == 'unauthorized': return InvalidSignatureError() if e == 'bad_nonce': return BadNonceError() if e == 'insufficient_funds': return InsufficientBalanceError() if e == 'invalid_account': return AccountNotFoundError() return Error(f'error: {e}')
[docs]class TransactionEvent: """An event indicating a transaction has completed (either successfully or unsuccessfully). :param tx_id: the id of the transaction. Either a 32-byte Stellar transaction hash or a 64-byte Solana transaction signature. :param solana_event: any Solana data related to the transaction. :param invoice_list: (optional) the InvoiceList related to the transaction. """ def __init__( self, tx_id: bytes, solana_event: SolanaEvent, invoice_list: InvoiceList = None, ): self.tx_id = tx_id self.invoice_list = invoice_list self.solana_event = solana_event
[docs] @classmethod def from_json(cls, data: dict) -> 'TransactionEvent': tx_id = base64.b64decode(data.get('tx_id')) if 'tx_id' in data else b'' if len(tx_id) == 0: raise ValueError('`tx_id` is required') il = data.get('invoice_list') if il: proto_il = Parse(json.dumps(il), model_pb2.InvoiceList()) invoice_list = InvoiceList.from_proto(proto_il) else: invoice_list = None solana_data = data.get('solana_event', None) if not solana_data: raise ValueError('`solana_event` is required') return cls(tx_id, SolanaEvent.from_json(solana_data), invoice_list=invoice_list)
[docs]class Event: """An event container for a specific type of event triggered by a blockchain operation. :param transaction_event: (optional) A :class:`TransactionEvent <TransactionEvent>`. """ def __init__(self, transaction_event: Optional['TransactionEvent'] = None): self.transaction_event = transaction_event
[docs] @classmethod def from_json(cls, data: dict) -> 'Event': tx_event_data = data.get('transaction_event') tx_event = TransactionEvent.from_json(tx_event_data) if tx_event_data else None return cls(transaction_event=tx_event)