ts: Event decode api updates (#292)

This commit is contained in:
Armani Ferrante 2021-05-20 02:28:27 -07:00 committed by GitHub
parent 364f957c9a
commit 24b723e1e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 38 deletions

View File

@ -18,6 +18,8 @@ incremented for features.
## Breaking Changes
* ts: Event coder `decode` API changed to decode strings directly instead of buffers ([#292](https://github.com/project-serum/anchor/pull/292)).
* ts: Event coder `encode` API removed ([#292](https://github.com/project-serum/anchor/pull/292)).
* ts: Replace deprecated `web3.Account` with `web3.Signer` in public APIs ([#296](https://github.com/project-serum/anchor/pull/296)).
## [0.5.0] - 2021-05-07

View File

@ -1,4 +1,5 @@
import camelCase from "camelcase";
import * as base64 from "base64-js";
import { snakeCase } from "snake-case";
import { Layout } from "buffer-layout";
import * as sha256 from "js-sha256";
@ -213,6 +214,11 @@ class EventCoder {
*/
private layouts: Map<string, Layout>;
/**
* Maps base64 encoded event discriminator to event name.
*/
private discriminators: Map<string, string>;
public constructor(idl: Idl) {
if (idl.events === undefined) {
this.layouts = new Map();
@ -232,18 +238,29 @@ class EventCoder {
});
// @ts-ignore
this.layouts = new Map(layouts);
this.discriminators = new Map<string, string>(
idl.events === undefined
? []
: idl.events.map((e) => [
base64.fromByteArray(eventDiscriminator(e.name)),
e.name,
])
);
}
public encode<T = any>(eventName: string, account: T): Buffer {
const buffer = Buffer.alloc(1000); // TODO: use a tighter buffer.
const layout = this.layouts.get(eventName);
const len = layout.encode(account, buffer);
return buffer.slice(0, len);
}
public decode<T = any>(log: string): T | null {
const logArr = Buffer.from(base64.toByteArray(log));
const disc = base64.fromByteArray(logArr.slice(0, 8));
// Only deserialize if the discriminator implies a proper event.
const eventName = this.discriminators.get(disc);
if (eventName === undefined) {
return undefined;
}
public decode<T = any>(eventName: string, ix: Buffer): T {
const layout = this.layouts.get(eventName);
return layout.decode(ix);
return layout.decode(logArr.slice(8));
}
}

View File

@ -1,8 +1,7 @@
import { PublicKey } from "@solana/web3.js";
import * as base64 from "base64-js";
import * as assert from "assert";
import Coder, { eventDiscriminator } from "../coder";
import { Idl } from "../idl";
import Coder from "../coder";
const LOG_START_INDEX = "Program log: ".length;
@ -15,20 +14,10 @@ export type Event = {
export class EventParser {
private coder: Coder;
private programId: PublicKey;
// Maps base64 encoded event discriminator to event name.
private discriminators: Map<string, string>;
constructor(coder: Coder, programId: PublicKey, idl: Idl) {
constructor(coder: Coder, programId: PublicKey) {
this.coder = coder;
this.programId = programId;
this.discriminators = new Map<string, string>(
idl.events === undefined
? []
: idl.events.map((e) => [
base64.fromByteArray(eventDiscriminator(e.name)),
e.name,
])
);
}
// Each log given, represents an array of messages emitted by
@ -88,17 +77,7 @@ export class EventParser {
// This is a `msg!` log.
if (log.startsWith("Program log:")) {
const logStr = log.slice(LOG_START_INDEX);
const logArr = Buffer.from(base64.toByteArray(logStr));
const disc = base64.fromByteArray(logArr.slice(0, 8));
// Only deserialize if the discriminator implies a proper event.
let event = null;
let eventName = this.discriminators.get(disc);
if (eventName !== undefined) {
event = {
name: eventName,
data: this.coder.events.decode(eventName, logArr.slice(8)),
};
}
const event = this.coder.events.decode(logStr);
return [event, null, false];
}
// System log.

View File

@ -301,11 +301,7 @@ export class Program {
eventName: string,
callback: (event: any, slot: number) => void
): number {
const eventParser = new EventParser(
this._coder,
this._programId,
this._idl
);
const eventParser = new EventParser(this._coder, this._programId);
return this._provider.connection.onLogs(this._programId, (logs, ctx) => {
if (logs.err) {
console.error(logs);

View File

@ -63,7 +63,7 @@ export default class SimulateFactory {
const events = [];
if (idl.events) {
let parser = new EventParser(coder, programId, idl);
let parser = new EventParser(coder, programId);
parser.parseLogs(logs, (event) => {
events.push(event);
});