From ad32b4a39800fb7a077fc384e6e5d9a0a5971d14 Mon Sep 17 00:00:00 2001 From: c4605 Date: Tue, 4 Feb 2025 18:10:10 +0100 Subject: [PATCH] feat: add runtime function getMapEntryFactory --- package.json | 8 ++-- pnpm-lock.yaml | 12 +++--- src/index.ts | 1 + src/runtime/executeReadonlyCall.ts | 4 +- src/runtime/getMapEntry.ts | 69 ++++++++++++++++++++++++++++++ tsconfig.json | 2 +- 6 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 src/runtime/getMapEntry.ts diff --git a/package.json b/package.json index c52c064..550dc3d 100644 --- a/package.json +++ b/package.json @@ -34,13 +34,13 @@ } }, "devDependencies": { - "@stacks/transactions": "^7.0.2", "@stacks/common": "^7.0.2", + "@stacks/transactions": "^7.0.2", "@types/lodash": "^4.14.194", "@types/node": "^20.1.5", "@types/yargs": "^17.0.24", "prettier": "^2.8.8", - "typescript": "^5.0.4" + "typescript": "^5.7.3" }, "dependencies": { "@stacks/stacks-blockchain-api-types": "^7.1.10", @@ -50,7 +50,7 @@ "yqueue": "^1.0.1" }, "peerDependencies": { - "@stacks/transactions": "^7.0.2", - "@stacks/common": "^7.0.2" + "@stacks/common": "^7.0.2", + "@stacks/transactions": "^7.0.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e25bb6..0d1b853 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,8 +43,8 @@ importers: specifier: ^2.8.8 version: 2.8.8 typescript: - specifier: ^5.0.4 - version: 5.0.4 + specifier: ^5.7.3 + version: 5.7.3 packages: @@ -195,9 +195,9 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} hasBin: true webidl-conversions@3.0.1: @@ -358,7 +358,7 @@ snapshots: tr46@0.0.3: {} - typescript@5.0.4: {} + typescript@5.7.3: {} webidl-conversions@3.0.1: {} diff --git a/src/index.ts b/src/index.ts index 0bb08ab..d70aedf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,4 +6,5 @@ export * from "./runtime/decodeContractCallTransaction"; export * from "./runtime/types"; export * from "./runtime/composeTxOptions"; export * from "./runtime/executeReadonlyCall"; +export * from "./runtime/getMapEntry"; export * from "./utils/helpers"; diff --git a/src/runtime/executeReadonlyCall.ts b/src/runtime/executeReadonlyCall.ts index 61fa7d1..c4fe596 100644 --- a/src/runtime/executeReadonlyCall.ts +++ b/src/runtime/executeReadonlyCall.ts @@ -44,7 +44,7 @@ export const executeReadonlyCallFactory = if (functionDescriptor.mode !== "readonly") { throw new Error( - `[composeTx] function ${contractName}.${functionName} should be a readonly function` + `[executeReadonlyCall] function ${contractName}.${functionName} should be a readonly function` ); } @@ -55,7 +55,7 @@ export const executeReadonlyCallFactory = const deployerAddress = options.deployerAddress ?? factoryOptions.defaultSenderAddress; if (deployerAddress == null) { - throw new Error(`[composeTxOptionsFactory] deployer address required`); + throw new Error(`[executeReadonlyCall] deployer address required`); } const senderAddress = diff --git a/src/runtime/getMapEntry.ts b/src/runtime/getMapEntry.ts new file mode 100644 index 0000000..09e97f2 --- /dev/null +++ b/src/runtime/getMapEntry.ts @@ -0,0 +1,69 @@ +import { fetchContractMapEntry } from "@stacks/transactions"; +import type { StringOnly } from "../utils/helpers"; +import type { + ContractBaseType, + ParameterObjOfDescriptor, + MapEntryDescriptor, + ReturnTypeOfDescriptor, +} from "./contractBase"; + +export type FetchContractMapEntryFn = typeof fetchContractMapEntry; + +export type GetMapEntryFn = < + T extends StringOnly, + F extends StringOnly, + Descriptor extends Contracts[T][F] +>( + contractName: T, + mapName: F, + mapKey: Descriptor extends MapEntryDescriptor + ? ParameterObjOfDescriptor + : never, + options?: { + deployerAddress?: string; + fetchContractMapEntry?: FetchContractMapEntryFn; + } +) => Promise< + Descriptor extends MapEntryDescriptor + ? ReturnTypeOfDescriptor + : never +>; + +export const getMapEntryFactory = + ( + contracts: T, + factoryOptions: { + deployerAddress?: string; + fetchContractMapEntry?: FetchContractMapEntryFn; + } + ): GetMapEntryFn => + async (contractName, mapName, mapKey, options = {}) => { + const descriptor = contracts[contractName][mapName]; + + if (descriptor.mode !== "mapEntry") { + throw new Error( + `[getMapEntry] ${contractName}.${mapName} should be a mapEntry` + ); + } + + const clarityMapKey = descriptor.input.encode(mapKey); + + const deployerAddress = options.deployerAddress; + if (deployerAddress == null) { + throw new Error(`[getMapEntry] deployer address required`); + } + + const _fetchContractMapEntry = + options.fetchContractMapEntry ?? + factoryOptions.fetchContractMapEntry ?? + fetchContractMapEntry; + + const result = await _fetchContractMapEntry({ + contractName, + mapName, + mapKey: clarityMapKey, + contractAddress: deployerAddress, + }); + + return descriptor.output.decode(result); + }; diff --git a/tsconfig.json b/tsconfig.json index 7ac154a..0283079 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,7 @@ /* Modules */ "module": "ESNext" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */