Files
xahau.js/packages/xrpl/tools/createValidate.js
Mayukha Vadari 91e7369f1b feat: add support for current sidechain design (#2039)
* Update definitions.json

* add new st types

* add tests

* add XChainClaim tx

* add XChainCommit tx

* add XChainCreateBridge tx

* add XChainCreateClaimID tx

* update definitions.json

* rename Bridge -> XChainBridge in binary codec, fix tests

* rename Bridge -> XChainBridge in models

* add codec support for XChainAddAttestation

* add XChainAddAttestation model

* undo debugging change

* fix linting issues

* update definitions.json for new rippled code, add new tests/update old tests

* add/update models

* update history

* update binary-codec

* add XChainModifyBridge model

* update RPCs

* update to latest rippled

* more fixes

* fix definitions.json

* fix spacing

* update definitions.json to avoid conflict with amm

* update definitions.json to resolve amm conflicts

* audit code

* more updates

* update rpcs

* switch to beta version

* add destination tag to XChainClaim

* rename IssuedCurrency -> Issue to match rippled

* update Issue form

* fix account object filters

* fix issue from typing

* fix LedgerEntry types

* fix attestation destination type

* Update definitions.json

* rename XChainAddAttestation -> XChainAddAttestationBatch

* add XChainAddClaimAttestation

* add XChainAddAccountCreateAttestation

* remove XChainAddAttestationBatch

* update definitions

* fix attestation txns

* fix attestation object

* add validate for new txs

* add Bridge ledger object

* add XChainOwnedClaimID ledger object

* add XChainOwnedCreateAccountClaimID ledger object

* update account_objects

* update models to latest rippled

* fix minor issues

* fix bridge ledger_entry

* add XChainModifyBridge flag

* Update definitions.json

* add rbc tests for the new txs

* update validateXChainModifyBridge

* add validate methods to other xchain txs

* fix isXChainBridge

* fix isIssue typing

* fix model types

* update changelog

* switch prepare to prepublishOnly

* add docs

* fix AccountObjectsType filter

* export common types

* fix account_objects filter

* update LedgerEntry

* add sidechain faucet info

* add snippet

* improve snippet

* fix spacing issues

* update ledger_entry

* remove AMMDelete tests for now

* Update definitions.json

* fix unit tests

* convert createValidate script to JS
* remove unneeded linter ignores

* respond to comments

* more snippet fixes

* make validate functions more readable

* add getXChainClaimID method to parse metadata

* re-add linter rules

* clean up common

* fix getXChainClaimID test

* return undefined for failed tx

* test: add model tests for new sidechain transactions (#2059)

* add XChainAddAttestation tests, fix model

* add XChainClaim model tests

* add XChainCommit model tests, fix typo

* add XChainCreateBridge model tests

* add XChainCreateClaimID model tests

* add XChainModifyBridge tests

* update to most recent version of code

* remove XChainAddAttestationBatch tests

* add more validation tests

* switch createValidateTests to JS
2023-09-26 10:01:21 -04:00

148 lines
3.8 KiB
JavaScript

/* eslint-disable no-continue -- unneeded here */
/**
* This file writes the `validate` function for a transaction, when provided the model name in the `src/models/transactions`
* folder.
*/
const fs = require('fs')
const NORMAL_TYPES = ['number', 'string']
const NUMBERS = ['0', '1']
// TODO: rewrite this to use regex
async function main() {
if (process.argv.length < 3) {
console.log(`Usage: ${process.argv[0]} ${process.argv[1]} TxName`)
process.exit(1)
}
const modelName = process.argv[2]
const filename = `./src/models/transactions/${modelName}.ts`
const [model, txName] = await getModel(filename)
return processModel(model, txName)
}
async function getModel(filename) {
let model = ''
let started = false
let ended = false
const data = await fs.promises.readFile(filename, { encoding: 'utf8' })
const lines = data.split('\n')
for (const line of lines) {
if (ended) {
continue
}
if (!started && !line.startsWith('export')) {
continue
}
if (!started && line.includes('Flags')) {
continue
}
if (!started) {
started = true
}
model += `${line}\n`
if (line === '}') {
ended = true
}
}
const name_line = model.split('\n')[0].split(' ')
const txName = name_line[2]
return [model, txName]
}
function getValidationFunction(paramType) {
if (NORMAL_TYPES.includes(paramType)) {
const paramTypeCapitalized =
paramType.substring(0, 1).toUpperCase() + paramType.substring(1)
return `is${paramTypeCapitalized}(inp)`
}
if (NUMBERS.includes(paramType)) {
return `inp === ${paramType}`
}
return `is${paramType}(inp)`
}
function getValidationLine(validationFns) {
if (validationFns.length === 1) {
if (!validationFns[0].includes('===')) {
// Example: `validateRequiredFields(tx, 'Amount', isAmount)`
const validationFn = validationFns[0]
// strip the `(inp)` in e.g. `isAmount(inp)`
return validationFn.substring(0, validationFn.length - 5)
}
}
// Example:
// `validateRequiredFields(tx, 'XChainAccountCreateCount',
// (inp) => isNumber(inp) || isString(inp)))`
return `(inp) => ${validationFns.join(' || ')}`
}
function processModel(model, txName) {
let output = ''
// process the TS model and get the types of each parameter
for (let line of model.split('\n')) {
if (line === '') {
continue
}
if (line.startsWith('export')) {
continue
}
if (line === '}') {
continue
}
line = line.trim()
if (line.startsWith('TransactionType')) {
continue
}
if (line.startsWith('Flags')) {
continue
}
if (line.startsWith('/**')) {
continue
}
if (line.startsWith('*')) {
continue
}
// process the line with a type
const split = line.split(' ')
const param = split[0].replace('?:', '').replace(':', '').trim()
const paramTypes = split.slice(1)
const optional = split[0].endsWith('?:')
const functionName = optional
? 'validateOptionalField'
: 'validateRequiredField'
// process the types and turn them into a validation function
let idx = 0
const if_outputs = []
while (idx < paramTypes.length) {
const paramType = paramTypes[idx]
if_outputs.push(getValidationFunction(paramType))
idx += 2
}
output += ` ${functionName}(tx, '${param}', ${getValidationLine(
if_outputs,
)})\n\n`
}
output = output.substring(0, output.length - 1)
output += '}\n'
// initial output content
output = `/**
* Verify the form and type of a ${txName} at runtime.
*
* @param tx - A ${txName} Transaction.
* @throws When the ${txName} is malformed.
*/
export function validate${txName}(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
${output}`
return output
}
main().then(console.log)