ts: Event decode api updates (#292)
This commit is contained in:
parent
364f957c9a
commit
24b723e1e1
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue