Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
dee5e1cb9e
|
|||
|
e388a55575
|
|||
|
c52ec1dc43
|
|||
|
9b2d4d1096
|
|||
|
fae58c223b
|
|||
|
7e5a8c74a5
|
|||
|
df09c952de
|
56
README.md
56
README.md
@@ -2,18 +2,54 @@
|
|||||||
|
|
||||||
TypeScript library for MeshCore protocol utilities.
|
TypeScript library for MeshCore protocol utilities.
|
||||||
|
|
||||||
Quick start
|
## Packet parsing
|
||||||
|
|
||||||
1. Install dev dependencies:
|
Using the library to decode MeshCore packets:
|
||||||
|
|
||||||
```bash
|
```ts
|
||||||
npm install --save-dev typescript tsup
|
import { Packet } from '@hamradio/meshcore';
|
||||||
|
|
||||||
|
const raw = new Uint8Array(Buffer.from("050AA50E2CB0336DB67BBF78928A3BB9BF7A8B677C83B6EC0716F9DD10002A06", "hex"));
|
||||||
|
const packet = Packet.fromBytes(raw);
|
||||||
|
console.log(packet);
|
||||||
|
|
||||||
|
/*
|
||||||
|
_Packet {
|
||||||
|
header: 5,
|
||||||
|
transport: undefined,
|
||||||
|
pathLength: 10,
|
||||||
|
path: Uint8Array(10) [
|
||||||
|
165, 14, 44, 176,
|
||||||
|
51, 109, 182, 123,
|
||||||
|
191, 120
|
||||||
|
],
|
||||||
|
payload: Uint8Array(20) [
|
||||||
|
146, 138, 59, 185, 191, 122,
|
||||||
|
139, 103, 124, 131, 182, 236,
|
||||||
|
7, 22, 249, 221, 16, 0,
|
||||||
|
42, 6
|
||||||
|
],
|
||||||
|
routeType: 1,
|
||||||
|
payloadVersion: 0,
|
||||||
|
payloadType: 1,
|
||||||
|
pathHashCount: 10,
|
||||||
|
pathHashSize: 1,
|
||||||
|
pathHashBytes: 10,
|
||||||
|
pathHashes: [
|
||||||
|
'a5', '0e', '2c',
|
||||||
|
'b0', '33', '6d',
|
||||||
|
'b6', '7b', 'bf',
|
||||||
|
'78'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Build the library:
|
## Identities
|
||||||
|
|
||||||
```bash
|
The package supports:
|
||||||
npm run build
|
- `Identity` for public key management.
|
||||||
```
|
- `LocalIdentity` for private key management.
|
||||||
|
- `Contact` for managing named identities.
|
||||||
3. Use the build output from the `dist/` folder or publish to npm.
|
- `Group` for managing groups.
|
||||||
|
- `KeyManager` for managing all of the above and handling decryption.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "meshcore",
|
"name": "@hamradio/meshcore",
|
||||||
"version": "1.1.0",
|
"version": "1.1.3",
|
||||||
"description": "MeshCore protocol support for Typescript",
|
"description": "MeshCore protocol support for Typescript",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"MeshCore",
|
"MeshCore",
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://git.maze.io/ham/meshcore.js"
|
"url": "https://git.maze.io/ham/meshcore.js"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Wijnand Modderman-Lenstra",
|
"author": "Wijnand Modderman-Lenstra",
|
||||||
|
|||||||
19
src/index.ts
19
src/index.ts
@@ -1,9 +1,20 @@
|
|||||||
export * from './identity';
|
export * from './identity';
|
||||||
export * from './identity.types';
|
import * as identityTypes from './identity.types';
|
||||||
export type * from './identity.types';
|
import type * as identityTypesTypes from './identity.types';
|
||||||
|
|
||||||
export * from './crypto';
|
export * from './crypto';
|
||||||
export type * from './crypto.types';
|
import * as cryptoTypes from './crypto.types';
|
||||||
|
import type * as cryptoTypesTypes from './crypto.types';
|
||||||
|
|
||||||
export * from './packet';
|
export * from './packet';
|
||||||
export type * from './packet.types';
|
import * as packetTypes from './packet.types';
|
||||||
|
import type * as packetTypesTypes from './packet.types';
|
||||||
|
|
||||||
|
export type {
|
||||||
|
identityTypes,
|
||||||
|
identityTypesTypes,
|
||||||
|
cryptoTypes,
|
||||||
|
cryptoTypesTypes,
|
||||||
|
packetTypes,
|
||||||
|
packetTypesTypes
|
||||||
|
};
|
||||||
|
|||||||
@@ -52,13 +52,13 @@ export class Packet implements IPacket {
|
|||||||
this.payloadVersion = (header >> 6) & 0x03;
|
this.payloadVersion = (header >> 6) & 0x03;
|
||||||
this.payloadType = (header >> 2) & 0x0f;
|
this.payloadType = (header >> 2) & 0x0f;
|
||||||
|
|
||||||
this.pathHashCount = (pathLength >> 6) + 1;
|
this.pathHashSize = (pathLength >> 6) + 1;
|
||||||
this.pathHashSize = pathLength & 0x3f;
|
this.pathHashCount = pathLength & 0x3f;
|
||||||
this.pathHashBytes = this.pathHashCount * this.pathHashSize;
|
this.pathHashBytes = this.pathHashCount * this.pathHashSize;
|
||||||
|
|
||||||
this.pathHashes = [];
|
this.pathHashes = [];
|
||||||
for (let i = 0; i < this.pathHashCount; i++) {
|
for (let i = 0; i < this.pathHashBytes; i += this.pathHashSize) {
|
||||||
const hashBytes = this.path.slice(i * this.pathHashSize, (i + 1) * this.pathHashSize);
|
const hashBytes = this.path.slice(i, i + this.pathHashSize);
|
||||||
const hashHex = bytesToHex(hashBytes);
|
const hashHex = bytesToHex(hashBytes);
|
||||||
this.pathHashes.push(hashHex);
|
this.pathHashes.push(hashHex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { PublicKey, PrivateKey, SharedSecret, StaticSecret } from './crypto';
|
import { PublicKey, PrivateKey, SharedSecret, StaticSecret } from '../src/crypto';
|
||||||
import { bytesToHex, hexToBytes } from './parser';
|
import { bytesToHex, hexToBytes } from '../src/parser';
|
||||||
|
|
||||||
const randomBytes = (len: number) => Uint8Array.from({ length: len }, () => Math.floor(Math.random() * 256));
|
const randomBytes = (len: number) => Uint8Array.from({ length: len }, () => Math.floor(Math.random() * 256));
|
||||||
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { describe, it, expect, beforeEach } from 'vitest';
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
import { Identity, LocalIdentity, Contact, Group, Contacts, parseNodeHash } from './identity';
|
import { Identity, LocalIdentity, Contact, Group, Contacts, parseNodeHash } from '../src/identity';
|
||||||
import { PrivateKey, PublicKey, SharedSecret } from './crypto';
|
import { PrivateKey, PublicKey, SharedSecret } from '../src/crypto';
|
||||||
import { DecryptedGroupText, DecryptedGroupData } from './packet.types';
|
import { DecryptedGroupText, DecryptedGroupData } from '../src/packet.types';
|
||||||
import { bytesToHex } from './parser';
|
import { bytesToHex } from '../src/parser';
|
||||||
|
|
||||||
function randomBytes(len: number) {
|
function randomBytes(len: number) {
|
||||||
return Uint8Array.from({ length: len }, () => Math.floor(Math.random() * 256));
|
return Uint8Array.from({ length: len }, () => Math.floor(Math.random() * 256));
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vitest';
|
||||||
import { Packet } from './packet';
|
import { Packet } from '../src/packet';
|
||||||
import { PayloadType, RouteType, NodeType, TracePayload, AdvertPayload, RequestPayload, TextPayload, ResponsePayload, RawCustomPayload, AnonReqPayload } from './packet.types';
|
import { PayloadType, RouteType, NodeType, TracePayload, AdvertPayload, RequestPayload, TextPayload, ResponsePayload, RawCustomPayload, AnonReqPayload } from '../src/packet.types';
|
||||||
import { hexToBytes, bytesToHex } from './parser';
|
import { hexToBytes, bytesToHex } from '../src/parser';
|
||||||
|
|
||||||
describe('Packet.fromBytes', () => {
|
describe('Packet.fromBytes', () => {
|
||||||
test('frame 1: len=122 type=5 payload_len=99', () => {
|
test('frame 1: len=122 type=5 payload_len=99', () => {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { describe, it, expect } from 'vitest';
|
import { describe, it, expect } from 'vitest';
|
||||||
import { base64ToBytes, hexToBytes, BufferReader, BufferWriter } from './parser';
|
import { base64ToBytes, hexToBytes, BufferReader, BufferWriter } from '../src/parser';
|
||||||
|
|
||||||
describe('base64ToBytes', () => {
|
describe('base64ToBytes', () => {
|
||||||
it('decodes a simple base64 string', () => {
|
it('decodes a simple base64 string', () => {
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"forceConsistentCasingInFileNames": true
|
"forceConsistentCasingInFileNames": true
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src", "test/crypto.test.ts", "test/identity.test.ts", "test/packet.test.ts", "test/parser.test.ts"],
|
||||||
"exclude": ["node_modules", "dist", "test"]
|
"exclude": ["node_modules", "dist", "test"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user