@secondlayer/cli 0.3.7 → 0.3.9

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.d.ts CHANGED
@@ -41,6 +41,11 @@ interface StacksConfig {
41
41
  * Base URL for Stacks API (optional override)
42
42
  */
43
43
  apiUrl?: string;
44
+ /**
45
+ * Default deployer address for local contracts without explicit addresses
46
+ * Defaults to ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM (devnet default)
47
+ */
48
+ defaultAddress?: string;
44
49
  }
45
50
  interface ResolvedContract {
46
51
  name: string;
package/dist/index.js CHANGED
@@ -15,13 +15,53 @@ var __toESM = (mod, isNodeMode, target) => {
15
15
  });
16
16
  return to;
17
17
  };
18
+ var __export = (target, all) => {
19
+ for (var name in all)
20
+ __defProp(target, name, {
21
+ get: all[name],
22
+ enumerable: true,
23
+ configurable: true,
24
+ set: (newValue) => all[name] = () => newValue
25
+ });
26
+ };
27
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
18
28
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
29
 
30
+ // src/utils/format.ts
31
+ var exports_format = {};
32
+ __export(exports_format, {
33
+ formatCode: () => formatCode,
34
+ PRETTIER_OPTIONS: () => PRETTIER_OPTIONS
35
+ });
36
+ import { format } from "prettier";
37
+ async function formatCode(code) {
38
+ return format(code, PRETTIER_OPTIONS);
39
+ }
40
+ var PRETTIER_OPTIONS;
41
+ var init_format = __esm(() => {
42
+ PRETTIER_OPTIONS = {
43
+ parser: "typescript",
44
+ singleQuote: true,
45
+ semi: true,
46
+ printWidth: 100,
47
+ trailingComma: "es5"
48
+ };
49
+ });
50
+
20
51
  // src/core/plugin-manager.ts
21
52
  import { promises as fs } from "fs";
22
53
  import path from "path";
23
54
  import { validateStacksAddress } from "@stacks/transactions";
24
55
 
56
+ // src/types/plugin.ts
57
+ function isClarinetContract(c) {
58
+ return "_clarinetSource" in c && c._clarinetSource === true;
59
+ }
60
+ function isDirectFileContract(c) {
61
+ return "_directFile" in c && c._directFile === true;
62
+ }
63
+
64
+ // src/core/plugin-manager.ts
25
65
  class PluginManager {
26
66
  plugins = [];
27
67
  logger;
@@ -81,7 +121,7 @@ class PluginManager {
81
121
  async transformContracts(contracts, _config) {
82
122
  const processedContracts = [];
83
123
  for (let contract of contracts) {
84
- if (contract._clarinetSource && contract.abi) {
124
+ if (isClarinetContract(contract) && contract.abi) {
85
125
  const address = typeof contract.address === "string" ? contract.address : "";
86
126
  const [contractAddress, contractName] = address.split(".");
87
127
  const processed = {
@@ -95,7 +135,7 @@ class PluginManager {
95
135
  processedContracts.push(processed);
96
136
  continue;
97
137
  }
98
- if (contract._directFile && contract.abi) {
138
+ if (isDirectFileContract(contract) && contract.abi) {
99
139
  const address = typeof contract.address === "string" ? contract.address : "";
100
140
  const [contractAddress, contractName] = address.split(".");
101
141
  const processed = {
@@ -281,14 +321,8 @@ ${JSON.stringify(content, null, 2)}`;
281
321
  return { address, contractName };
282
322
  },
283
323
  formatCode: async (code) => {
284
- const { format } = await import("prettier");
285
- return format(code, {
286
- parser: "typescript",
287
- singleQuote: true,
288
- semi: true,
289
- printWidth: 100,
290
- trailingComma: "es5"
291
- });
324
+ const { formatCode: formatCode2 } = await Promise.resolve().then(() => (init_format(), exports_format));
325
+ return formatCode2(code);
292
326
  },
293
327
  resolvePath: (relativePath) => {
294
328
  return path.resolve(process.cwd(), relativePath);
@@ -315,9 +349,10 @@ ${JSON.stringify(content, null, 2)}`;
315
349
  }
316
350
  // src/plugins/clarinet/index.ts
317
351
  import { initSimnet } from "@hirosystems/clarinet-sdk";
352
+ import { toCamelCase as toCamelCase3 } from "@secondlayer/clarity-types";
318
353
 
319
354
  // src/generators/contract.ts
320
- import { format } from "prettier";
355
+ init_format();
321
356
  import {
322
357
  toCamelCase as toCamelCase2
323
358
  } from "@secondlayer/clarity-types";
@@ -346,6 +381,9 @@ function clarityTypeToTS(type) {
346
381
  return "string";
347
382
  default: {
348
383
  const typeStr = type;
384
+ if (typeStr === "none") {
385
+ return "null";
386
+ }
349
387
  if (typeStr.includes("string") || typeStr.includes("ascii") || typeStr.includes("utf8")) {
350
388
  return "string";
351
389
  }
@@ -455,14 +493,7 @@ ${validationUtils}
455
493
  ${networkUtils}
456
494
 
457
495
  ${contractsCode}`;
458
- const formatted = await format(code, {
459
- parser: "typescript",
460
- singleQuote: true,
461
- semi: true,
462
- printWidth: 100,
463
- trailingComma: "es5"
464
- });
465
- return formatted;
496
+ return formatCode(code);
466
497
  }
467
498
  function generateContract(contract) {
468
499
  const { name, address, contractName, abi } = contract;
@@ -692,34 +723,41 @@ function generateMapsObject(maps, address, contractName) {
692
723
  const keyConversion = generateMapKeyConversion(map.key);
693
724
  return `${methodName}: {
694
725
  async get(key: ${keyType}, options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType} | null> {
695
- const { cvToJSON, serializeCV } = await import('@stacks/transactions');
696
- const baseUrl = getApiUrl('${address}', options?.network);
697
- const mapKey = ${keyConversion};
698
- const keyHex = serializeCV(mapKey).toString('hex');
699
-
700
- const response = await fetch(
701
- \`\${baseUrl}/v2/map_entry/${address}/${contractName}/${map.name}\`,
702
- {
703
- method: 'POST',
704
- headers: { 'Content-Type': 'application/json' },
705
- body: JSON.stringify(keyHex)
726
+ try {
727
+ const { cvToJSON, serializeCV } = await import('@stacks/transactions');
728
+ const baseUrl = getApiUrl('${address}', options?.network);
729
+ const mapKey = ${keyConversion};
730
+ const keyHex = serializeCV(mapKey).toString('hex');
731
+
732
+ const response = await fetch(
733
+ \`\${baseUrl}/v2/map_entry/${address}/${contractName}/${map.name}\`,
734
+ {
735
+ method: 'POST',
736
+ headers: { 'Content-Type': 'application/json' },
737
+ body: JSON.stringify(keyHex)
738
+ }
739
+ );
740
+
741
+ if (!response.ok) {
742
+ throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
706
743
  }
707
- );
708
744
 
709
- if (!response.ok) {
710
- throw new Error(\`Failed to fetch map entry: \${response.statusText}\`);
711
- }
745
+ const result = await response.json();
746
+ if (!result.data || result.data === '0x09') {
747
+ return null; // none value
748
+ }
712
749
 
713
- const result = await response.json();
714
- if (!result.data || result.data === '0x09') {
715
- return null; // none value
750
+ const { deserializeCV } = await import('@stacks/transactions');
751
+ const cv = deserializeCV(result.data);
752
+ const parsed = cvToJSON(cv);
753
+ // Unwrap the (some ...) wrapper
754
+ return parsed.value?.value ?? parsed.value ?? null;
755
+ } catch (error) {
756
+ if (error instanceof Error) {
757
+ throw new Error(\`Map access failed for '${map.name}': \${error.message}\`);
758
+ }
759
+ throw error;
716
760
  }
717
-
718
- const { deserializeCV } = await import('@stacks/transactions');
719
- const cv = deserializeCV(result.data);
720
- const parsed = cvToJSON(cv);
721
- // Unwrap the (some ...) wrapper
722
- return parsed.value?.value ?? parsed.value ?? null;
723
761
  },
724
762
  keyType: ${JSON.stringify(map.key)} as const,
725
763
  valueType: ${JSON.stringify(map.value)} as const
@@ -744,21 +782,28 @@ function generateVarsObject(variables, address, contractName) {
744
782
  const valueType = getTypeForArg({ type: variable.type });
745
783
  return `${methodName}: {
746
784
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
747
- const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
748
- const baseUrl = getApiUrl('${address}', options?.network);
785
+ try {
786
+ const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
787
+ const baseUrl = getApiUrl('${address}', options?.network);
749
788
 
750
- const response = await fetch(
751
- \`\${baseUrl}/v2/data_var/${address}/${contractName}/${variable.name}?proof=0\`
752
- );
789
+ const response = await fetch(
790
+ \`\${baseUrl}/v2/data_var/${address}/${contractName}/${variable.name}?proof=0\`
791
+ );
753
792
 
754
- if (!response.ok) {
755
- throw new Error(\`Failed to fetch data var: \${response.statusText}\`);
756
- }
793
+ if (!response.ok) {
794
+ throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
795
+ }
757
796
 
758
- const result = await response.json();
759
- const cv = deserializeCV(result.data);
760
- const parsed = cvToJSON(cv);
761
- return parsed.value ?? parsed;
797
+ const result = await response.json();
798
+ const cv = deserializeCV(result.data);
799
+ const parsed = cvToJSON(cv);
800
+ return parsed.value ?? parsed;
801
+ } catch (error) {
802
+ if (error instanceof Error) {
803
+ throw new Error(\`Variable access failed for '${variable.name}': \${error.message}\`);
804
+ }
805
+ throw error;
806
+ }
762
807
  },
763
808
  type: ${JSON.stringify(variable.type)} as const
764
809
  }`;
@@ -782,21 +827,28 @@ function generateConstantsObject(variables, address, contractName) {
782
827
  const valueType = getTypeForArg({ type: constant.type });
783
828
  return `${methodName}: {
784
829
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
785
- const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
786
- const baseUrl = getApiUrl('${address}', options?.network);
830
+ try {
831
+ const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
832
+ const baseUrl = getApiUrl('${address}', options?.network);
787
833
 
788
- const response = await fetch(
789
- \`\${baseUrl}/v2/constant_val/${address}/${contractName}/${constant.name}?proof=0\`
790
- );
834
+ const response = await fetch(
835
+ \`\${baseUrl}/v2/constant_val/${address}/${contractName}/${constant.name}?proof=0\`
836
+ );
791
837
 
792
- if (!response.ok) {
793
- throw new Error(\`Failed to fetch constant: \${response.statusText}\`);
794
- }
838
+ if (!response.ok) {
839
+ throw new Error(\`HTTP \${response.status}: \${response.statusText}\`);
840
+ }
795
841
 
796
- const result = await response.json();
797
- const cv = deserializeCV(result.data);
798
- const parsed = cvToJSON(cv);
799
- return parsed.value ?? parsed;
842
+ const result = await response.json();
843
+ const cv = deserializeCV(result.data);
844
+ const parsed = cvToJSON(cv);
845
+ return parsed.value ?? parsed;
846
+ } catch (error) {
847
+ if (error instanceof Error) {
848
+ throw new Error(\`Constant access failed for '${constant.name}': \${error.message}\`);
849
+ }
850
+ throw error;
851
+ }
800
852
  },
801
853
  type: ${JSON.stringify(constant.type)} as const
802
854
  }`;
@@ -820,9 +872,6 @@ function generateMapKeyConversion(keyType) {
820
872
  }
821
873
 
822
874
  // src/plugins/clarinet/index.ts
823
- function toCamelCase3(str) {
824
- return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/-([A-Z])/g, (_, letter) => letter).replace(/-(\d)/g, (_, digit) => digit).replace(/-/g, "").replace(/^\d/, "_$&");
825
- }
826
875
  function sanitizeContractName(name) {
827
876
  return toCamelCase3(name);
828
877
  }
@@ -1279,7 +1328,7 @@ ${indentedHelpersCode}
1279
1328
  });
1280
1329
  }
1281
1330
  // src/plugins/react/provider/index.ts
1282
- import { format as format2 } from "prettier";
1331
+ init_format();
1283
1332
  async function generateProvider() {
1284
1333
  const code = `/**
1285
1334
  * Generated Stacks React Provider
@@ -1367,18 +1416,11 @@ export function useStacksConfig(): StacksReactConfig {
1367
1416
 
1368
1417
  return context
1369
1418
  }`;
1370
- const formatted = await format2(code, {
1371
- parser: "typescript",
1372
- singleQuote: true,
1373
- semi: false,
1374
- printWidth: 100,
1375
- trailingComma: "es5"
1376
- });
1377
- return formatted;
1419
+ return formatCode(code);
1378
1420
  }
1379
1421
 
1380
1422
  // src/plugins/react/generators/generic.ts
1381
- import { format as format3 } from "prettier";
1423
+ init_format();
1382
1424
  var GENERIC_HOOKS = [
1383
1425
  "useAccount",
1384
1426
  "useConnect",
@@ -1399,10 +1441,37 @@ async function generateGenericHooks(excludeList = []) {
1399
1441
  const imports = `import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
1400
1442
  import { useState, useCallback } from 'react'
1401
1443
  import { useStacksConfig } from './provider'
1402
- import { connect, disconnect, isConnected, request, openContractCall as stacksOpenContractCall } from '@stacks/connect'
1444
+ import { connect, disconnect, isConnected, request, openContractCall as stacksOpenContractCall, openSTXTransfer, openSignatureRequestPopup, openContractDeploy } from '@stacks/connect'
1403
1445
  import { Cl, validateStacksAddress } from '@stacks/transactions'
1404
1446
  import type { PostCondition } from '@stacks/transactions'
1405
- import type { ExtractFunctionArgs, ExtractFunctionNames, ClarityContract } from '@secondlayer/clarity-types'`;
1447
+ import type { ExtractFunctionArgs, ExtractFunctionNames, ClarityContract } from '@secondlayer/clarity-types'
1448
+
1449
+ const API_URLS: Record<string, string> = {
1450
+ mainnet: 'https://api.hiro.so',
1451
+ testnet: 'https://api.testnet.hiro.so',
1452
+ devnet: 'http://localhost:3999'
1453
+ }
1454
+
1455
+ async function fetchTransaction({ txId, network, apiUrl }: { txId: string; network?: string; apiUrl?: string }): Promise<any> {
1456
+ const baseUrl = apiUrl || API_URLS[network || 'mainnet']
1457
+ const response = await fetch(\`\${baseUrl}/extended/v1/tx/\${txId}\`)
1458
+ if (!response.ok) throw new Error(\`Failed to fetch transaction: \${response.statusText}\`)
1459
+ return response.json()
1460
+ }
1461
+
1462
+ async function fetchBlock({ height, network, apiUrl }: { height: number; network?: string; apiUrl?: string }): Promise<any> {
1463
+ const baseUrl = apiUrl || API_URLS[network || 'mainnet']
1464
+ const response = await fetch(\`\${baseUrl}/extended/v1/block/by_height/\${height}\`)
1465
+ if (!response.ok) throw new Error(\`Failed to fetch block: \${response.statusText}\`)
1466
+ return response.json()
1467
+ }
1468
+
1469
+ async function fetchAccountTransactions({ address, network, apiUrl }: { address: string; network?: string; apiUrl?: string }): Promise<any> {
1470
+ const baseUrl = apiUrl || API_URLS[network || 'mainnet']
1471
+ const response = await fetch(\`\${baseUrl}/extended/v1/address/\${address}/transactions\`)
1472
+ if (!response.ok) throw new Error(\`Failed to fetch transactions: \${response.statusText}\`)
1473
+ return response.json()
1474
+ }`;
1406
1475
  const header = `/**
1407
1476
  * Generated generic Stacks React hooks
1408
1477
  * DO NOT EDIT MANUALLY
@@ -1415,14 +1484,7 @@ import type { ExtractFunctionArgs, ExtractFunctionNames, ClarityContract } from
1415
1484
  ${header}
1416
1485
 
1417
1486
  ${hooksCode}`;
1418
- const formatted = await format3(code, {
1419
- parser: "typescript",
1420
- singleQuote: true,
1421
- semi: false,
1422
- printWidth: 100,
1423
- trailingComma: "es5"
1424
- });
1425
- return formatted;
1487
+ return formatCode(code);
1426
1488
  }
1427
1489
  function generateGenericHook(hookName) {
1428
1490
  switch (hookName) {
@@ -2187,7 +2249,7 @@ function generateGenericHook(hookName) {
2187
2249
  }
2188
2250
 
2189
2251
  // src/plugins/react/generators/contract.ts
2190
- import { format as format4 } from "prettier";
2252
+ init_format();
2191
2253
 
2192
2254
  // src/plugins/react/generators/utils.ts
2193
2255
  import { toCamelCase as toCamelCase5 } from "@secondlayer/clarity-types";
@@ -2253,14 +2315,7 @@ import { ${contracts.map((c) => c.name).join(", ")} } from './contracts'`;
2253
2315
  ${header}
2254
2316
 
2255
2317
  ${hooksCode}`;
2256
- const formatted = await format4(code, {
2257
- parser: "typescript",
2258
- singleQuote: true,
2259
- semi: false,
2260
- printWidth: 100,
2261
- trailingComma: "es5"
2262
- });
2263
- return formatted;
2318
+ return formatCode(code);
2264
2319
  }
2265
2320
  function generateContractHookMethods(contract, excludeList) {
2266
2321
  const { abi, name, address, contractName } = contract;
@@ -2924,5 +2979,5 @@ export {
2924
2979
  PluginManager
2925
2980
  };
2926
2981
 
2927
- //# debugId=7C8745101A6FCC2D64756E2164756E21
2982
+ //# debugId=FE7B5594AE67250064756E2164756E21
2928
2983
  //# sourceMappingURL=index.js.map