json-web3
v1.3.1
Published
BigInt-safe JSON serialization and deserialization for Web3 use cases.
Maintainers
Readme
json-web3
BigInt-safe JSON serialization and deserialization for Web3 data.
Install
pnpm add json-web3
# or
npm i json-web3
# or
yarn add json-web3Usage
import jsonWeb3 from 'json-web3'
const payload = {
balance: 1234567890123456789n,
decimals: 18n,
u8Array: new Uint8Array([1, 2, 3, 255]),
u16Array: new Uint16Array([1, 2, 3, 255]),
bigIntArray: new BigInt64Array([18446744073709551615n, 2n, 3n, 255n]),
createdAt: new Date('2020-01-02T03:04:05.006Z'),
ids: new Set([123, 456]),
headers: new Map([['hello', 'world']]),
re: /([^\s]+)/g,
url: new URL('https://example.com/'),
fn: function echo(arg) {
return arg
},
}
const text = jsonWeb3.stringify(payload)
// => {"balance":{"[email protected]__":"1234567890123456789"},"decimals":{"[email protected]__":"18"},"u8Array":{"[email protected]__":{"type":"Uint8Array","bytes":"0x010203ff"}},"u16Array":{"[email protected]__":{"type":"Uint16Array","bytes":"0x010002000300ff00"}},"bigIntArray":{"[email protected]__":{"type":"BigInt64Array","bytes":"0xffffffffffffffff02000000000000000300000000000000ff00000000000000"}}}
const restored = jsonWeb3.parse(text)
/* =>
{
balance: 1234567890123456789n,
decimals: 18n,
u8Array: Uint8Array(4) [1, 2, 3, 255]...,
u16Array: Uint16Array(4)...,
bigIntArray: BigInt64Array(4)...,
createdAt: Date(...),
ids: Set(2) {...},
headers: Map(1) {...},
re: /([^\s]+)/g,
url: URL(...),
fn: undefined
}
*/
const textUnsafe = jsonWeb3.stringify_UNSAFE(payload)
const restoredUnsafe = jsonWeb3.parse_UNSAFE(textUnsafe)
// restoredUnsafe.fn is a callable functionAPI (Fully compatible with native globalThis.JSON)
stringify(value, replacer?, space?)parse(text, reviver?)stringify_UNSAFE(value, replacer?, space?)(serializesFunctionpayloads)parse_UNSAFE(text, reviver?)(revivesFunctionpayloads vianew Function(...))
Type support
| type | supported by standard JSON? | supported by json-web3? |
| ------------------- | --------------------------- | ------------------------------------- |
| string | ✅ | ✅ |
| number | ✅ | ✅ |
| boolean | ✅ | ✅ |
| null | ✅ | ✅ |
| Array | ✅ | ✅ |
| Object | ✅ | ✅ |
| undefined | ❌ | ❌ |
| Infinity | ❌ | ✅ |
| -Infinity | ❌ | ✅ |
| NaN | ❌ | ✅ |
| BigInt | ❌ | ✅ |
| Date | ❌ | ✅ |
| RegExp | ❌ | ✅ |
| Set | ❌ | ✅ |
| Map | ❌ | ✅ |
| URL | ❌ | ✅ |
| ArrayBuffer | ❌ | ✅ |
| Uint8Array | ❌ | ✅ |
| Uint8ClampedArray | ❌ | ✅ |
| Uint16Array | ❌ | ✅ |
| Uint32Array | ❌ | ✅ |
| Int8Array | ❌ | ✅ |
| Int16Array | ❌ | ✅ |
| Int32Array | ❌ | ✅ |
| Float16Array | ❌ | ✅ |
| Float32Array | ❌ | ✅ |
| Float64Array | ❌ | ✅ |
| BigInt64Array | ❌ | ✅ |
| BigUint64Array | ❌ | ✅ |
| Function | ❌ | ✅ ⚠️(use UNSAFE api, it's dangerous) |
Note
bigintvalues are encoded as objects:{"[email protected]__":"<value>"}.- Non-finite numbers (
NaN,Infinity,-Infinity) are encoded as{"[email protected]__":"<value>"}. Datevalues are encoded as{"[email protected]__":<timestamp>}.Mapvalues are encoded as{"[email protected]__":[[k,v],...]}andSetvalues as{"[email protected]__":[...]}.RegExpvalues are encoded as{"[email protected]__":{"source":"...","flags":"..."}}.URLvalues are encoded as{"[email protected]__":"..."}.Functionvalues are encoded as{"[email protected]__":"<source>"}bystringify_UNSAFEand are only revived byparse_UNSAFEusingnew Function(...)(using the UNSAFE function pair is dangerous; make sure your data is trusted).ArrayBuffervalues are encoded as{"[email protected]__":{"bytes":"0x..."}}and decoded back toArrayBuffer.- Node
BufferJSON shapes and typed arrays are encoded as{"[email protected]__":{"type":"<Name>","bytes":"0x..."}}and decoded back to the original typed array (Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array,Int8Array,Int16Array,Int32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array).
Compared to libraries that require eval-based parsing (for example, serialize-javascript), this approach is generally safer and more efficient.
