@secondlayer/cli 0.3.0 → 0.3.2

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/index.js CHANGED
@@ -316,12 +316,46 @@ import { initSimnet } from "@hirosystems/clarinet-sdk";
316
316
 
317
317
  // src/generators/contract.ts
318
318
  import { format } from "prettier";
319
+ function generateNetworkUtils() {
320
+ return `/**
321
+ * API URLs for different networks
322
+ */
323
+ const API_URLS: Record<'mainnet' | 'testnet' | 'devnet', string> = {
324
+ mainnet: 'https://api.hiro.so',
325
+ testnet: 'https://api.testnet.hiro.so',
326
+ devnet: 'http://localhost:3999'
327
+ };
328
+
329
+ /**
330
+ * Infer network from Stacks address prefix
331
+ * SP/SM = mainnet, ST/SN = testnet
332
+ */
333
+ function inferNetworkFromAddress(address: string): 'mainnet' | 'testnet' | undefined {
334
+ if (address.startsWith('SP') || address.startsWith('SM')) return 'mainnet';
335
+ if (address.startsWith('ST') || address.startsWith('SN')) return 'testnet';
336
+ return undefined;
337
+ }
338
+
339
+ /**
340
+ * Get API URL, inferring network from contract address if not specified
341
+ */
342
+ function getApiUrl(
343
+ contractAddress: string,
344
+ explicitNetwork?: 'mainnet' | 'testnet' | 'devnet'
345
+ ): string {
346
+ const network = explicitNetwork ?? inferNetworkFromAddress(contractAddress) ?? 'mainnet';
347
+ return API_URLS[network];
348
+ }`;
349
+ }
319
350
  async function generateContractInterface(contracts) {
320
351
  const imports = `import { Cl, validateStacksAddress } from '@stacks/transactions'`;
321
352
  const header = `/**
322
353
  * Generated by @secondlayer/cli
323
354
  * DO NOT EDIT MANUALLY
355
+ *
356
+ * @requires @stacks/transactions - Install with: npm install @stacks/transactions
324
357
  */`;
358
+ const networkUtils = generateNetworkUtils();
325
359
  const contractsCode = contracts.map((contract) => generateContract(contract)).join(`
326
360
 
327
361
  `);
@@ -329,6 +363,8 @@ async function generateContractInterface(contracts) {
329
363
 
330
364
  ${header}
331
365
 
366
+ ${networkUtils}
367
+
332
368
  ${contractsCode}`;
333
369
  const formatted = await format(code, {
334
370
  parser: "typescript",
@@ -486,9 +522,8 @@ function generateClarityConversion(argName, argType) {
486
522
  }
487
523
  if (${argName}.includes(".")) {
488
524
  return Cl.contractPrincipal(address, contractName);
489
- } else {
490
- return Cl.standardPrincipal(${argName});
491
525
  }
526
+ return Cl.standardPrincipal(${argName});
492
527
  })()`;
493
528
  default:
494
529
  return `${argName}`;
@@ -526,8 +561,9 @@ function generateClarityConversion(argName, argType) {
526
561
  if (value.startsWith('0x') || /^[0-9a-fA-F]+$/.test(value)) {
527
562
  return Cl.bufferFromHex(value);
528
563
  }
529
- // Check for non-ASCII characters (UTF-8)
530
- if (!/^[\\x00-\\x7F]*$/.test(value)) {
564
+ // Check for non-ASCII characters (UTF-8) using char code comparison
565
+ const hasNonAscii = value.split('').some(char => char.charCodeAt(0) > 127);
566
+ if (hasNonAscii) {
531
567
  return Cl.bufferFromUtf8(value);
532
568
  }
533
569
  // Default to ASCII for simple ASCII strings
@@ -579,12 +615,7 @@ function generateMapsObject(maps, address, contractName) {
579
615
  return `${methodName}: {
580
616
  async get(key: ${keyType}, options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType} | null> {
581
617
  const { cvToJSON, serializeCV } = await import('@stacks/transactions');
582
- const apiUrls: Record<string, string> = {
583
- mainnet: 'https://api.hiro.so',
584
- testnet: 'https://api.testnet.hiro.so',
585
- devnet: 'http://localhost:3999'
586
- };
587
- const baseUrl = apiUrls[options?.network || 'mainnet'];
618
+ const baseUrl = getApiUrl('${address}', options?.network);
588
619
  const mapKey = ${keyConversion};
589
620
  const keyHex = serializeCV(mapKey).toString('hex');
590
621
 
@@ -636,12 +667,7 @@ function generateVarsObject(variables, address, contractName) {
636
667
  return `${methodName}: {
637
668
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
638
669
  const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
639
- const apiUrls: Record<string, string> = {
640
- mainnet: 'https://api.hiro.so',
641
- testnet: 'https://api.testnet.hiro.so',
642
- devnet: 'http://localhost:3999'
643
- };
644
- const baseUrl = apiUrls[options?.network || 'mainnet'];
670
+ const baseUrl = getApiUrl('${address}', options?.network);
645
671
 
646
672
  const response = await fetch(
647
673
  \`\${baseUrl}/v2/data_var/${address}/${contractName}/${variable.name}?proof=0\`
@@ -679,12 +705,7 @@ function generateConstantsObject(variables, address, contractName) {
679
705
  return `${methodName}: {
680
706
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
681
707
  const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
682
- const apiUrls: Record<string, string> = {
683
- mainnet: 'https://api.hiro.so',
684
- testnet: 'https://api.testnet.hiro.so',
685
- devnet: 'http://localhost:3999'
686
- };
687
- const baseUrl = apiUrls[options?.network || 'mainnet'];
708
+ const baseUrl = getApiUrl('${address}', options?.network);
688
709
 
689
710
  const response = await fetch(
690
711
  \`\${baseUrl}/v2/constant_val/${address}/${contractName}/${constant.name}?proof=0\`
@@ -915,9 +936,8 @@ function generateClarityConversion2(argName, argType) {
915
936
  }
916
937
  if (${argName}.includes(".")) {
917
938
  return Cl.contractPrincipal(address, contractName);
918
- } else {
919
- return Cl.standardPrincipal(${argName});
920
939
  }
940
+ return Cl.standardPrincipal(${argName});
921
941
  })()`;
922
942
  default:
923
943
  return `${argName}`;
@@ -951,7 +971,8 @@ function generateClarityConversion2(argName, argType) {
951
971
  if (value.startsWith('0x') || /^[0-9a-fA-F]+$/.test(value)) {
952
972
  return Cl.bufferFromHex(value);
953
973
  }
954
- if (!/^[\\x00-\\x7F]*$/.test(value)) {
974
+ const hasNonAscii = value.split('').some(char => char.charCodeAt(0) > 127);
975
+ if (hasNonAscii) {
955
976
  return Cl.bufferFromUtf8(value);
956
977
  }
957
978
  return Cl.bufferFromAscii(value);
@@ -1013,7 +1034,7 @@ function generateReadHelpers(contract, options) {
1013
1034
  const methodName = toCamelCase3(func.name);
1014
1035
  const argsSignature = generateArgsSignature(func.args);
1015
1036
  const clarityArgs = generateClarityArgs(func.args, name);
1016
- return `async ${methodName}(${argsSignature}options?: {
1037
+ return `async ${methodName}(${argsSignature}options?: {
1017
1038
  network?: 'mainnet' | 'testnet' | 'devnet';
1018
1039
  senderAddress?: string;
1019
1040
  }) {
@@ -1022,7 +1043,7 @@ function generateReadHelpers(contract, options) {
1022
1043
  contractName: '${contract.contractName}',
1023
1044
  functionName: '${func.name}',
1024
1045
  functionArgs: [${clarityArgs}],
1025
- network: options?.network || 'mainnet',
1046
+ network: options?.network ?? inferNetworkFromAddress('${contract.address}') ?? 'mainnet',
1026
1047
  senderAddress: options?.senderAddress || 'SP000000000000000000002Q6VF78'
1027
1048
  });
1028
1049
  }`;
@@ -2900,5 +2921,5 @@ export {
2900
2921
  PluginManager
2901
2922
  };
2902
2923
 
2903
- //# debugId=3D064257DAF105D164756E2164756E21
2924
+ //# debugId=64D634146C316F4864756E2164756E21
2904
2925
  //# sourceMappingURL=index.js.map