Skip to content

Commit

Permalink
ts: Event decode api updates (#292)
Browse files Browse the repository at this point in the history
  • Loading branch information
armaniferrante authored May 20, 2021
1 parent 364f957 commit 24b723e
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 38 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 25 additions & 8 deletions ts/src/coder.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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();
Expand All @@ -232,18 +238,29 @@ class EventCoder {
});
// @ts-ignore
this.layouts = new Map(layouts);
}

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);
this.discriminators = new Map<string, string>(
idl.events === undefined
? []
: idl.events.map((e) => [
base64.fromByteArray(eventDiscriminator(e.name)),
e.name,
])
);
}

public decode<T = any>(eventName: string, ix: Buffer): T {
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;
}

const layout = this.layouts.get(eventName);
return layout.decode(ix);
return layout.decode(logArr.slice(8));
}
}

Expand Down
27 changes: 3 additions & 24 deletions ts/src/program/event.ts
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 1 addition & 5 deletions ts/src/program/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion ts/src/program/namespace/simulate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down

0 comments on commit 24b723e

Please sign in to comment.