{"_id":"@atendi9/atxp-protocol","_rev":"5-df1338871c745e7b1638790ae42f419c","name":"@atendi9/atxp-protocol","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"@atendi9/atxp-protocol","version":"1.0.0","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"author":{"name":"atendi9"},"license":"MIT","_id":"@atendi9/atxp-protocol@1.0.0","maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"homepage":"https://github.com/atendi9/atxp#readme","bugs":{"url":"https://github.com/atendi9/atxp/issues"},"dist":{"shasum":"cd7406c9844b85813913fd60fb1409d8f9948e23","tarball":"https://registry.npmjs.org/@atendi9/atxp-protocol/-/atxp-protocol-1.0.0.tgz","fileCount":14,"integrity":"sha512-2kIp5MmCaHAuVUsu45Xqj6UZBUYNBeYvTDcyk/dEmXn3G7n+qorAw7zgdGNRW8kV/fQZOFUmNGHqi3zHyzqWUw==","signatures":[{"sig":"MEUCIQC66h/ul8K8Il1oClHTN2QlUwrGk1SY+qR63XPsNDtrugIgSW0E0aSXnUbSodWgn9LkwCttbj9maIZflNKzJxu8KTY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57426},"main":"atxp.js","type":"module","gitHead":"dd0c685711f28e4f5c030917c018c554f05762c8","scripts":{"test":"node --test"},"_npmUser":{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"},"repository":{"url":"git+https://github.com/atendi9/atxp.git","type":"git"},"_npmVersion":"10.8.2","description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/atxp-protocol_1.0.0_1780324200098_0.7442980144641338","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@atendi9/atxp-protocol","version":"1.0.1","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"author":{"name":"atendi9"},"license":"MIT","_id":"@atendi9/atxp-protocol@1.0.1","maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"homepage":"https://github.com/atendi9/atxp#readme","bugs":{"url":"https://github.com/atendi9/atxp/issues"},"dist":{"shasum":"bf4b8c7fe7cba7203fac88fc0a9c281f0f6d0ea4","tarball":"https://registry.npmjs.org/@atendi9/atxp-protocol/-/atxp-protocol-1.0.1.tgz","fileCount":16,"integrity":"sha512-ZYbwVZt6iK0vVqBviUeKxwX+6frCuWqNZ1y2w5V11hqzV33neqGOMzB8C+kfNuBYrEQ8/kKE6XfvM2MrTbJRrg==","signatures":[{"sig":"MEYCIQC+ZSlVEGwr4gjJ1PBnH2ys0FnpQYsQoBzYxvPPnhPblgIhANPebw8Og85qrdnu4F1nobnEyW8iqmLX8cCIJS8Poddt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63005},"main":"atxp.js","type":"module","types":"index.d.ts","gitHead":"cc571fdd9e13a39306f87f1dbb1383a5714fcca4","scripts":{"test":"node --test"},"_npmUser":{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"},"repository":{"url":"git+https://github.com/atendi9/atxp.git","type":"git"},"_npmVersion":"10.8.2","description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/atxp-protocol_1.0.1_1780328468743_0.8202646356572882","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@atendi9/atxp-protocol","version":"1.1.0","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"author":{"name":"atendi9"},"license":"MIT","_id":"@atendi9/atxp-protocol@1.1.0","maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"homepage":"https://github.com/atendi9/atxp#readme","bugs":{"url":"https://github.com/atendi9/atxp/issues"},"dist":{"shasum":"42c8e191911be90b4657a4c1c10b31433e8a5f67","tarball":"https://registry.npmjs.org/@atendi9/atxp-protocol/-/atxp-protocol-1.1.0.tgz","fileCount":16,"integrity":"sha512-m3Qk8at1b+EAD/zw2p2kO9sFK5ZVgc1hGIUeSg2eUG+3lKIqkZT0SHlcynd/pcHWAej/OsIu6ZQGzd5V1bTTHg==","signatures":[{"sig":"MEYCIQCYxGGrCZDduyBtXd8uV3y1+AzBvUV5+C1cl3+mgdCamAIhANHKWz5ZTwqToVX9CWtL45exQEFSuGyLefrEKI6JXxaq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67664},"main":"atxp.js","type":"module","types":"index.d.ts","gitHead":"50c5f847e44b64c6b4600a87e9982282d081b72e","scripts":{"test":"node --test"},"_npmUser":{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"},"repository":{"url":"git+https://github.com/atendi9/atxp.git","type":"git"},"_npmVersion":"10.8.2","description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/atxp-protocol_1.1.0_1780332464028_0.39721397277648074","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@atendi9/atxp-protocol","version":"1.2.0","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"author":{"name":"atendi9"},"license":"MIT","_id":"@atendi9/atxp-protocol@1.2.0","maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"homepage":"https://github.com/atendi9/atxp#readme","bugs":{"url":"https://github.com/atendi9/atxp/issues"},"dist":{"shasum":"950d16993a8c4836ec22f5dddfc576bd04ebfb8f","tarball":"https://registry.npmjs.org/@atendi9/atxp-protocol/-/atxp-protocol-1.2.0.tgz","fileCount":16,"integrity":"sha512-jYwftLhRjpIbE/gJlOPx6D43p1paLGehAwygd0o453bx6w1zBMLCmHoQA6dn8ebucfqcELqWk7d6FPdvx4NytQ==","signatures":[{"sig":"MEQCIC+l7ldQGBH11n7TXxYH/VBXB0m6ost5f+DWKEqXeIXTAiBvJPoReDXYTNYPIK2UNaZS9QmsMNuZyccqk0cPi44CPA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69781},"main":"atxp.js","type":"module","types":"index.d.ts","gitHead":"9aacd1ea09652806db12d420f0a90e6282ab3b45","scripts":{"test":"node --test"},"_npmUser":{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"},"repository":{"url":"git+https://github.com/atendi9/atxp.git","type":"git"},"_npmVersion":"10.8.2","description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","directories":{},"_nodeVersion":"20.20.2","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/atxp-protocol_1.2.0_1780334167954_0.03582494162653971","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@atendi9/atxp-protocol","version":"1.3.0","description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"homepage":"https://github.com/atendi9/atxp#readme","bugs":{"url":"https://github.com/atendi9/atxp/issues"},"repository":{"type":"git","url":"git+https://github.com/atendi9/atxp.git"},"license":"MIT","author":{"name":"atendi9"},"type":"module","main":"atxp.js","types":"index.d.ts","scripts":{"test":"node --test"},"_id":"@atendi9/atxp-protocol@1.3.0","gitHead":"e3cdcc874a861bd2b5f2d978685f2467096aee7d","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-ON1xq4MtApMOdnkaDh5I8LQtlNvcM0hlP7rJaBpx/23tN0X5/bTxGC/uDp6NKFQ4ayYWwOjgPvA3u/e+Spz9ag==","shasum":"ea75eea06afd03c41190423b1c22a775b33eb166","tarball":"https://registry.npmjs.org/@atendi9/atxp-protocol/-/atxp-protocol-1.3.0.tgz","fileCount":28,"unpackedSize":166186,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDa/PEXcWjbZrw9Q+44UhkMH42TYAnolk3QXzURuzzyfQIgWgi1t4VXTgNqj4fioGcsla5zfrPuh3aiu9A+6JYr1hM="}]},"_npmUser":{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"},"directories":{},"maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/atxp-protocol_1.3.0_1781615161257_0.15034784151066827"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-01T14:29:59.935Z","modified":"2026-06-16T13:06:01.557Z","1.0.0":"2026-06-01T14:30:00.224Z","1.0.1":"2026-06-01T15:41:08.877Z","1.1.0":"2026-06-01T16:47:44.177Z","1.2.0":"2026-06-01T17:16:08.102Z","1.3.0":"2026-06-16T13:06:01.445Z"},"bugs":{"url":"https://github.com/atendi9/atxp/issues"},"author":{"name":"atendi9"},"license":"MIT","homepage":"https://github.com/atendi9/atxp#readme","keywords":["atendi9","atxp","atxp-protocol","protocol","tcp"],"repository":{"type":"git","url":"git+https://github.com/atendi9/atxp.git"},"description":"lightweight, text-framed application wire protocol designed for secure, fast, and structured communication over raw TCP or encrypted TLS transport layers. ","maintainers":[{"name":"atendi9","email":"npm.atendi9.msgtp@gmail.com"}],"readme":"# ATXP (Atendi9 Transmission Exchange Protocol)\n\nA lightweight, **encrypted** application wire protocol for fast, structured communication over raw TCP or TLS. Every frame is encrypted with AES-256-GCM under a key derived from a shared password — **the password is never transmitted**. This repository provides cross-ecosystem implementations for both **Node.js (NPM)** and **Go (Golang)** with a byte-identical wire format.\n\n> ⚠️ **About V1.** The original ATXP was a proof of concept: it sent credentials and payloads in **cleartext** and its text delimiters (`\\t\\t`, `\\n\\n`, `::`) collided with arbitrary binary data, corrupting PDFs and other files. It is **insecure and deprecated** — this README documents only the secure **V2** protocol. The V1 symbols remain in the codebase for backward compatibility but must not be used on untrusted networks.\n\n## 📦 Installation\n\n### Node.js (NPM)\n\n```bash\nnpm install @atendi9/atxp-protocol\n```\n\n### Go (pkg.go.dev)\n\n```sh\ngo get -u github.com/atendi9/atxp\n```\n\n---\n\n## 🔐 Why V2 is secure\n\n| Property | Mechanism |\n| --- | --- |\n| **Confidentiality** | AES-256-GCM encrypts the whole frame. |\n| **Integrity** | GCM authentication tag detects any tampering. |\n| **Authentication** | Implicit — only a peer holding the shared password derives the key that opens frames. |\n| **Secret never on the wire** | Key is derived from the password via PBKDF2-HMAC-SHA256; the password itself is never sent. |\n| **Binary-safe** | Length-prefixed binary envelope carries PDFs/images losslessly. |\n| **DoS resistance** | Frame cap (16 MiB default, [configurable](#-tuning-the-frame-size-cap)), bounded reads, and I/O deadlines. |\n| **Replay resistance** | Strictly increasing per-connection sequence numbers. |\n\nFull details in [`docs/protocol.md`](docs/protocol.md) and [`docs/security.md`](docs/security.md).\n\n---\n\n## 🛠️ Usage Guide: Node.js\n\n### 1. Initialize a Secure Server\n\n```javascript\nimport { ServerV2, MT, ResponseCode, AuthData, validateURLHandler } from '@atendi9/atxp-protocol';\n\n// The shared password derives the encryption key. Authorization is by username\n// only — possession of the password is already proven by successful decryption.\nconst server = new ServerV2('shared-secret', (username) => {\n  if (username === 'atendi9') {\n    return { authorized: true, data: new AuthData({ role: 'admin' }) };\n  }\n  return { authorized: false, data: new AuthData(null) };\n});\n\nserver.registerHandler(MT.URL, validateURLHandler());\n\nserver.registerHandler(MT.DOCUMENT, (msg) => {\n  console.log(`[Document Received]: ${msg.filename || 'unknown'}, ${msg.data.length} encrypted bytes`);\n  return ResponseCode.OK;\n});\n\nconst listening = await server.listen(8443);\nconsole.log('ATXP V2 server running on port 8443');\n```\n\n### 2. Initialize a Secure Client\n\n```javascript\nimport net from 'node:net';\nimport { newClientV2 } from '@atendi9/atxp-protocol';\n\nconst socket = net.createConnection({ port: 8443 }, async () => {\n  // newClientV2 performs the encrypted handshake before resolving.\n  const client = await newClientV2(socket, 'shared-secret', 'atendi9');\n\n  // A binary PDF travels fully encrypted and arrives intact.\n  const fileBuffer = Buffer.from('%PDF-1.7\\n...binary content...');\n  const code = await client.sendDocument(fileBuffer, 'annual_report.pdf');\n  console.log(`Server returned: ${code}`);\n\n  client.close();\n});\n```\n\n---\n\n## 🐹 Usage Guide: Go (Golang)\n\n### 1. Initialize a Secure Server\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"log\"\n\n    \"github.com/atendi9/atxp\"\n    \"github.com/atendi9/box\"\n)\n\nfunc main() {\n    // The shared password derives the per-connection key; auth is by username.\n    server, err := atxp.NewServerV2(\"shared-secret\", func(username string) (bool, atxp.AuthData) {\n        if username == \"atendi9\" {\n            return true, box.NewSome(map[string]any{\"role\": \"admin\"})\n        }\n        return false, box.NewNone[map[string]any]()\n    })\n    if err != nil {\n        log.Fatalf(\"Failed to create server: %v\", err)\n    }\n\n    server.RegisterHandler(atxp.DOCUMENT, func(msg *atxp.Message, _ atxp.AuthData) atxp.ResponseCode {\n        fmt.Printf(\"[Go Server] Document %q received, %d encrypted bytes\\n\", msg.Filename, len(msg.Data.Get()))\n        return atxp.OK\n    })\n\n    listener, err := atxp.CreateServer(8443)\n    if err != nil {\n        log.Fatalf(\"Failed to bind listener: %v\", err)\n    }\n\n    fmt.Println(\"ATXP V2 Go server listening on port 8443...\")\n    if err := server.Serve(listener); err != nil {\n        log.Fatalf(\"Server loop failed: %v\", err)\n    }\n}\n```\n\n### 2. Initialize a Secure Client\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"log\"\n\n    \"github.com/atendi9/atxp\"\n)\n\nfunc main() {\n    conn, err := atxp.ConnectClient(\"127.0.0.1\", 8443)\n    if err != nil {\n        log.Fatalf(\"Failed to dial host: %v\", err)\n    }\n\n    // NewClientV2 performs the encrypted handshake on construction.\n    client, err := atxp.NewClientV2(conn, \"shared-secret\", \"atendi9\")\n    if err != nil {\n        log.Fatalf(\"Handshake failed: %v\", err)\n    }\n    defer client.Close()\n\n    documentBytes := []byte(\"%PDF-1.7\\n...binary content...\")\n    status, err := client.SendDocument(documentBytes, \"report.pdf\")\n    if err != nil {\n        log.Fatalf(\"Failed to send frame: %v\", err)\n    }\n\n    fmt.Printf(\"Server returned status: %v\\n\", status)\n}\n```\n\n---\n\n## 🧩 Registering custom message types\n\nV2 message types are registrable at runtime. Codes must be unique and fit in a `uint32`.\n\n```go\natxp.NewMT(atxp.MT_V2{Name: \"WEBHOOK\", Code: 100, Description: \"external webhook registration\"}) // Go\n```\n```javascript\nnewMT({ name: 'WEBHOOK', code: 100, description: 'external webhook registration' }); // JS\n```\n\nThen send with the custom code:\n\n```go\nclient.Send(100, payload, \"\")            // Go\n```\n```javascript\nawait client.send(100, payload, '');     // JS\n```\n\n---\n\n## 📏 Tuning the frame size cap\n\nEach encrypted frame is capped at **16 MiB by default** to bound memory use. Beefier servers that must transfer larger documents can raise the cap — and constrained environments can lower it. Set it on both the server and the client (a sender's cap must not exceed the receiver's, or large frames are rejected):\n\n```go\n// Go — 64 MiB cap. Values below the minimum valid frame size are ignored.\nserver, _ := atxp.NewServerV2(\"shared-secret\", authFn, atxp.WithMaxFrameSize(64<<20))\nclient, _ := atxp.NewClientV2(conn, \"shared-secret\", \"atendi9\", atxp.WithMaxFrameSize(64<<20))\n```\n```javascript\n// Node.js — 64 MiB cap via the options object.\nconst server = new ServerV2('shared-secret', authFn, { maxFrameSize: 64 * 1024 * 1024 });\nconst client = await newClientV2(socket, 'shared-secret', 'atendi9', { maxFrameSize: 64 * 1024 * 1024 });\n```\n\n---\n\n## 📑 V2 Wire Protocol Specification\n\nEach connection begins with a server-initiated handshake, after which every frame is encrypted.\n\n**Handshake (22 bytes, server → client):**\n\n```text\n\"ATXP2\" (5B magic) | version (1B = 0x02) | salt (16B random)\n```\n\nBoth peers derive `K = PBKDF2-HMAC-SHA256(password, salt, 600000, 32)`.\n\n**Encrypted frame (both directions):**\n\n```text\nlength (4B BE uint32) | nonce (12B) | AES-256-GCM(ciphertext + tag)\n```\n\n**Inner plaintext envelope (length-prefixed, binary-safe):**\n\n```text\nkind (1B)            # 0x01 = Message, 0x02 = Response\nseq  (8B BE uint64)  # monotonic per connection (anti-replay)\nmtCode      (4B BE) | payloadLen (4B) | payload | userLen (4B) | username | fnameLen (4B) | filename\n```\n\nThere is **no password field** anywhere on the wire. See [`docs/protocol.md`](docs/protocol.md) for the complete specification, including cross-language known-answer test vectors.\n\n### Built-in Message Types\n\n| Name | `MT.X` (Node.js) | `atxp.X` (Go) | Code | Description |\n| --- | --- | --- | --- | --- |\n| **URL** | `MT.URL` | `atxp.URL` | `0` | URLs / webhook registration. |\n| **DOCUMENT** | `MT.DOCUMENT` | `atxp.DOCUMENT` | `1` | Binary file transfer with optional filename. |\n| **NOTIFICATION** | `MT.NOTIFICATION` | `atxp.NOTIFICATION` | `2` | JSON or events for event-driven architectures. |\n\n---\n\n## 📜 License\n\nDistributed under the terms of the open-source **MIT License**.\n","readmeFilename":"README.md"}