ripple-binary-codec 1.7.1 → 1.9.0
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/dist/enums/definitions.json +250 -1
- package/dist/enums/src/enums/definitions.json +250 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/issue.d.ts +39 -0
- package/dist/types/issue.js +81 -0
- package/dist/types/issue.js.map +1 -0
- package/dist/types/xchain-bridge.d.ts +45 -0
- package/dist/types/xchain-bridge.js +102 -0
- package/dist/types/xchain-bridge.js.map +1 -0
- package/package.json +3 -4
- package/src/README.md +3 -0
- package/src/binary.ts +188 -0
- package/src/coretypes.ts +31 -0
- package/src/enums/README.md +144 -0
- package/src/enums/bytes.ts +75 -0
- package/src/enums/constants.ts +4 -0
- package/src/enums/definitions.json +2599 -0
- package/src/enums/field.ts +85 -0
- package/src/enums/index.ts +34 -0
- package/src/enums/utils-renumber.ts +134 -0
- package/src/enums/xrpl-definitions-base.ts +111 -0
- package/src/enums/xrpl-definitions.ts +32 -0
- package/src/hash-prefixes.ts +40 -0
- package/src/hashes.ts +76 -0
- package/src/index.ts +141 -0
- package/src/ledger-hashes.ts +187 -0
- package/src/quality.ts +39 -0
- package/src/serdes/binary-parser.ts +217 -0
- package/src/serdes/binary-serializer.ts +166 -0
- package/src/shamap.ts +186 -0
- package/src/types/account-id.ts +86 -0
- package/src/types/amount.ts +256 -0
- package/src/types/blob.ts +43 -0
- package/src/types/currency.ts +140 -0
- package/src/types/hash-128.ts +33 -0
- package/src/types/hash-160.ts +20 -0
- package/src/types/hash-256.ts +16 -0
- package/src/types/hash.ts +81 -0
- package/src/types/index.ts +61 -0
- package/src/types/issue.ts +96 -0
- package/src/types/path-set.ts +290 -0
- package/src/types/serialized-type.ts +120 -0
- package/src/types/st-array.ts +107 -0
- package/src/types/st-object.ts +192 -0
- package/src/types/uint-16.ts +49 -0
- package/src/types/uint-32.ts +56 -0
- package/src/types/uint-64.ts +105 -0
- package/src/types/uint-8.ts +49 -0
- package/src/types/uint.ts +57 -0
- package/src/types/vector-256.ts +84 -0
- package/test/amount.test.js +0 -43
- package/test/binary-json.test.js +0 -45
- package/test/binary-parser.test.js +0 -396
- package/test/binary-serializer.test.js +0 -289
- package/test/definitions.test.js +0 -160
- package/test/fixtures/account-tx-transactions.db +0 -0
- package/test/fixtures/codec-fixtures.json +0 -4466
- package/test/fixtures/data-driven-tests.json +0 -2919
- package/test/fixtures/delivermin-tx-binary.json +0 -1
- package/test/fixtures/delivermin-tx.json +0 -98
- package/test/fixtures/deposit-preauth-tx-binary.json +0 -1
- package/test/fixtures/deposit-preauth-tx-meta-binary.json +0 -1
- package/test/fixtures/deposit-preauth-tx.json +0 -58
- package/test/fixtures/escrow-cancel-binary.json +0 -1
- package/test/fixtures/escrow-cancel-tx.json +0 -6
- package/test/fixtures/escrow-create-binary.json +0 -1
- package/test/fixtures/escrow-create-tx.json +0 -10
- package/test/fixtures/escrow-finish-binary.json +0 -1
- package/test/fixtures/escrow-finish-meta-binary.json +0 -1
- package/test/fixtures/escrow-finish-tx.json +0 -95
- package/test/fixtures/ledger-full-38129.json +0 -1
- package/test/fixtures/ledger-full-40000.json +0 -1
- package/test/fixtures/negative-unl.json +0 -12
- package/test/fixtures/nf-token.json +0 -547
- package/test/fixtures/payment-channel-claim-binary.json +0 -1
- package/test/fixtures/payment-channel-claim-tx.json +0 -8
- package/test/fixtures/payment-channel-create-binary.json +0 -1
- package/test/fixtures/payment-channel-create-tx.json +0 -11
- package/test/fixtures/payment-channel-fund-binary.json +0 -1
- package/test/fixtures/payment-channel-fund-tx.json +0 -7
- package/test/fixtures/signerlistset-tx-binary.json +0 -1
- package/test/fixtures/signerlistset-tx-meta-binary.json +0 -1
- package/test/fixtures/signerlistset-tx.json +0 -94
- package/test/fixtures/ticket-create-binary.json +0 -1
- package/test/fixtures/ticket-create-tx.json +0 -7
- package/test/fixtures/x-codec-fixtures.json +0 -188
- package/test/hash.test.js +0 -135
- package/test/ledger.test.js +0 -29
- package/test/lower-case-hex.test.js +0 -46
- package/test/pseudo-transaction.test.js +0 -38
- package/test/quality.test.js +0 -15
- package/test/shamap.test.js +0 -89
- package/test/signing-data-encoding.test.js +0 -242
- package/test/tx-encode-decode.test.js +0 -119
- package/test/types.test.js +0 -34
- package/test/uint.test.js +0 -148
- package/test/utils.js +0 -30
- package/test/x-address.test.js +0 -181
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Bytes } from './bytes'
|
|
2
|
+
import { SerializedType } from '../types/serialized-type'
|
|
3
|
+
import { TYPE_WIDTH } from './constants'
|
|
4
|
+
import { Buffer } from 'buffer/'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Encoding information for a rippled field, often used in transactions.
|
|
8
|
+
* See the enums [README.md](https://github.com/XRPLF/xrpl.js/tree/main/packages/ripple-binary-codec/src/enums) for more details on what each means.
|
|
9
|
+
*/
|
|
10
|
+
export interface FieldInfo {
|
|
11
|
+
nth: number
|
|
12
|
+
isVLEncoded: boolean
|
|
13
|
+
isSerialized: boolean
|
|
14
|
+
isSigningField: boolean
|
|
15
|
+
type: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface FieldInstance {
|
|
19
|
+
readonly nth: number
|
|
20
|
+
readonly isVariableLengthEncoded: boolean
|
|
21
|
+
readonly isSerialized: boolean
|
|
22
|
+
readonly isSigningField: boolean
|
|
23
|
+
readonly type: Bytes
|
|
24
|
+
readonly ordinal: number
|
|
25
|
+
readonly name: string
|
|
26
|
+
readonly header: Buffer
|
|
27
|
+
readonly associatedType: typeof SerializedType
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* @brief: Serialize a field based on type_code and Field.nth
|
|
32
|
+
*/
|
|
33
|
+
function fieldHeader(type: number, nth: number): Buffer {
|
|
34
|
+
const header: Array<number> = []
|
|
35
|
+
if (type < 16) {
|
|
36
|
+
if (nth < 16) {
|
|
37
|
+
header.push((type << 4) | nth)
|
|
38
|
+
} else {
|
|
39
|
+
header.push(type << 4, nth)
|
|
40
|
+
}
|
|
41
|
+
} else if (nth < 16) {
|
|
42
|
+
header.push(nth, type)
|
|
43
|
+
} else {
|
|
44
|
+
header.push(0, type, nth)
|
|
45
|
+
}
|
|
46
|
+
return Buffer.from(header)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function buildField(
|
|
50
|
+
[name, info]: [string, FieldInfo],
|
|
51
|
+
typeOrdinal: number,
|
|
52
|
+
): FieldInstance {
|
|
53
|
+
const field = fieldHeader(typeOrdinal, info.nth)
|
|
54
|
+
return {
|
|
55
|
+
name: name,
|
|
56
|
+
nth: info.nth,
|
|
57
|
+
isVariableLengthEncoded: info.isVLEncoded,
|
|
58
|
+
isSerialized: info.isSerialized,
|
|
59
|
+
isSigningField: info.isSigningField,
|
|
60
|
+
ordinal: (typeOrdinal << 16) | info.nth,
|
|
61
|
+
type: new Bytes(info.type, typeOrdinal, TYPE_WIDTH),
|
|
62
|
+
header: field,
|
|
63
|
+
associatedType: SerializedType, // For later assignment in ./types/index.js or Definitions.updateAll(...)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* @brief: The collection of all fields as defined in definitions.json
|
|
69
|
+
*/
|
|
70
|
+
export class FieldLookup {
|
|
71
|
+
constructor(
|
|
72
|
+
fields: Array<[string, FieldInfo]>,
|
|
73
|
+
types: Record<string, number>,
|
|
74
|
+
) {
|
|
75
|
+
fields.forEach(([name, field_info]) => {
|
|
76
|
+
const typeOrdinal = types[field_info.type]
|
|
77
|
+
this[name] = buildField([name, field_info], typeOrdinal)
|
|
78
|
+
this[this[name].ordinal.toString()] = this[name]
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
fromString(value: string): FieldInstance {
|
|
83
|
+
return this[value] as FieldInstance
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as enums from './definitions.json'
|
|
2
|
+
import {
|
|
3
|
+
XrplDefinitionsBase,
|
|
4
|
+
FieldInstance,
|
|
5
|
+
Bytes,
|
|
6
|
+
} from './xrpl-definitions-base'
|
|
7
|
+
/**
|
|
8
|
+
* By default, coreTypes from the `types` folder is where known type definitions are initialized to avoid import cycles.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_DEFINITIONS = new XrplDefinitionsBase(enums, {})
|
|
11
|
+
|
|
12
|
+
const Type = DEFAULT_DEFINITIONS.type
|
|
13
|
+
const LedgerEntryType = DEFAULT_DEFINITIONS.ledgerEntryType
|
|
14
|
+
const TransactionType = DEFAULT_DEFINITIONS.transactionType
|
|
15
|
+
const TransactionResult = DEFAULT_DEFINITIONS.transactionResult
|
|
16
|
+
const Field = DEFAULT_DEFINITIONS.field
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* @brief: All valid transaction types
|
|
20
|
+
*/
|
|
21
|
+
const TRANSACTION_TYPES = DEFAULT_DEFINITIONS.transactionNames
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
Bytes,
|
|
25
|
+
XrplDefinitionsBase,
|
|
26
|
+
DEFAULT_DEFINITIONS,
|
|
27
|
+
Field,
|
|
28
|
+
FieldInstance,
|
|
29
|
+
Type,
|
|
30
|
+
LedgerEntryType,
|
|
31
|
+
TransactionResult,
|
|
32
|
+
TransactionType,
|
|
33
|
+
TRANSACTION_TYPES,
|
|
34
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick script to re-number values
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const input = {
|
|
6
|
+
temBAD_SEND_XRP_PATHS: -283,
|
|
7
|
+
temBAD_SEQUENCE: -282,
|
|
8
|
+
temBAD_SIGNATURE: -281,
|
|
9
|
+
temBAD_SRC_ACCOUNT: -280,
|
|
10
|
+
temBAD_TRANSFER_RATE: -279,
|
|
11
|
+
temDST_IS_SRC: -278,
|
|
12
|
+
temDST_NEEDED: -277,
|
|
13
|
+
temINVALID: -276,
|
|
14
|
+
temINVALID_FLAG: -275,
|
|
15
|
+
temREDUNDANT: -274,
|
|
16
|
+
temRIPPLE_EMPTY: -273,
|
|
17
|
+
temDISABLED: -272,
|
|
18
|
+
temBAD_SIGNER: -271,
|
|
19
|
+
temBAD_QUORUM: -270,
|
|
20
|
+
temBAD_WEIGHT: -269,
|
|
21
|
+
temBAD_TICK_SIZE: -268,
|
|
22
|
+
temINVALID_ACCOUNT_ID: -267,
|
|
23
|
+
temCANNOT_PREAUTH_SELF: -266,
|
|
24
|
+
|
|
25
|
+
temUNCERTAIN: -265,
|
|
26
|
+
temUNKNOWN: -264,
|
|
27
|
+
|
|
28
|
+
tefFAILURE: -199,
|
|
29
|
+
tefALREADY: -198,
|
|
30
|
+
tefBAD_ADD_AUTH: -197,
|
|
31
|
+
tefBAD_AUTH: -196,
|
|
32
|
+
tefBAD_LEDGER: -195,
|
|
33
|
+
tefCREATED: -194,
|
|
34
|
+
tefEXCEPTION: -193,
|
|
35
|
+
tefINTERNAL: -192,
|
|
36
|
+
tefNO_AUTH_REQUIRED: -191,
|
|
37
|
+
tefPAST_SEQ: -190,
|
|
38
|
+
tefWRONG_PRIOR: -189,
|
|
39
|
+
tefMASTER_DISABLED: -188,
|
|
40
|
+
tefMAX_LEDGER: -187,
|
|
41
|
+
tefBAD_SIGNATURE: -186,
|
|
42
|
+
tefBAD_QUORUM: -185,
|
|
43
|
+
tefNOT_MULTI_SIGNING: -184,
|
|
44
|
+
tefBAD_AUTH_MASTER: -183,
|
|
45
|
+
tefINVARIANT_FAILED: -182,
|
|
46
|
+
tefTOO_BIG: -181,
|
|
47
|
+
|
|
48
|
+
terRETRY: -99,
|
|
49
|
+
terFUNDS_SPENT: -98,
|
|
50
|
+
terINSUF_FEE_B: -97,
|
|
51
|
+
terNO_ACCOUNT: -96,
|
|
52
|
+
terNO_AUTH: -95,
|
|
53
|
+
terNO_LINE: -94,
|
|
54
|
+
terOWNERS: -93,
|
|
55
|
+
terPRE_SEQ: -92,
|
|
56
|
+
terLAST: -91,
|
|
57
|
+
terNO_RIPPLE: -90,
|
|
58
|
+
terQUEUED: -89,
|
|
59
|
+
|
|
60
|
+
tesSUCCESS: 0,
|
|
61
|
+
|
|
62
|
+
tecCLAIM: 100,
|
|
63
|
+
tecPATH_PARTIAL: 101,
|
|
64
|
+
tecUNFUNDED_ADD: 102,
|
|
65
|
+
tecUNFUNDED_OFFER: 103,
|
|
66
|
+
tecUNFUNDED_PAYMENT: 104,
|
|
67
|
+
tecFAILED_PROCESSING: 105,
|
|
68
|
+
tecDIR_FULL: 121,
|
|
69
|
+
tecINSUF_RESERVE_LINE: 122,
|
|
70
|
+
tecINSUF_RESERVE_OFFER: 123,
|
|
71
|
+
tecNO_DST: 124,
|
|
72
|
+
tecNO_DST_INSUF_XRP: 125,
|
|
73
|
+
tecNO_LINE_INSUF_RESERVE: 126,
|
|
74
|
+
tecNO_LINE_REDUNDANT: 127,
|
|
75
|
+
tecPATH_DRY: 128,
|
|
76
|
+
tecUNFUNDED: 129,
|
|
77
|
+
tecNO_ALTERNATIVE_KEY: 130,
|
|
78
|
+
tecNO_REGULAR_KEY: 131,
|
|
79
|
+
tecOWNERS: 132,
|
|
80
|
+
tecNO_ISSUER: 133,
|
|
81
|
+
tecNO_AUTH: 134,
|
|
82
|
+
tecNO_LINE: 135,
|
|
83
|
+
tecINSUFF_FEE: 136,
|
|
84
|
+
tecFROZEN: 137,
|
|
85
|
+
tecNO_TARGET: 138,
|
|
86
|
+
tecNO_PERMISSION: 139,
|
|
87
|
+
tecNO_ENTRY: 140,
|
|
88
|
+
tecINSUFFICIENT_RESERVE: 141,
|
|
89
|
+
tecNEED_MASTER_KEY: 142,
|
|
90
|
+
tecDST_TAG_NEEDED: 143,
|
|
91
|
+
tecINTERNAL: 144,
|
|
92
|
+
tecOVERSIZE: 145,
|
|
93
|
+
tecCRYPTOCONDITION_ERROR: 146,
|
|
94
|
+
tecINVARIANT_FAILED: 147,
|
|
95
|
+
tecEXPIRED: 148,
|
|
96
|
+
tecDUPLICATE: 149,
|
|
97
|
+
tecKILLED: 150,
|
|
98
|
+
tecHAS_OBLIGATIONS: 151,
|
|
99
|
+
tecTOO_SOON: 152,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let startingFromTemBADSENDXRPPATHS = -284
|
|
103
|
+
|
|
104
|
+
let startingFromTefFAILURE = -199
|
|
105
|
+
|
|
106
|
+
let startingFromTerRETRY = -99
|
|
107
|
+
|
|
108
|
+
const tesSUCCESS = 0
|
|
109
|
+
|
|
110
|
+
let startingFromTecCLAIM = 100
|
|
111
|
+
|
|
112
|
+
const startingFromTecDIRFULL = 121
|
|
113
|
+
|
|
114
|
+
let previousKey = 'tem'
|
|
115
|
+
Object.keys(input).forEach((key) => {
|
|
116
|
+
if (key.substring(0, 3) !== previousKey.substring(0, 3)) {
|
|
117
|
+
console.log()
|
|
118
|
+
previousKey = key
|
|
119
|
+
}
|
|
120
|
+
if (key.substring(0, 3) === 'tem') {
|
|
121
|
+
console.log(` "${key}": ${startingFromTemBADSENDXRPPATHS++},`)
|
|
122
|
+
} else if (key.substring(0, 3) === 'tef') {
|
|
123
|
+
console.log(` "${key}": ${startingFromTefFAILURE++},`)
|
|
124
|
+
} else if (key.substring(0, 3) === 'ter') {
|
|
125
|
+
console.log(` "${key}": ${startingFromTerRETRY++},`)
|
|
126
|
+
} else if (key.substring(0, 3) === 'tes') {
|
|
127
|
+
console.log(` "${key}": ${tesSUCCESS},`)
|
|
128
|
+
} else if (key.substring(0, 3) === 'tec') {
|
|
129
|
+
if (key === 'tecDIR_FULL') {
|
|
130
|
+
startingFromTecCLAIM = startingFromTecDIRFULL
|
|
131
|
+
}
|
|
132
|
+
console.log(` "${key}": ${startingFromTecCLAIM++},`)
|
|
133
|
+
}
|
|
134
|
+
})
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { SerializedType } from '../types/serialized-type'
|
|
2
|
+
import { Bytes, BytesLookup } from './bytes'
|
|
3
|
+
import { FieldInfo, FieldLookup, FieldInstance } from './field'
|
|
4
|
+
import {
|
|
5
|
+
TYPE_WIDTH,
|
|
6
|
+
LEDGER_ENTRY_WIDTH,
|
|
7
|
+
TRANSACTION_TYPE_WIDTH,
|
|
8
|
+
TRANSACTION_RESULT_WIDTH,
|
|
9
|
+
} from './constants'
|
|
10
|
+
|
|
11
|
+
interface DefinitionsData {
|
|
12
|
+
TYPES: Record<string, number>
|
|
13
|
+
LEDGER_ENTRY_TYPES: Record<string, number>
|
|
14
|
+
FIELDS: (string | FieldInfo)[][]
|
|
15
|
+
TRANSACTION_RESULTS: Record<string, number>
|
|
16
|
+
TRANSACTION_TYPES: Record<string, number>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Stores the various types and fields for rippled to be used to encode/decode information later on.
|
|
21
|
+
* XrplDefinitions should be instantiated instead of this class.
|
|
22
|
+
*/
|
|
23
|
+
class XrplDefinitionsBase {
|
|
24
|
+
// A collection of fields that can be included in transactions
|
|
25
|
+
field: FieldLookup
|
|
26
|
+
// A collection of ids corresponding to types of ledger objects
|
|
27
|
+
ledgerEntryType: BytesLookup
|
|
28
|
+
// A collection of type flags used to determine how to serialize a field's data
|
|
29
|
+
type: BytesLookup
|
|
30
|
+
// Errors and result codes for transactions
|
|
31
|
+
transactionResult: BytesLookup
|
|
32
|
+
// Defined transactions that can be submitted to the ledger
|
|
33
|
+
transactionType: BytesLookup
|
|
34
|
+
// Valid transaction names
|
|
35
|
+
transactionNames: string[]
|
|
36
|
+
// Maps serializable types to their TypeScript class implementation
|
|
37
|
+
dataTypes: Record<string, typeof SerializedType>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Present rippled types in a typed and updatable format.
|
|
41
|
+
* For an example of the input format see `definitions.json`
|
|
42
|
+
* To generate a new definitions file from rippled source code, use this tool: https://github.com/RichardAH/xrpl-codec-gen
|
|
43
|
+
*
|
|
44
|
+
* See the definitions.test.js file for examples of how to create your own updated definitions.json.
|
|
45
|
+
*
|
|
46
|
+
* @param enums - A json encoding of the core types, transaction types, transaction results, transaction names, and fields.
|
|
47
|
+
* @param types - A list of type objects with the same name as the fields defined.
|
|
48
|
+
* You can use the coreTypes object if you are not adding new types.
|
|
49
|
+
*/
|
|
50
|
+
constructor(
|
|
51
|
+
enums: DefinitionsData,
|
|
52
|
+
types: Record<string, typeof SerializedType>,
|
|
53
|
+
) {
|
|
54
|
+
this.type = new BytesLookup(enums.TYPES, TYPE_WIDTH)
|
|
55
|
+
this.ledgerEntryType = new BytesLookup(
|
|
56
|
+
enums.LEDGER_ENTRY_TYPES,
|
|
57
|
+
LEDGER_ENTRY_WIDTH,
|
|
58
|
+
)
|
|
59
|
+
this.transactionType = new BytesLookup(
|
|
60
|
+
enums.TRANSACTION_TYPES,
|
|
61
|
+
TRANSACTION_TYPE_WIDTH,
|
|
62
|
+
)
|
|
63
|
+
this.transactionResult = new BytesLookup(
|
|
64
|
+
enums.TRANSACTION_RESULTS,
|
|
65
|
+
TRANSACTION_RESULT_WIDTH,
|
|
66
|
+
)
|
|
67
|
+
this.field = new FieldLookup(
|
|
68
|
+
enums.FIELDS as Array<[string, FieldInfo]>,
|
|
69
|
+
enums.TYPES,
|
|
70
|
+
)
|
|
71
|
+
this.transactionNames = Object.entries(enums.TRANSACTION_TYPES)
|
|
72
|
+
.filter(([_key, value]) => value >= 0)
|
|
73
|
+
.map(([key, _value]) => key)
|
|
74
|
+
|
|
75
|
+
this.dataTypes = {} // Filled in via associateTypes
|
|
76
|
+
this.associateTypes(types)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Associates each Field to a corresponding class that TypeScript can recognize.
|
|
81
|
+
*
|
|
82
|
+
* @param types a list of type objects with the same name as the fields defined.
|
|
83
|
+
* Defaults to xrpl.js's core type definitions.
|
|
84
|
+
*/
|
|
85
|
+
public associateTypes(types: Record<string, typeof SerializedType>): void {
|
|
86
|
+
// Overwrite any existing type definitions with the given types
|
|
87
|
+
this.dataTypes = Object.assign({}, this.dataTypes, types)
|
|
88
|
+
|
|
89
|
+
Object.values(this.field).forEach((field) => {
|
|
90
|
+
field.associatedType = this.dataTypes[field.type.name]
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
this.field['TransactionType'].associatedType = this.transactionType
|
|
94
|
+
this.field['TransactionResult'].associatedType = this.transactionResult
|
|
95
|
+
this.field['LedgerEntryType'].associatedType = this.ledgerEntryType
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public getAssociatedTypes(): Record<string, typeof SerializedType> {
|
|
99
|
+
return this.dataTypes
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
DefinitionsData,
|
|
105
|
+
XrplDefinitionsBase,
|
|
106
|
+
FieldLookup,
|
|
107
|
+
FieldInfo,
|
|
108
|
+
FieldInstance,
|
|
109
|
+
Bytes,
|
|
110
|
+
BytesLookup,
|
|
111
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type DefinitionsData,
|
|
3
|
+
XrplDefinitionsBase,
|
|
4
|
+
} from './xrpl-definitions-base'
|
|
5
|
+
import { coreTypes } from '../types'
|
|
6
|
+
import { SerializedType } from '../types/serialized-type'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Stores the various types and fields for rippled to be used to encode/decode information later on.
|
|
10
|
+
* Should be used instead of XrplDefinitionsBase since this defines default `types` for serializing/deserializing
|
|
11
|
+
* ledger data.
|
|
12
|
+
*/
|
|
13
|
+
export class XrplDefinitions extends XrplDefinitionsBase {
|
|
14
|
+
/**
|
|
15
|
+
* Present rippled types in a typed and updatable format.
|
|
16
|
+
* For an example of the input format see `definitions.json`
|
|
17
|
+
* To generate a new definitions file from rippled source code, use this tool: https://github.com/RichardAH/xrpl-codec-gen
|
|
18
|
+
*
|
|
19
|
+
* See the definitions.test.js file for examples of how to create your own updated definitions.json.
|
|
20
|
+
*
|
|
21
|
+
* @param enums - A json encoding of the core types, transaction types, transaction results, transaction names, and fields.
|
|
22
|
+
* @param additionalTypes - A list of SerializedType objects with the same name as the fields defined.
|
|
23
|
+
* These types will be included in addition to the coreTypes used on mainnet.
|
|
24
|
+
*/
|
|
25
|
+
constructor(
|
|
26
|
+
enums: DefinitionsData,
|
|
27
|
+
additionalTypes?: Record<string, typeof SerializedType>,
|
|
28
|
+
) {
|
|
29
|
+
const types = Object.assign({}, coreTypes, additionalTypes)
|
|
30
|
+
super(enums, types)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Buffer } from 'buffer/'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Write a 32 bit integer to a Buffer
|
|
5
|
+
*
|
|
6
|
+
* @param uint32 32 bit integer to write to buffer
|
|
7
|
+
* @returns a buffer with the bytes representation of uint32
|
|
8
|
+
*/
|
|
9
|
+
function bytes(uint32: number): Buffer {
|
|
10
|
+
const result = Buffer.alloc(4)
|
|
11
|
+
result.writeUInt32BE(uint32, 0)
|
|
12
|
+
return result
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Maps HashPrefix names to their byte representation
|
|
17
|
+
*/
|
|
18
|
+
const HashPrefix: Record<string, Buffer> = {
|
|
19
|
+
transactionID: bytes(0x54584e00),
|
|
20
|
+
// transaction plus metadata
|
|
21
|
+
transaction: bytes(0x534e4400),
|
|
22
|
+
// account state
|
|
23
|
+
accountStateEntry: bytes(0x4d4c4e00),
|
|
24
|
+
// inner node in tree
|
|
25
|
+
innerNode: bytes(0x4d494e00),
|
|
26
|
+
// ledger master data for signing
|
|
27
|
+
ledgerHeader: bytes(0x4c575200),
|
|
28
|
+
// inner transaction to sign
|
|
29
|
+
transactionSig: bytes(0x53545800),
|
|
30
|
+
// inner transaction to sign
|
|
31
|
+
transactionMultiSig: bytes(0x534d5400),
|
|
32
|
+
// validation for signing
|
|
33
|
+
validation: bytes(0x56414c00),
|
|
34
|
+
// proposal for signing
|
|
35
|
+
proposal: bytes(0x50525000),
|
|
36
|
+
// payment channel claim
|
|
37
|
+
paymentChannelClaim: bytes(0x434c4d00),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { HashPrefix }
|
package/src/hashes.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { HashPrefix } from './hash-prefixes'
|
|
2
|
+
import createHash = require('create-hash')
|
|
3
|
+
import { Hash256 } from './types/hash-256'
|
|
4
|
+
import { BytesList } from './serdes/binary-serializer'
|
|
5
|
+
import { Buffer } from 'buffer/'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Class for hashing with SHA512
|
|
9
|
+
* @extends BytesList So SerializedTypes can write bytes to a Sha512Half
|
|
10
|
+
*/
|
|
11
|
+
class Sha512Half extends BytesList {
|
|
12
|
+
private hash = createHash('sha512')
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Construct a new Sha512Hash and write bytes this.hash
|
|
16
|
+
*
|
|
17
|
+
* @param bytes bytes to write to this.hash
|
|
18
|
+
* @returns the new Sha512Hash object
|
|
19
|
+
*/
|
|
20
|
+
static put(bytes: Buffer): Sha512Half {
|
|
21
|
+
return new Sha512Half().put(bytes)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Write bytes to an existing Sha512Hash
|
|
26
|
+
*
|
|
27
|
+
* @param bytes bytes to write to object
|
|
28
|
+
* @returns the Sha512 object
|
|
29
|
+
*/
|
|
30
|
+
put(bytes: Buffer): Sha512Half {
|
|
31
|
+
this.hash.update(bytes)
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Compute SHA512 hash and slice in half
|
|
37
|
+
*
|
|
38
|
+
* @returns half of a SHA512 hash
|
|
39
|
+
*/
|
|
40
|
+
finish256(): Buffer {
|
|
41
|
+
return Buffer.from(this.hash.digest().slice(0, 32))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Constructs a Hash256 from the Sha512Half object
|
|
46
|
+
*
|
|
47
|
+
* @returns a Hash256 object
|
|
48
|
+
*/
|
|
49
|
+
finish(): Hash256 {
|
|
50
|
+
return new Hash256(this.finish256())
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* compute SHA512 hash of a list of bytes
|
|
56
|
+
*
|
|
57
|
+
* @param args zero or more arguments to hash
|
|
58
|
+
* @returns the sha512half hash of the arguments.
|
|
59
|
+
*/
|
|
60
|
+
function sha512Half(...args: Buffer[]): Buffer {
|
|
61
|
+
const hash = new Sha512Half()
|
|
62
|
+
args.forEach((a) => hash.put(a))
|
|
63
|
+
return hash.finish256()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Construct a transactionID from a Serialized Transaction
|
|
68
|
+
*
|
|
69
|
+
* @param serialized bytes to hash
|
|
70
|
+
* @returns a Hash256 object
|
|
71
|
+
*/
|
|
72
|
+
function transactionID(serialized: Buffer): Hash256 {
|
|
73
|
+
return new Hash256(sha512Half(HashPrefix.transactionID, serialized))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { Sha512Half, sha512Half, transactionID }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as assert from 'assert'
|
|
2
|
+
import { quality, binary, HashPrefix } from './coretypes'
|
|
3
|
+
import { decodeLedgerData } from './ledger-hashes'
|
|
4
|
+
import { ClaimObject } from './binary'
|
|
5
|
+
import { JsonObject } from './types/serialized-type'
|
|
6
|
+
import {
|
|
7
|
+
XrplDefinitionsBase,
|
|
8
|
+
TRANSACTION_TYPES,
|
|
9
|
+
DEFAULT_DEFINITIONS,
|
|
10
|
+
} from './enums'
|
|
11
|
+
import { XrplDefinitions } from './enums/xrpl-definitions'
|
|
12
|
+
import { coreTypes } from './types'
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
signingData,
|
|
16
|
+
signingClaimData,
|
|
17
|
+
multiSigningData,
|
|
18
|
+
binaryToJSON,
|
|
19
|
+
serializeObject,
|
|
20
|
+
} = binary
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Decode a transaction
|
|
24
|
+
*
|
|
25
|
+
* @param binary hex-string of the encoded transaction
|
|
26
|
+
* @param definitions Custom rippled types to use instead of the default. Used for sidechains and amendments.
|
|
27
|
+
* @returns the JSON representation of the transaction
|
|
28
|
+
*/
|
|
29
|
+
function decode(binary: string, definitions?: XrplDefinitionsBase): JsonObject {
|
|
30
|
+
assert.ok(typeof binary === 'string', 'binary must be a hex string')
|
|
31
|
+
return binaryToJSON(binary, definitions)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Encode a transaction
|
|
36
|
+
*
|
|
37
|
+
* @param json The JSON representation of a transaction
|
|
38
|
+
* @param definitions Custom rippled types to use instead of the default. Used for sidechains and amendments.
|
|
39
|
+
*
|
|
40
|
+
* @returns A hex-string of the encoded transaction
|
|
41
|
+
*/
|
|
42
|
+
function encode(json: object, definitions?: XrplDefinitionsBase): string {
|
|
43
|
+
assert.ok(typeof json === 'object')
|
|
44
|
+
return serializeObject(json as JsonObject, { definitions })
|
|
45
|
+
.toString('hex')
|
|
46
|
+
.toUpperCase()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Encode a transaction and prepare for signing
|
|
51
|
+
*
|
|
52
|
+
* @param json JSON object representing the transaction
|
|
53
|
+
* @param signer string representing the account to sign the transaction with
|
|
54
|
+
* @param definitions Custom rippled types to use instead of the default. Used for sidechains and amendments.
|
|
55
|
+
* @returns a hex string of the encoded transaction
|
|
56
|
+
*/
|
|
57
|
+
function encodeForSigning(
|
|
58
|
+
json: object,
|
|
59
|
+
definitions?: XrplDefinitionsBase,
|
|
60
|
+
): string {
|
|
61
|
+
assert.ok(typeof json === 'object')
|
|
62
|
+
return signingData(json as JsonObject, HashPrefix.transactionSig, {
|
|
63
|
+
definitions,
|
|
64
|
+
})
|
|
65
|
+
.toString('hex')
|
|
66
|
+
.toUpperCase()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Encode a transaction and prepare for signing with a claim
|
|
71
|
+
*
|
|
72
|
+
* @param json JSON object representing the transaction
|
|
73
|
+
* @param signer string representing the account to sign the transaction with
|
|
74
|
+
* @param definitions Custom rippled types to use instead of the default. Used for sidechains and amendments.
|
|
75
|
+
* @returns a hex string of the encoded transaction
|
|
76
|
+
*/
|
|
77
|
+
function encodeForSigningClaim(json: object): string {
|
|
78
|
+
assert.ok(typeof json === 'object')
|
|
79
|
+
return signingClaimData(json as ClaimObject)
|
|
80
|
+
.toString('hex')
|
|
81
|
+
.toUpperCase()
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Encode a transaction and prepare for multi-signing
|
|
86
|
+
*
|
|
87
|
+
* @param json JSON object representing the transaction
|
|
88
|
+
* @param signer string representing the account to sign the transaction with
|
|
89
|
+
* @param definitions Custom rippled types to use instead of the default. Used for sidechains and amendments.
|
|
90
|
+
* @returns a hex string of the encoded transaction
|
|
91
|
+
*/
|
|
92
|
+
function encodeForMultisigning(
|
|
93
|
+
json: object,
|
|
94
|
+
signer: string,
|
|
95
|
+
definitions?: XrplDefinitionsBase,
|
|
96
|
+
): string {
|
|
97
|
+
assert.ok(typeof json === 'object')
|
|
98
|
+
assert.equal(json['SigningPubKey'], '')
|
|
99
|
+
const definitionsOpt = definitions ? { definitions } : undefined
|
|
100
|
+
return multiSigningData(json as JsonObject, signer, definitionsOpt)
|
|
101
|
+
.toString('hex')
|
|
102
|
+
.toUpperCase()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Encode a quality value
|
|
107
|
+
*
|
|
108
|
+
* @param value string representation of a number
|
|
109
|
+
* @returns a hex-string representing the quality
|
|
110
|
+
*/
|
|
111
|
+
function encodeQuality(value: string): string {
|
|
112
|
+
assert.ok(typeof value === 'string')
|
|
113
|
+
return quality.encode(value).toString('hex').toUpperCase()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Decode a quality value
|
|
118
|
+
*
|
|
119
|
+
* @param value hex-string of a quality
|
|
120
|
+
* @returns a string representing the quality
|
|
121
|
+
*/
|
|
122
|
+
function decodeQuality(value: string): string {
|
|
123
|
+
assert.ok(typeof value === 'string')
|
|
124
|
+
return quality.decode(value).toString()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export {
|
|
128
|
+
decode,
|
|
129
|
+
encode,
|
|
130
|
+
encodeForSigning,
|
|
131
|
+
encodeForSigningClaim,
|
|
132
|
+
encodeForMultisigning,
|
|
133
|
+
encodeQuality,
|
|
134
|
+
decodeQuality,
|
|
135
|
+
decodeLedgerData,
|
|
136
|
+
TRANSACTION_TYPES,
|
|
137
|
+
XrplDefinitions,
|
|
138
|
+
XrplDefinitionsBase,
|
|
139
|
+
DEFAULT_DEFINITIONS,
|
|
140
|
+
coreTypes,
|
|
141
|
+
}
|