@meshcore-cz/meshpkt 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  MeshCore radio packet codec for JavaScript and TypeScript, powered by WebAssembly.
7
7
 
8
+ > **Early development.** This package is a work in progress. APIs may change before v1.0 — pin to a specific version in production.
9
+
8
10
  - **npm:** [npmjs.com/package/@meshcore-cz/meshpkt](https://www.npmjs.com/package/@meshcore-cz/meshpkt)
9
11
  - **Go source & docs:** [pkg.go.dev/github.com/meshcore-cz/meshpkt](https://pkg.go.dev/github.com/meshcore-cz/meshpkt)
10
12
 
@@ -113,20 +115,31 @@ console.log(msg.destHash); // first-byte hash of recipient's public key
113
115
 
114
116
  ### Node advertisements (ADVERT)
115
117
 
118
+ The signature is verified automatically. `decodeAdvert` returns `{ error }` if
119
+ the packet carries a non-zero signature that does not verify — tampered data is
120
+ rejected before you ever see the fields.
121
+
116
122
  ```ts
117
123
  const env = meshpkt.decodeEnvelope(rawHex);
118
124
  if ("error" in env || env.type !== "ADVERT") return;
119
125
 
120
126
  const adv = meshpkt.decodeAdvert(env.payloadHex);
121
- if ("error" in adv) throw new Error(adv.error);
127
+ if ("error" in adv) throw new Error(adv.error); // also catches bad signatures
122
128
 
123
- console.log(adv.name); // "CZ.NIC Repeater"
124
- console.log(adv.nodeType); // 2 = repeater
129
+ console.log(adv.name); // "CZ.NIC Repeater"
130
+ console.log(adv.publicKey); // 64-char hex — treat this as the stable identity
131
+ console.log(adv.nodeType); // 2 = repeater
132
+ console.log(adv.sigVerified); // true = Ed25519 signature verified
133
+ // false = all-zero signature (unsigned packet)
125
134
  if (adv.hasGPS) {
126
135
  console.log(adv.lat, adv.lon);
127
136
  }
128
137
  ```
129
138
 
139
+ > **Note:** `sigVerified: true` proves the holder of `publicKey` signed exactly
140
+ > this name and these coordinates. It does not prove the name is unique — use
141
+ > `publicKey` as the stable identity, and treat the name as a signed label.
142
+
130
143
  ---
131
144
 
132
145
  ### Key utilities
package/dist/meshpkt.wasm CHANGED
Binary file
@@ -41,6 +41,7 @@ export interface AdvertPayload {
41
41
  hasGPS: boolean;
42
42
  lat?: number;
43
43
  lon?: number;
44
+ sigVerified: boolean;
44
45
  }
45
46
  export interface AckPayload {
46
47
  crc: number;
@@ -87,6 +88,23 @@ export interface ControlPayload {
87
88
  discoverSNR?: number;
88
89
  discoverPubKey?: string;
89
90
  }
91
+ export interface TracePayload {
92
+ tag: number;
93
+ authCode: number;
94
+ flags: number;
95
+ hashWidth: number;
96
+ routeHashes: string[];
97
+ snrs: string[];
98
+ hopCount: number;
99
+ }
100
+ export interface MultipartPayload {
101
+ remaining: number;
102
+ innerType: string;
103
+ innerTypeCode: number;
104
+ innerPayloadHex: string;
105
+ ackCrc?: number;
106
+ ackCrcHex?: string;
107
+ }
90
108
  export interface KeypairResult {
91
109
  publicKey: string;
92
110
  privateKey: string;
@@ -102,6 +120,8 @@ export interface MeshcoreWasm {
102
120
  encodeReq(privKey: string, peerPubKey: string, reqType: number, data: string): HexResult | ErrResult;
103
121
  encodeAnonReq(destPubKey: string, myPrivKey: string, data: string): HexResult | ErrResult;
104
122
  encodeDiscoverReq(typeFilter: number, tag: number, since: number, prefixOnly: number): HexResult | ErrResult;
123
+ encodeTrace(tag: number, authCode: number, flags: number, routeHashes: string): HexResult | ErrResult;
124
+ encodeMultipartAck(remaining: number, crc: number): HexResult | ErrResult;
105
125
  encodeRaw(route: number, payloadType: number, version: number, pathHashSize: number, payload: string): HexResult | ErrResult;
106
126
  decodeEnvelope(packet: string): Envelope | ErrResult;
107
127
  decodeGroupText(payload: string, channelName: string): GroupTextPayload | ErrResult;
@@ -116,11 +136,13 @@ export interface MeshcoreWasm {
116
136
  decodePath(payload: string, privKey: string, peerPubKey: string): PathPayload | ErrResult;
117
137
  decodeAnonReq(payload: string, myPrivKey: string): AnonReqPayload | ErrResult;
118
138
  decodeControl(payload: string): ControlPayload | ErrResult;
139
+ decodeTrace(packet: string): TracePayload | ErrResult;
140
+ decodeMultipart(payload: string): MultipartPayload | ErrResult;
119
141
  generateKeypair(): KeypairResult | ErrResult;
120
142
  deriveChannelSecret(channelName: string): HexResult | ErrResult;
121
143
  sharedSecret(privKey: string, peerPubKey: string): HexResult | ErrResult;
122
144
  }
123
- export declare const meshcoreOpNames: readonly ["encodeGroupText", "encodeGroupTextSecret", "encodeGrpData", "encodeGrpDataSecret", "encodeDirectText", "encodeAdvert", "encodeAck", "encodeReq", "encodeAnonReq", "encodeDiscoverReq", "encodeRaw", "decodeEnvelope", "decodeGroupText", "decodeGroupTextSecret", "decodeDirectText", "decodeAdvert", "decodeAck", "decodeGrpData", "decodeGrpDataSecret", "decodeReq", "decodeResponse", "decodePath", "decodeAnonReq", "decodeControl", "generateKeypair", "deriveChannelSecret", "sharedSecret"];
145
+ export declare const meshcoreOpNames: readonly ["encodeGroupText", "encodeGroupTextSecret", "encodeGrpData", "encodeGrpDataSecret", "encodeDirectText", "encodeAdvert", "encodeAck", "encodeReq", "encodeAnonReq", "encodeDiscoverReq", "encodeTrace", "encodeMultipartAck", "encodeRaw", "decodeEnvelope", "decodeGroupText", "decodeGroupTextSecret", "decodeDirectText", "decodeAdvert", "decodeAck", "decodeGrpData", "decodeGrpDataSecret", "decodeReq", "decodeResponse", "decodePath", "decodeAnonReq", "decodeControl", "decodeTrace", "decodeMultipart", "generateKeypair", "deriveChannelSecret", "sharedSecret"];
124
146
  export declare const RouteTypes: readonly [{
125
147
  readonly code: 0;
126
148
  readonly label: "TRANSPORT_FLOOD";
package/dist/wasm.gen.js CHANGED
@@ -11,6 +11,8 @@ export const meshcoreOpNames = [
11
11
  "encodeReq",
12
12
  "encodeAnonReq",
13
13
  "encodeDiscoverReq",
14
+ "encodeTrace",
15
+ "encodeMultipartAck",
14
16
  "encodeRaw",
15
17
  "decodeEnvelope",
16
18
  "decodeGroupText",
@@ -25,6 +27,8 @@ export const meshcoreOpNames = [
25
27
  "decodePath",
26
28
  "decodeAnonReq",
27
29
  "decodeControl",
30
+ "decodeTrace",
31
+ "decodeMultipart",
28
32
  "generateKeypair",
29
33
  "deriveChannelSecret",
30
34
  "sharedSecret",
@@ -727,6 +731,130 @@ export const OpMetas = [
727
731
  { name: "hex", kind: "string", optional: false, label: "Hex packet" },
728
732
  ],
729
733
  },
734
+ {
735
+ name: "encodeTrace",
736
+ category: "encode",
737
+ label: "Encode TRACE",
738
+ tabGroup: "trace",
739
+ tabGroupLabel: "TRACE",
740
+ tabGroupSub: "path trace",
741
+ tabGroupDoc: "",
742
+ tabLabel: "",
743
+ packetType: "",
744
+ resultTypeName: "HexResult",
745
+ params: [
746
+ {
747
+ name: "tag",
748
+ kind: "int",
749
+ label: "Tag (random)",
750
+ placeholder: "0",
751
+ optional: false,
752
+ choices: [],
753
+ showWhen: "",
754
+ showValue: 0,
755
+ group: "",
756
+ action: "",
757
+ widget: "",
758
+ autoFill: "",
759
+ secret: false,
760
+ },
761
+ {
762
+ name: "authCode",
763
+ kind: "int",
764
+ label: "Auth code (opaque)",
765
+ placeholder: "0",
766
+ optional: false,
767
+ choices: [],
768
+ showWhen: "",
769
+ showValue: 0,
770
+ group: "",
771
+ action: "",
772
+ widget: "",
773
+ autoFill: "",
774
+ secret: false,
775
+ },
776
+ {
777
+ name: "flags",
778
+ kind: "int",
779
+ label: "Flags (hash width: 0=1B 1=2B 2=4B 3=8B)",
780
+ placeholder: "0",
781
+ optional: false,
782
+ choices: [],
783
+ showWhen: "",
784
+ showValue: 0,
785
+ group: "",
786
+ action: "",
787
+ widget: "",
788
+ autoFill: "",
789
+ secret: false,
790
+ },
791
+ {
792
+ name: "routeHashes",
793
+ kind: "hex",
794
+ label: "Route hashes (hex)",
795
+ placeholder: "",
796
+ optional: true,
797
+ choices: [],
798
+ showWhen: "",
799
+ showValue: 0,
800
+ group: "",
801
+ action: "",
802
+ widget: "textarea",
803
+ autoFill: "",
804
+ secret: false,
805
+ },
806
+ ],
807
+ result: [
808
+ { name: "hex", kind: "string", optional: false, label: "Hex packet" },
809
+ ],
810
+ },
811
+ {
812
+ name: "encodeMultipartAck",
813
+ category: "encode",
814
+ label: "Encode MULTIPART ACK",
815
+ tabGroup: "multipart",
816
+ tabGroupLabel: "MULTIPART",
817
+ tabGroupSub: "repeated ACK",
818
+ tabGroupDoc: "",
819
+ tabLabel: "",
820
+ packetType: "",
821
+ resultTypeName: "HexResult",
822
+ params: [
823
+ {
824
+ name: "remaining",
825
+ kind: "int",
826
+ label: "Remaining (packets still to send after this)",
827
+ placeholder: "0",
828
+ optional: false,
829
+ choices: [],
830
+ showWhen: "",
831
+ showValue: 0,
832
+ group: "",
833
+ action: "",
834
+ widget: "",
835
+ autoFill: "",
836
+ secret: false,
837
+ },
838
+ {
839
+ name: "crc",
840
+ kind: "int",
841
+ label: "ACK CRC32",
842
+ placeholder: "0",
843
+ optional: false,
844
+ choices: [],
845
+ showWhen: "",
846
+ showValue: 0,
847
+ group: "",
848
+ action: "",
849
+ widget: "",
850
+ autoFill: "",
851
+ secret: false,
852
+ },
853
+ ],
854
+ result: [
855
+ { name: "hex", kind: "string", optional: false, label: "Hex packet" },
856
+ ],
857
+ },
730
858
  {
731
859
  name: "encodeRaw",
732
860
  category: "encode",
@@ -813,7 +941,6 @@ export const OpMetas = [
813
941
  { value: 1, label: "1" },
814
942
  { value: 2, label: "2" },
815
943
  { value: 3, label: "3" },
816
- { value: 4, label: "4" },
817
944
  ],
818
945
  showWhen: "",
819
946
  showValue: 0,
@@ -1092,6 +1219,7 @@ export const OpMetas = [
1092
1219
  { name: "hasGPS", kind: "boolean", optional: false, label: "Has GPS" },
1093
1220
  { name: "lat", kind: "number", optional: true, label: "Latitude" },
1094
1221
  { name: "lon", kind: "number", optional: true, label: "Longitude" },
1222
+ { name: "sigVerified", kind: "boolean", optional: false, label: "Signature verified" },
1095
1223
  ],
1096
1224
  },
1097
1225
  {
@@ -1511,6 +1639,81 @@ export const OpMetas = [
1511
1639
  { name: "discoverPubKey", kind: "string", optional: true, label: "Public key" },
1512
1640
  ],
1513
1641
  },
1642
+ {
1643
+ name: "decodeTrace",
1644
+ category: "decode",
1645
+ label: "Decode TRACE packet",
1646
+ tabGroup: "",
1647
+ tabGroupLabel: "",
1648
+ tabGroupSub: "",
1649
+ tabGroupDoc: "",
1650
+ tabLabel: "",
1651
+ packetType: "TRACE",
1652
+ resultTypeName: "TracePayload",
1653
+ params: [
1654
+ {
1655
+ name: "packet",
1656
+ kind: "hex",
1657
+ label: "Full packet hex (SNR bytes are in the path field)",
1658
+ placeholder: "",
1659
+ optional: false,
1660
+ choices: [],
1661
+ showWhen: "",
1662
+ showValue: 0,
1663
+ group: "",
1664
+ action: "",
1665
+ widget: "",
1666
+ autoFill: "packetHex",
1667
+ secret: false,
1668
+ },
1669
+ ],
1670
+ result: [
1671
+ { name: "tag", kind: "number", optional: false, label: "Tag" },
1672
+ { name: "authCode", kind: "number", optional: false, label: "Auth code" },
1673
+ { name: "flags", kind: "number", optional: false, label: "Flags" },
1674
+ { name: "hashWidth", kind: "number", optional: false, label: "Route hash width (bytes)" },
1675
+ { name: "routeHashes", kind: "string[]", optional: false, label: "Route hashes" },
1676
+ { name: "snrs", kind: "string[]", optional: false, label: "SNR values (dB)" },
1677
+ { name: "hopCount", kind: "number", optional: false, label: "Hops with SNR" },
1678
+ ],
1679
+ },
1680
+ {
1681
+ name: "decodeMultipart",
1682
+ category: "decode",
1683
+ label: "Decode MULTIPART",
1684
+ tabGroup: "",
1685
+ tabGroupLabel: "",
1686
+ tabGroupSub: "",
1687
+ tabGroupDoc: "",
1688
+ tabLabel: "",
1689
+ packetType: "MULTIPART",
1690
+ resultTypeName: "MultipartPayload",
1691
+ params: [
1692
+ {
1693
+ name: "payload",
1694
+ kind: "hex",
1695
+ label: "",
1696
+ placeholder: "",
1697
+ optional: false,
1698
+ choices: [],
1699
+ showWhen: "",
1700
+ showValue: 0,
1701
+ group: "",
1702
+ action: "",
1703
+ widget: "",
1704
+ autoFill: "payloadHex",
1705
+ secret: false,
1706
+ },
1707
+ ],
1708
+ result: [
1709
+ { name: "remaining", kind: "number", optional: false, label: "Remaining packets" },
1710
+ { name: "innerType", kind: "string", optional: false, label: "Inner type" },
1711
+ { name: "innerTypeCode", kind: "number", optional: false, label: "Inner type code" },
1712
+ { name: "innerPayloadHex", kind: "string", optional: false, label: "Inner payload (hex)" },
1713
+ { name: "ackCrc", kind: "number", optional: true, label: "ACK CRC32" },
1714
+ { name: "ackCrcHex", kind: "string", optional: true, label: "ACK CRC32 (hex)" },
1715
+ ],
1716
+ },
1514
1717
  {
1515
1718
  name: "generateKeypair",
1516
1719
  category: "key",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshcore-cz/meshpkt",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "MeshCore radio packet codec for JavaScript and TypeScript, powered by WebAssembly",
5
5
  "type": "module",
6
6
  "license": "MIT",