import { getLogger , DefaultSignatureVerifier , RpcClient , serializeObject , serializeObjectAsHexString , SignatureProvider , SignatureVerifier , } from '@pigi/core-utils' ; import { KeyValueStore } from '@pigi/core-db' ; import { AGGREGATOR_API , EMPTY_AGGREGATOR_SIGNATURE , NON_EXISTENT_SLOT_INDEX , } from './utils' ; import { Address , RollupTransaction , SignatureError , SignedStateReceipt , } from '../types' ; import { abiEncodeStateReceipt , abiEncodeTransaction } from './serialization' ; const log = getLogger ( 'rollup-client' ) ; /**
 * Simple Rollup Client enabling getting balances & sending transactions.
 */ export class RollupClient { public rpcClient : RpcClient ; param db param aggregatorAddress param signatureVerifier constructor ( private readonly db , private readonly aggregatorAddress , private readonly signatureVerifier = DefaultSignatureVerifier . instance ( ) ) { } param rpcClient public connect ( rpcClient ) { this . rpcClient = rpcClient ; } param account returns public async getState ( account ) { const receipt = await this . rpcClient . handle < SignedStateReceipt > ( AGGREGATOR_API . getState , account ) ; this . verifyTransactionReceipt ( receipt ) ; return receipt ; } public async sendTransaction ( transaction , signatureProvider ) { const signature = await signatureProvider . sign ( abiEncodeTransaction ( transaction ) ) ; const receipts = await this . rpcClient . handle < SignedStateReceipt [ ] > ( AGGREGATOR_API . applyTransaction , { signature , transaction , } ) ; for ( const receipt of receipts ) { this . verifyTransactionReceipt ( receipt ) ; } return receipts ; } public async requestFaucetFunds ( transaction , signatureProvider ) { const signature = await signatureProvider . sign ( serializeObjectAsHexString ( transaction ) ) ; const receipt = await this . rpcClient . handle < SignedStateReceipt > ( AGGREGATOR_API . requestFaucetFunds , { signature , transaction , } ) ; this . verifyTransactionReceipt ( receipt ) ; return receipt ; } private verifyTransactionReceipt ( receipt ) { if ( receipt . signature === EMPTY_AGGREGATOR_SIGNATURE && receipt . stateReceipt . slotIndex === NON_EXISTENT_SLOT_INDEX ) { return ; } const signer = this . signatureVerifier . verifyMessage ( abiEncodeStateReceipt ( receipt . stateReceipt ) , receipt . signature ) ; if ( signer !== this . aggregatorAddress ) { log . error ( `Received invalid SignedStateReceipt from the Aggregator: ${ serializeObject ( receipt ) }` ) ; throw new SignatureError ( ) ; } } }