Files
grin-web-wallet/scripts/slate_input.js
2024-12-20 18:08:44 -08:00

419 lines
9.8 KiB
JavaScript
Executable File

// Use strict
"use strict";
// Classes
// Slate input class
class SlateInput {
// Public
// Constructor
constructor(serializedSlateInputOrFeatures, slateOrCommit) {
// Reset
this.reset();
// Check if a binary serialized slate input is provided
if(serializedSlateInputOrFeatures instanceof BitReader === true) {
// Get serialized slate input
var serializedSlateInput = serializedSlateInputOrFeatures;
// Get slate
var slate = slateOrCommit;
// Unserialize the serialized slate input
this.unserialize(serializedSlateInput, slate);
}
// Otherwise check if a serialized slate input is provided
else if(Object.isObject(serializedSlateInputOrFeatures) === true) {
// Get serialized slate input
var serializedSlateInput = serializedSlateInputOrFeatures;
// Get slate
var slate = slateOrCommit;
// Unserialize the serialized slate input
this.unserialize(serializedSlateInput, slate);
}
// Otherwise check if arguments are provided
else if(typeof serializedSlateInputOrFeatures === "number") {
// Get features
var features = serializedSlateInputOrFeatures;
// Get Commit
var commit = slateOrCommit;
// Set features to provided features
this.features = features;
// Set commit to provided commit
this.commit = commit;
}
// Otherwise
else {
// Throw error
throw "Unsupported input.";
}
}
// Serialize
serialize(slateOrVersion, bitWriter) {
// Get slate version
var slateVersion = (slateOrVersion instanceof Slate === true) ? slateOrVersion.getVersion() : slateOrVersion;
// Check slate's version
switch((slateVersion instanceof BigNumber === true) ? slateVersion.toFixed() : slateVersion) {
// Version two and three
case Slate.VERSION_TWO.toFixed():
case Slate.VERSION_THREE.toFixed():
// Return serialized slate input
return {
// Features
"features": SlateInput.featuresToText(this.getFeatures()),
// Commit
"commit": Common.toHexString(this.getCommit())
};
// Version four
case Slate.VERSION_FOUR.toFixed():
// Check if serializing slate input as binary
if(typeof bitWriter !== "undefined") {
// Try
try {
// Write features
bitWriter.setBytes([this.getFeatures()]);
// Write commit
bitWriter.setBytes(this.getCommit());
}
// Catch errors
catch(error) {
// Throw error
throw "Unsupported input.";
}
}
// Otherwise
else {
// Create serialized slate input
var serializedSlateInput = {
// Commit
"c": Common.toHexString(this.getCommit())
};
// Check if not plain
if(this.isPlain() === false) {
// Set serialized slate input's features
serializedSlateInput["f"] = this.getFeatures();
}
// Return serialized slate input
return serializedSlateInput;
}
// Break
break;
// Default
default:
// Throw error
throw "Unsupported slate version.";
}
}
// Get transaction
getTransaction() {
// Return transaction
return {
// Features
"features": SlateInput.featuresToText(this.getFeatures()),
// Commit
"commit": Common.toHexString(this.getCommit())
};
}
// Get features
getFeatures() {
// Return features
return this.features;
}
// Get commit
getCommit() {
// Return commit
return this.commit;
}
// Is plain
isPlain() {
// Return if features is plain
return this.getFeatures() === SlateInput.PLAIN_FEATURES;
}
// Is coinbase
isCoinbase() {
// Return if features is coinbase
return this.getFeatures() === SlateInput.COINBASE_FEATURES;
}
// Get hash
getHash() {
// Return hash
return new Hash([
// Features
new Uint8Array([this.getFeatures()]),
// Commit
this.getCommit()
]);
}
// Is equal to
isEqualTo(slateInput) {
// Check if features aren't equal
if(this.getFeatures() !== slateInput.getFeatures())
// Return false
return false;
// Check if commits aren't equal
if(Common.arraysAreEqual(this.getCommit(), slateInput.getCommit()) === false)
// Return false
return false;
// Return true
return true;
}
// Private
// Reset
reset() {
// Set features to plain features
this.features = SlateInput.PLAIN_FEATURES;
}
// Unserialize
unserialize(serializedSlateInput, slate) {
// Check slate's version
switch((slate.getVersion() instanceof BigNumber === true) ? slate.getVersion().toFixed() : slate.getVersion()) {
// Version two and three
case Slate.VERSION_TWO.toFixed():
case Slate.VERSION_THREE.toFixed():
// Check if serialized slate input's features isn't supported
if("features" in serializedSlateInput === false || SlateInput.textToFeatures(serializedSlateInput["features"]) === SlateInput.UNSUPPORTED_FEATURES) {
// Throw error
throw "Unsupported input.";
}
// Set features to serialized slate input's features
this.features = SlateInput.textToFeatures(serializedSlateInput["features"]);
// Check if serialized slate input's commit isn't supported
if("commit" in serializedSlateInput === false || Common.isHexString(serializedSlateInput["commit"]) === false || Common.hexStringLength(serializedSlateInput["commit"]) !== Crypto.COMMIT_LENGTH || Secp256k1Zkp.isValidCommit(Common.fromHexString(serializedSlateInput["commit"])) !== true) {
// Throw error
throw "Unsupported input.";
}
// Set commit to serialized slate input's commit
this.commit = Common.fromHexString(serializedSlateInput["commit"]);
// Break
break;
// Version four
case Slate.VERSION_FOUR.toFixed():
// Check if serialized slate input is binary
if(serializedSlateInput instanceof BitReader === true) {
// Get bit reader
var bitReader = serializedSlateInput;
// Try
try {
// Set features to serialized slate input's features
this.features = bitReader.getBytes(1)[0];
// Check if serialized slate input's features isn't supported
if(this.getFeatures() !== SlateInput.PLAIN_FEATURES && this.getFeatures() !== SlateInput.COINBASE_FEATURES) {
// Throw error
throw "Unsupported input.";
}
// Set commit to serialized slate input's commit
this.commit = bitReader.getBytes(Crypto.COMMIT_LENGTH);
// Check if serialized slate input's commit isn't supported
if(Secp256k1Zkp.isValidCommit(this.getCommit()) !== true) {
// Throw error
throw "Unsupported input.";
}
}
// Catch errors
catch(error) {
// Throw error
throw "Unsupported input.";
}
}
// Otherwise
else {
// Check if serialized slate input's features isn't supported
if("f" in serializedSlateInput === true && ((Common.isNumberString(serializedSlateInput["f"]) === false && serializedSlateInput["f"] instanceof BigNumber === false) || ((new BigNumber(serializedSlateInput["f"])).isEqualTo(SlateInput.PLAIN_FEATURES) === false && (new BigNumber(serializedSlateInput["f"])).isEqualTo(SlateInput.COINBASE_FEATURES) === false))) {
// Throw error
throw "Unsupported input.";
}
// Set features to serialized slate input's features
this.features = ("f" in serializedSlateInput === true) ? (new BigNumber(serializedSlateInput["f"])).toNumber() : SlateInput.PLAIN_FEATURES;
// Check if serialized slate input's commit isn't supported
if("c" in serializedSlateInput === false || Common.isHexString(serializedSlateInput["c"]) === false || Common.hexStringLength(serializedSlateInput["c"]) !== Crypto.COMMIT_LENGTH || Secp256k1Zkp.isValidCommit(Common.fromHexString(serializedSlateInput["c"])) !== true) {
// Throw error
throw "Unsupported input.";
}
// Set commit to serialized slate input's commit
this.commit = Common.fromHexString(serializedSlateInput["c"]);
}
// Break
break;
// Default
default:
// Throw error
throw "Unsupported input.";
}
}
// Features to text
static featuresToText(features) {
// Check features
switch(features) {
// Plain features
case SlateInput.PLAIN_FEATURES:
// Return plain text
return "Plain";
// Coinbase features
case SlateInput.COINBASE_FEATURES:
// Return coinbase text
return "Coinbase";
// Default
default:
// Return unsupported features
return SlateInput.UNSUPPORTED_FEATURES;
}
}
// Text to feature
static textToFeatures(text) {
// Check text
switch(text) {
// Plain text
case "Plain":
// Return plain features
return SlateInput.PLAIN_FEATURES;
// Coinbase text
case "Coinbase":
// Return coinbase features
return SlateInput.COINBASE_FEATURES;
// Default
default:
// Return unsupported features
return SlateInput.UNSUPPORTED_FEATURES;
}
}
// Plain features
static get PLAIN_FEATURES() {
// Return plain features
return 0;
}
// Coinbase features
static get COINBASE_FEATURES() {
// Return coinbase features
return SlateInput.PLAIN_FEATURES + 1;
}
// Unsupported features
static get UNSUPPORTED_FEATURES() {
// Return unsupported features
return SlateInput.COINBASE_FEATURES + 1;
}
}
// Main function
// Set global object's slate input
globalThis["SlateInput"] = SlateInput;