@unilogin/sdk
Version:
SDK is a JS library, that communicates with relayer. SDK allows managing contract, by creating basic contract-calling messages.
65 lines (57 loc) • 2.3 kB
text/typescript
import {arrayRemove} from '@unilogin/commons';
import {WalletEventType, WalletEventObservableRecord} from '../models/events';
import {parseArgs, parseArgsGnosis} from '../utils/events';
import {Log} from 'ethers/providers';
import {BlockchainService} from '@unilogin/contracts';
import {WalletContractInterface, GnosisSafeInterface} from '@unilogin/contracts';
const eventInterface = {...WalletContractInterface.events, ...GnosisSafeInterface.events};
export class WalletEventsObserver {
private readonly observableRecords: Record<WalletEventType, WalletEventObservableRecord[]> = {
KeyAdded: [],
KeyRemoved: [],
AddedOwner: [],
RemovedOwner: [],
};
constructor(public readonly contractAddress: string, public readonly blockchainService: BlockchainService) {
}
subscribe(type: WalletEventType, observableRecord: WalletEventObservableRecord) {
this.observableRecords[type].push(observableRecord);
return () => {
this.observableRecords[type] = arrayRemove(this.observableRecords[type], observableRecord);
};
}
async fetchEvents(lastBlock: number, types: WalletEventType[]) {
const typesWithSubscriptions = types.filter(type => this.observableRecords[type].length > 0);
for (const type of typesWithSubscriptions) {
const topics = [eventInterface[type].topic];
const eventsFilter = {fromBlock: lastBlock, address: this.contractAddress, topics};
const events: Log[] = await this.blockchainService.getLogs(eventsFilter);
this.processEvents(events, type);
}
}
processEvents(events: Log[], type: WalletEventType) {
for (const event of events) {
this.processEvent(type, event);
}
}
private processEvent(type: WalletEventType, event: Log) {
let args: {key: string};
switch (type) {
case 'KeyAdded':
case 'KeyRemoved':
args = parseArgs(type, event);
break;
case 'AddedOwner':
case 'RemovedOwner':
args = parseArgsGnosis(type, event);
break;
default:
throw TypeError(`Invalid event type: ${type}`);
};
for (const observableRecord of this.observableRecords[type]) {
if (observableRecord.key === 'undefined' || observableRecord.key === args.key) {
observableRecord.callback(args);
}
}
}
}