|
| 1 | +import { erc20FeeProxyArtifact } from '@requestnetwork/smart-contracts'; |
| 2 | +import { |
| 3 | + CurrencyTypes, |
| 4 | + ExtensionTypes, |
| 5 | + PaymentTypes, |
| 6 | + RequestLogicTypes, |
| 7 | +} from '@requestnetwork/types'; |
| 8 | +import { TronChains, isSameChain } from '@requestnetwork/currency'; |
| 9 | + |
| 10 | +import { ERC20FeeProxyPaymentDetectorBase } from '../erc20/fee-proxy-contract'; |
| 11 | +import { NetworkNotSupported } from '../balance-error'; |
| 12 | +import { ReferenceBasedDetectorOptions, TGetSubGraphClient } from '../types'; |
| 13 | +import { TronInfoRetriever, TronPaymentEvent } from './tron-info-retriever'; |
| 14 | +import { TheGraphClient } from '../thegraph'; |
| 15 | + |
| 16 | +/** |
| 17 | + * Handle payment networks with ERC20 fee proxy contract extension on TRON chains |
| 18 | + */ |
| 19 | +export class TronERC20FeeProxyPaymentDetector extends ERC20FeeProxyPaymentDetectorBase< |
| 20 | + ExtensionTypes.PnFeeReferenceBased.IFeeReferenceBased, |
| 21 | + TronPaymentEvent |
| 22 | +> { |
| 23 | + private readonly getSubgraphClient: TGetSubGraphClient<CurrencyTypes.TronChainName>; |
| 24 | + protected readonly network: CurrencyTypes.TronChainName | undefined; |
| 25 | + |
| 26 | + constructor({ |
| 27 | + advancedLogic, |
| 28 | + currencyManager, |
| 29 | + getSubgraphClient, |
| 30 | + network, |
| 31 | + }: ReferenceBasedDetectorOptions & { |
| 32 | + network?: CurrencyTypes.TronChainName; |
| 33 | + getSubgraphClient: TGetSubGraphClient<CurrencyTypes.TronChainName>; |
| 34 | + }) { |
| 35 | + super( |
| 36 | + ExtensionTypes.PAYMENT_NETWORK_ID.ERC20_FEE_PROXY_CONTRACT, |
| 37 | + advancedLogic.getFeeProxyContractErc20ForNetwork(network) ?? |
| 38 | + advancedLogic.extensions.feeProxyContractErc20, |
| 39 | + currencyManager, |
| 40 | + ); |
| 41 | + this.getSubgraphClient = getSubgraphClient; |
| 42 | + this.network = network; |
| 43 | + } |
| 44 | + |
| 45 | + /** |
| 46 | + * Gets the deployment information for the ERC20FeeProxy contract on TRON |
| 47 | + */ |
| 48 | + public static getDeploymentInformation( |
| 49 | + network: CurrencyTypes.TronChainName, |
| 50 | + _paymentNetworkVersion?: string, |
| 51 | + ): { address: string; creationBlockNumber: number } { |
| 52 | + void _paymentNetworkVersion; // Parameter kept for API compatibility |
| 53 | + // For TRON, we use the 'tron' version of the artifact |
| 54 | + const address = erc20FeeProxyArtifact.getAddress(network, 'tron'); |
| 55 | + const creationBlockNumber = |
| 56 | + network === 'tron' |
| 57 | + ? 79216121 // TRON mainnet |
| 58 | + : 63208782; // Nile testnet |
| 59 | + |
| 60 | + return { address, creationBlockNumber }; |
| 61 | + } |
| 62 | + |
| 63 | + /** |
| 64 | + * Extracts the payment events of a request on TRON |
| 65 | + */ |
| 66 | + protected async extractEvents( |
| 67 | + eventName: PaymentTypes.EVENTS_NAMES, |
| 68 | + toAddress: string | undefined, |
| 69 | + paymentReference: string, |
| 70 | + requestCurrency: RequestLogicTypes.ICurrency, |
| 71 | + paymentChain: CurrencyTypes.TronChainName, |
| 72 | + _paymentNetwork: ExtensionTypes.IState, |
| 73 | + ): Promise<PaymentTypes.AllNetworkEvents<TronPaymentEvent>> { |
| 74 | + void _paymentNetwork; // Parameter required by parent class signature |
| 75 | + // Validate that the payment chain is a supported TRON chain |
| 76 | + if (!TronChains.isChainSupported(paymentChain)) { |
| 77 | + throw new NetworkNotSupported( |
| 78 | + `Unsupported TRON network '${paymentChain}' for TRON payment detector`, |
| 79 | + ); |
| 80 | + } |
| 81 | + |
| 82 | + if (this.network && !isSameChain(paymentChain, this.network)) { |
| 83 | + throw new NetworkNotSupported( |
| 84 | + `Unsupported network '${paymentChain}' for payment detector instantiated with '${this.network}'`, |
| 85 | + ); |
| 86 | + } |
| 87 | + |
| 88 | + if (!toAddress) { |
| 89 | + return { |
| 90 | + paymentEvents: [], |
| 91 | + }; |
| 92 | + } |
| 93 | + |
| 94 | + const { address: proxyContractAddress } = |
| 95 | + TronERC20FeeProxyPaymentDetector.getDeploymentInformation(paymentChain); |
| 96 | + |
| 97 | + const subgraphClient = this.getSubgraphClient( |
| 98 | + paymentChain, |
| 99 | + ) as TheGraphClient<CurrencyTypes.TronChainName>; |
| 100 | + |
| 101 | + if (!subgraphClient) { |
| 102 | + throw new Error( |
| 103 | + `Could not get a TheGraph-based info retriever for TRON chain ${paymentChain}. ` + |
| 104 | + `Ensure the TRON Substreams-powered subgraph is deployed and accessible.`, |
| 105 | + ); |
| 106 | + } |
| 107 | + |
| 108 | + const infoRetriever = new TronInfoRetriever(subgraphClient); |
| 109 | + |
| 110 | + return infoRetriever.getTransferEvents({ |
| 111 | + eventName, |
| 112 | + paymentReference, |
| 113 | + toAddress, |
| 114 | + contractAddress: proxyContractAddress, |
| 115 | + paymentChain, |
| 116 | + acceptedTokens: [requestCurrency.value], |
| 117 | + }); |
| 118 | + } |
| 119 | +} |
0 commit comments