mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
X-address compatibility (#90)
ripple-binary-codec can encode transactions with X-Addresses
This commit is contained in:
@@ -42,6 +42,11 @@ Encode a transaction object into a hex-string.
|
||||
'1100612200000000240000000125000000072D0000000055DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF6240000002540BE4008114D0F5430B66E06498D4CEEC816C7B3337F9982337'
|
||||
```
|
||||
|
||||
#### X-Address Compatibility
|
||||
* ripple-binary-codec handles X-addresses by looking for a few specific files (Account/SourceTag, Destination/DestinationTag).
|
||||
* If other fields (in the future) must to support X-addresses with tags, this library will need to be updated.
|
||||
* When decoding rippled binary, the output will always output classic address + tag, with no X-addresses. X-address support only applies when encoding to binary.
|
||||
|
||||
### encodeForSigning(json: object): string
|
||||
|
||||
Encode the transaction object for signing.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { decodeAccountID, encodeAccountID } from "ripple-address-codec";
|
||||
import { Hash160 } from "./hash-160";
|
||||
|
||||
const HEX_REGEX = /^[A-F0-9]{40}$/;
|
||||
|
||||
/**
|
||||
* Class defining how to encode and decode an AccountID
|
||||
*/
|
||||
@@ -27,9 +29,9 @@ class AccountID extends Hash160 {
|
||||
return new AccountID();
|
||||
}
|
||||
|
||||
return /^r/.test(value)
|
||||
? this.fromBase58(value)
|
||||
: new AccountID(Buffer.from(value, "hex"));
|
||||
return HEX_REGEX.test(value)
|
||||
? new AccountID(Buffer.from(value, "hex"))
|
||||
: this.fromBase58(value);
|
||||
}
|
||||
|
||||
throw new Error("Cannot construct AccountID from value given");
|
||||
|
||||
@@ -1,11 +1,53 @@
|
||||
import { Field, FieldInstance } from "../enums";
|
||||
import { SerializedType, JsonObject } from "./serialized-type";
|
||||
import {
|
||||
xAddressToClassicAddress,
|
||||
isValidXAddress,
|
||||
} from "ripple-address-codec";
|
||||
import { BinaryParser } from "../serdes/binary-parser";
|
||||
import { BinarySerializer, BytesList } from "../serdes/binary-serializer";
|
||||
|
||||
const OBJECT_END_MARKER = Buffer.from([0xe1]);
|
||||
const OBJECT_END_MARKER_NAME = "ObjectEndMarker";
|
||||
const OBJECT_FIELD_TYPE_NAME = "STObject";
|
||||
const OBJECT_END_MARKER_BYTE = Buffer.from([0xe1]);
|
||||
const OBJECT_END_MARKER = "ObjectEndMarker";
|
||||
const ST_OBJECT = "STObject";
|
||||
const DESTINATION = "Destination";
|
||||
const ACCOUNT = "Account";
|
||||
const SOURCE_TAG = "SourceTag";
|
||||
const DEST_TAG = "DestinationTag";
|
||||
|
||||
/**
|
||||
* Break down an X-Address into an account and a tag
|
||||
*
|
||||
* @param field Name of field
|
||||
* @param xAddress X-Address corresponding to the field
|
||||
*/
|
||||
function handleXAddress(field: string, xAddress: string): JsonObject {
|
||||
const decoded = xAddressToClassicAddress(xAddress);
|
||||
|
||||
let tagName;
|
||||
if (field === DESTINATION) tagName = DEST_TAG;
|
||||
else if (field === ACCOUNT) tagName = SOURCE_TAG;
|
||||
else if (decoded.tag !== false)
|
||||
throw new Error(`${field} cannot have an associated tag`);
|
||||
|
||||
return decoded.tag !== false
|
||||
? { [field]: decoded.classicAddress, [tagName]: decoded.tag }
|
||||
: { [field]: decoded.classicAddress };
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that two objects don't both have the same tag fields
|
||||
*
|
||||
* @param obj1 First object to check for tags
|
||||
* @param obj2 Second object to check for tags
|
||||
* @throws When both objects have SourceTag or DestinationTag
|
||||
*/
|
||||
function checkForDuplicateTags(obj1: JsonObject, obj2: JsonObject): void {
|
||||
if (!(obj1[SOURCE_TAG] === undefined || obj2[SOURCE_TAG] === undefined))
|
||||
throw new Error("Cannot have Account X-Address and SourceTag");
|
||||
if (!(obj1[DEST_TAG] === undefined || obj2[DEST_TAG] === undefined))
|
||||
throw new Error("Cannot have Destination X-Address and DestinationTag");
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for Serializing/Deserializing objects
|
||||
@@ -23,15 +65,15 @@ class STObject extends SerializedType {
|
||||
|
||||
while (!parser.end()) {
|
||||
const field = parser.readField();
|
||||
if (field.name === OBJECT_END_MARKER_NAME) {
|
||||
if (field.name === OBJECT_END_MARKER) {
|
||||
break;
|
||||
}
|
||||
|
||||
const associatedValue = parser.readFieldValue(field);
|
||||
|
||||
bytes.writeFieldAndValue(field, associatedValue);
|
||||
if (field.type.name === OBJECT_FIELD_TYPE_NAME) {
|
||||
bytes.put(OBJECT_END_MARKER);
|
||||
if (field.type.name === ST_OBJECT) {
|
||||
bytes.put(OBJECT_END_MARKER_BYTE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +98,16 @@ class STObject extends SerializedType {
|
||||
const list: BytesList = new BytesList();
|
||||
const bytes: BinarySerializer = new BinarySerializer(list);
|
||||
|
||||
let sorted = Object.keys(value)
|
||||
const xAddressDecoded = Object.entries(value).reduce((acc, [key, val]) => {
|
||||
let handled: JsonObject | undefined = undefined;
|
||||
if (isValidXAddress(val)) {
|
||||
handled = handleXAddress(key, val);
|
||||
checkForDuplicateTags(handled, value as JsonObject);
|
||||
}
|
||||
return Object.assign(acc, handled ?? { [key]: val });
|
||||
}, {});
|
||||
|
||||
let sorted = Object.keys(xAddressDecoded)
|
||||
.map((f: string): FieldInstance => Field[f] as FieldInstance)
|
||||
.filter((f: FieldInstance): boolean => f !== undefined && f.isSerialized)
|
||||
.sort((a, b) => {
|
||||
@@ -68,11 +119,13 @@ class STObject extends SerializedType {
|
||||
}
|
||||
|
||||
sorted.forEach((field) => {
|
||||
const associatedValue = field.associatedType.from(value[field.name]);
|
||||
const associatedValue = field.associatedType.from(
|
||||
xAddressDecoded[field.name]
|
||||
);
|
||||
|
||||
bytes.writeFieldAndValue(field, associatedValue);
|
||||
if (field.type.name === OBJECT_FIELD_TYPE_NAME) {
|
||||
bytes.put(OBJECT_END_MARKER);
|
||||
if (field.type.name === ST_OBJECT) {
|
||||
bytes.put(OBJECT_END_MARKER_BYTE);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -90,7 +143,7 @@ class STObject extends SerializedType {
|
||||
|
||||
while (!objectParser.end()) {
|
||||
const field = objectParser.readField();
|
||||
if (field.name === OBJECT_END_MARKER_NAME) {
|
||||
if (field.name === OBJECT_END_MARKER) {
|
||||
break;
|
||||
}
|
||||
accumulator[field.name] = objectParser.readFieldValue(field).toJSON();
|
||||
|
||||
188
packages/ripple-binary-codec/test/fixtures/x-codec-fixtures.json
vendored
Normal file
188
packages/ripple-binary-codec/test/fixtures/x-codec-fixtures.json
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
{
|
||||
"transactions": [{
|
||||
"rjson": {
|
||||
"Account": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||
"Destination": "rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639",
|
||||
"SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E",
|
||||
"Amount": "10000000000",
|
||||
"DestinationTag": 1010,
|
||||
"SourceTag": 84854,
|
||||
"Fee": "10",
|
||||
"Flags": 0,
|
||||
"Sequence": 62
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "X7tFPvjMH7nDxP8nTGkeeggcUpCZj8UbyT2QoiRHGDfjqrB",
|
||||
"Destination": "XVYmGpJqHS95ir411XvanwY1xt5Z2314WsamHPVgUNABUGV",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639",
|
||||
"SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E",
|
||||
"Amount": "10000000000",
|
||||
"Fee": "10",
|
||||
"Flags": 0,
|
||||
"Sequence": 62
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "r4DymtkgUAh2wqRxVfdd3Xtswzim6eC6c5",
|
||||
"Amount": "199000000",
|
||||
"Destination": "rsekGH9p9neiPxym2TMJhqaCzHFuokenTU",
|
||||
"DestinationTag": 3663729509,
|
||||
"Fee": "6335",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313352,
|
||||
"Sequence": 105791,
|
||||
"SigningPubKey": "02053A627976CE1157461336AC65290EC1571CAAD1B327339980F7BF65EF776F83",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "30440220086D3330CD6CE01D891A26BA0355D8D5A5D28A5C9A1D0C5E06E321C81A02318A0220027C3F6606E41FEA35103EDE5224CC489B6514ACFE27543185B0419DD02E301C"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "r4DymtkgUAh2wqRxVfdd3Xtswzim6eC6c5",
|
||||
"Amount": "199000000",
|
||||
"Destination": "X7cBoj6a5xSEfPCr6AStN9YPhbMAA2yaN2XYWwRJKAKb3y5",
|
||||
"Fee": "6335",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313352,
|
||||
"Sequence": 105791,
|
||||
"SigningPubKey": "02053A627976CE1157461336AC65290EC1571CAAD1B327339980F7BF65EF776F83",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "30440220086D3330CD6CE01D891A26BA0355D8D5A5D28A5C9A1D0C5E06E321C81A02318A0220027C3F6606E41FEA35103EDE5224CC489B6514ACFE27543185B0419DD02E301C"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "rDsbeomae4FXwgQTJp9Rs64Qg9vDiTCdBv",
|
||||
"Amount": "105302107",
|
||||
"Destination": "r33hypJXDs47LVpmvta7hMW9pR8DYeBtkW",
|
||||
"DestinationTag": 1658156118,
|
||||
"Fee": "60000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313566,
|
||||
"Sequence": 1113196,
|
||||
"SigningPubKey": "03D847C2DBED3ABF0453F71DCD7641989136277218DF516AD49519C9693F32727E",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3045022100FCA10FBAC65EA60C115A970CD52E6A526B1F9DDB6C4F843DA3DE7A97DFF9492D022037824D0FC6F663FB08BE0F2812CBADE1F61836528D44945FC37F10CC03215111"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "rDsbeomae4FXwgQTJp9Rs64Qg9vDiTCdBv",
|
||||
"Amount": "105302107",
|
||||
"Destination": "X7ikFY5asEwp6ikt2AJdTfBLALEs5JN35kkeqKVeT1GdvY1",
|
||||
"Fee": "60000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313566,
|
||||
"Sequence": 1113196,
|
||||
"SigningPubKey": "03D847C2DBED3ABF0453F71DCD7641989136277218DF516AD49519C9693F32727E",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3045022100FCA10FBAC65EA60C115A970CD52E6A526B1F9DDB6C4F843DA3DE7A97DFF9492D022037824D0FC6F663FB08BE0F2812CBADE1F61836528D44945FC37F10CC03215111"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "rDsbeomae4FXwgQTJp9Rs64Qg9vDiTCdBv",
|
||||
"Amount": "3899911571",
|
||||
"Destination": "rU2mEJSLqBRkYLVTv55rFTgQajkLTnT6mA",
|
||||
"DestinationTag": 255406,
|
||||
"Fee": "60000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313566,
|
||||
"Sequence": 1113197,
|
||||
"SigningPubKey": "03D847C2DBED3ABF0453F71DCD7641989136277218DF516AD49519C9693F32727E",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3044022077642D94BB3C49BF3CB4C804255EC830D2C6009EA4995E38A84602D579B8AAD702206FAD977C49980226E8B495BF03C8D9767380F1546BBF5A4FD47D604C0D2CCF9B"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "rDsbeomae4FXwgQTJp9Rs64Qg9vDiTCdBv",
|
||||
"Amount": "3899911571",
|
||||
"Destination": "XVfH8gwNWVbB5Kft16jmTNgGTqgw1dzA8ZTBkNjSLw6JdXS",
|
||||
"Fee": "60000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57313566,
|
||||
"Sequence": 1113197,
|
||||
"SigningPubKey": "03D847C2DBED3ABF0453F71DCD7641989136277218DF516AD49519C9693F32727E",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3044022077642D94BB3C49BF3CB4C804255EC830D2C6009EA4995E38A84602D579B8AAD702206FAD977C49980226E8B495BF03C8D9767380F1546BBF5A4FD47D604C0D2CCF9B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "r4eEbLKZGbVSBHnSUBZW8i5XaMjGLdqT4a",
|
||||
"Amount": "820370849",
|
||||
"Destination": "rDhmyBh4JwDAtXyRZDarNgg52UcLLRoGje",
|
||||
"DestinationTag": 2017780486,
|
||||
"Fee": "6000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57315579,
|
||||
"Sequence": 234254,
|
||||
"SigningPubKey": "038CF47114672A12B269AEE015BF7A8438609B994B0640E4B28B2F56E93D948B15",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3044022015004653B1CBDD5CCA1F7B38555F1B37FE3F811E9D5070281CCC6C8A93460D870220679E9899184901EA69750C8A9325768490B1B9C1A733842446727653FF3D1DC0"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "r4eEbLKZGbVSBHnSUBZW8i5XaMjGLdqT4a",
|
||||
"Amount": "820370849",
|
||||
"Destination": "XV31huWNJQXsAJFwgE6rnC8uf8jRx4H4waq4MyGUxz5CXzS",
|
||||
"Fee": "6000",
|
||||
"Flags": 2147483648,
|
||||
"LastLedgerSequence": 57315579,
|
||||
"Sequence": 234254,
|
||||
"SigningPubKey": "038CF47114672A12B269AEE015BF7A8438609B994B0640E4B28B2F56E93D948B15",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "3044022015004653B1CBDD5CCA1F7B38555F1B37FE3F811E9D5070281CCC6C8A93460D870220679E9899184901EA69750C8A9325768490B1B9C1A733842446727653FF3D1DC0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "rsGeDwS4rpocUumu9smpXomzaaeG4Qyifz",
|
||||
"Amount": "1500000000",
|
||||
"Destination": "rDxfhNRgCDNDckm45zT5ayhKDC4Ljm7UoP",
|
||||
"DestinationTag": 1000635172,
|
||||
"Fee": "5000",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 55741075,
|
||||
"SigningPubKey": "02ECB814477DF9D8351918878E235EE6AF147A2A5C20F1E71F291F0F3303357C36",
|
||||
"SourceTag": 1000635172,
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304402202A90972E21823214733082E1977F9EA2D6B5101902F108E7BDD7D128CEEA7AF3022008852C8DAD746A7F18E66A47414FABF551493674783E8EA7409C501D3F05F99A"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "rsGeDwS4rpocUumu9smpXomzaaeG4Qyifz",
|
||||
"Amount": "1500000000",
|
||||
"Destination": "XVBkK1yLutMqFGwTm6hykn7YXGDUrjsZSkpzMgRveZrMbHs",
|
||||
"Fee": "5000",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 55741075,
|
||||
"SigningPubKey": "02ECB814477DF9D8351918878E235EE6AF147A2A5C20F1E71F291F0F3303357C36",
|
||||
"SourceTag": 1000635172,
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304402202A90972E21823214733082E1977F9EA2D6B5101902F108E7BDD7D128CEEA7AF3022008852C8DAD746A7F18E66A47414FABF551493674783E8EA7409C501D3F05F99A"
|
||||
}
|
||||
},
|
||||
{
|
||||
"rjson": {
|
||||
"Account": "rHWcuuZoFvDS6gNbmHSdpb7u1hZzxvCoMt",
|
||||
"Amount": "48918500000",
|
||||
"Destination": "rEb8TK3gBgk5auZkwc6sHnwrGVJH8DuaLh",
|
||||
"DestinationTag": 105959914,
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 32641,
|
||||
"SigningPubKey": "02E98DA545CCCC5D14C82594EE9E6CCFCF5171108E2410B3E784183E1068D33429",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304502210091DCA7AF189CD9DC93BDE24DEAE87381FBF16789C43113EE312241D648982B2402201C6055FEFFF1F119640AAC0B32C4F37375B0A96033E0527A21C1366920D6A524"
|
||||
},
|
||||
"xjson": {
|
||||
"Account": "rHWcuuZoFvDS6gNbmHSdpb7u1hZzxvCoMt",
|
||||
"Amount": "48918500000",
|
||||
"Destination": "XVH3aqvbYGhRhrD1FYSzGooNuxdzbG3VR2fuM47oqbXxQr7",
|
||||
"Fee": "10",
|
||||
"Flags": 2147483648,
|
||||
"Sequence": 32641,
|
||||
"SigningPubKey": "02E98DA545CCCC5D14C82594EE9E6CCFCF5171108E2410B3E784183E1068D33429",
|
||||
"TransactionType": "Payment",
|
||||
"TxnSignature": "304502210091DCA7AF189CD9DC93BDE24DEAE87381FBF16789C43113EE312241D648982B2402201C6055FEFFF1F119640AAC0B32C4F37375B0A96033E0527A21C1366920D6A524"
|
||||
}
|
||||
}]
|
||||
}
|
||||
@@ -16,10 +16,14 @@ describe('Hash160', function () {
|
||||
expect(h1.lt(h2)).toBe(true)
|
||||
expect(h3.lt(h2)).toBe(true)
|
||||
})
|
||||
test('throws when constructed from invalid hash length', () => {
|
||||
expect(() => Hash160.from('10000000000000000000000000000000000000')).toThrow('Invalid Hash length 19')
|
||||
expect(() => Hash160.from('100000000000000000000000000000000000000000')).toThrow('Invalid Hash length 21')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Hash256', function () {
|
||||
test('has a static width membmer', function () {
|
||||
test('has a static width member', function () {
|
||||
expect(Hash256.width).toBe(32)
|
||||
})
|
||||
test('has a ZERO_256 member', function () {
|
||||
|
||||
137
packages/ripple-binary-codec/test/x-address.test.js
Normal file
137
packages/ripple-binary-codec/test/x-address.test.js
Normal file
@@ -0,0 +1,137 @@
|
||||
const { encode, decode } = require("./../dist/index");
|
||||
const fixtures = require('./fixtures/x-codec-fixtures.json')
|
||||
|
||||
let json_x1 = {
|
||||
OwnerCount: 0,
|
||||
Account: "XVXdn5wEVm5G4UhEHWDPqjvdeH361P7BsapL4m2D2XnPSwT",
|
||||
PreviousTxnLgrSeq: 7,
|
||||
LedgerEntryType: "AccountRoot",
|
||||
PreviousTxnID: "DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF",
|
||||
Flags: 0,
|
||||
Sequence: 1,
|
||||
Balance: "10000000000"
|
||||
}
|
||||
|
||||
let json_r1 = {
|
||||
OwnerCount: 0,
|
||||
Account: 'rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv',
|
||||
PreviousTxnLgrSeq: 7,
|
||||
LedgerEntryType: 'AccountRoot',
|
||||
PreviousTxnID: 'DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF',
|
||||
Flags: 0,
|
||||
Sequence: 1,
|
||||
Balance: '10000000000',
|
||||
SourceTag: 12345,
|
||||
}
|
||||
|
||||
let json_null_x = {
|
||||
"OwnerCount": 0,
|
||||
"Account": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Destination": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Issuer": "XVXdn5wEVm5G4UhEHWDPqjvdeH361P4GETfNyyXGaoqBj71",
|
||||
"PreviousTxnLgrSeq": 7,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"PreviousTxnID": "DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF",
|
||||
"Flags": 0,
|
||||
"Sequence": 1,
|
||||
"Balance": "10000000000"
|
||||
}
|
||||
|
||||
let json_invalid_x = {
|
||||
"OwnerCount": 0,
|
||||
"Account": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Destination": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Issuer": "XVXdn5wEVm5g4UhEHWDPqjvdeH361P4GETfNyyXGaoqBj71",
|
||||
"PreviousTxnLgrSeq": 7,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"PreviousTxnID": "DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF",
|
||||
"Flags": 0,
|
||||
"Sequence": 1,
|
||||
"Balance": "10000000000"
|
||||
}
|
||||
|
||||
let json_null_r = {
|
||||
"OwnerCount": 0,
|
||||
"Account": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Destination": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Issuer": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"PreviousTxnLgrSeq": 7,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"PreviousTxnID": "DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF",
|
||||
"Flags": 0,
|
||||
"Sequence": 1,
|
||||
"Balance": "10000000000"
|
||||
}
|
||||
|
||||
let invalid_json_issuer_tagged = {
|
||||
"OwnerCount": 0,
|
||||
"Account": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Destination": "rLs1MzkFWCxTbuAHgjeTZK4fcCDDnf2KRv",
|
||||
"Issuer": "XVXdn5wEVm5G4UhEHWDPqjvdeH361P7BsapL4m2D2XnPSwT",
|
||||
"PreviousTxnLgrSeq": 7,
|
||||
"LedgerEntryType": "AccountRoot",
|
||||
"PreviousTxnID": "DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF",
|
||||
"Flags": 0,
|
||||
"Sequence": 1,
|
||||
"Balance": "10000000000"
|
||||
}
|
||||
|
||||
let invalid_json_x_and_tagged = {
|
||||
OwnerCount: 0,
|
||||
Account: 'XVXdn5wEVm5G4UhEHWDPqjvdeH361P7BsapL4m2D2XnPSwT',
|
||||
PreviousTxnLgrSeq: 7,
|
||||
LedgerEntryType: 'AccountRoot',
|
||||
PreviousTxnID: 'DF530FB14C5304852F20080B0A8EEF3A6BDD044F41F4EBBD68B8B321145FE4FF',
|
||||
Flags: 0,
|
||||
Sequence: 1,
|
||||
Balance: '10000000000',
|
||||
SourceTag: 12345,
|
||||
}
|
||||
|
||||
describe("X-Address Account is equivalent to a classic address w/ SourceTag", () => {
|
||||
let encoded_x = encode(json_x1);
|
||||
let encoded_r = encode(json_r1);
|
||||
test("Can encode with x-Address", () => {
|
||||
expect(encoded_x).toEqual(encoded_r);
|
||||
})
|
||||
|
||||
test("decoded X-address is object w/ source and tag", () => {
|
||||
let decoded_x = decode(encoded_x);
|
||||
expect(decoded_x).toEqual(json_r1);
|
||||
})
|
||||
|
||||
test("Encoding issuer X-Address w/ undefined destination tag", () => {
|
||||
expect(encode(json_null_x)).toEqual(encode(json_null_r));
|
||||
})
|
||||
|
||||
test("Throws when X-Address is invalid", () => {
|
||||
expect(() => encode(json_invalid_x)).toThrow("checksum_invalid");
|
||||
})
|
||||
})
|
||||
|
||||
describe("Invalid X-Address behavior", () => {
|
||||
test("X-Address with tag throws value for invalid field",() => {
|
||||
expect(() => encode(invalid_json_issuer_tagged)).toThrow(new Error("Issuer cannot have an associated tag"))
|
||||
})
|
||||
|
||||
test("Throws when Account has both X-Addr and Destination Tag", () => {
|
||||
expect(() => encode(invalid_json_x_and_tagged)).toThrow(new Error("Cannot have Account X-Address and SourceTag"));
|
||||
});
|
||||
})
|
||||
|
||||
describe('ripple-binary-codec x-address test', function () {
|
||||
function makeSuite (name, entries) {
|
||||
describe(name, function () {
|
||||
entries.forEach((t, testN) => {
|
||||
test(`${name}[${testN}] encodes X-address json equivalent to classic address json`,
|
||||
() => {
|
||||
expect(encode(t.rjson)).toEqual(encode(t.xjson))
|
||||
})
|
||||
test(`${name}[${testN}] decodes X-address json equivalent to classic address json`, () => {
|
||||
expect(decode(encode(t.xjson))).toEqual(t.rjson);
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
makeSuite('transactions', fixtures.transactions)
|
||||
})
|
||||
Reference in New Issue
Block a user