Skip to content

Commit c504a17

Browse files
committed
remove change-case dependency and usage of snakeCase in libauthTemplate generation
1 parent e730a6d commit c504a17

File tree

6 files changed

+44
-85
lines changed

6 files changed

+44
-85
lines changed

packages/cashscript/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"@cashscript/utils": "^0.11.0-next.2",
4848
"@electrum-cash/network": "^4.1.1",
4949
"@mr-zwets/bchn-api-wrapper": "^1.0.1",
50-
"change-case": "^5.4.4",
5150
"delay": "^6.0.0",
5251
"fast-deep-equal": "^3.1.3",
5352
"pako": "^2.1.0",
@@ -56,7 +55,6 @@
5655
"devDependencies": {
5756
"@jest/globals": "^29.7.0",
5857
"@psf/bch-js": "^6.8.0",
59-
"@types/change-case": "^2.3.5",
6058
"@types/pako": "^2.0.3",
6159
"@types/semver": "^7.5.8",
6260
"eslint": "^8.54.0",

packages/cashscript/src/LibauthTemplate.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
import SignatureTemplate from './SignatureTemplate.js';
3838
import { Transaction } from './Transaction.js';
3939
import { EncodedConstructorArgument, EncodedFunctionArgument } from './Argument.js';
40-
import { addressToLockScript, extendedStringify, snakeCase, zip } from './utils.js';
40+
import { addressToLockScript, extendedStringify, zip } from './utils.js';
4141
import { Contract } from './Contract.js';
4242

4343
interface BuildTemplateOptions {
@@ -89,9 +89,9 @@ export const buildTemplate = async ({
8989
const hashtypeName = getHashTypeName(input.template.getHashType(false));
9090
const signatureString = `${placeholderKeyName}.${signatureAlgorithmName}.${hashtypeName}`;
9191

92-
template.entities[snakeCase(contract.name + 'Parameters')].scripts!.push(lockScriptName, unlockScriptName);
93-
template.entities[snakeCase(contract.name + 'Parameters')].variables = {
94-
...template.entities[snakeCase(contract.name + 'Parameters')].variables,
92+
template.entities[contract.name + '_parameters'].scripts!.push(lockScriptName, unlockScriptName);
93+
template.entities[contract.name + '_parameters'].variables = {
94+
...template.entities[contract.name + '_parameters'].variables,
9595
[placeholderKeyName]: {
9696
description: placeholderKeyName,
9797
name: placeholderKeyName,
@@ -132,7 +132,7 @@ const generateTemplateEntities = (
132132
): WalletTemplate['entities'] => {
133133
const functionParameters = Object.fromEntries<WalletTemplateVariable>(
134134
abiFunction.inputs.map((input, index) => ([
135-
snakeCase(input.name),
135+
input.name,
136136
{
137137
description: `"${input.name}" parameter of function "${abiFunction.name}"`,
138138
name: input.name,
@@ -143,7 +143,7 @@ const generateTemplateEntities = (
143143

144144
const constructorParameters = Object.fromEntries<WalletTemplateVariable>(
145145
artifact.constructorInputs.map((input) => ([
146-
snakeCase(input.name),
146+
input.name,
147147
{
148148
description: `"${input.name}" parameter of this contract`,
149149
name: input.name,
@@ -153,12 +153,12 @@ const generateTemplateEntities = (
153153
);
154154

155155
const entities = {
156-
[snakeCase(artifact.contractName + 'Parameters')]: {
156+
[artifact.contractName + '_parameters']: {
157157
description: 'Contract creation and function parameters',
158-
name: snakeCase(artifact.contractName + 'Parameters'),
158+
name: artifact.contractName + '_parameters',
159159
scripts: [
160-
snakeCase(artifact.contractName + '_lock'),
161-
snakeCase(artifact.contractName + '_unlock'),
160+
artifact.contractName + '_lock',
161+
artifact.contractName + '_unlock',
162162
],
163163
variables: {
164164
...functionParameters,
@@ -169,7 +169,7 @@ const generateTemplateEntities = (
169169

170170
// function_index is a special variable that indicates the function to execute
171171
if (artifact.abi.length > 1) {
172-
entities[snakeCase(artifact.contractName + 'Parameters')].variables.function_index = {
172+
entities[artifact.contractName + '_parameters'].variables.function_index = {
173173
description: 'Script function index to execute',
174174
name: 'function_index',
175175
type: 'WalletData',
@@ -188,8 +188,8 @@ const generateTemplateScripts = (
188188
): WalletTemplate['scripts'] => {
189189
// definition of locking scripts and unlocking scripts with their respective bytecode
190190
return {
191-
[snakeCase(artifact.contractName + '_unlock')]: generateTemplateUnlockScript(artifact, abiFunction, encodedFunctionArgs),
192-
[snakeCase(artifact.contractName + '_lock')]: generateTemplateLockScript(artifact, addressType, encodedConstructorArgs),
191+
[artifact.contractName + '_unlock']: generateTemplateUnlockScript(artifact, abiFunction, encodedFunctionArgs),
192+
[artifact.contractName + '_lock']: generateTemplateLockScript(artifact, addressType, encodedConstructorArgs),
193193
};
194194
};
195195

@@ -200,7 +200,7 @@ const generateTemplateLockScript = (
200200
): WalletTemplateScriptLocking => {
201201
return {
202202
lockingType: addressType,
203-
name: snakeCase(artifact.contractName + '_lock'),
203+
name: artifact.contractName + '_lock',
204204
script: [
205205
`// "${artifact.contractName}" contract constructor parameters`,
206206
formatParametersForDebugging(artifact.constructorInputs, constructorArguments),
@@ -224,15 +224,15 @@ const generateTemplateUnlockScript = (
224224

225225
return {
226226
// this unlocking script must pass our only scenario
227-
passes: [snakeCase(artifact.contractName + 'Evaluate')],
228-
name: snakeCase(artifact.contractName + '_unlock'),
227+
passes: [artifact.contractName + '_evaluate'],
228+
name: artifact.contractName + '_unlock',
229229
script: [
230230
`// "${abiFunction.name}" function parameters`,
231231
formatParametersForDebugging(abiFunction.inputs, encodedFunctionArgs),
232232
'',
233233
...functionIndexString,
234234
].join('\n'),
235-
unlocks: snakeCase(artifact.contractName + '_lock'),
235+
unlocks: artifact.contractName + '_lock',
236236
};
237237
};
238238

@@ -250,8 +250,8 @@ const generateTemplateScenarios = (
250250

251251
const scenarios = {
252252
// single scenario to spend out transaction under test given the CashScript parameters provided
253-
[snakeCase(artifact.contractName + 'Evaluate')]: {
254-
name: snakeCase(artifact.contractName + 'Evaluate'),
253+
[artifact.contractName + '_evaluate']: {
254+
name: artifact.contractName + '_evaluate',
255255
description: 'An example evaluation where this script execution passes.',
256256
data: {
257257
// encode values for the variables defined above in `entities` property
@@ -272,7 +272,7 @@ const generateTemplateScenarios = (
272272

273273
if (artifact.abi.length > 1) {
274274
const functionIndex = artifact.abi.findIndex((func) => func.name === transaction.abiFunction.name);
275-
scenarios![snakeCase(artifact.contractName + 'Evaluate')].data!.bytecode!.function_index = functionIndex.toString();
275+
scenarios![artifact.contractName + '_evaluate'].data!.bytecode!.function_index = functionIndex.toString();
276276
}
277277

278278
return scenarios;
@@ -382,7 +382,7 @@ export const generateTemplateScenarioParametersValues = (
382382
.map(([input, arg]) => {
383383
const encodedArgumentHex = binToHex(arg as Uint8Array);
384384
const prefixedEncodedArgument = addHexPrefixExceptEmpty(encodedArgumentHex);
385-
return [snakeCase(input.name), prefixedEncodedArgument] as const;
385+
return [input.name, prefixedEncodedArgument] as const;
386386
});
387387

388388
return Object.fromEntries(entries);
@@ -400,7 +400,7 @@ export const generateTemplateScenarioKeys = (
400400

401401
const entries = typesAndArguments
402402
.filter(([, arg]) => arg instanceof SignatureTemplate)
403-
.map(([input, arg]) => ([snakeCase(input.name), binToHex((arg as SignatureTemplate).privateKey)] as const));
403+
.map(([input, arg]) => ([input.name, binToHex((arg as SignatureTemplate).privateKey)] as const));
404404

405405
return Object.fromEntries(entries);
406406
};
@@ -415,14 +415,14 @@ export const formatParametersForDebugging = (types: readonly AbiInput[], args: E
415415
if (arg instanceof SignatureTemplate) {
416416
const signatureAlgorithmName = getSignatureAlgorithmName(arg.getSignatureAlgorithm());
417417
const hashtypeName = getHashTypeName(arg.getHashType(false));
418-
return `<${snakeCase(input.name)}.${signatureAlgorithmName}.${hashtypeName}> // ${input.type}`;
418+
return `<${input.name}.${signatureAlgorithmName}.${hashtypeName}> // ${input.type}`;
419419
}
420420

421421
const typeStr = input.type === 'bytes' ? `bytes${arg.length}` : input.type;
422422

423423
// we output these values as pushdata, comment will contain the type and the value of the variable
424424
// e.g. <timeout> // int = <0xa08601>
425-
return `<${snakeCase(input.name)}> // ${typeStr} = <${`0x${binToHex(arg)}`}>`;
425+
return `<${input.name}> // ${typeStr} = <${`0x${binToHex(arg)}`}>`;
426426
}).join('\n');
427427
};
428428

packages/cashscript/src/advanced/LibauthTemplate.ts

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {
3939
} from '../LibauthTemplate.js';
4040
import SignatureTemplate from '../SignatureTemplate.js';
4141
import { Transaction } from '../Transaction.js';
42-
import { addressToLockScript, snakeCase, titleCase } from '../utils.js';
42+
import { addressToLockScript } from '../utils.js';
4343
import { TransactionBuilder } from '../TransactionBuilder.js';
4444

4545

@@ -87,33 +87,33 @@ export const generateTemplateEntitiesP2SH = (
8787
): WalletTemplate['entities'] => {
8888
const functionParameters = Object.fromEntries<WalletTemplateVariable>(
8989
abiFunction.inputs.map((input, index) => ([
90-
snakeCase(input.name),
90+
input.name,
9191
{
9292
description: `"${input.name}" parameter of function "${abiFunction.name}"`,
93-
name: titleCase(input.name),
93+
name: input.name,
9494
type: encodedFunctionArgs[index] instanceof SignatureTemplate ? 'Key' : 'WalletData',
9595
},
9696
])),
9797
);
9898

9999
const constructorParameters = Object.fromEntries<WalletTemplateVariable>(
100100
artifact.constructorInputs.map((input) => ([
101-
snakeCase(input.name),
101+
input.name,
102102
{
103103
description: `"${input.name}" parameter of this contract`,
104-
name: titleCase(input.name),
104+
name: input.name,
105105
type: 'WalletData',
106106
},
107107
])),
108108
);
109109

110110
const entities = {
111-
[snakeCase(artifact.contractName + 'Parameters' + '_input' + inputIndex)]: {
111+
[artifact.contractName + '_parameters' + '_input' + inputIndex]: {
112112
description: 'Contract creation and function parameters',
113113
name: `${artifact.contractName} (input #${inputIndex})`,
114114
scripts: [
115-
snakeCase(artifact.contractName + '_lock'),
116-
snakeCase(artifact.contractName + '_' + abiFunction.name + '_input' + inputIndex + '_unlock'),
115+
artifact.contractName + '_lock',
116+
artifact.contractName + '_' + abiFunction.name + '_input' + inputIndex + '_unlock',
117117
],
118118
variables: {
119119
...functionParameters,
@@ -124,9 +124,9 @@ export const generateTemplateEntitiesP2SH = (
124124

125125
// function_index is a special variable that indicates the function to execute
126126
if (artifact.abi.length > 1) {
127-
entities[snakeCase(artifact.contractName + 'Parameters' + '_input' + inputIndex)].variables.function_index = {
127+
entities[artifact.contractName + '_parameters' + '_input' + inputIndex].variables.function_index = {
128128
description: 'Script function index to execute',
129-
name: titleCase('function_index'),
129+
name: 'function_index',
130130
type: 'WalletData',
131131
};
132132
}
@@ -188,8 +188,8 @@ export const generateTemplateScriptsP2SH = (
188188
inputIndex: number,
189189
): WalletTemplate['scripts'] => {
190190
// definition of locking scripts and unlocking scripts with their respective bytecode
191-
const unlockingScriptName = snakeCase(artifact.contractName + '_' + abiFunction.name + '_input' + inputIndex + '_unlock');
192-
const lockingScriptName = snakeCase(artifact.contractName + '_lock');
191+
const unlockingScriptName = artifact.contractName + '_' + abiFunction.name + '_input' + inputIndex + '_unlock';
192+
const lockingScriptName = artifact.contractName + '_lock';
193193

194194
return {
195195
[unlockingScriptName]: generateTemplateUnlockScript(artifact, abiFunction, encodedFunctionArgs, scenarioId, inputIndex),
@@ -252,7 +252,7 @@ const generateTemplateUnlockScript = (
252252
'',
253253
...functionIndexString,
254254
].join('\n'),
255-
unlocks: snakeCase(artifact.contractName + '_lock'),
255+
unlocks: artifact.contractName + '_lock',
256256
};
257257
};
258258

@@ -271,7 +271,7 @@ export const generateTemplateScenarios = (
271271
const scenarios = {
272272
// single scenario to spend out transaction under test given the CashScript parameters provided
273273
[scenarioIdentifier]: {
274-
name: snakeCase(artifact.contractName + '_' + abiFunction.name + 'Evaluate'),
274+
name: artifact.contractName + '_' + abiFunction.name + '_evaluate',
275275
description: 'An example evaluation where this script execution passes.',
276276
data: {
277277
// encode values for the variables defined above in `entities` property
@@ -421,17 +421,15 @@ export const getLibauthTemplates = (
421421
let scenarioIdentifier = baseIdentifier;
422422
let counter = 0;
423423

424-
const scenarioIds = [snakeCase(scenarioIdentifier)];
424+
const scenarioIds = [scenarioIdentifier];
425425

426426
// Find first available unique identifier by incrementing counter
427-
while (scenarios[snakeCase(scenarioIdentifier)]) {
427+
while (scenarios[scenarioIdentifier]) {
428428
counter++;
429429
scenarioIdentifier = `${baseIdentifier}${counter}`;
430-
scenarioIds.push(snakeCase(scenarioIdentifier));
430+
scenarioIds.push(scenarioIdentifier);
431431
}
432432

433-
scenarioIdentifier = snakeCase(scenarioIdentifier);
434-
435433
// Encode the function arguments for this contract input
436434
const encodedArgs = encodeFunctionArguments(
437435
abiFunction,
@@ -567,9 +565,7 @@ const generateLockingScriptParams = (
567565
addHexPrefixExceptEmpty(binToHex(csInput.unlocker!.contract!.encodedConstructorArgs[index])),
568566
]);
569567

570-
const constructorParams = Object.fromEntries(
571-
constructorParamsEntries.map(([key, value]) => [snakeCase(key), value]),
572-
);
568+
const constructorParams = Object.fromEntries(constructorParamsEntries);
573569

574570
return {
575571
script: lockScriptName,

packages/cashscript/src/debugging.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AuthenticationErrorCommon, AuthenticationInstruction, AuthenticationProgramCommon, AuthenticationProgramStateCommon, AuthenticationVirtualMachine, ResolvedTransactionCommon, WalletTemplate, WalletTemplateScriptUnlocking, binToHex, createCompiler, createVirtualMachineBch2025, encodeAuthenticationInstruction, walletTemplateToCompilerConfiguration } from '@bitauth/libauth';
22
import { Artifact, LogEntry, Op, PrimitiveType, StackItem, bytecodeToAsm, decodeBool, decodeInt, decodeString } from '@cashscript/utils';
3-
import { findLastIndex, snakeCase, toRegExp } from './utils.js';
3+
import { findLastIndex, toRegExp } from './utils.js';
44
import { FailedRequireError, FailedTransactionError, FailedTransactionEvaluationError } from './Errors.js';
55
import { getBitauthUri } from './LibauthTemplate.js';
66

@@ -17,7 +17,7 @@ export const debugTemplate = (template: WalletTemplate, artifacts: Artifact[]):
1717
// There are no scenarios defined for P2PKH placeholder scripts, so we skip them
1818
if (scenarioIds.length === 0) continue;
1919

20-
const matchingArtifact = artifacts.find((artifact) => unlockingScriptId.startsWith(snakeCase(artifact.contractName)));
20+
const matchingArtifact = artifacts.find((artifact) => unlockingScriptId.startsWith(artifact.contractName));
2121

2222
if (!matchingArtifact) {
2323
throw new Error(`No artifact found for unlocking script ${unlockingScriptId}`);

packages/cashscript/src/utils.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ import {
4141
UndefinedInputError,
4242
} from './Errors.js';
4343

44-
export { snakeCase } from 'change-case';
45-
4644
// ////////// PARAMETER VALIDATION ////////////////////////////////////////////
4745
export function validateInput(utxo: Utxo): void {
4846
if (!utxo) {
@@ -349,27 +347,6 @@ export function findLastIndex<T>(array: Array<T>, predicate: (value: T, index: n
349347
return -1;
350348
}
351349

352-
// TODO: Somehow, this turns P2PKHLock into p2pkh_lock, but P2PKH_Lock into p2_pkh_lock
353-
// export const snakeCase = (str: string): string => (
354-
// str
355-
// && str
356-
// .match(
357-
// /([A-Z]+\d*[A-Z]*(?=[A-Z][a-z])|[A-Z]?[a-z]+\d*[a-z]+|[A-Z]?[a-z]+\d*|[A-Z]+\d*|\d+)/g,
358-
// )!
359-
// .map((s) => s.toLowerCase())
360-
// .join('_')
361-
// );
362-
363-
export const titleCase = (str: string): string => {
364-
if (!str) return '';
365-
return str
366-
.match(
367-
/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g,
368-
)!
369-
.map((s) => s.charAt(0).toUpperCase() + s.slice(1).toLowerCase())
370-
.join(' ');
371-
};
372-
373350
// JSON.stringify version that can serialize otherwise unsupported types (bigint and Uint8Array)
374351
export const extendedStringify = (obj: any, spaces?: number): string => JSON.stringify(
375352
obj,

yarn.lock

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,13 +2704,6 @@
27042704
dependencies:
27052705
"@babel/types" "^7.3.0"
27062706

2707-
"@types/change-case@^2.3.5":
2708-
version "2.3.5"
2709-
resolved "https://registry.yarnpkg.com/@types/change-case/-/change-case-2.3.5.tgz#7c86cefd5897738980fc3bcbe466b03b38026dbd"
2710-
integrity sha512-JvctDvBuY3MVSEisGbSgaAdJTcs+2JjBKO60W1Isr3GnX2YZCyJYLDY96bV4eWensEUrQLRGEL+egAkIXYrW1Q==
2711-
dependencies:
2712-
change-case "*"
2713-
27142707
"@types/color-name@^1.1.1":
27152708
version "1.1.4"
27162709
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.4.tgz#e002611ff627347818d440a05e81650e9a4053b8"
@@ -3894,11 +3887,6 @@ chalk@^5.2.0, chalk@^5.4.1:
38943887
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8"
38953888
integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==
38963889

3897-
change-case@*, change-case@^5.4.4:
3898-
version "5.4.4"
3899-
resolved "https://registry.yarnpkg.com/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02"
3900-
integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
3901-
39023890
char-regex@^1.0.2:
39033891
version "1.0.2"
39043892
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"

0 commit comments

Comments
 (0)