diff --git a/src/stacks-rpc-api/smart-contracts/index.ts b/src/stacks-rpc-api/smart-contracts/index.ts index 6726cb3..527ecf9 100644 --- a/src/stacks-rpc-api/smart-contracts/index.ts +++ b/src/stacks-rpc-api/smart-contracts/index.ts @@ -2,8 +2,11 @@ import { mapEntry } from "./map-entry.js"; export type * as MapEntry from "./map-entry.js"; import { readOnly } from "./read-only.js"; export type * as ReadOnly from "./read-only.js"; +import { contractInterface } from "./interface.js"; +export type * as ContractInterface from "./interface.js"; export const smartContracts = { + contractInterface, mapEntry, readOnly, }; diff --git a/src/stacks-rpc-api/smart-contracts/interface.ts b/src/stacks-rpc-api/smart-contracts/interface.ts new file mode 100644 index 0000000..ec07d84 --- /dev/null +++ b/src/stacks-rpc-api/smart-contracts/interface.ts @@ -0,0 +1,53 @@ +import type { ClarityAbi } from "@stacks/transactions"; +import type { ApiRequestOptions, ProofAndTip } from "../../stacks-api/types.js"; +import { error, safePromise, success, type Result } from "../../utils/safe.js"; + +export type Args = { + contractAddress: string; + contractName: string; +} & ApiRequestOptions & + ProofAndTip; + +export type InterfaceResponse = ClarityAbi; + +export async function contractInterface( + args: Args, +): Promise> { + const search = new URLSearchParams(); + if (args.proof === 0) search.append("proof", "0"); + if (args.tip) search.append("tip", args.tip); + + const init: RequestInit = {}; + if (args.apiKeyConfig) { + init.headers = { + [args.apiKeyConfig.header]: args.apiKeyConfig.key, + }; + } + + const endpoint = `${args.baseUrl}/v2/contracts/interface/${args.contractAddress}/${args.contractName}`; + const res = await fetch(endpoint, init); + if (!res.ok) { + return error({ + name: "FetcContractInterfaceError", + message: "Failed to fetch contract interface.", + data: { + init, + status: res.status, + statusText: res.statusText, + endpoint, + bodyText: await safePromise(res.text()), + }, + }); + } + + const [jsonError, data] = await safePromise(res.json()); + if (jsonError) { + return error({ + name: "ParseBodyError", + message: "Failed to parse response body as JSON.", + data: jsonError, + }); + } + + return success(data as InterfaceResponse); +}