
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@hqtsm/struct
Advanced tools
Binary structures
ArrayBufferView
, like native binary typesEndianness can be defined for each individual member.
import { int8, Struct, uint16BE, uint16LE } from '@hqtsm/struct';
class Example extends Struct {
declare public alpha: number;
declare public beta: number;
declare public gamma: number;
static {
uint16LE(this, 'alpha');
uint16BE(this, 'beta');
int8(this, 'gamma');
}
}
const data = new Uint8Array(Example.BYTE_LENGTH);
const example = new Example(data.buffer);
example.alpha = 0xABCD;
example.beta = 0xBCDE;
example.gamma = -123;
console.assert(data.join(' ') === '205 171 188 222 133');
Using the endian passed into the constructor, or host endianness.
import { Struct, uint16 } from '@hqtsm/struct';
class Example extends Struct {
declare public alpha: number;
declare public beta: number;
static {
uint16(this, 'alpha');
uint16(this, 'beta');
}
}
const data = new Uint8Array(Example.BYTE_LENGTH);
const exampleLE = new Example(data.buffer, 0, true);
exampleLE.alpha = 0xABCD;
exampleLE.beta = 0xBCDE;
console.assert(data.join(' ') === '205 171 222 188');
const exampleBE = new Example(data.buffer, 0, false);
exampleBE.alpha = 0xABCD;
exampleBE.beta = 0xBCDE;
console.assert(data.join(' ') === '171 205 188 222');
Structures can be extended with new child members.
import { float32, Struct, uint32 } from '@hqtsm/struct';
class Variable extends Struct {
declare public type: number;
static {
uint32(this, 'type');
}
}
class VariableFloat extends Variable {
declare public value: number;
static {
float32(this, 'value');
}
}
const data = new Uint8Array(VariableFloat.BYTE_LENGTH);
const varFloat = new VariableFloat(data.buffer, 0, true);
varFloat.type = 0xF;
varFloat.value = 3.1415;
console.assert(data.join(' ') === '15 0 0 0 86 14 73 64');
Defining a child structure is easy.
import { Arr, array, member, Struct, uint16BE, Uint8Ptr } from '@hqtsm/struct';
class Child extends Struct {
declare public alpha: number;
declare public beta: number;
static {
uint16BE(this, 'alpha');
uint16BE(this, 'beta');
}
}
class Parent extends Struct {
declare public child1: Child;
declare public child2: Child;
static {
member(Child, this, 'child1');
member(Child, this, 'child2');
}
}
const data = new Uint8Array(Parent.BYTE_LENGTH);
const stru = new Parent(data.buffer);
stru.child1.alpha = 97;
stru.child1.beta = 98;
stru.child2.alpha = 65;
stru.child2.beta = 66;
console.assert(data.join(' ') === '0 97 0 98 0 65 0 66');
Comes with pointers for primitives, and a factory for pointers to types.
import { int8, Int8Ptr, pointer, Struct } from '@hqtsm/struct';
const data = new Int8Array(6);
// Starting at an offset.
const i8p = new Int8Ptr(data.buffer, 2);
// Setting values by index.
i8p[0] = 0;
i8p[1] = 1;
i8p[2] = 2;
i8p[3] = 3;
// Negative indexing also works, accessing memory before offset.
i8p[-1] = -1;
i8p[-2] = -2;
console.assert(data.join(' ') === '-2 -1 0 1 2 3');
class XY extends Struct {
declare public x: number;
declare public y: number;
static {
int8(this, 'x');
int8(this, 'y');
}
}
// Pointer for custom type.
const XYPtr = pointer(XY);
const xyp = new XYPtr(data.buffer, 2);
console.assert(xyp[0].x === 0);
console.assert(xyp[0].y === 1);
console.assert(xyp[1].x === 2);
console.assert(xyp[1].y === 3);
console.assert(xyp[-1].x === -2);
console.assert(xyp[-1].y === -1);
// Type memory can also be assigned.
const xy = new XY(new ArrayBuffer(XY.BYTE_LENGTH));
xy.x = 88;
xy.y = 89;
xyp[0] = xy;
console.assert(data.join(' ') === '-2 -1 88 89 2 3');
A pointer extended to a type of a fixed length.
import {
Arr,
array,
int8,
member,
pointer,
Struct,
Uint8Ptr,
} from '@hqtsm/struct';
class XY extends Struct {
declare public x: number;
declare public y: number;
static {
int8(this, 'x');
int8(this, 'y');
}
}
class Example extends Struct {
declare public bytes: Arr<number>;
declare public xys: Arr<XY>;
static {
member(array(Uint8Ptr, 4), this, 'bytes');
member(array(XY, 2), this, 'xys');
}
}
const data = new Uint8Array(Example.BYTE_LENGTH);
const example = new Example(data.buffer);
example.bytes[0] = 10;
example.bytes[1] = 20;
example.bytes[2] = 30;
example.bytes[3] = 40;
example.xys[0].x = 150;
example.xys[0].y = 160;
example.xys[1].x = 170;
example.xys[1].y = 180;
console.assert(data.join(' ') === '10 20 30 40 150 160 170 180');
A union will automatically use overlapping member memory.
import { Arr, array, member, uint32BE, Uint8Ptr, Union } from '@hqtsm/struct';
class FourCC extends Union {
declare public int: number;
declare public chars: Arr<number>;
static {
uint32BE(this, 'int');
member(array(Uint8Ptr, 4), this, 'chars');
}
}
const data = new Uint8Array(FourCC.BYTE_LENGTH);
const four = new FourCC(data.buffer);
four.int = 0x41424344;
console.assert(four.chars[0] === 0x41);
console.assert(String.fromCharCode(...four.chars) === 'ABCD');
By default member memory is sequentially without alignment or padding.
import { pad, Struct, uint32, uint8 } from '@hqtsm/struct';
class Example extends Struct {
declare private alpha: number;
declare protected beta: number;
declare public gamma: number;
public setAlpha(value: number): void {
this.alpha = value;
}
public setBeta(value: number): void {
this.beta = value;
}
static {
uint8(this, 'alpha' as never);
uint32(this, 'beta' as never);
uint8(this, 'gamma');
}
}
console.assert(Example.BYTE_LENGTH === 6);
Padding can be manually added as a property or anonymously.
import { pad, Struct, uint32, uint8 } from '@hqtsm/struct';
class Example extends Struct {
declare private alpha: number;
declare public padding: never;
declare protected beta: number;
declare public gamma: number;
public setAlpha(value: number): void {
this.alpha = value;
}
public setBeta(value: number): void {
this.beta = value;
}
static {
uint8(this, 'alpha' as never);
pad(3, this, 'padding'); // Property.
uint32(this, 'beta' as never);
uint8(this, 'gamma');
pad(3, this); // Anonymous.
}
}
console.assert(Example.BYTE_LENGTH === 12);
Using intergers or arrays for padding also works.
Members can be made private
or protected
but type checking must be relaxed.
Casting the name to never
or any
will pass the type checker.
import { Struct, uint8 } from '@hqtsm/struct';
class Example extends Struct {
declare private alpha: number;
declare protected beta: number;
declare public gamma: number;
public setAlpha(value: number): void {
this.alpha = value;
}
public setBeta(value: number): void {
this.beta = value;
}
static {
uint8(this, 'alpha' as never);
uint8(this, 'beta' as never);
uint8(this, 'gamma');
}
}
const data = new Uint8Array(Example.BYTE_LENGTH);
const example = new Example(data.buffer);
example.setAlpha(65);
example.setBeta(66);
example.gamma = 71;
console.assert(data.join(' ') === '65 66 71');
FAQs
Binary structures
The npm package @hqtsm/struct receives a total of 1 weekly downloads. As such, @hqtsm/struct popularity was classified as not popular.
We found that @hqtsm/struct demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.