mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Revert "[FEATURE] improve memo support"
This reverts commit 89adcf4f4e.
This commit is contained in:
@@ -2,9 +2,6 @@
|
||||
* Data type map.
|
||||
*
|
||||
* Mapping of type ids to data types. The type id is specified by the high
|
||||
*
|
||||
* For reference, see rippled's definition:
|
||||
* https://github.com/ripple/rippled/blob/develop/src/ripple/data/protocol/SField.cpp
|
||||
*/
|
||||
var TYPES_MAP = exports.types = [
|
||||
void(0),
|
||||
@@ -378,7 +375,7 @@ exports.ledger = {
|
||||
['Balance', REQUIRED],
|
||||
['LowLimit', REQUIRED],
|
||||
['HighLimit', REQUIRED]])
|
||||
};
|
||||
}
|
||||
|
||||
exports.metadata = [
|
||||
[ 'TransactionIndex' , REQUIRED ],
|
||||
|
||||
@@ -24,7 +24,6 @@ var Currency = amount.Currency;
|
||||
// Shortcuts
|
||||
var hex = sjcl.codec.hex;
|
||||
var bytes = sjcl.codec.bytes;
|
||||
var utf8 = sjcl.codec.utf8String;
|
||||
|
||||
var BigInteger = utils.jsbn.BigInteger;
|
||||
|
||||
@@ -53,7 +52,7 @@ function isBigInteger(val) {
|
||||
return val instanceof BigInteger;
|
||||
};
|
||||
|
||||
function serializeHex(so, hexData, noLength) {
|
||||
function serialize_hex(so, hexData, noLength) {
|
||||
var byteData = bytes.fromBits(hex.toBits(hexData));
|
||||
if (!noLength) {
|
||||
SerializedType.serialize_varint(so, byteData.length);
|
||||
@@ -64,18 +63,10 @@ function serializeHex(so, hexData, noLength) {
|
||||
/**
|
||||
* parses bytes as hex
|
||||
*/
|
||||
function convertByteArrayToHex (byte_array) {
|
||||
function convert_bytes_to_hex (byte_array) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(byte_array)).toUpperCase();
|
||||
};
|
||||
|
||||
function convertStringToHex(string) {
|
||||
return hex.fromBits(utf8.toBits(string)).toUpperCase();
|
||||
}
|
||||
|
||||
function convertHexToString(hexString) {
|
||||
return utf8.fromBits(hex.toBits(hexString));
|
||||
}
|
||||
|
||||
SerializedType.serialize_varint = function (so, val) {
|
||||
if (val < 0) {
|
||||
throw new Error('Variable integers are unsigned.');
|
||||
@@ -124,7 +115,7 @@ SerializedType.prototype.parse_varint = function (so) {
|
||||
*
|
||||
* The result is appended to the serialized object ('so').
|
||||
*/
|
||||
function convertIntegerToByteArray(val, bytes) {
|
||||
function append_byte_array(so, val, bytes) {
|
||||
if (!isNumber(val)) {
|
||||
throw new Error('Value is not a number', bytes);
|
||||
}
|
||||
@@ -139,7 +130,7 @@ function convertIntegerToByteArray(val, bytes) {
|
||||
newBytes.unshift(val >>> (i * 8) & 0xff);
|
||||
}
|
||||
|
||||
return newBytes;
|
||||
so.append(newBytes);
|
||||
};
|
||||
|
||||
// Convert a certain number of bytes from the serialized object ('so') into an integer.
|
||||
@@ -161,7 +152,7 @@ function readAndSum(so, bytes) {
|
||||
|
||||
var STInt8 = exports.Int8 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append(convertIntegerToByteArray(val, 1));
|
||||
append_byte_array(so, val, 1);
|
||||
},
|
||||
parse: function (so) {
|
||||
return readAndSum(so, 1);
|
||||
@@ -172,7 +163,7 @@ STInt8.id = 16;
|
||||
|
||||
var STInt16 = exports.Int16 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append(convertIntegerToByteArray(val, 2));
|
||||
append_byte_array(so, val, 2);
|
||||
},
|
||||
parse: function (so) {
|
||||
return readAndSum(so, 2);
|
||||
@@ -183,7 +174,7 @@ STInt16.id = 1;
|
||||
|
||||
var STInt32 = exports.Int32 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append(convertIntegerToByteArray(val, 4));
|
||||
append_byte_array(so, val, 4);
|
||||
},
|
||||
parse: function (so) {
|
||||
return readAndSum(so, 4);
|
||||
@@ -226,7 +217,7 @@ var STInt64 = exports.Int64 = new SerializedType({
|
||||
hex = '0' + hex;
|
||||
}
|
||||
|
||||
serializeHex(so, hex, true); //noLength = true
|
||||
serialize_hex(so, hex, true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
var bytes = so.read(8);
|
||||
@@ -246,7 +237,7 @@ var STHash128 = exports.Hash128 = new SerializedType({
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error('Invalid Hash128');
|
||||
}
|
||||
serializeHex(so, hash.to_hex(), true); //noLength = true
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
return UInt128.from_bytes(so.read(16));
|
||||
@@ -261,7 +252,7 @@ var STHash256 = exports.Hash256 = new SerializedType({
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error('Invalid Hash256');
|
||||
}
|
||||
serializeHex(so, hash.to_hex(), true); //noLength = true
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
return UInt256.from_bytes(so.read(32));
|
||||
@@ -276,7 +267,7 @@ var STHash160 = exports.Hash160 = new SerializedType({
|
||||
if (!hash.is_valid()) {
|
||||
throw new Error('Invalid Hash160');
|
||||
}
|
||||
serializeHex(so, hash.to_hex(), true); //noLength = true
|
||||
serialize_hex(so, hash.to_hex(), true); //noLength = true
|
||||
},
|
||||
parse: function (so) {
|
||||
return UInt160.from_bytes(so.read(20));
|
||||
@@ -303,7 +294,7 @@ var STCurrency = new SerializedType({
|
||||
// UInt160 value and consider it valid. But it doesn't, so for the
|
||||
// deserialization to be usable, we need to allow invalid results for now.
|
||||
//if (!currency.is_valid()) {
|
||||
// throw new Error('Invalid currency: '+convertByteArrayToHex(bytes));
|
||||
// throw new Error('Invalid currency: '+convert_bytes_to_hex(bytes));
|
||||
//}
|
||||
return currency;
|
||||
}
|
||||
@@ -418,16 +409,15 @@ STAmount.id = 6;
|
||||
|
||||
var STVL = exports.VariableLength = exports.VL = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
|
||||
if (typeof val === 'string') {
|
||||
serializeHex(so, val);
|
||||
serialize_hex(so, val);
|
||||
} else {
|
||||
throw new Error('Unknown datatype.');
|
||||
}
|
||||
},
|
||||
parse: function (so) {
|
||||
var len = this.parse_varint(so);
|
||||
return convertByteArrayToHex(so.read(len));
|
||||
return convert_bytes_to_hex(so.read(len));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -439,7 +429,7 @@ var STAccount = exports.Account = new SerializedType({
|
||||
if (!account.is_valid()) {
|
||||
throw new Error('Invalid account!');
|
||||
}
|
||||
serializeHex(so, account.to_hex());
|
||||
serialize_hex(so, account.to_hex());
|
||||
},
|
||||
parse: function (so) {
|
||||
var len = this.parse_varint(so);
|
||||
@@ -451,6 +441,7 @@ var STAccount = exports.Account = new SerializedType({
|
||||
var result = UInt160.from_bytes(so.read(len));
|
||||
result.set_version(Base.VER_ACCOUNT_ID);
|
||||
|
||||
//console.log('PARSED 160:', result.to_json());
|
||||
if (false && !result.is_valid()) {
|
||||
throw new Error('Invalid Account');
|
||||
}
|
||||
@@ -602,104 +593,6 @@ var STVector256 = exports.Vector256 = new SerializedType({
|
||||
|
||||
STVector256.id = 19;
|
||||
|
||||
// Internal
|
||||
var STMemo = exports.STMemo = new SerializedType({
|
||||
serialize: function(so, val, no_marker) {
|
||||
|
||||
var keys = [];
|
||||
|
||||
Object.keys(val).forEach(function (key) {
|
||||
// Ignore lowercase field names - they're non-serializable fields by
|
||||
// convention.
|
||||
if (key[0] === key[0].toLowerCase()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof binformat.fieldsInverseMap[key] === 'undefined') {
|
||||
throw new Error('JSON contains unknown field: "' + key + '"');
|
||||
}
|
||||
|
||||
keys.push(key);
|
||||
});
|
||||
|
||||
// Sort fields
|
||||
keys = sort_fields(keys);
|
||||
|
||||
// store that we're dealing with json
|
||||
var isJson = val.MemoFormat === 'json';
|
||||
|
||||
for (var i=0; i<keys.length; i++) {
|
||||
var key = keys[i];
|
||||
switch (key) {
|
||||
|
||||
// MemoType and MemoFormat are always ASCII strings
|
||||
case 'MemoType':
|
||||
case 'MemoFormat':
|
||||
val[key] = convertStringToHex(val[key]);
|
||||
break;
|
||||
|
||||
// MemoData can be a JSON object, otherwise it's a string
|
||||
case 'MemoData':
|
||||
if (typeof val[key] !== 'string') {
|
||||
if (isJson) {
|
||||
try {
|
||||
val[key] = convertStringToHex(JSON.stringify(val[key]));
|
||||
} catch (e) {
|
||||
throw new Error('MemoFormat json with invalid JSON in MemoData field');
|
||||
}
|
||||
} else {
|
||||
throw new Error('MemoData can only be a JSON object with a valid json MemoFormat');
|
||||
}
|
||||
} else if (isString(val[key])) {
|
||||
val[key] = convertStringToHex(val[key]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
serialize(so, key, val[key]);
|
||||
}
|
||||
|
||||
if (!no_marker) {
|
||||
//Object ending marker
|
||||
STInt8.serialize(so, 0xe1);
|
||||
}
|
||||
|
||||
},
|
||||
parse: function(so) {
|
||||
var output = {};
|
||||
while (so.peek(1)[0] !== 0xe1) {
|
||||
var keyval = parse(so);
|
||||
output[keyval[0]] = keyval[1];
|
||||
}
|
||||
|
||||
if (output['MemoType'] !== void(0)) {
|
||||
output['parsed_memo_type'] = convertHexToString(output['MemoType']);
|
||||
}
|
||||
|
||||
if (output['MemoFormat'] !== void(0)) {
|
||||
output['parsed_memo_format'] = convertHexToString(output['MemoFormat']);
|
||||
}
|
||||
|
||||
if (output['MemoData'] !== void(0)) {
|
||||
|
||||
// see if we can parse JSON
|
||||
if (output['parsed_memo_format'] === 'json') {
|
||||
try {
|
||||
output['parsed_memo_data'] = JSON.parse(convertHexToString(output['MemoData']));
|
||||
} catch(e) {
|
||||
// fail, which is fine, we just won't add the memo_data field
|
||||
}
|
||||
} else if(output['parsed_memo_format'] === 'text') {
|
||||
output['parsed_memo_data'] = convertHexToString(output['MemoData']);
|
||||
}
|
||||
}
|
||||
|
||||
so.read(1);
|
||||
return output;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.serialize = exports.serialize_whatever = serialize;
|
||||
|
||||
function serialize(so, field_name, value) {
|
||||
@@ -729,15 +622,9 @@ function serialize(so, field_name, value) {
|
||||
STInt8.serialize(so, field_bits);
|
||||
}
|
||||
|
||||
// Get the serializer class (ST...)
|
||||
var serialized_object_type;
|
||||
if (field_name === 'Memo' && typeof value === 'object') {
|
||||
// for Memo we override the default behavior with our STMemo serializer
|
||||
serialized_object_type = exports.STMemo;
|
||||
} else {
|
||||
// for a field based on the type bits.
|
||||
serialized_object_type = exports[binformat.types[type_bits]];
|
||||
}
|
||||
// Get the serializer class (ST...) for a field based on the type bits.
|
||||
var serialized_object_type = exports[binformat.types[type_bits]];
|
||||
//do something with val[keys] and val[keys[i]];
|
||||
|
||||
try {
|
||||
serialized_object_type.serialize(so, value);
|
||||
@@ -758,6 +645,10 @@ function parse(so) {
|
||||
type_bits = so.read(1)[0];
|
||||
}
|
||||
|
||||
// Get the parser class (ST...) for a field based on the type bits.
|
||||
var type = exports[binformat.types[type_bits]];
|
||||
|
||||
assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16));
|
||||
|
||||
var field_bits = tag_byte & 0x0f;
|
||||
var field_name = (field_bits === 0)
|
||||
@@ -766,13 +657,6 @@ function parse(so) {
|
||||
|
||||
assert(field_name, 'Unknown field - header byte is 0x' + tag_byte.toString(16));
|
||||
|
||||
// Get the parser class (ST...) for a field based on the type bits.
|
||||
var type = (field_name === 'Memo')
|
||||
? exports.STMemo
|
||||
: exports[binformat.types[type_bits]];
|
||||
|
||||
assert(type, 'Unknown type - header byte is 0x' + tag_byte.toString(16));
|
||||
|
||||
return [ field_name, type.parse(so) ]; //key, value
|
||||
};
|
||||
|
||||
@@ -794,20 +678,18 @@ function sort_fields(keys) {
|
||||
|
||||
var STObject = exports.Object = new SerializedType({
|
||||
serialize: function (so, val, no_marker) {
|
||||
var keys = [];
|
||||
var keys = Object.keys(val);
|
||||
|
||||
Object.keys(val).forEach(function (key) {
|
||||
// Ignore lowercase field names - they're non-serializable fields by
|
||||
// convention.
|
||||
if (key[0] === key[0].toLowerCase()) {
|
||||
return;
|
||||
}
|
||||
keys = keys.filter(function (key) {
|
||||
return key[0] !== key[0].toLowerCase();
|
||||
});
|
||||
|
||||
keys.forEach(function (key) {
|
||||
if (typeof binformat.fieldsInverseMap[key] === 'undefined') {
|
||||
throw new Error('JSON contains unknown field: "' + key + '"');
|
||||
}
|
||||
|
||||
keys.push(key);
|
||||
});
|
||||
|
||||
// Sort fields
|
||||
|
||||
@@ -181,8 +181,6 @@ Transaction.prototype.consts = {
|
||||
tecCLAIMED: 100
|
||||
};
|
||||
|
||||
Transaction.prototype.ascii_regex = /^[\x00-\x7F]*$/;
|
||||
|
||||
Transaction.from_json = function(j) {
|
||||
return (new Transaction()).parseJson(j);
|
||||
};
|
||||
@@ -622,52 +620,40 @@ Transaction.prototype.setFlags = function(flags) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a Memo to transaction.
|
||||
* Add a Memo to transaction. Memos can be used as key-value,
|
||||
* using the MemoType as a key
|
||||
*
|
||||
* @param {String} memoType - describes what the data represents, needs to be valid ASCII
|
||||
* @param {String} memoFormat - describes what format the data is in, MIME type, needs to be valid ASCII
|
||||
* @param {String} memoData - data for the memo, can be any JS object. Any object other than string will be stringified (JSON) for transport
|
||||
* @param {String} type
|
||||
* @param {String} data
|
||||
*/
|
||||
|
||||
Transaction.prototype.addMemo = function(memoType, memoFormat, memoData) {
|
||||
|
||||
if (typeof memoType === 'object') {
|
||||
var opts = memoType;
|
||||
memoType = opts.memoType;
|
||||
memoFormat = opts.memoFormat;
|
||||
memoData = opts.memoData;
|
||||
}
|
||||
|
||||
if (!/(undefined|string)/.test(typeof memoType)) {
|
||||
Transaction.prototype.addMemo = function(type, data) {
|
||||
if (!/(undefined|string)/.test(typeof type)) {
|
||||
throw new Error('MemoType must be a string');
|
||||
} else if (!this.ascii_regex.test(memoType)) {
|
||||
throw new Error('MemoType must be valid ASCII');
|
||||
}
|
||||
|
||||
if (!/(undefined|string)/.test(typeof memoFormat)) {
|
||||
throw new Error('MemoFormat must be a string');
|
||||
} else if (!this.ascii_regex.test(memoFormat)) {
|
||||
throw new Error('MemoFormat must be valid ASCII');
|
||||
if (!/(undefined|string)/.test(typeof data)) {
|
||||
throw new Error('MemoData must be a string');
|
||||
}
|
||||
|
||||
function toHex(str) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.utf8String.toBits(str));
|
||||
};
|
||||
|
||||
var memo = { };
|
||||
|
||||
if (memoType) {
|
||||
if (Transaction.MEMO_TYPES[memoType]) {
|
||||
if (type) {
|
||||
if (Transaction.MEMO_TYPES[type]) {
|
||||
//XXX Maybe in the future we want a schema validator for
|
||||
//memo types
|
||||
memo.MemoType = Transaction.MEMO_TYPES[memoType];
|
||||
memo.MemoType = Transaction.MEMO_TYPES[type];
|
||||
} else {
|
||||
memo.MemoType = memoType;
|
||||
memo.MemoType = toHex(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (memoFormat) {
|
||||
memo.MemoFormat = memoFormat;
|
||||
}
|
||||
|
||||
if (memoData) {
|
||||
memo.MemoData = memoData;
|
||||
if (data) {
|
||||
memo.MemoData = toHex(data);
|
||||
}
|
||||
|
||||
this.tx_json.Memos = (this.tx_json.Memos || []).concat({ Memo: memo });
|
||||
|
||||
@@ -35,7 +35,6 @@ describe('Serialized object', function() {
|
||||
assert.deepEqual(input_json, output_json);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#from_json', function() {
|
||||
it('understands TransactionType as a Number', function() {
|
||||
var input_json = {
|
||||
@@ -53,7 +52,6 @@ describe('Serialized object', function() {
|
||||
assert.equal(0, input_json.TransactionType);
|
||||
assert.equal("Payment", output_json.TransactionType);
|
||||
});
|
||||
|
||||
it('understands LedgerEntryType as a Number', function() {
|
||||
var input_json = {
|
||||
// no, non required fields
|
||||
@@ -67,7 +65,6 @@ describe('Serialized object', function() {
|
||||
assert.equal(100, input_json.LedgerEntryType);
|
||||
assert.equal("DirectoryNode", output_json.LedgerEntryType);
|
||||
});
|
||||
|
||||
describe('Format validation', function() {
|
||||
// Peercover actually had a problem submitting transactions without a `Fee`
|
||||
// and rippled was only informing of "transaction is invalid"
|
||||
@@ -83,198 +80,14 @@ describe('Serialized object', function() {
|
||||
};
|
||||
assert.throws (
|
||||
function() {
|
||||
SerializedObject.from_json(input_json);
|
||||
var output_json = SerializedObject.from_json(input_json);
|
||||
},
|
||||
/Payment is missing fields: \["Fee"\]/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Memos', function() {
|
||||
|
||||
var input_json;
|
||||
|
||||
beforeEach(function() {
|
||||
input_json = {
|
||||
"Flags": 2147483648,
|
||||
"TransactionType": "Payment",
|
||||
"Account": "rhXzSyt1q9J8uiFXpK3qSugAAPJKXLtnrF",
|
||||
"Amount": "1",
|
||||
"Destination": "radqi6ppXFxVhJdjzaATRBxdrPcVTf1Ung",
|
||||
"Sequence": 281,
|
||||
"SigningPubKey": "03D642E6457B8AB4D140E2C66EB4C484FAFB1BF267CB578EC4815FE6CD06379C51",
|
||||
"Fee": "12000",
|
||||
"LastLedgerSequence": 10074214,
|
||||
"TxnSignature": "304402201180636F2CE215CE97A29CD302618FAE60D63EBFC8903DE17A356E857A449C430220290F4A54F9DE4AC79034C8BEA5F1F8757F7505F1A6FF04D2E19B6D62E867256B"
|
||||
};
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, all strings text/plain ', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "text",
|
||||
"MemoData": "some data"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'text';
|
||||
input_json.Memos[0].Memo.parsed_memo_data = 'some data';
|
||||
|
||||
assert.deepEqual(so, input_json);
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, all strings, invalid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "application/json",
|
||||
"MemoData": "some data"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'application/json';
|
||||
assert.deepEqual(so, input_json);
|
||||
assert.strictEqual(input_json.Memos[0].Memo.parsed_memo_data, void(0));
|
||||
});
|
||||
|
||||
it('should throw an error - full memo, json data, invalid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "text",
|
||||
"MemoData": {
|
||||
"string" : "some_string",
|
||||
"boolean" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
assert.throws(function() {
|
||||
SerializedObject.from_json(input_json);
|
||||
}, /^Error: MemoData can only be a JSON object with a valid json MemoFormat \(Memo\) \(Memos\)/);
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, json data, valid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "json",
|
||||
"ignored" : "ignored",
|
||||
"MemoData": {
|
||||
"string" : "some_string",
|
||||
"boolean" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
delete input_json.Memos[0].Memo.ignored;
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'json';
|
||||
input_json.Memos[0].Memo.parsed_memo_data = {
|
||||
"string" : "some_string",
|
||||
"boolean" : true
|
||||
};
|
||||
|
||||
assert.deepEqual(so, input_json);
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, json data, valid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "json",
|
||||
"MemoData": {
|
||||
"string" : "some_string",
|
||||
"boolean" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'json';
|
||||
input_json.Memos[0].Memo.parsed_memo_data = {
|
||||
"string" : "some_string",
|
||||
"boolean" : true
|
||||
};
|
||||
|
||||
assert.deepEqual(so, input_json);
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, json data, valid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "json",
|
||||
"MemoData": 3
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'json';
|
||||
input_json.Memos[0].Memo.parsed_memo_data = 3;
|
||||
assert.deepEqual(so, input_json);
|
||||
});
|
||||
|
||||
it('should serialize and parse - full memo, json data, valid MemoFormat', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoFormat": "json",
|
||||
"MemoData": 3
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var so = SerializedObject.from_json(input_json).to_json();
|
||||
input_json.Memos[0].Memo.parsed_memo_type = 'test';
|
||||
input_json.Memos[0].Memo.parsed_memo_format = 'json';
|
||||
input_json.Memos[0].Memo.parsed_memo_data = 3;
|
||||
assert.deepEqual(so, input_json);
|
||||
});
|
||||
|
||||
it('should throw an error - invalid Memo field', function() {
|
||||
input_json.Memos = [
|
||||
{
|
||||
"Memo": {
|
||||
"MemoType": "test",
|
||||
"MemoParty": "json",
|
||||
"MemoData": 3
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
assert.throws(function() {
|
||||
SerializedObject.from_json(input_json);
|
||||
}, /^Error: JSON contains unknown field: "MemoParty" \(Memo\) \(Memos\)/);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1052,83 +1052,25 @@ describe('Transaction', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
var memoType = 'message';
|
||||
var memoFormat = 'application/json';
|
||||
var memoData = {
|
||||
string: 'value',
|
||||
bool: true,
|
||||
integer: 1
|
||||
};
|
||||
|
||||
transaction.addMemo(memoType, memoFormat, memoData);
|
||||
|
||||
var expected = [
|
||||
{
|
||||
Memo:
|
||||
{
|
||||
MemoType: memoType,
|
||||
MemoFormat: memoFormat,
|
||||
MemoData: memoData
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
assert.deepEqual(transaction.tx_json.Memos, expected);
|
||||
});
|
||||
|
||||
it('Add Memo - by object', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
var memo = {
|
||||
memoType: 'type',
|
||||
memoData: 'data'
|
||||
};
|
||||
|
||||
transaction.addMemo(memo);
|
||||
|
||||
var expected = [
|
||||
{
|
||||
Memo: {
|
||||
MemoType: memo.memoType,
|
||||
MemoData: memo.memoData
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
assert.deepEqual(transaction.tx_json.Memos, expected);
|
||||
});
|
||||
|
||||
it('Add Memos', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
transaction.addMemo('testkey', void(0), 'testvalue');
|
||||
transaction.addMemo('testkey2', void(0), 'testvalue2');
|
||||
transaction.addMemo('testkey3', 'text/html');
|
||||
transaction.addMemo(void(0), void(0), 'testvalue4');
|
||||
transaction.addMemo('testkey4', 'text/html', '<html>');
|
||||
transaction.addMemo('testkey', 'testvalue');
|
||||
transaction.addMemo('testkey2', 'testvalue2');
|
||||
transaction.addMemo('testkey3');
|
||||
transaction.addMemo(void(0), 'testvalue4');
|
||||
|
||||
var expected = [
|
||||
{ Memo: {
|
||||
MemoType: 'testkey',
|
||||
MemoData: 'testvalue'
|
||||
MemoType: new Buffer('testkey').toString('hex'),
|
||||
MemoData: new Buffer('testvalue').toString('hex')
|
||||
}},
|
||||
{ Memo: {
|
||||
MemoType: 'testkey2',
|
||||
MemoData: 'testvalue2'
|
||||
MemoType: new Buffer('testkey2').toString('hex'),
|
||||
MemoData: new Buffer('testvalue2').toString('hex')
|
||||
}},
|
||||
{ Memo: {
|
||||
MemoType: 'testkey3',
|
||||
MemoFormat: 'text/html'
|
||||
MemoType: new Buffer('testkey3').toString('hex')
|
||||
}},
|
||||
{ Memo: {
|
||||
MemoData: 'testvalue4'
|
||||
}},
|
||||
{ Memo: {
|
||||
MemoType: 'testkey4',
|
||||
MemoFormat: 'text/html',
|
||||
MemoData: '<html>'
|
||||
MemoData: new Buffer('testvalue4').toString('hex')
|
||||
} }
|
||||
];
|
||||
|
||||
@@ -1144,76 +1086,13 @@ describe('Transaction', function() {
|
||||
}, /^Error: MemoType must be a string$/);
|
||||
});
|
||||
|
||||
it('Add Memo - invalid ASCII MemoType', function() {
|
||||
it('Add Memo - invalid MemoData', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.addMemo('한국어');
|
||||
}, /^Error: MemoType must be valid ASCII$/);
|
||||
});
|
||||
|
||||
it('Add Memo - invalid MemoFormat', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.addMemo(void(0), 1);
|
||||
}, /^Error: MemoFormat must be a string$/);
|
||||
});
|
||||
|
||||
it('Add Memo - invalid ASCII MemoFormat', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
assert.throws(function() {
|
||||
transaction.addMemo(void(0), 'России');
|
||||
}, /^Error: MemoFormat must be valid ASCII$/);
|
||||
});
|
||||
|
||||
it('Add Memo - MemoData string', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
transaction.addMemo({memoData:'some_string'});
|
||||
|
||||
assert.deepEqual(transaction.tx_json.Memos, [
|
||||
{
|
||||
Memo: {
|
||||
MemoData: 'some_string'
|
||||
}
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('Add Memo - MemoData complex object', function() {
|
||||
var transaction = new Transaction();
|
||||
transaction.tx_json.TransactionType = 'Payment';
|
||||
|
||||
var memo = {
|
||||
memoData: {
|
||||
string: 'string',
|
||||
int: 1,
|
||||
array: [
|
||||
{
|
||||
string: 'string'
|
||||
}
|
||||
],
|
||||
object: {
|
||||
string: 'string'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
transaction.addMemo(memo);
|
||||
|
||||
assert.deepEqual(transaction.tx_json.Memos, [
|
||||
{
|
||||
Memo: {
|
||||
MemoData: memo.memoData
|
||||
}
|
||||
}
|
||||
]);
|
||||
transaction.addMemo('key', 1);
|
||||
}, /^Error: MemoData must be a string$/);
|
||||
});
|
||||
|
||||
it('Construct AccountSet transaction', function() {
|
||||
@@ -1390,7 +1269,7 @@ describe('Transaction', function() {
|
||||
var bid = '1/USD/rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm';
|
||||
var ask = '1/EUR/rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm';
|
||||
assert.throws(function() {
|
||||
new Transaction().offerCreate('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', bid, ask);
|
||||
var transaction = new Transaction().offerCreate('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', bid, ask);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1423,13 +1302,13 @@ describe('Transaction', function() {
|
||||
|
||||
it('Construct SetRegularKey transaction - invalid account', function() {
|
||||
assert.throws(function() {
|
||||
new Transaction().setRegularKey('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 'r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
var transaction = new Transaction().setRegularKey('xrsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 'r36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
});
|
||||
});
|
||||
|
||||
it('Construct SetRegularKey transaction - invalid regularKey', function() {
|
||||
assert.throws(function() {
|
||||
new Transaction().setRegularKey('rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 'xr36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
var transaction = new Transaction().setRegularKey('rsLEU1TPdCJPPysqhWYw9jD97xtG5WqSJm', 'xr36xtKNKR43SeXnGn7kN4r4JdQzcrkqpWe');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user