@secondlayer/cli 0.2.5 → 0.3.1
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 +207 -6
- package/dist/cli.js.map +4 -4
- package/dist/index.js +309 -41
- package/dist/index.js.map +8 -8
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -316,12 +316,44 @@ 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
|
|
324
355
|
*/`;
|
|
356
|
+
const networkUtils = generateNetworkUtils();
|
|
325
357
|
const contractsCode = contracts.map((contract) => generateContract(contract)).join(`
|
|
326
358
|
|
|
327
359
|
`);
|
|
@@ -329,6 +361,8 @@ async function generateContractInterface(contracts) {
|
|
|
329
361
|
|
|
330
362
|
${header}
|
|
331
363
|
|
|
364
|
+
${networkUtils}
|
|
365
|
+
|
|
332
366
|
${contractsCode}`;
|
|
333
367
|
const formatted = await format(code, {
|
|
334
368
|
parser: "typescript",
|
|
@@ -345,12 +379,18 @@ function generateContract(contract) {
|
|
|
345
379
|
const methods = abi.functions.filter((func) => func.access !== "private").map((func) => generateMethod(func, address, contractName)).join(`,
|
|
346
380
|
|
|
347
381
|
`);
|
|
382
|
+
const mapsObject = generateMapsObject(abi.maps || [], address, contractName);
|
|
383
|
+
const varsObject = generateVarsObject(abi.variables || [], address, contractName);
|
|
384
|
+
const constantsObject = generateConstantsObject(abi.variables || [], address, contractName);
|
|
385
|
+
const allMembers = [methods, mapsObject, varsObject, constantsObject].filter(Boolean);
|
|
348
386
|
const contractCode = `export const ${name} = {
|
|
349
387
|
address: '${address}',
|
|
350
388
|
contractAddress: '${address}',
|
|
351
389
|
contractName: '${contractName}',
|
|
352
|
-
|
|
353
|
-
${
|
|
390
|
+
|
|
391
|
+
${allMembers.join(`,
|
|
392
|
+
|
|
393
|
+
`)}
|
|
354
394
|
} as const`;
|
|
355
395
|
return `${abiCode}
|
|
356
396
|
|
|
@@ -561,6 +601,143 @@ function generateClarityConversion(argName, argType) {
|
|
|
561
601
|
}
|
|
562
602
|
return `${argName}`;
|
|
563
603
|
}
|
|
604
|
+
function generateMapsObject(maps, address, contractName) {
|
|
605
|
+
if (!maps || maps.length === 0) {
|
|
606
|
+
return "";
|
|
607
|
+
}
|
|
608
|
+
const mapMethods = maps.map((map) => {
|
|
609
|
+
const methodName = toCamelCase(map.name);
|
|
610
|
+
const keyType = getTypeForArg({ type: map.key });
|
|
611
|
+
const valueType = getTypeForArg({ type: map.value });
|
|
612
|
+
const keyConversion = generateMapKeyConversion(map.key);
|
|
613
|
+
return `${methodName}: {
|
|
614
|
+
async get(key: ${keyType}, options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType} | null> {
|
|
615
|
+
const { cvToJSON, serializeCV } = await import('@stacks/transactions');
|
|
616
|
+
const baseUrl = getApiUrl('${address}', options?.network);
|
|
617
|
+
const mapKey = ${keyConversion};
|
|
618
|
+
const keyHex = serializeCV(mapKey).toString('hex');
|
|
619
|
+
|
|
620
|
+
const response = await fetch(
|
|
621
|
+
\`\${baseUrl}/v2/map_entry/${address}/${contractName}/${map.name}\`,
|
|
622
|
+
{
|
|
623
|
+
method: 'POST',
|
|
624
|
+
headers: { 'Content-Type': 'application/json' },
|
|
625
|
+
body: JSON.stringify(keyHex)
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
if (!response.ok) {
|
|
630
|
+
throw new Error(\`Failed to fetch map entry: \${response.statusText}\`);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
const result = await response.json();
|
|
634
|
+
if (!result.data || result.data === '0x09') {
|
|
635
|
+
return null; // none value
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const { deserializeCV } = await import('@stacks/transactions');
|
|
639
|
+
const cv = deserializeCV(result.data);
|
|
640
|
+
const parsed = cvToJSON(cv);
|
|
641
|
+
// Unwrap the (some ...) wrapper
|
|
642
|
+
return parsed.value?.value ?? parsed.value ?? null;
|
|
643
|
+
},
|
|
644
|
+
keyType: ${JSON.stringify(map.key)} as const,
|
|
645
|
+
valueType: ${JSON.stringify(map.value)} as const
|
|
646
|
+
}`;
|
|
647
|
+
});
|
|
648
|
+
return `maps: {
|
|
649
|
+
${mapMethods.join(`,
|
|
650
|
+
|
|
651
|
+
`)}
|
|
652
|
+
}`;
|
|
653
|
+
}
|
|
654
|
+
function generateVarsObject(variables, address, contractName) {
|
|
655
|
+
if (!variables || variables.length === 0) {
|
|
656
|
+
return "";
|
|
657
|
+
}
|
|
658
|
+
const dataVars = variables.filter((v) => v.access === "variable");
|
|
659
|
+
if (dataVars.length === 0) {
|
|
660
|
+
return "";
|
|
661
|
+
}
|
|
662
|
+
const varMethods = dataVars.map((variable) => {
|
|
663
|
+
const methodName = toCamelCase(variable.name);
|
|
664
|
+
const valueType = getTypeForArg({ type: variable.type });
|
|
665
|
+
return `${methodName}: {
|
|
666
|
+
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
667
|
+
const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
|
|
668
|
+
const baseUrl = getApiUrl('${address}', options?.network);
|
|
669
|
+
|
|
670
|
+
const response = await fetch(
|
|
671
|
+
\`\${baseUrl}/v2/data_var/${address}/${contractName}/${variable.name}?proof=0\`
|
|
672
|
+
);
|
|
673
|
+
|
|
674
|
+
if (!response.ok) {
|
|
675
|
+
throw new Error(\`Failed to fetch data var: \${response.statusText}\`);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const result = await response.json();
|
|
679
|
+
const cv = deserializeCV(result.data);
|
|
680
|
+
const parsed = cvToJSON(cv);
|
|
681
|
+
return parsed.value ?? parsed;
|
|
682
|
+
},
|
|
683
|
+
type: ${JSON.stringify(variable.type)} as const
|
|
684
|
+
}`;
|
|
685
|
+
});
|
|
686
|
+
return `vars: {
|
|
687
|
+
${varMethods.join(`,
|
|
688
|
+
|
|
689
|
+
`)}
|
|
690
|
+
}`;
|
|
691
|
+
}
|
|
692
|
+
function generateConstantsObject(variables, address, contractName) {
|
|
693
|
+
if (!variables || variables.length === 0) {
|
|
694
|
+
return "";
|
|
695
|
+
}
|
|
696
|
+
const constants = variables.filter((v) => v.access === "constant");
|
|
697
|
+
if (constants.length === 0) {
|
|
698
|
+
return "";
|
|
699
|
+
}
|
|
700
|
+
const constMethods = constants.map((constant) => {
|
|
701
|
+
const methodName = toCamelCase(constant.name);
|
|
702
|
+
const valueType = getTypeForArg({ type: constant.type });
|
|
703
|
+
return `${methodName}: {
|
|
704
|
+
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
705
|
+
const { cvToJSON, deserializeCV } = await import('@stacks/transactions');
|
|
706
|
+
const baseUrl = getApiUrl('${address}', options?.network);
|
|
707
|
+
|
|
708
|
+
const response = await fetch(
|
|
709
|
+
\`\${baseUrl}/v2/constant_val/${address}/${contractName}/${constant.name}?proof=0\`
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
if (!response.ok) {
|
|
713
|
+
throw new Error(\`Failed to fetch constant: \${response.statusText}\`);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const result = await response.json();
|
|
717
|
+
const cv = deserializeCV(result.data);
|
|
718
|
+
const parsed = cvToJSON(cv);
|
|
719
|
+
return parsed.value ?? parsed;
|
|
720
|
+
},
|
|
721
|
+
type: ${JSON.stringify(constant.type)} as const
|
|
722
|
+
}`;
|
|
723
|
+
});
|
|
724
|
+
return `constants: {
|
|
725
|
+
${constMethods.join(`,
|
|
726
|
+
|
|
727
|
+
`)}
|
|
728
|
+
}`;
|
|
729
|
+
}
|
|
730
|
+
function generateMapKeyConversion(keyType) {
|
|
731
|
+
if (keyType.tuple) {
|
|
732
|
+
const fields = keyType.tuple.map((field) => {
|
|
733
|
+
const camelFieldName = toCamelCase(field.name);
|
|
734
|
+
const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
|
|
735
|
+
return `"${field.name}": ${fieldConversion}`;
|
|
736
|
+
}).join(", ");
|
|
737
|
+
return `Cl.tuple({ ${fields} })`;
|
|
738
|
+
}
|
|
739
|
+
return generateClarityConversion("key", { type: keyType });
|
|
740
|
+
}
|
|
564
741
|
|
|
565
742
|
// src/plugins/clarinet/index.ts
|
|
566
743
|
function toCamelCase2(str) {
|
|
@@ -855,7 +1032,7 @@ function generateReadHelpers(contract, options) {
|
|
|
855
1032
|
const methodName = toCamelCase3(func.name);
|
|
856
1033
|
const argsSignature = generateArgsSignature(func.args);
|
|
857
1034
|
const clarityArgs = generateClarityArgs(func.args, name);
|
|
858
|
-
return `async ${methodName}(${argsSignature}options?: {
|
|
1035
|
+
return `async ${methodName}(${argsSignature}options?: {
|
|
859
1036
|
network?: 'mainnet' | 'testnet' | 'devnet';
|
|
860
1037
|
senderAddress?: string;
|
|
861
1038
|
}) {
|
|
@@ -864,7 +1041,7 @@ function generateReadHelpers(contract, options) {
|
|
|
864
1041
|
contractName: '${contract.contractName}',
|
|
865
1042
|
functionName: '${func.name}',
|
|
866
1043
|
functionArgs: [${clarityArgs}],
|
|
867
|
-
network: options?.network
|
|
1044
|
+
network: options?.network ?? inferNetworkFromAddress('${contract.address}') ?? 'mainnet',
|
|
868
1045
|
senderAddress: options?.senderAddress || 'SP000000000000000000002Q6VF78'
|
|
869
1046
|
});
|
|
870
1047
|
}`;
|
|
@@ -904,7 +1081,7 @@ function generateWriteHelpers(contract, options) {
|
|
|
904
1081
|
fee?: string | number | undefined;
|
|
905
1082
|
nonce?: bigint;
|
|
906
1083
|
anchorMode?: 1 | 2 | 3; // AnchorMode: OnChainOnly = 1, OffChainOnly = 2, Any = 3
|
|
907
|
-
postConditions?:
|
|
1084
|
+
postConditions?: PostCondition[];
|
|
908
1085
|
validateWithAbi?: boolean;
|
|
909
1086
|
}) {
|
|
910
1087
|
const { senderKey, network = 'mainnet', ...txOptions } = options;
|
|
@@ -988,17 +1165,27 @@ var actions = (options = {}) => {
|
|
|
988
1165
|
};
|
|
989
1166
|
};
|
|
990
1167
|
function addRequiredImports(content) {
|
|
991
|
-
if (content.includes("fetchCallReadOnlyFunction") && content.includes("makeContractCall")) {
|
|
992
|
-
return content;
|
|
993
|
-
}
|
|
994
1168
|
const transactionsImportRegex = /import\s+\{([^}]+)\}\s+from\s+['"]@stacks\/transactions['"];/;
|
|
995
1169
|
const match = content.match(transactionsImportRegex);
|
|
996
1170
|
if (match) {
|
|
997
1171
|
const existingImports = match[1].trim();
|
|
998
|
-
const
|
|
1172
|
+
const requiredImports = [
|
|
1173
|
+
"fetchCallReadOnlyFunction",
|
|
1174
|
+
"makeContractCall"
|
|
1175
|
+
];
|
|
1176
|
+
const newImports = requiredImports.filter((imp) => !existingImports.includes(imp)).join(", ");
|
|
999
1177
|
if (newImports) {
|
|
1000
1178
|
const updatedImport = `import { ${existingImports}, ${newImports} } from '@stacks/transactions';`;
|
|
1001
|
-
|
|
1179
|
+
let updatedContent = content.replace(transactionsImportRegex, updatedImport);
|
|
1180
|
+
if (!updatedContent.includes("type PostCondition")) {
|
|
1181
|
+
updatedContent = updatedContent.replace(updatedImport, `${updatedImport}
|
|
1182
|
+
import type { PostCondition } from '@stacks/transactions';`);
|
|
1183
|
+
}
|
|
1184
|
+
return updatedContent;
|
|
1185
|
+
}
|
|
1186
|
+
if (!content.includes("type PostCondition")) {
|
|
1187
|
+
return content.replace(transactionsImportRegex, `${match[0]}
|
|
1188
|
+
import type { PostCondition } from '@stacks/transactions';`);
|
|
1002
1189
|
}
|
|
1003
1190
|
}
|
|
1004
1191
|
return content;
|
|
@@ -1144,6 +1331,7 @@ import { useState, useCallback } from 'react'
|
|
|
1144
1331
|
import { useStacksConfig } from './provider'
|
|
1145
1332
|
import { connect, disconnect, isConnected, request, openContractCall as stacksOpenContractCall } from '@stacks/connect'
|
|
1146
1333
|
import { Cl, validateStacksAddress } from '@stacks/transactions'
|
|
1334
|
+
import type { PostCondition } from '@stacks/transactions'
|
|
1147
1335
|
import type { ExtractFunctionArgs, ExtractFunctionNames, ClarityContract } from '@secondlayer/clarity-types'`;
|
|
1148
1336
|
const header = `/**
|
|
1149
1337
|
* Generated generic Stacks React hooks
|
|
@@ -1471,7 +1659,7 @@ function generateGenericHook(hookName) {
|
|
|
1471
1659
|
functionName: string;
|
|
1472
1660
|
functionArgs: any[]; // Pre-converted Clarity values
|
|
1473
1661
|
network?: string;
|
|
1474
|
-
postConditions?:
|
|
1662
|
+
postConditions?: PostCondition[];
|
|
1475
1663
|
attachment?: string;
|
|
1476
1664
|
onFinish?: (data: any) => void;
|
|
1477
1665
|
onCancel?: () => void;
|
|
@@ -1547,7 +1735,7 @@ function generateGenericHook(hookName) {
|
|
|
1547
1735
|
abi: T;
|
|
1548
1736
|
functionArgs: ExtractFunctionArgs<T, FN>;
|
|
1549
1737
|
network?: string;
|
|
1550
|
-
postConditions?:
|
|
1738
|
+
postConditions?: PostCondition[];
|
|
1551
1739
|
attachment?: string;
|
|
1552
1740
|
onFinish?: (data: any) => void;
|
|
1553
1741
|
onCancel?: () => void;
|
|
@@ -1868,7 +2056,7 @@ function generateGenericHook(hookName) {
|
|
|
1868
2056
|
contractName: string;
|
|
1869
2057
|
codeBody: string;
|
|
1870
2058
|
network?: string;
|
|
1871
|
-
postConditions?:
|
|
2059
|
+
postConditions?: PostCondition[];
|
|
1872
2060
|
onFinish?: (data: any) => void;
|
|
1873
2061
|
onCancel?: () => void;
|
|
1874
2062
|
}) => {
|
|
@@ -1905,7 +2093,7 @@ function generateGenericHook(hookName) {
|
|
|
1905
2093
|
contractName: string;
|
|
1906
2094
|
codeBody: string;
|
|
1907
2095
|
network?: string;
|
|
1908
|
-
postConditions?:
|
|
2096
|
+
postConditions?: PostCondition[];
|
|
1909
2097
|
onFinish?: (data: any) => void;
|
|
1910
2098
|
onCancel?: () => void;
|
|
1911
2099
|
}) => {
|
|
@@ -1981,18 +2169,30 @@ function mapClarityTypeToTS(clarityType) {
|
|
|
1981
2169
|
return "boolean";
|
|
1982
2170
|
if (clarityType?.string || clarityType?.ascii)
|
|
1983
2171
|
return "string";
|
|
2172
|
+
if (clarityType?.["string-ascii"] || clarityType?.["string-utf8"])
|
|
2173
|
+
return "string";
|
|
1984
2174
|
if (clarityType?.buff)
|
|
1985
2175
|
return "Uint8Array";
|
|
1986
2176
|
if (clarityType?.optional) {
|
|
1987
2177
|
const innerType = mapClarityTypeToTS(clarityType.optional);
|
|
1988
2178
|
return `${innerType} | null`;
|
|
1989
2179
|
}
|
|
1990
|
-
if (clarityType?.response)
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
return
|
|
1994
|
-
|
|
1995
|
-
|
|
2180
|
+
if (clarityType?.response) {
|
|
2181
|
+
const okType = mapClarityTypeToTS(clarityType.response.ok);
|
|
2182
|
+
const errType = mapClarityTypeToTS(clarityType.response.error);
|
|
2183
|
+
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
2184
|
+
}
|
|
2185
|
+
if (clarityType?.tuple) {
|
|
2186
|
+
const fields = clarityType.tuple.map((field) => `${toCamelCase4(field.name)}: ${mapClarityTypeToTS(field.type)}`).join("; ");
|
|
2187
|
+
return `{ ${fields} }`;
|
|
2188
|
+
}
|
|
2189
|
+
if (clarityType?.list) {
|
|
2190
|
+
const innerType = mapClarityTypeToTS(clarityType.list.type);
|
|
2191
|
+
if (innerType.includes(" | ")) {
|
|
2192
|
+
return `(${innerType})[]`;
|
|
2193
|
+
}
|
|
2194
|
+
return `${innerType}[]`;
|
|
2195
|
+
}
|
|
1996
2196
|
return "any";
|
|
1997
2197
|
}
|
|
1998
2198
|
if (clarityType.includes("uint") || clarityType.includes("int"))
|
|
@@ -2009,12 +2209,6 @@ function mapClarityTypeToTS(clarityType) {
|
|
|
2009
2209
|
const innerType = clarityType.replace(/optional\s*/, "").trim();
|
|
2010
2210
|
return `${mapClarityTypeToTS(innerType)} | null`;
|
|
2011
2211
|
}
|
|
2012
|
-
if (clarityType.includes("response"))
|
|
2013
|
-
return "any";
|
|
2014
|
-
if (clarityType.includes("tuple"))
|
|
2015
|
-
return "any";
|
|
2016
|
-
if (clarityType.includes("list"))
|
|
2017
|
-
return "any[]";
|
|
2018
2212
|
return "any";
|
|
2019
2213
|
}
|
|
2020
2214
|
function generateObjectArgs(args) {
|
|
@@ -2029,6 +2223,7 @@ async function generateContractHooks(contracts, excludeList = []) {
|
|
|
2029
2223
|
import { useCallback } from 'react'
|
|
2030
2224
|
import { useStacksConfig } from './provider'
|
|
2031
2225
|
import { request, openContractCall as stacksOpenContractCall } from '@stacks/connect'
|
|
2226
|
+
import type { PostCondition } from '@stacks/transactions'
|
|
2032
2227
|
import { ${contracts.map((c) => c.name).join(", ")} } from './contracts'`;
|
|
2033
2228
|
const header = `/**
|
|
2034
2229
|
* Generated contract-specific React hooks
|
|
@@ -2052,8 +2247,10 @@ ${hooksCode}`;
|
|
|
2052
2247
|
return formatted;
|
|
2053
2248
|
}
|
|
2054
2249
|
function generateContractHookMethods(contract, excludeList) {
|
|
2055
|
-
const { abi, name } = contract;
|
|
2250
|
+
const { abi, name, address, contractName } = contract;
|
|
2056
2251
|
const functions = abi.functions || [];
|
|
2252
|
+
const maps = abi.maps || [];
|
|
2253
|
+
const variables = abi.variables || [];
|
|
2057
2254
|
const readOnlyFunctions = functions.filter((f) => f.access === "read_only" || f.access === "read-only");
|
|
2058
2255
|
const publicFunctions = functions.filter((f) => f.access === "public");
|
|
2059
2256
|
const readHooks = readOnlyFunctions.map((func) => {
|
|
@@ -2070,7 +2267,30 @@ function generateContractHookMethods(contract, excludeList) {
|
|
|
2070
2267
|
}
|
|
2071
2268
|
return generateWriteHook(func, name);
|
|
2072
2269
|
}).filter(Boolean);
|
|
2073
|
-
const
|
|
2270
|
+
const mapHooks = maps.map((map) => {
|
|
2271
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase4(map.name))}`;
|
|
2272
|
+
if (excludeList.includes(hookName)) {
|
|
2273
|
+
return null;
|
|
2274
|
+
}
|
|
2275
|
+
return generateMapHook(map, name, address, contractName);
|
|
2276
|
+
}).filter(Boolean);
|
|
2277
|
+
const dataVars = variables.filter((v) => v.access === "variable");
|
|
2278
|
+
const varHooks = dataVars.map((variable) => {
|
|
2279
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase4(variable.name))}`;
|
|
2280
|
+
if (excludeList.includes(hookName)) {
|
|
2281
|
+
return null;
|
|
2282
|
+
}
|
|
2283
|
+
return generateVarHook(variable, name, address, contractName);
|
|
2284
|
+
}).filter(Boolean);
|
|
2285
|
+
const constants = variables.filter((v) => v.access === "constant");
|
|
2286
|
+
const constantHooks = constants.map((constant) => {
|
|
2287
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase4(constant.name))}`;
|
|
2288
|
+
if (excludeList.includes(hookName)) {
|
|
2289
|
+
return null;
|
|
2290
|
+
}
|
|
2291
|
+
return generateConstantHook(constant, name, address, contractName);
|
|
2292
|
+
}).filter(Boolean);
|
|
2293
|
+
const allHooks = [...readHooks, ...writeHooks, ...mapHooks, ...varHooks, ...constantHooks];
|
|
2074
2294
|
if (allHooks.length === 0) {
|
|
2075
2295
|
return "";
|
|
2076
2296
|
}
|
|
@@ -2082,12 +2302,13 @@ function generateReadHook(func, contractName) {
|
|
|
2082
2302
|
const hookName = `use${capitalize(contractName)}${capitalize(toCamelCase4(func.name))}`;
|
|
2083
2303
|
const argsSignature = generateHookArgsSignature(func.args);
|
|
2084
2304
|
const enabledParam = func.args.length > 0 ? ", options?: { enabled?: boolean }" : "options?: { enabled?: boolean }";
|
|
2305
|
+
const returnType = mapClarityTypeToTS(func.outputs);
|
|
2085
2306
|
return `export function ${hookName}(${argsSignature}${enabledParam}) {
|
|
2086
2307
|
const config = useStacksConfig()
|
|
2087
|
-
|
|
2088
|
-
return useQuery({
|
|
2308
|
+
|
|
2309
|
+
return useQuery<${returnType}>({
|
|
2089
2310
|
queryKey: ['${func.name}', ${contractName}.address, ${generateQueryKeyArgs(func.args)}],
|
|
2090
|
-
queryFn: () => ${contractName}.read.${toCamelCase4(func.name)}(${generateFunctionCallArgs(func.args) ? `{ ${generateObjectArgs(func.args)} }, ` : ""}{
|
|
2311
|
+
queryFn: () => ${contractName}.read.${toCamelCase4(func.name)}(${generateFunctionCallArgs(func.args) ? `{ ${generateObjectArgs(func.args)} }, ` : ""}{
|
|
2091
2312
|
network: config.network,
|
|
2092
2313
|
senderAddress: config.senderAddress || 'SP000000000000000000002Q6VF78'
|
|
2093
2314
|
}),
|
|
@@ -2107,7 +2328,7 @@ function generateWriteHook(func, contractName) {
|
|
|
2107
2328
|
mutationFn: async (params: {
|
|
2108
2329
|
args: ${argsType};
|
|
2109
2330
|
options?: {
|
|
2110
|
-
postConditions?:
|
|
2331
|
+
postConditions?: PostCondition[];
|
|
2111
2332
|
attachment?: string;
|
|
2112
2333
|
onFinish?: (data: any) => void;
|
|
2113
2334
|
onCancel?: () => void;
|
|
@@ -2165,9 +2386,9 @@ function generateWriteHook(func, contractName) {
|
|
|
2165
2386
|
})
|
|
2166
2387
|
|
|
2167
2388
|
const ${toCamelCase4(func.name)} = useCallback(async (
|
|
2168
|
-
args: ${argsType},
|
|
2389
|
+
args: ${argsType},
|
|
2169
2390
|
options?: {
|
|
2170
|
-
postConditions?:
|
|
2391
|
+
postConditions?: PostCondition[];
|
|
2171
2392
|
attachment?: string;
|
|
2172
2393
|
onFinish?: (data: any) => void;
|
|
2173
2394
|
onCancel?: () => void;
|
|
@@ -2188,6 +2409,53 @@ function generateWriteHook(func, contractName) {
|
|
|
2188
2409
|
}
|
|
2189
2410
|
}`;
|
|
2190
2411
|
}
|
|
2412
|
+
function generateMapHook(map, contractVarName, _address, _contractName) {
|
|
2413
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase4(map.name))}`;
|
|
2414
|
+
const keyType = mapClarityTypeToTS(map.key);
|
|
2415
|
+
const valueType = mapClarityTypeToTS(map.value);
|
|
2416
|
+
return `export function ${hookName}(key: ${keyType}, options?: { enabled?: boolean }) {
|
|
2417
|
+
const config = useStacksConfig()
|
|
2418
|
+
|
|
2419
|
+
return useQuery<${valueType} | null>({
|
|
2420
|
+
queryKey: ['${contractVarName}', '${map.name}', 'map', key, config.network],
|
|
2421
|
+
queryFn: async () => {
|
|
2422
|
+
return ${contractVarName}.maps.${toCamelCase4(map.name)}.get(key, { network: config.network })
|
|
2423
|
+
},
|
|
2424
|
+
enabled: options?.enabled ?? true
|
|
2425
|
+
})
|
|
2426
|
+
}`;
|
|
2427
|
+
}
|
|
2428
|
+
function generateVarHook(variable, contractVarName, _address, _contractName) {
|
|
2429
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase4(variable.name))}`;
|
|
2430
|
+
const valueType = mapClarityTypeToTS(variable.type);
|
|
2431
|
+
return `export function ${hookName}(options?: { enabled?: boolean }) {
|
|
2432
|
+
const config = useStacksConfig()
|
|
2433
|
+
|
|
2434
|
+
return useQuery<${valueType}>({
|
|
2435
|
+
queryKey: ['${contractVarName}', '${variable.name}', 'var', config.network],
|
|
2436
|
+
queryFn: async () => {
|
|
2437
|
+
return ${contractVarName}.vars.${toCamelCase4(variable.name)}.get({ network: config.network })
|
|
2438
|
+
},
|
|
2439
|
+
enabled: options?.enabled ?? true
|
|
2440
|
+
})
|
|
2441
|
+
}`;
|
|
2442
|
+
}
|
|
2443
|
+
function generateConstantHook(constant, contractVarName, _address, _contractName) {
|
|
2444
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase4(constant.name))}`;
|
|
2445
|
+
const valueType = mapClarityTypeToTS(constant.type);
|
|
2446
|
+
return `export function ${hookName}(options?: { enabled?: boolean }) {
|
|
2447
|
+
const config = useStacksConfig()
|
|
2448
|
+
|
|
2449
|
+
return useQuery<${valueType}>({
|
|
2450
|
+
queryKey: ['${contractVarName}', '${constant.name}', 'constant', config.network],
|
|
2451
|
+
queryFn: async () => {
|
|
2452
|
+
return ${contractVarName}.constants.${toCamelCase4(constant.name)}.get({ network: config.network })
|
|
2453
|
+
},
|
|
2454
|
+
enabled: options?.enabled ?? true,
|
|
2455
|
+
staleTime: Infinity // Constants never change
|
|
2456
|
+
})
|
|
2457
|
+
}`;
|
|
2458
|
+
}
|
|
2191
2459
|
|
|
2192
2460
|
// src/plugins/react/index.ts
|
|
2193
2461
|
var react = (options = {}) => {
|
|
@@ -2441,7 +2709,7 @@ function getMapKeyType(keyType) {
|
|
|
2441
2709
|
}
|
|
2442
2710
|
return getTypeForArg3({ type: keyType });
|
|
2443
2711
|
}
|
|
2444
|
-
function
|
|
2712
|
+
function generateMapKeyConversion2(keyType) {
|
|
2445
2713
|
if (keyType.tuple) {
|
|
2446
2714
|
const fields = keyType.tuple.map((field) => {
|
|
2447
2715
|
const camelFieldName = toCamelCase5(field.name);
|
|
@@ -2455,7 +2723,7 @@ function generateMapKeyConversion(keyType) {
|
|
|
2455
2723
|
function generateMapEntryHelper(map, contractId) {
|
|
2456
2724
|
const methodName = toCamelCase5(map.name);
|
|
2457
2725
|
const keyType = getMapKeyType(map.key);
|
|
2458
|
-
const keyConversion =
|
|
2726
|
+
const keyConversion = generateMapKeyConversion2(map.key);
|
|
2459
2727
|
return `${methodName}: (key: ${keyType}) => {
|
|
2460
2728
|
return simnet.getMapEntry(
|
|
2461
2729
|
'${contractId}',
|
|
@@ -2464,7 +2732,7 @@ function generateMapEntryHelper(map, contractId) {
|
|
|
2464
2732
|
);
|
|
2465
2733
|
}`;
|
|
2466
2734
|
}
|
|
2467
|
-
function
|
|
2735
|
+
function generateVarsObject2(variables, contractId) {
|
|
2468
2736
|
const dataVars = variables.filter((v) => v.access === "variable");
|
|
2469
2737
|
if (dataVars.length === 0) {
|
|
2470
2738
|
return "";
|
|
@@ -2476,7 +2744,7 @@ function generateVarsObject(variables, contractId) {
|
|
|
2476
2744
|
`)}
|
|
2477
2745
|
}`;
|
|
2478
2746
|
}
|
|
2479
|
-
function
|
|
2747
|
+
function generateMapsObject2(maps, contractId) {
|
|
2480
2748
|
if (maps.length === 0) {
|
|
2481
2749
|
return "";
|
|
2482
2750
|
}
|
|
@@ -2499,8 +2767,8 @@ function generateContractHelper(contract, options) {
|
|
|
2499
2767
|
const publicHelpers = publicFns.map((f) => generatePublicFunction(f, address));
|
|
2500
2768
|
const readOnlyHelpers = readOnlyFns.map((f) => generateReadOnlyFunction(f, address));
|
|
2501
2769
|
const privateHelpers = privateFns.map((f) => generatePrivateFunction(f, address));
|
|
2502
|
-
const varsObject =
|
|
2503
|
-
const mapsObject =
|
|
2770
|
+
const varsObject = generateVarsObject2(variables, address);
|
|
2771
|
+
const mapsObject = generateMapsObject2(maps, address);
|
|
2504
2772
|
const allHelpers = [...publicHelpers, ...readOnlyHelpers, ...privateHelpers];
|
|
2505
2773
|
if (varsObject) {
|
|
2506
2774
|
allHelpers.push(varsObject);
|
|
@@ -2651,5 +2919,5 @@ export {
|
|
|
2651
2919
|
PluginManager
|
|
2652
2920
|
};
|
|
2653
2921
|
|
|
2654
|
-
//# debugId=
|
|
2922
|
+
//# debugId=7F2D601996EE7CEE64756E2164756E21
|
|
2655
2923
|
//# sourceMappingURL=index.js.map
|