@secondlayer/cli 8.6.1 → 8.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +17 -563
- package/dist/cli.js.map +6 -9
- package/dist/plugins/index.js +62 -597
- package/dist/plugins/index.js.map +6 -7
- package/package.json +5 -4
package/dist/cli.js
CHANGED
|
@@ -20296,562 +20296,15 @@ var require_out4 = __commonJS((exports, module) => {
|
|
|
20296
20296
|
module.exports = FastGlob;
|
|
20297
20297
|
});
|
|
20298
20298
|
|
|
20299
|
-
// src/utils/clarity-conversion.ts
|
|
20300
|
-
import {
|
|
20301
|
-
isAbiBuffer as isAbiBuffer2,
|
|
20302
|
-
isAbiList,
|
|
20303
|
-
isAbiOptional as isAbiOptional2,
|
|
20304
|
-
isAbiResponse,
|
|
20305
|
-
isAbiStringAscii as isAbiStringAscii2,
|
|
20306
|
-
isAbiStringUtf8 as isAbiStringUtf82,
|
|
20307
|
-
isAbiTuple,
|
|
20308
|
-
toCamelCase as toCamelCase4
|
|
20309
|
-
} from "@secondlayer/stacks/clarity";
|
|
20310
|
-
function generateClarityConversion(argName, argType) {
|
|
20311
|
-
const type = argType.type;
|
|
20312
|
-
if (typeof type === "string") {
|
|
20313
|
-
switch (type) {
|
|
20314
|
-
case "uint128":
|
|
20315
|
-
return `Cl.uint(${argName})`;
|
|
20316
|
-
case "int128":
|
|
20317
|
-
return `Cl.int(${argName})`;
|
|
20318
|
-
case "bool":
|
|
20319
|
-
return `Cl.bool(${argName})`;
|
|
20320
|
-
case "principal":
|
|
20321
|
-
case "trait_reference":
|
|
20322
|
-
return `(() => {
|
|
20323
|
-
const [address, contractName] = ${argName}.split(".") as [string, string | undefined];
|
|
20324
|
-
if (!validateStacksAddress(address)) {
|
|
20325
|
-
throw new Error("Invalid Stacks address format");
|
|
20326
|
-
}
|
|
20327
|
-
if (contractName !== undefined) {
|
|
20328
|
-
if (!CONTRACT_NAME_REGEX.test(contractName)) {
|
|
20329
|
-
throw new Error("Invalid contract name format: must start with letter and contain only letters, numbers, and hyphens");
|
|
20330
|
-
}
|
|
20331
|
-
return Cl.contractPrincipal(address, contractName);
|
|
20332
|
-
}
|
|
20333
|
-
return Cl.standardPrincipal(${argName});
|
|
20334
|
-
})()`;
|
|
20335
|
-
default:
|
|
20336
|
-
return `${argName}`;
|
|
20337
|
-
}
|
|
20338
|
-
}
|
|
20339
|
-
if (isAbiStringAscii2(type)) {
|
|
20340
|
-
return `Cl.stringAscii(${argName})`;
|
|
20341
|
-
}
|
|
20342
|
-
if (isAbiStringUtf82(type)) {
|
|
20343
|
-
return `Cl.stringUtf8(${argName})`;
|
|
20344
|
-
}
|
|
20345
|
-
if (isAbiBuffer2(type)) {
|
|
20346
|
-
return `(() => {
|
|
20347
|
-
const value = ${argName};
|
|
20348
|
-
if (value instanceof Uint8Array) {
|
|
20349
|
-
return Cl.buffer(value);
|
|
20350
|
-
}
|
|
20351
|
-
if (typeof value === 'object' && value !== null && value.type && value.value) {
|
|
20352
|
-
switch (value.type) {
|
|
20353
|
-
case 'ascii':
|
|
20354
|
-
return Cl.bufferFromAscii(value.value);
|
|
20355
|
-
case 'utf8':
|
|
20356
|
-
return Cl.bufferFromUtf8(value.value);
|
|
20357
|
-
case 'hex':
|
|
20358
|
-
return Cl.bufferFromHex(value.value);
|
|
20359
|
-
default:
|
|
20360
|
-
throw new Error(\`Unsupported buffer type: \${value.type}\`);
|
|
20361
|
-
}
|
|
20362
|
-
}
|
|
20363
|
-
if (typeof value === 'string') {
|
|
20364
|
-
if (value.startsWith('0x') || /^[0-9a-fA-F]+$/.test(value)) {
|
|
20365
|
-
return Cl.bufferFromHex(value);
|
|
20366
|
-
}
|
|
20367
|
-
const hasNonAscii = value.split('').some(char => char.charCodeAt(0) > 127);
|
|
20368
|
-
if (hasNonAscii) {
|
|
20369
|
-
return Cl.bufferFromUtf8(value);
|
|
20370
|
-
}
|
|
20371
|
-
return Cl.bufferFromAscii(value);
|
|
20372
|
-
}
|
|
20373
|
-
throw new Error(\`Invalid buffer value: \${value}\`);
|
|
20374
|
-
})()`;
|
|
20375
|
-
}
|
|
20376
|
-
if (isAbiOptional2(type)) {
|
|
20377
|
-
const innerConversion = generateClarityConversion(argName, {
|
|
20378
|
-
type: type.optional
|
|
20379
|
-
});
|
|
20380
|
-
return `${argName} !== null ? Cl.some(${innerConversion.replace(argName, `${argName}`)}) : Cl.none()`;
|
|
20381
|
-
}
|
|
20382
|
-
if (isAbiList(type)) {
|
|
20383
|
-
const innerConversion = generateClarityConversion("item", {
|
|
20384
|
-
type: type.list.type
|
|
20385
|
-
});
|
|
20386
|
-
const maxLength = type.list.length || 100;
|
|
20387
|
-
return `(() => {
|
|
20388
|
-
const listValue = ${argName};
|
|
20389
|
-
if (listValue.length > ${maxLength}) {
|
|
20390
|
-
throw new Error(\`List length \${listValue.length} exceeds max ${maxLength}\`);
|
|
20391
|
-
}
|
|
20392
|
-
return Cl.list(listValue.map(item => ${innerConversion}));
|
|
20393
|
-
})()`;
|
|
20394
|
-
}
|
|
20395
|
-
if (isAbiTuple(type)) {
|
|
20396
|
-
const requiredFields = type.tuple.map((f) => f.name);
|
|
20397
|
-
const fieldNames = JSON.stringify(requiredFields);
|
|
20398
|
-
const fields = type.tuple.map((field) => {
|
|
20399
|
-
const camelFieldName = toCamelCase4(field.name);
|
|
20400
|
-
const fieldConversion = generateClarityConversion(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
20401
|
-
return `"${field.name}": ${fieldConversion}`;
|
|
20402
|
-
}).join(", ");
|
|
20403
|
-
return `(() => {
|
|
20404
|
-
const tupleValue = ${argName};
|
|
20405
|
-
const requiredFields = ${fieldNames};
|
|
20406
|
-
for (const fieldName of requiredFields) {
|
|
20407
|
-
const camelName = fieldName.replace(/-([a-z])/g, (_: string, l: string) => l.toUpperCase());
|
|
20408
|
-
if (!(fieldName in tupleValue) && !(camelName in tupleValue)) {
|
|
20409
|
-
throw new Error(\`Missing tuple field: \${fieldName}\`);
|
|
20410
|
-
}
|
|
20411
|
-
}
|
|
20412
|
-
return Cl.tuple({ ${fields} });
|
|
20413
|
-
})()`;
|
|
20414
|
-
}
|
|
20415
|
-
if (isAbiResponse(type)) {
|
|
20416
|
-
const okConversion = generateClarityConversion("responseValue.ok", {
|
|
20417
|
-
type: type.response.ok
|
|
20418
|
-
});
|
|
20419
|
-
const errConversion = generateClarityConversion("responseValue.err", {
|
|
20420
|
-
type: type.response.error
|
|
20421
|
-
});
|
|
20422
|
-
return `(() => {
|
|
20423
|
-
const responseValue = ${argName};
|
|
20424
|
-
const hasOk = 'ok' in responseValue;
|
|
20425
|
-
const hasErr = 'err' in responseValue;
|
|
20426
|
-
if (hasOk && !hasErr) {
|
|
20427
|
-
return Cl.ok(${okConversion});
|
|
20428
|
-
}
|
|
20429
|
-
if (hasErr && !hasOk) {
|
|
20430
|
-
return Cl.error(${errConversion});
|
|
20431
|
-
}
|
|
20432
|
-
throw new Error("Response must have exactly 'ok' or 'err' property");
|
|
20433
|
-
})()`;
|
|
20434
|
-
}
|
|
20435
|
-
return `${argName}`;
|
|
20436
|
-
}
|
|
20437
|
-
var init_clarity_conversion = () => {};
|
|
20438
|
-
|
|
20439
|
-
// src/utils/type-mapping.ts
|
|
20440
|
-
import {
|
|
20441
|
-
isAbiBuffer as isAbiBuffer3,
|
|
20442
|
-
isAbiList as isAbiList2,
|
|
20443
|
-
isAbiOptional as isAbiOptional3,
|
|
20444
|
-
isAbiResponse as isAbiResponse2,
|
|
20445
|
-
isAbiStringAscii as isAbiStringAscii3,
|
|
20446
|
-
isAbiStringUtf8 as isAbiStringUtf83,
|
|
20447
|
-
isAbiTuple as isAbiTuple2,
|
|
20448
|
-
toCamelCase as toCamelCase5
|
|
20449
|
-
} from "@secondlayer/stacks/clarity";
|
|
20450
|
-
function clarityTypeToTS(type) {
|
|
20451
|
-
if (typeof type === "string") {
|
|
20452
|
-
switch (type) {
|
|
20453
|
-
case "uint128":
|
|
20454
|
-
case "int128":
|
|
20455
|
-
return "bigint";
|
|
20456
|
-
case "bool":
|
|
20457
|
-
return "boolean";
|
|
20458
|
-
case "principal":
|
|
20459
|
-
case "trait_reference":
|
|
20460
|
-
return "string";
|
|
20461
|
-
default: {
|
|
20462
|
-
const typeStr = type;
|
|
20463
|
-
if (typeStr === "none") {
|
|
20464
|
-
return "null";
|
|
20465
|
-
}
|
|
20466
|
-
if (typeStr.includes("string") || typeStr.includes("ascii") || typeStr.includes("utf8")) {
|
|
20467
|
-
return "string";
|
|
20468
|
-
}
|
|
20469
|
-
if (typeStr.includes("buff")) {
|
|
20470
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
20471
|
-
}
|
|
20472
|
-
if (typeStr.includes("uint") || typeStr.includes("int")) {
|
|
20473
|
-
return "bigint";
|
|
20474
|
-
}
|
|
20475
|
-
return "any";
|
|
20476
|
-
}
|
|
20477
|
-
}
|
|
20478
|
-
}
|
|
20479
|
-
if (isAbiBuffer3(type)) {
|
|
20480
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
20481
|
-
}
|
|
20482
|
-
if (isAbiStringAscii3(type) || isAbiStringUtf83(type)) {
|
|
20483
|
-
return "string";
|
|
20484
|
-
}
|
|
20485
|
-
if (isAbiOptional3(type)) {
|
|
20486
|
-
const innerType = clarityTypeToTS(type.optional);
|
|
20487
|
-
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
20488
|
-
return `(${innerType}) | null`;
|
|
20489
|
-
}
|
|
20490
|
-
return `${innerType} | null`;
|
|
20491
|
-
}
|
|
20492
|
-
if (isAbiList2(type)) {
|
|
20493
|
-
const innerType = clarityTypeToTS(type.list.type);
|
|
20494
|
-
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
20495
|
-
return `(${innerType})[]`;
|
|
20496
|
-
}
|
|
20497
|
-
return `${innerType}[]`;
|
|
20498
|
-
}
|
|
20499
|
-
if (isAbiTuple2(type)) {
|
|
20500
|
-
const fields = type.tuple.map((field) => `${toCamelCase5(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
|
|
20501
|
-
return `{ ${fields} }`;
|
|
20502
|
-
}
|
|
20503
|
-
if (isAbiResponse2(type)) {
|
|
20504
|
-
const okType = clarityTypeToTS(type.response.ok);
|
|
20505
|
-
const errType = clarityTypeToTS(type.response.error);
|
|
20506
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
20507
|
-
}
|
|
20508
|
-
return "any";
|
|
20509
|
-
}
|
|
20510
|
-
function getTypeForArg(arg) {
|
|
20511
|
-
return clarityTypeToTS(arg.type);
|
|
20512
|
-
}
|
|
20513
|
-
var init_type_mapping = () => {};
|
|
20514
|
-
|
|
20515
|
-
// src/utils/generator-helpers.ts
|
|
20516
|
-
import {
|
|
20517
|
-
isAbiTuple as isAbiTuple3,
|
|
20518
|
-
toCamelCase as toCamelCase6
|
|
20519
|
-
} from "@secondlayer/stacks/clarity";
|
|
20520
|
-
function generateArgsSignature(args) {
|
|
20521
|
-
if (args.length === 0)
|
|
20522
|
-
return "";
|
|
20523
|
-
const argsTypes = args.map((arg) => {
|
|
20524
|
-
const camelName = toCamelCase6(arg.name);
|
|
20525
|
-
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
20526
|
-
}).join("; ");
|
|
20527
|
-
return `args: { ${argsTypes} }, `;
|
|
20528
|
-
}
|
|
20529
|
-
function generateClarityArgs(args) {
|
|
20530
|
-
if (args.length === 0)
|
|
20531
|
-
return "";
|
|
20532
|
-
return args.map((arg) => {
|
|
20533
|
-
const argName = `args.${toCamelCase6(arg.name)}`;
|
|
20534
|
-
return generateClarityConversion(argName, arg);
|
|
20535
|
-
}).join(", ");
|
|
20536
|
-
}
|
|
20537
|
-
function generateMapKeyConversion(keyType) {
|
|
20538
|
-
if (isAbiTuple3(keyType)) {
|
|
20539
|
-
const fields = keyType.tuple.map((field) => {
|
|
20540
|
-
const camelFieldName = toCamelCase6(field.name);
|
|
20541
|
-
const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
|
|
20542
|
-
return `"${field.name}": ${fieldConversion}`;
|
|
20543
|
-
}).join(", ");
|
|
20544
|
-
return `Cl.tuple({ ${fields} })`;
|
|
20545
|
-
}
|
|
20546
|
-
return generateClarityConversion("key", { type: keyType });
|
|
20547
|
-
}
|
|
20548
|
-
var init_generator_helpers = __esm(() => {
|
|
20549
|
-
init_clarity_conversion();
|
|
20550
|
-
init_type_mapping();
|
|
20551
|
-
});
|
|
20552
|
-
|
|
20553
20299
|
// src/generators/contract.ts
|
|
20554
20300
|
import {
|
|
20555
|
-
|
|
20556
|
-
} from "@secondlayer/
|
|
20557
|
-
function generateNetworkUtils() {
|
|
20558
|
-
return `/**
|
|
20559
|
-
* API URLs for different networks
|
|
20560
|
-
*/
|
|
20561
|
-
const API_URLS: Record<'mainnet' | 'testnet' | 'devnet', string> = {
|
|
20562
|
-
mainnet: 'https://api.hiro.so',
|
|
20563
|
-
testnet: 'https://api.testnet.hiro.so',
|
|
20564
|
-
devnet: 'http://localhost:3999'
|
|
20565
|
-
};
|
|
20566
|
-
|
|
20567
|
-
/**
|
|
20568
|
-
* Infer network from Stacks address prefix
|
|
20569
|
-
* SP/SM = mainnet, ST/SN = testnet
|
|
20570
|
-
*/
|
|
20571
|
-
function inferNetworkFromAddress(address: string): 'mainnet' | 'testnet' | undefined {
|
|
20572
|
-
if (address.startsWith('SP') || address.startsWith('SM')) return 'mainnet';
|
|
20573
|
-
if (address.startsWith('ST') || address.startsWith('SN')) return 'testnet';
|
|
20574
|
-
return undefined;
|
|
20575
|
-
}
|
|
20576
|
-
|
|
20577
|
-
/**
|
|
20578
|
-
* Get API URL, inferring network from contract address if not specified
|
|
20579
|
-
*/
|
|
20580
|
-
function getApiUrl(
|
|
20581
|
-
contractAddress: string,
|
|
20582
|
-
explicitNetwork?: 'mainnet' | 'testnet' | 'devnet'
|
|
20583
|
-
): string {
|
|
20584
|
-
const network = explicitNetwork ?? inferNetworkFromAddress(contractAddress) ?? 'mainnet';
|
|
20585
|
-
return API_URLS[network];
|
|
20586
|
-
}`;
|
|
20587
|
-
}
|
|
20588
|
-
function generateValidationUtils() {
|
|
20589
|
-
return `/**
|
|
20590
|
-
* Contract name validation regex
|
|
20591
|
-
* Must start with letter, contain only letters, numbers, and hyphens, max 128 chars
|
|
20592
|
-
*/
|
|
20593
|
-
const CONTRACT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9\\-]{0,127}$/;`;
|
|
20594
|
-
}
|
|
20301
|
+
generateContractInterface as buildContractInterface
|
|
20302
|
+
} from "@secondlayer/scaffold";
|
|
20595
20303
|
async function generateContractInterface(contracts) {
|
|
20596
|
-
|
|
20597
|
-
const header = `/**
|
|
20598
|
-
* Generated by @secondlayer/cli
|
|
20599
|
-
* DO NOT EDIT MANUALLY
|
|
20600
|
-
*
|
|
20601
|
-
* @requires @secondlayer/stacks - Install with: npm install @secondlayer/stacks
|
|
20602
|
-
*/`;
|
|
20603
|
-
const validationUtils = generateValidationUtils();
|
|
20604
|
-
const networkUtils = generateNetworkUtils();
|
|
20605
|
-
const contractsCode = contracts.map((contract) => generateContract(contract)).join(`
|
|
20606
|
-
|
|
20607
|
-
`);
|
|
20608
|
-
const code = `${imports}
|
|
20609
|
-
|
|
20610
|
-
${header}
|
|
20611
|
-
|
|
20612
|
-
${validationUtils}
|
|
20613
|
-
|
|
20614
|
-
${networkUtils}
|
|
20615
|
-
|
|
20616
|
-
${contractsCode}`;
|
|
20617
|
-
return formatCode(code);
|
|
20618
|
-
}
|
|
20619
|
-
function generateContract(contract) {
|
|
20620
|
-
const { name, address, contractName, abi } = contract;
|
|
20621
|
-
const abiCode = generateAbiConstant(name, abi);
|
|
20622
|
-
const methods = abi.functions.filter((func) => func.access !== "private").map((func) => generateMethod(func, address, contractName)).join(`,
|
|
20623
|
-
|
|
20624
|
-
`);
|
|
20625
|
-
const mapsObject = generateMapsObject(abi.maps || [], address, contractName);
|
|
20626
|
-
const varsObject = generateVarsObject(abi.variables || [], address, contractName);
|
|
20627
|
-
const constantsObject = generateConstantsObject(abi.variables || [], address, contractName);
|
|
20628
|
-
const allMembers = [methods, mapsObject, varsObject, constantsObject].filter(Boolean);
|
|
20629
|
-
const contractCode = `export const ${name} = {
|
|
20630
|
-
address: '${address}',
|
|
20631
|
-
contractAddress: '${address}',
|
|
20632
|
-
contractName: '${contractName}',
|
|
20633
|
-
|
|
20634
|
-
${allMembers.join(`,
|
|
20635
|
-
|
|
20636
|
-
`)}
|
|
20637
|
-
} as const`;
|
|
20638
|
-
return `${abiCode}
|
|
20639
|
-
|
|
20640
|
-
${contractCode}`;
|
|
20641
|
-
}
|
|
20642
|
-
function generateAbiConstant(name, abi) {
|
|
20643
|
-
const abiJson = JSON.stringify(abi, null, 2).replace(/"([a-zA-Z_$][a-zA-Z0-9_$]*)":/g, "$1:").replace(/"/g, "'");
|
|
20644
|
-
return `export const ${name}Abi = ${abiJson} as const`;
|
|
20645
|
-
}
|
|
20646
|
-
function generateMethod(func, address, contractName) {
|
|
20647
|
-
const methodName = toCamelCase7(func.name);
|
|
20648
|
-
if (func.args.length === 0) {
|
|
20649
|
-
return `${methodName}() {
|
|
20650
|
-
return {
|
|
20651
|
-
contractAddress: '${address}',
|
|
20652
|
-
contractName: '${contractName}',
|
|
20653
|
-
functionName: '${func.name}',
|
|
20654
|
-
functionArgs: []
|
|
20655
|
-
}
|
|
20656
|
-
}`;
|
|
20657
|
-
}
|
|
20658
|
-
if (func.args.length === 1) {
|
|
20659
|
-
const originalArgName = func.args[0].name;
|
|
20660
|
-
const argName = toCamelCase7(originalArgName);
|
|
20661
|
-
const argType = getTypeForArg(func.args[0]);
|
|
20662
|
-
const clarityConversion = generateClarityConversion(argName, func.args[0]);
|
|
20663
|
-
return `${methodName}(...args: [{ ${argName}: ${argType} }] | [${argType}]) {
|
|
20664
|
-
const ${argName} = args.length === 1 && typeof args[0] === 'object' && args[0] !== null && '${argName}' in args[0]
|
|
20665
|
-
? args[0].${argName}
|
|
20666
|
-
: args[0] as ${argType}
|
|
20667
|
-
|
|
20668
|
-
return {
|
|
20669
|
-
contractAddress: '${address}',
|
|
20670
|
-
contractName: '${contractName}',
|
|
20671
|
-
functionName: '${func.name}',
|
|
20672
|
-
functionArgs: [${clarityConversion}]
|
|
20673
|
-
}
|
|
20674
|
-
}`;
|
|
20675
|
-
}
|
|
20676
|
-
const argsList = func.args.map((arg) => toCamelCase7(arg.name)).join(", ");
|
|
20677
|
-
const argsTypes = func.args.map((arg) => {
|
|
20678
|
-
const camelName = toCamelCase7(arg.name);
|
|
20679
|
-
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
20680
|
-
}).join("; ");
|
|
20681
|
-
const argsArray = func.args.map((arg) => {
|
|
20682
|
-
const argName = toCamelCase7(arg.name);
|
|
20683
|
-
return generateClarityConversion(argName, arg);
|
|
20684
|
-
}).join(", ");
|
|
20685
|
-
const objectAccess = func.args.map((arg) => {
|
|
20686
|
-
const camelName = toCamelCase7(arg.name);
|
|
20687
|
-
return `args[0].${camelName}`;
|
|
20688
|
-
}).join(", ");
|
|
20689
|
-
const positionTypes = func.args.map((arg) => getTypeForArg(arg)).join(", ");
|
|
20690
|
-
return `${methodName}(...args: [{ ${argsTypes} }] | [${positionTypes}]) {
|
|
20691
|
-
const [${argsList}] = args.length === 1 && typeof args[0] === 'object' && args[0] !== null
|
|
20692
|
-
? [${objectAccess}]
|
|
20693
|
-
: args as [${positionTypes}]
|
|
20694
|
-
|
|
20695
|
-
return {
|
|
20696
|
-
contractAddress: '${address}',
|
|
20697
|
-
contractName: '${contractName}',
|
|
20698
|
-
functionName: '${func.name}',
|
|
20699
|
-
functionArgs: [${argsArray}]
|
|
20700
|
-
}
|
|
20701
|
-
}`;
|
|
20702
|
-
}
|
|
20703
|
-
function generateMapsObject(maps, address, contractName) {
|
|
20704
|
-
if (!maps || maps.length === 0) {
|
|
20705
|
-
return "";
|
|
20706
|
-
}
|
|
20707
|
-
const mapMethods = maps.map((map) => {
|
|
20708
|
-
const methodName = toCamelCase7(map.name);
|
|
20709
|
-
const keyType = getTypeForArg({ type: map.key });
|
|
20710
|
-
const valueType = getTypeForArg({ type: map.value });
|
|
20711
|
-
const keyConversion = generateMapKeyConversion(map.key);
|
|
20712
|
-
return `${methodName}: {
|
|
20713
|
-
async get(key: ${keyType}, options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType} | null> {
|
|
20714
|
-
try {
|
|
20715
|
-
const { cvToJSON, serializeCV } = await import('@secondlayer/stacks/clarity');
|
|
20716
|
-
const baseUrl = getApiUrl('${address}', options?.network);
|
|
20717
|
-
const mapKey = ${keyConversion};
|
|
20718
|
-
const keyHex = serializeCV(mapKey).toString('hex');
|
|
20719
|
-
|
|
20720
|
-
const response = await fetch(
|
|
20721
|
-
\`\${baseUrl}/v2/map_entry/${address}/${contractName}/${map.name}\`,
|
|
20722
|
-
{
|
|
20723
|
-
method: 'POST',
|
|
20724
|
-
headers: { 'Content-Type': 'application/json' },
|
|
20725
|
-
body: JSON.stringify(keyHex)
|
|
20726
|
-
}
|
|
20727
|
-
);
|
|
20728
|
-
|
|
20729
|
-
if (!response.ok) {
|
|
20730
|
-
throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
|
|
20731
|
-
}
|
|
20732
|
-
|
|
20733
|
-
const result = await response.json();
|
|
20734
|
-
if (!result.data || result.data === '0x09') {
|
|
20735
|
-
return null; // none value
|
|
20736
|
-
}
|
|
20737
|
-
|
|
20738
|
-
const { deserializeCV } = await import('@secondlayer/stacks/clarity');
|
|
20739
|
-
const cv = deserializeCV(result.data);
|
|
20740
|
-
const parsed = cvToJSON(cv);
|
|
20741
|
-
// Unwrap the (some ...) wrapper
|
|
20742
|
-
return parsed.value?.value ?? parsed.value ?? null;
|
|
20743
|
-
} catch (error) {
|
|
20744
|
-
if (error instanceof Error) {
|
|
20745
|
-
throw new Error(\`Map access failed for '${map.name}': \${error.message}\`);
|
|
20746
|
-
}
|
|
20747
|
-
throw error;
|
|
20748
|
-
}
|
|
20749
|
-
},
|
|
20750
|
-
keyType: ${JSON.stringify(map.key)} as const,
|
|
20751
|
-
valueType: ${JSON.stringify(map.value)} as const
|
|
20752
|
-
}`;
|
|
20753
|
-
});
|
|
20754
|
-
return `maps: {
|
|
20755
|
-
${mapMethods.join(`,
|
|
20756
|
-
|
|
20757
|
-
`)}
|
|
20758
|
-
}`;
|
|
20759
|
-
}
|
|
20760
|
-
function generateVarsObject(variables, address, contractName) {
|
|
20761
|
-
if (!variables || variables.length === 0) {
|
|
20762
|
-
return "";
|
|
20763
|
-
}
|
|
20764
|
-
const dataVars = variables.filter((v) => v.access === "variable");
|
|
20765
|
-
if (dataVars.length === 0) {
|
|
20766
|
-
return "";
|
|
20767
|
-
}
|
|
20768
|
-
const varMethods = dataVars.map((variable) => {
|
|
20769
|
-
const methodName = toCamelCase7(variable.name);
|
|
20770
|
-
const valueType = getTypeForArg({ type: variable.type });
|
|
20771
|
-
return `${methodName}: {
|
|
20772
|
-
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
20773
|
-
try {
|
|
20774
|
-
const { cvToJSON, deserializeCV } = await import('@secondlayer/stacks/clarity');
|
|
20775
|
-
const baseUrl = getApiUrl('${address}', options?.network);
|
|
20776
|
-
|
|
20777
|
-
const response = await fetch(
|
|
20778
|
-
\`\${baseUrl}/v2/data_var/${address}/${contractName}/${variable.name}?proof=0\`
|
|
20779
|
-
);
|
|
20780
|
-
|
|
20781
|
-
if (!response.ok) {
|
|
20782
|
-
throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
|
|
20783
|
-
}
|
|
20784
|
-
|
|
20785
|
-
const result = await response.json();
|
|
20786
|
-
const cv = deserializeCV(result.data);
|
|
20787
|
-
const parsed = cvToJSON(cv);
|
|
20788
|
-
return parsed.value ?? parsed;
|
|
20789
|
-
} catch (error) {
|
|
20790
|
-
if (error instanceof Error) {
|
|
20791
|
-
throw new Error(\`Variable access failed for '${variable.name}': \${error.message}\`);
|
|
20792
|
-
}
|
|
20793
|
-
throw error;
|
|
20794
|
-
}
|
|
20795
|
-
},
|
|
20796
|
-
type: ${JSON.stringify(variable.type)} as const
|
|
20797
|
-
}`;
|
|
20798
|
-
});
|
|
20799
|
-
return `vars: {
|
|
20800
|
-
${varMethods.join(`,
|
|
20801
|
-
|
|
20802
|
-
`)}
|
|
20803
|
-
}`;
|
|
20804
|
-
}
|
|
20805
|
-
function generateConstantsObject(variables, address, contractName) {
|
|
20806
|
-
if (!variables || variables.length === 0) {
|
|
20807
|
-
return "";
|
|
20808
|
-
}
|
|
20809
|
-
const constants = variables.filter((v) => v.access === "constant");
|
|
20810
|
-
if (constants.length === 0) {
|
|
20811
|
-
return "";
|
|
20812
|
-
}
|
|
20813
|
-
const constMethods = constants.map((constant) => {
|
|
20814
|
-
const methodName = toCamelCase7(constant.name);
|
|
20815
|
-
const valueType = getTypeForArg({ type: constant.type });
|
|
20816
|
-
return `${methodName}: {
|
|
20817
|
-
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
20818
|
-
try {
|
|
20819
|
-
const { cvToJSON, deserializeCV } = await import('@secondlayer/stacks/clarity');
|
|
20820
|
-
const baseUrl = getApiUrl('${address}', options?.network);
|
|
20821
|
-
|
|
20822
|
-
const response = await fetch(
|
|
20823
|
-
\`\${baseUrl}/v2/constant_val/${address}/${contractName}/${constant.name}?proof=0\`
|
|
20824
|
-
);
|
|
20825
|
-
|
|
20826
|
-
if (!response.ok) {
|
|
20827
|
-
throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
|
|
20828
|
-
}
|
|
20829
|
-
|
|
20830
|
-
const result = await response.json();
|
|
20831
|
-
const cv = deserializeCV(result.data);
|
|
20832
|
-
const parsed = cvToJSON(cv);
|
|
20833
|
-
return parsed.value ?? parsed;
|
|
20834
|
-
} catch (error) {
|
|
20835
|
-
if (error instanceof Error) {
|
|
20836
|
-
throw new Error(\`Constant access failed for '${constant.name}': \${error.message}\`);
|
|
20837
|
-
}
|
|
20838
|
-
throw error;
|
|
20839
|
-
}
|
|
20840
|
-
},
|
|
20841
|
-
type: ${JSON.stringify(constant.type)} as const
|
|
20842
|
-
}`;
|
|
20843
|
-
});
|
|
20844
|
-
return `constants: {
|
|
20845
|
-
${constMethods.join(`,
|
|
20846
|
-
|
|
20847
|
-
`)}
|
|
20848
|
-
}`;
|
|
20304
|
+
return formatCode(buildContractInterface(contracts));
|
|
20849
20305
|
}
|
|
20850
20306
|
var init_contract = __esm(() => {
|
|
20851
|
-
init_clarity_conversion();
|
|
20852
20307
|
init_format();
|
|
20853
|
-
init_generator_helpers();
|
|
20854
|
-
init_type_mapping();
|
|
20855
20308
|
});
|
|
20856
20309
|
|
|
20857
20310
|
// src/utils/config.ts
|
|
@@ -32098,7 +31551,7 @@ __export(exports_generate, {
|
|
|
32098
31551
|
});
|
|
32099
31552
|
import path11 from "node:path";
|
|
32100
31553
|
import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
|
|
32101
|
-
import { toCamelCase as
|
|
31554
|
+
import { toCamelCase as toCamelCase4 } from "@secondlayer/stacks/clarity";
|
|
32102
31555
|
function isContractAddress(input5) {
|
|
32103
31556
|
const contractIdPattern = /^(SP|ST|SM|SN)[A-Z0-9]{38,}\.[a-zA-Z][a-zA-Z0-9-]*$/;
|
|
32104
31557
|
return contractIdPattern.test(input5);
|
|
@@ -32159,7 +31612,7 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey, defaultAddre
|
|
|
32159
31612
|
const apiClient = new StacksApiClient(network, apiKey);
|
|
32160
31613
|
const contractInfo = await apiClient.getContractInfo(contractId);
|
|
32161
31614
|
const abi = parseApiResponse(contractInfo);
|
|
32162
|
-
const name =
|
|
31615
|
+
const name = toCamelCase4(contractName);
|
|
32163
31616
|
contracts.push({
|
|
32164
31617
|
name,
|
|
32165
31618
|
address: contractId,
|
|
@@ -32354,7 +31807,7 @@ var {
|
|
|
32354
31807
|
// package.json
|
|
32355
31808
|
var package_default = {
|
|
32356
31809
|
name: "@secondlayer/cli",
|
|
32357
|
-
version: "8.6.
|
|
31810
|
+
version: "8.6.3",
|
|
32358
31811
|
repository: {
|
|
32359
31812
|
type: "git",
|
|
32360
31813
|
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
@@ -32403,9 +31856,10 @@ var package_default = {
|
|
|
32403
31856
|
dependencies: {
|
|
32404
31857
|
"@inquirer/prompts": "^8.2.0",
|
|
32405
31858
|
"@secondlayer/bundler": "^0.3.7",
|
|
32406
|
-
"@secondlayer/
|
|
32407
|
-
"@secondlayer/
|
|
32408
|
-
"@secondlayer/
|
|
31859
|
+
"@secondlayer/scaffold": "^1.1.0",
|
|
31860
|
+
"@secondlayer/sdk": "^6.19.0",
|
|
31861
|
+
"@secondlayer/shared": "^6.28.0",
|
|
31862
|
+
"@secondlayer/stacks": "^2.4.0",
|
|
32409
31863
|
"@secondlayer/subgraphs": "^3.10.0",
|
|
32410
31864
|
"@biomejs/js-api": "^0.7.0",
|
|
32411
31865
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
@@ -34631,9 +34085,11 @@ import { dirname as dirname5, join as join7, resolve as resolve2 } from "node:pa
|
|
|
34631
34085
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
34632
34086
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
34633
34087
|
import { ByoBreakingChangeError } from "@secondlayer/sdk";
|
|
34088
|
+
import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
|
|
34634
34089
|
|
|
34635
34090
|
// src/generators/subgraph-scaffold.ts
|
|
34636
34091
|
init_format();
|
|
34092
|
+
import { generateTraitSubgraph } from "@secondlayer/scaffold";
|
|
34637
34093
|
import { classifyContract } from "@secondlayer/stacks/clarity";
|
|
34638
34094
|
|
|
34639
34095
|
// src/generators/clarity-to-subgraph.ts
|
|
@@ -34710,7 +34166,7 @@ ${handlers}
|
|
|
34710
34166
|
}
|
|
34711
34167
|
function tokenScaffold(name, source) {
|
|
34712
34168
|
const isFt = source.type === "ft_transfer";
|
|
34713
|
-
const scope =
|
|
34169
|
+
const scope = `assetIdentifier: '${source.assetIdentifier}'`;
|
|
34714
34170
|
const cols = isFt ? ` sender: { type: 'principal' },
|
|
34715
34171
|
recipient: { type: 'principal' },
|
|
34716
34172
|
amount: { type: 'uint' },
|
|
@@ -34774,9 +34230,7 @@ ${cols || " sender: { type: 'principal' }"}
|
|
|
34774
34230
|
}
|
|
34775
34231
|
async function generateSubgraphScaffold(input2) {
|
|
34776
34232
|
if (input2.trait) {
|
|
34777
|
-
|
|
34778
|
-
const type = input2.trait === "sip-009" ? "nft_transfer" : "ft_transfer";
|
|
34779
|
-
return formatCode(tokenScaffold(name2, { type, trait: input2.trait }));
|
|
34233
|
+
return formatCode(generateTraitSubgraph({ trait: input2.trait, name: input2.subgraphName }));
|
|
34780
34234
|
}
|
|
34781
34235
|
const { contractId, abi } = input2;
|
|
34782
34236
|
if (!contractId || !abi) {
|
|
@@ -36348,8 +35802,8 @@ Examples:
|
|
|
36348
35802
|
process.exit(1);
|
|
36349
35803
|
}
|
|
36350
35804
|
const trait = options2.trait;
|
|
36351
|
-
if (trait && !
|
|
36352
|
-
error(
|
|
35805
|
+
if (trait && !TRAIT_STANDARDS.includes(trait)) {
|
|
35806
|
+
error(`--trait must be one of: ${TRAIT_STANDARDS.join(", ")}`);
|
|
36353
35807
|
process.exit(1);
|
|
36354
35808
|
}
|
|
36355
35809
|
if (!trait && !contractAddress) {
|
|
@@ -38458,5 +37912,5 @@ registerAccountCommand(program);
|
|
|
38458
37912
|
registerKeysCommand(program);
|
|
38459
37913
|
program.parse();
|
|
38460
37914
|
|
|
38461
|
-
//# debugId=
|
|
37915
|
+
//# debugId=FD969C75B9A203B164756E2164756E21
|
|
38462
37916
|
//# sourceMappingURL=cli.js.map
|