Add comprehensive installation and setup documentation

- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
This commit is contained in:
Dorian
2026-01-27 17:18:21 +00:00
parent a81f655133
commit 0d073fa89e
22658 changed files with 4494151 additions and 6 deletions
+161
View File
@@ -0,0 +1,161 @@
# [4.0.0](https://github.com/webtorrent/node-bencode/compare/v3.1.0...v4.0.0) (2023-08-09)
### chore
* force major release ([#156](https://github.com/webtorrent/node-bencode/issues/156)) ([a075f8a](https://github.com/webtorrent/node-bencode/commit/a075f8a02408eb4bf82350d1bfce9f0488e15e0e))
### BREAKING CHANGES
* update uint8-util
# [3.1.0](https://github.com/webtorrent/node-bencode/compare/v3.0.3...v3.1.0) (2023-07-31)
### Features
* update uint8-util ([#153](https://github.com/webtorrent/node-bencode/issues/153)) ([7941736](https://github.com/webtorrent/node-bencode/commit/79417361876a5e5b6b9b17260a5ede8042cfa3e6))
## [3.0.3](https://github.com/webtorrent/node-bencode/compare/v3.0.2...v3.0.3) (2023-01-31)
### Bug Fixes
* update dependency nanobench to v3 ([#130](https://github.com/webtorrent/node-bencode/issues/130)) ([f7027c4](https://github.com/webtorrent/node-bencode/commit/f7027c46f9cf86017f388fa6d811417b13e03e8e))
## [3.0.2](https://github.com/webtorrent/node-bencode/compare/v3.0.1...v3.0.2) (2023-01-31)
### Bug Fixes
* package.json for exporting lib ([#140](https://github.com/webtorrent/node-bencode/issues/140)) ([f63c09a](https://github.com/webtorrent/node-bencode/commit/f63c09a8a525e67b00cc0e7619eb84bd159855b2))
## [3.0.1](https://github.com/webtorrent/node-bencode/compare/v3.0.0...v3.0.1) (2023-01-31)
### Bug Fixes
* imports ([#138](https://github.com/webtorrent/node-bencode/issues/138)) ([abe29c3](https://github.com/webtorrent/node-bencode/commit/abe29c32ab327fafb323b05f17eda0aa9ca32478))
# [3.0.0](https://github.com/webtorrent/node-bencode/compare/v2.0.3...v3.0.0) (2022-11-28)
### Features
* esm ([#131](https://github.com/webtorrent/node-bencode/issues/131)) ([b111818](https://github.com/webtorrent/node-bencode/commit/b111818695c8e85e1268fa771fc49c7c6687167f))
### BREAKING CHANGES
* ESM only
## [2.0.3](https://github.com/webtorrent/node-bencode/compare/v2.0.2...v2.0.3) (2022-05-13)
## [2.0.2](https://github.com/webtorrent/node-bencode/compare/v2.0.1...v2.0.2) (2021-07-28)
### Bug Fixes
* Patch release to drop a dependecy to safe-buffer ([#99](https://github.com/webtorrent/node-bencode/issues/99)) ([a661715](https://github.com/webtorrent/node-bencode/commit/a6617150c53c3c00d0cd12c685c5f2ee47db30c0))
## 2.0.1
- fix deprecation warning on Buffer() constructor (@jhermsmeier)
- update dev depedencies (@jhermsmeier)
## 2.0.0
- Drop support for Node 0.10, 0.12., add support for Node 8 & 9 (@jhermsmeier)
- Support for typed arrays (@jhermsmeier, @nazar-pc)
## 1.0.0
- Support Node 0.10, 0.12, and early Node 4 (@feross)
## 0.12.0
- Add `btparse` to benchmarks (@themasch)
- Use `Buffer.from()` & `Buffer.allocUnsafe()` (@slang800)
- Use constants for character codes (@slang800)
- Fix Makefile (@zunsthy)
## 0.11.0
- Ignore null-values when encoding (@jhermsmeier)
- Add test/BEP-0023: Test correct handling of compacted peer lists (@jhermsmeier)
- Implement a faster way to parse intergers from buffers (@themasch)
- Fix string to be decoded in README (@ngotchac)
## 0.10.0
- Add `standard` code style (@slang800)
- Update benchmarks (@slang800)
- Remove `lib/dict.js` (@slang800)
- Move `main` entrypoint into ./lib (@slang800)
- Clean up `package.json` (@slang800)
- Remove extra files from being published to npm (@slang800)
## 0.9.0
- Implement the `abstract-encoding` API (@jhermsmeier)
## 0.8.0
- Add support for encoding `Boolean` values (@kaelar)
## 0.7.0
- Add binary key support (@deoxxa)
- Improve test output format (@jhermsmeier)
- Removed node v0.8 from CI tests
## 0.6.0
- Fixed invalid test data (@themasch)
- Added `Makefile` for browser tests (@themasch)
- Fixed Browserify compatibility (@themasch)
## 0.5.2
- Thorough fix for 64 bit and 53 bit numbers (@pwmckenna)
## 0.5.1
- Added warning on float conversion during encoding (@jhermsmeier)
## 0.5.0
- Added support for 64 bit number values (@pwmckenna)
- Switched benchmark lib to `matcha` (@themasch)
- Fixed npm scripts to work on Windows (@jhermsmeier)
## 0.4.3
* improved performance a lot
* dropped support for de- and encoding floats to respect the spec
*note:* node-bencode will still decodes stuff like "i42.23e" but will cast the
result to an interger
## 0.4.2
* bugfix: sort dictionary keys to follow the spec
## 0.4.1
* bugfix: number decoding was kinda broken
## 0.4.0
* fixed problems with multibyte strings
* some performance improvements
* improved code quality
## 0.3.0
* #decode() accepts a encoding as its second paramtere
## 0.2.0
* complete rewrite, @jhermsmeier joins the team
## 0.1.0
* added encoding
## 0.0.1
First version, decoding only
+11
View File
@@ -0,0 +1,11 @@
# Just a plain list of people who contributed to this project.
# People who are already listed in AUTHORS are not listed again.
Conrad Pankoff <deoxxa@fknsrs.biz>
Patrick Williams <patrick@bittorrent.com>
Jeffrey Hwang <kaelar@gmail.com>
Sean Lang <slang800@gmail.com>
Nicolas Gotchac <ngotchac@gmail.com>
Feross Aboukhadijeh <feross@feross.org>
Nazar Mokrynskyi <nazar@mokrynskyi.com>
Jimmy Wärting <jimmy@warting.se>
+23
View File
@@ -0,0 +1,23 @@
The MIT License (MIT)
=====================
Copyright (c) 2010 Mark Schmale
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+137
View File
@@ -0,0 +1,137 @@
# Bencode
[![npm](https://img.shields.io/npm/v/bencode.svg)](https://npmjs.com/bencode)
[![npm downloads](https://img.shields.io/npm/dm/bencode.svg)](https://npmjs.com/bencode)
[![ci](https://github.com/webtorrent/node-bencode/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/webtorrent/node-bencode/actions/workflows/ci.yml)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fwebtorrent%2Fnode-bencode.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fwebtorrent%2Fnode-bencode?ref=badge_shield)
A node library for encoding and decoding bencoded data,
according to the [BitTorrent specification](http://www.bittorrent.org/beps/bep_0003.html).
## Index
- [About BEncoding](#about-bencoding)
- [Installation](#install-with-npm)
- [Usage](#usage)
- [API](#api)
## About BEncoding
from [Wikipedia](https://en.wikipedia.org/wiki/Bencoding):
Bencode (pronounced like B encode) is the encoding used by the peer-to-peer
file sharing system BitTorrent for storing and transmitting loosely structured data.
It supports four different types of values:
- byte strings
- integers
- lists
- dictionaries
Bencoding is most commonly used in torrent files.
These metadata files are simply bencoded dictionaries.
## Install with [npm](https://npmjs.org)
```
npm install bencode
```
## Usage
```javascript
import bencode from 'bencode'
```
You can also use node-bencode with browserify to be able to use it in a lot of modern browsers.
### Encoding
```javascript
var data = {
string: 'Hello World',
integer: 12345,
dict: {
key: 'This is a string within a dictionary'
},
list: [ 1, 2, 3, 4, 'string', 5, {} ]
}
var result = bencode.encode( data )
```
**NOTE** As of `bencode@0.8.0`, boolean values will be cast to integers (false -> 0, true -> 1).
#### Output
```
d4:dictd3:key36:This is a string within a dictionarye7:integeri12345e4:listli1ei2ei3ei4e6:stringi5edee6:string11:Hello Worlde
```
### Decoding
```javascript
var data = Buffer.from('d6:string11:Hello World7:integeri12345e4:dictd3:key36:This is a string within a dictionarye4:listli1ei2ei3ei4e6:stringi5edeee')
var result = bencode.decode( data )
```
#### Output
```javascript
{
string: <Buffer 48 65 6c 6c 6f 20 57 6f 72 6c 64>,
integer: 12345,
dict: {
key: <Buffer 54 68 69 73 20 69 73 20 61 20 73 74 72 69 6e 67 20 77 69 74 68 69 6e 20 61 20 64 69 63 74 69 6f 6e 61 72 79>
},
list: [ 1, 2, 3, 4, <Buffer 73 74 72 69 6e 67>, 5, {} ]
}
```
Automagically convert bytestrings to strings:
```javascript
var result = bencode.decode( data, 'utf8' )
```
#### Output
```javascript
{
string: 'Hello World',
integer: 12345,
dict: {
key: 'This is a string within a dictionary'
},
list: [ 1, 2, 3, 4, 'string', 5, {} ]
}
```
## API
The API is compatible with the [`abstract-encoding`](https://github.com/mafintosh/abstract-encoding) specification.
### bencode.encode( *data*, *[buffer]*, *[offset]* )
> `Buffer` | `Array` | `String` | `Object` | `Number` | `Boolean` __data__
> `Buffer` __buffer__
> `Number` __offset__
Returns `Buffer`
### bencode.decode( *data*, *[start]*, *[end]*, *[encoding]* )
> `Buffer` __data__
> `Number` __start__
> `Number` __end__
> `String` __encoding__
If `encoding` is set, bytestrings are
automatically converted to strings.
Returns `Object` | `Array` | `Buffer` | `String` | `Number`
### bencode.byteLength( *value* ) or bencode.encodingLength( *value* )
> `Buffer` | `Array` | `String` | `Object` | `Number` | `Boolean` __value__
+11
View File
@@ -0,0 +1,11 @@
import encode from './lib/encode.js'
import decode from './lib/decode.js'
import byteLength from './lib/encoding-length.js'
/**
* Determines the amount of bytes
* needed to encode the given value
* @param {Object|Array|Uint8Array|String|Number|Boolean} value
* @return {Number} byteCount
*/
const encodingLength = byteLength
export default { encode, decode, byteLength, encodingLength }
+173
View File
@@ -0,0 +1,173 @@
import { arr2text, text2arr, arr2hex } from 'uint8-util'
const INTEGER_START = 0x69 // 'i'
const STRING_DELIM = 0x3A // ':'
const DICTIONARY_START = 0x64 // 'd'
const LIST_START = 0x6C // 'l'
const END_OF_TYPE = 0x65 // 'e'
/**
* replaces parseInt(buffer.toString('ascii', start, end)).
* For strings with less then ~30 charachters, this is actually a lot faster.
*
* @param {Uint8Array} data
* @param {Number} start
* @param {Number} end
* @return {Number} calculated number
*/
function getIntFromBuffer (buffer, start, end) {
let sum = 0
let sign = 1
for (let i = start; i < end; i++) {
const num = buffer[i]
if (num < 58 && num >= 48) {
sum = sum * 10 + (num - 48)
continue
}
if (i === start && num === 43) { // +
continue
}
if (i === start && num === 45) { // -
sign = -1
continue
}
if (num === 46) { // .
// its a float. break here.
break
}
throw new Error('not a number: buffer[' + i + '] = ' + num)
}
return sum * sign
}
/**
* Decodes bencoded data.
*
* @param {Uint8Array} data
* @param {Number} start (optional)
* @param {Number} end (optional)
* @param {String} encoding (optional)
* @return {Object|Array|Uint8Array|String|Number}
*/
function decode (data, start, end, encoding) {
if (data == null || data.length === 0) {
return null
}
if (typeof start !== 'number' && encoding == null) {
encoding = start
start = undefined
}
if (typeof end !== 'number' && encoding == null) {
encoding = end
end = undefined
}
decode.position = 0
decode.encoding = encoding || null
decode.data = !(ArrayBuffer.isView(data))
? text2arr(data)
: new Uint8Array(data.slice(start, end))
decode.bytes = decode.data.length
return decode.next()
}
decode.bytes = 0
decode.position = 0
decode.data = null
decode.encoding = null
decode.next = function () {
switch (decode.data[decode.position]) {
case DICTIONARY_START:
return decode.dictionary()
case LIST_START:
return decode.list()
case INTEGER_START:
return decode.integer()
default:
return decode.buffer()
}
}
decode.find = function (chr) {
let i = decode.position
const c = decode.data.length
const d = decode.data
while (i < c) {
if (d[i] === chr) return i
i++
}
throw new Error(
'Invalid data: Missing delimiter "' +
String.fromCharCode(chr) + '" [0x' +
chr.toString(16) + ']'
)
}
decode.dictionary = function () {
decode.position++
const dict = {}
while (decode.data[decode.position] !== END_OF_TYPE) {
const buffer = decode.buffer()
let key = arr2text(buffer)
if (key.includes('\uFFFD')) key = arr2hex(buffer)
dict[key] = decode.next()
}
decode.position++
return dict
}
decode.list = function () {
decode.position++
const lst = []
while (decode.data[decode.position] !== END_OF_TYPE) {
lst.push(decode.next())
}
decode.position++
return lst
}
decode.integer = function () {
const end = decode.find(END_OF_TYPE)
const number = getIntFromBuffer(decode.data, decode.position + 1, end)
decode.position += end + 1 - decode.position
return number
}
decode.buffer = function () {
let sep = decode.find(STRING_DELIM)
const length = getIntFromBuffer(decode.data, decode.position, sep)
const end = ++sep + length
decode.position = end
return decode.encoding
? arr2text(decode.data.slice(sep, end))
: decode.data.slice(sep, end)
}
export default decode
+136
View File
@@ -0,0 +1,136 @@
import { concat, text2arr } from 'uint8-util'
import { getType } from './util.js'
/**
* Encodes data in bencode.
*
* @param {Uint8Array|Array|String|Object|Number|Boolean} data
* @return {Uint8Array}
*/
function encode (data, buffer, offset) {
const buffers = []
let result = null
encode._encode(buffers, data)
result = concat(buffers)
encode.bytes = result.length
if (ArrayBuffer.isView(buffer)) {
buffer.set(result, offset)
return buffer
}
return result
}
encode.bytes = -1
encode._floatConversionDetected = false
encode._encode = function (buffers, data) {
if (data == null) { return }
switch (getType(data)) {
case 'object': encode.dict(buffers, data); break
case 'map': encode.dictMap(buffers, data); break
case 'array': encode.list(buffers, data); break
case 'set': encode.listSet(buffers, data); break
case 'string': encode.string(buffers, data); break
case 'number': encode.number(buffers, data); break
case 'boolean': encode.number(buffers, data); break
case 'arraybufferview': encode.buffer(buffers, new Uint8Array(data.buffer, data.byteOffset, data.byteLength)); break
case 'arraybuffer': encode.buffer(buffers, new Uint8Array(data)); break
}
}
const buffE = new Uint8Array([0x65])
const buffD = new Uint8Array([0x64])
const buffL = new Uint8Array([0x6C])
encode.buffer = function (buffers, data) {
buffers.push(text2arr(data.length + ':'), data)
}
encode.string = function (buffers, data) {
buffers.push(text2arr(text2arr(data).byteLength + ':' + data))
}
encode.number = function (buffers, data) {
if (Number.isInteger(data)) return buffers.push(text2arr('i' + BigInt(data) + 'e'))
const maxLo = 0x80000000
const hi = (data / maxLo) << 0
const lo = (data % maxLo) << 0
const val = hi * maxLo + lo
buffers.push(text2arr('i' + val + 'e'))
if (val !== data && !encode._floatConversionDetected) {
encode._floatConversionDetected = true
console.warn(
'WARNING: Possible data corruption detected with value "' + data + '":',
'Bencoding only defines support for integers, value was converted to "' + val + '"'
)
console.trace()
}
}
encode.dict = function (buffers, data) {
buffers.push(buffD)
let j = 0
let k
// fix for issue #13 - sorted dicts
const keys = Object.keys(data).sort()
const kl = keys.length
for (; j < kl; j++) {
k = keys[j]
if (data[k] == null) continue
encode.string(buffers, k)
encode._encode(buffers, data[k])
}
buffers.push(buffE)
}
encode.dictMap = function (buffers, data) {
buffers.push(buffD)
const keys = Array.from(data.keys()).sort()
for (const key of keys) {
if (data.get(key) == null) continue
ArrayBuffer.isView(key)
? encode._encode(buffers, key)
: encode.string(buffers, String(key))
encode._encode(buffers, data.get(key))
}
buffers.push(buffE)
}
encode.list = function (buffers, data) {
let i = 0
const c = data.length
buffers.push(buffL)
for (; i < c; i++) {
if (data[i] == null) continue
encode._encode(buffers, data[i])
}
buffers.push(buffE)
}
encode.listSet = function (buffers, data) {
buffers.push(buffL)
for (const item of data) {
if (item == null) continue
encode._encode(buffers, item)
}
buffers.push(buffE)
}
export default encode
+69
View File
@@ -0,0 +1,69 @@
import { text2arr } from 'uint8-util'
import { digitCount, getType } from './util.js'
function listLength (list) {
let length = 1 + 1 // type marker + end-of-type marker
for (const value of list) {
length += encodingLength(value)
}
return length
}
function mapLength (map) {
let length = 1 + 1 // type marker + end-of-type marker
for (const [key, value] of map) {
const keyLength = text2arr(key).byteLength
length += digitCount(keyLength) + 1 + keyLength
length += encodingLength(value)
}
return length
}
function objectLength (value) {
let length = 1 + 1 // type marker + end-of-type marker
const keys = Object.keys(value)
for (let i = 0; i < keys.length; i++) {
const keyLength = text2arr(keys[i]).byteLength
length += digitCount(keyLength) + 1 + keyLength
length += encodingLength(value[keys[i]])
}
return length
}
function stringLength (value) {
const length = text2arr(value).byteLength
return digitCount(length) + 1 + length
}
function arrayBufferLength (value) {
const length = value.byteLength - value.byteOffset
return digitCount(length) + 1 + length
}
function encodingLength (value) {
const length = 0
if (value == null) return length
const type = getType(value)
switch (type) {
case 'arraybufferview': return arrayBufferLength(value)
case 'string': return stringLength(value)
case 'array': case 'set': return listLength(value)
case 'number': return 1 + digitCount(Math.floor(value)) + 1
case 'bigint': return 1 + value.toString().length + 1
case 'object': return objectLength(value)
case 'map': return mapLength(value)
default:
throw new TypeError(`Unsupported value of type "${type}"`)
}
}
export default encodingLength
+20
View File
@@ -0,0 +1,20 @@
export function digitCount (value) {
// Add a digit for negative numbers, as the sign will be prefixed
const sign = value < 0 ? 1 : 0
// Guard against negative numbers & zero going into log10(),
// as that would return -Infinity
value = Math.abs(Number(value || 1))
return Math.floor(Math.log10(value)) + 1 + sign
}
export function getType (value) {
if (ArrayBuffer.isView(value)) return 'arraybufferview'
if (Array.isArray(value)) return 'array'
if (value instanceof Number) return 'number'
if (value instanceof Boolean) return 'boolean'
if (value instanceof Set) return 'set'
if (value instanceof Map) return 'map'
if (value instanceof String) return 'string'
if (value instanceof ArrayBuffer) return 'arraybuffer'
return typeof value
}
+72
View File
@@ -0,0 +1,72 @@
{
"name": "bencode",
"description": "Bencode de/encoder",
"version": "4.0.0",
"bugs": {
"url": "https://github.com/webtorrent/node-bencode/issues"
},
"type": "module",
"contributors": [
{
"name": "Mark Schmale",
"email": "masch@masch.it",
"url": "http://masch.it/"
},
{
"name": "Jonas Hermsmeier",
"email": "jhermsmeier@gmail.com",
"url": "https://jhermsmeier.de/"
}
],
"devDependencies": {
"@webtorrent/semantic-release-config": "1.0.10",
"bencoding": "latest",
"bncode": "latest",
"browserify": "^17.0.0",
"btparse": "latest",
"dht-bencode": "latest",
"dht.js": "latest",
"nanobench": "3.0.0",
"semantic-release": "21.0.7",
"standard": "17.1.0",
"tap-spec": "5.0.0",
"tape": "5.6.6"
},
"keywords": [
"bdecode",
"bencode",
"bencoding",
"bittorrent",
"torrent"
],
"license": "MIT",
"engines": {
"node": ">=12.20.0"
},
"exports": {
"import": "./index.js"
},
"repository": {
"type": "git",
"url": "git://github.com/webtorrent/node-bencode.git"
},
"scripts": {
"benchmark": "nanobench benchmark/*.js",
"bundle": "mkdir -p dist && npm run bundle:lib && npm run bundle:test",
"bundle:lib": "browserify lib/index.js -s bencode -o dist/bencode.js",
"bundle:test": "browserify test/*.test.js -o dist/tests.js",
"style": "standard --fix",
"test": "standard && tape test/*.test.js | tap-spec"
},
"renovate": {
"extends": [
"github>webtorrent/renovate-config"
]
},
"release": {
"extends": "@webtorrent/semantic-release-config"
},
"dependencies": {
"uint8-util": "^2.2.2"
}
}