@openzeppelin/contracts-ui-builder-adapter-midnight
Version:
Midnight Adapter for Contracts UI Builder
727 lines (702 loc) • 26.3 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/index.ts
var index_exports = {};
__export(index_exports, {
MidnightAdapter: () => MidnightAdapter,
default: () => adapter_default,
isMidnightContractArtifacts: () => isMidnightContractArtifacts,
midnightAdapterConfig: () => midnightAdapterConfig,
midnightNetworks: () => midnightNetworks,
midnightTestnet: () => midnightTestnet,
midnightTestnetNetworks: () => midnightTestnetNetworks
});
module.exports = __toCommonJS(index_exports);
// src/configuration/execution.ts
var import_contracts_ui_builder_utils2 = require("@openzeppelin/contracts-ui-builder-utils");
// src/types/artifacts.ts
function isMidnightContractArtifacts(obj) {
const record = obj;
return typeof obj === "object" && obj !== null && typeof record.contractAddress === "string" && typeof record.privateStateId === "string" && typeof record.contractSchema === "string";
}
// src/utils/artifacts.ts
function validateAndConvertMidnightArtifacts(source) {
if (typeof source === "string") {
throw new Error(
"Midnight adapter requires contract artifacts object, not just an address string."
);
}
if (!isMidnightContractArtifacts(source)) {
throw new Error(
"Invalid contract artifacts provided. Expected an object with contractAddress, privateStateId, and contractSchema properties."
);
}
return source;
}
// src/utils/schema-parser.ts
function parseMidnightContractInterface(interfaceContent) {
const circuits = extractCircuits(interfaceContent);
const queries = extractQueries(interfaceContent);
const functions = [...Object.values(circuits), ...Object.values(queries)];
const events = [];
return { functions, events };
}
function extractCircuits(content) {
const circuits = {};
const circuitsMatch = content.match(/export\s+type\s+Circuits\s*<[^>]*>\s*=\s*{([^}]*)}/s);
if (circuitsMatch) {
const circuitsContent = circuitsMatch[1];
const methodRegex = /(\w+)\s*\(\s*context\s*:[^,)]+(?:,\s*([^)]+))?\)/g;
let match;
while ((match = methodRegex.exec(circuitsContent)) !== null) {
const name = match[1];
const paramsText = match[2] || "";
circuits[name] = {
id: name,
// Simplified ID for now
name,
displayName: name.charAt(0).toUpperCase() + name.slice(1),
inputs: parseParameters(paramsText),
outputs: [],
// Assuming no direct outputs from circuits for now
modifiesState: true,
type: "function"
};
}
}
return circuits;
}
function extractQueries(content) {
const queries = {};
const ledgerMatch = content.match(/export\s+type\s+Ledger\s*=\s*{([^}]*)}/s);
if (ledgerMatch) {
const ledgerContent = ledgerMatch[1];
const propertyRegex = /readonly\s+(\w+)\s*:\s*([^;]*);/g;
let match;
while ((match = propertyRegex.exec(ledgerContent)) !== null) {
const name = match[1];
const typeStr = match[2].trim();
queries[name] = {
id: name,
name,
displayName: name.charAt(0).toUpperCase() + name.slice(1),
inputs: [],
outputs: [{ name: "value", type: typeStr }],
modifiesState: false,
type: "function",
stateMutability: "view"
};
}
}
return queries;
}
function parseParameters(paramsText) {
if (!paramsText.trim()) return [];
return paramsText.split(",").map((param) => {
const [name, type] = param.split(":").map((s) => s.trim());
return { name, type };
});
}
// src/utils/validator.ts
var import_contracts_ui_builder_utils = require("@openzeppelin/contracts-ui-builder-utils");
// src/configuration/explorer.ts
var import_contracts_ui_builder_utils3 = require("@openzeppelin/contracts-ui-builder-utils");
// src/configuration/rpc.ts
var import_contracts_ui_builder_utils4 = require("@openzeppelin/contracts-ui-builder-utils");
function validateMidnightRpcEndpoint(_rpcConfig) {
import_contracts_ui_builder_utils4.logger.info("validateMidnightRpcEndpoint", "Midnight RPC validation not yet implemented");
return true;
}
async function testMidnightRpcConnection(_rpcConfig) {
import_contracts_ui_builder_utils4.logger.info("testMidnightRpcConnection", "TODO: Implement RPC connection testing");
return { success: true };
}
// src/adapter.ts
var import_contracts_ui_builder_types = require("@openzeppelin/contracts-ui-builder-types");
var import_contracts_ui_builder_utils8 = require("@openzeppelin/contracts-ui-builder-utils");
// src/wallet/components/account/AccountDisplay.tsx
var import_lucide_react = require("lucide-react");
var import_contracts_ui_builder_ui = require("@openzeppelin/contracts-ui-builder-ui");
var import_contracts_ui_builder_utils5 = require("@openzeppelin/contracts-ui-builder-utils");
// src/wallet/hooks/useMidnightWallet.ts
var import_react2 = require("react");
// src/wallet/context/MidnightWalletContext.tsx
var import_react = require("react");
var MidnightWalletContext = (0, import_react.createContext)(
void 0
);
// src/wallet/hooks/useMidnightWallet.ts
var useMidnightWallet = () => {
const context = (0, import_react2.useContext)(MidnightWalletContext);
if (context === void 0) {
throw new Error("useMidnightWallet must be used within a MidnightWalletProvider");
}
return context;
};
// src/wallet/hooks/facade-hooks.ts
var useConnect = () => {
const { connect: connect2, isConnecting, error } = useMidnightWallet();
const connectors = [{ id: "mnLace", name: "Lace (Midnight)" }];
return {
connect: connect2,
connectors,
isConnecting,
error,
pendingConnector: void 0
// This adapter doesn't have a concept of a pending connector.
};
};
var useDisconnect = () => {
const { disconnect: disconnect2 } = useMidnightWallet();
return {
disconnect: disconnect2,
isDisconnecting: false,
// This adapter doesn't track disconnecting state.
error: null
};
};
var useAccount = () => {
const { address, isConnected, isConnecting } = useMidnightWallet();
return {
address,
isConnected,
isConnecting,
isDisconnected: !isConnected && !isConnecting,
isReconnecting: false,
// This adapter doesn't have a concept of reconnecting.
status: isConnected ? "connected" : isConnecting ? "connecting" : "disconnected"
};
};
var midnightFacadeHooks = {
useAccount,
useConnect,
useDisconnect
// Other hooks like useBalance, useSwitchChain, etc., can be added here
// in the future. For now, we only need the core connection hooks.
};
// src/wallet/utils/SafeMidnightComponent.tsx
var import_react3 = require("react");
var import_jsx_runtime = require("react/jsx-runtime");
var SafeMidnightComponent = ({
children,
fallback = null
}) => {
const context = (0, import_react3.useContext)(MidnightWalletContext);
if (!context) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: fallback });
}
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
};
// src/wallet/components/account/AccountDisplay.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var CustomAccountDisplay = ({ className }) => {
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SafeMidnightComponent, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AccountDisplayContent, { className }) });
};
var AccountDisplayContent = ({ className }) => {
const { address, isConnected } = useAccount();
const { disconnect: disconnect2 } = useDisconnect();
if (!isConnected || !address || !disconnect2) {
return null;
}
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_contracts_ui_builder_utils5.cn)("flex items-center gap-2", className), children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col", children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs font-medium", children: (0, import_contracts_ui_builder_utils5.truncateMiddle)(address, 4, 4) }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[9px] text-muted-foreground -mt-0.5", children: "Midnight Network" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
import_contracts_ui_builder_ui.Button,
{
onClick: () => disconnect2(),
variant: "ghost",
size: "icon",
className: "size-6 p-0",
title: "Disconnect wallet",
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.LogOut, { className: "size-3.5" })
}
)
] });
};
// src/wallet/components/connect/ConnectButton.tsx
var import_lucide_react2 = require("lucide-react");
var import_contracts_ui_builder_ui2 = require("@openzeppelin/contracts-ui-builder-ui");
var import_contracts_ui_builder_utils6 = require("@openzeppelin/contracts-ui-builder-utils");
var import_jsx_runtime3 = require("react/jsx-runtime");
var ConnectButton = ({
className,
hideWhenConnected = true
}) => {
const unavailableButton = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: (0, import_contracts_ui_builder_utils6.cn)("flex items-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_contracts_ui_builder_ui2.Button, { disabled: true, variant: "outline", size: "sm", className: "h-8 px-2 text-xs", children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Wallet, { className: "size-3.5 mr-1" }),
"Wallet Unavailable"
] }) });
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SafeMidnightComponent, { fallback: unavailableButton, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConnectButtonContent, { className, hideWhenConnected }) });
};
var ConnectButtonContent = ({ className, hideWhenConnected }) => {
const { isConnected } = useAccount();
const { connect: connect2, isConnecting, connectors, error: connectError } = useConnect();
const handleConnectClick = () => {
if (connect2 && !isConnected) {
connect2();
}
};
if (isConnected && hideWhenConnected) {
return null;
}
const showButtonLoading = isConnecting;
const hasWallet = connectors.length > 0;
let buttonText = "Connect Wallet";
if (!hasWallet) {
buttonText = "No Wallet Found";
} else if (showButtonLoading) {
buttonText = "Connecting...";
} else if (connectError) {
buttonText = "Connect Wallet";
}
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: (0, import_contracts_ui_builder_utils6.cn)("flex flex-col items-start gap-1", className), children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
import_contracts_ui_builder_ui2.Button,
{
onClick: handleConnectClick,
disabled: showButtonLoading || isConnected || !hasWallet,
variant: "outline",
size: "sm",
className: "h-8 px-2 text-xs",
children: [
showButtonLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Loader2, { className: "size-3.5 animate-spin mr-1" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Wallet, { className: "size-3.5 mr-1" }),
buttonText
]
}
) }),
connectError && !isConnecting && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-red-500 px-2", children: connectError.message || "Error connecting wallet" })
] });
};
// src/wallet/components/MidnightWalletProvider.tsx
var import_react4 = require("react");
var import_contracts_ui_builder_utils7 = require("@openzeppelin/contracts-ui-builder-utils");
// src/wallet/midnight-implementation.ts
var enabledApi = null;
var isEnabled = () => {
if (typeof window === "undefined" || !window.midnight?.mnLace) {
return Promise.resolve(false);
}
return window.midnight.mnLace.isEnabled();
};
var connect = async () => {
if (typeof window === "undefined" || !window.midnight?.mnLace) {
return Promise.reject(new Error("Lace wallet not found."));
}
const api = await window.midnight.mnLace.enable();
enabledApi = api;
return api;
};
var disconnect = () => {
enabledApi = null;
};
// src/wallet/components/MidnightWalletProvider.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
var MidnightWalletProvider = ({ children }) => {
const [api, setApi] = (0, import_react4.useState)(null);
const [error, setError] = (0, import_react4.useState)(null);
const [address, setAddress] = (0, import_react4.useState)(void 0);
const [isConnecting, setIsConnecting] = (0, import_react4.useState)(false);
const [isInitializing, setIsInitializing] = (0, import_react4.useState)(true);
const pollIntervalRef = (0, import_react4.useRef)(null);
const isConnected = !!address && !!api;
const cleanupTimer = (0, import_react4.useCallback)(() => {
if (pollIntervalRef.current) {
clearInterval(pollIntervalRef.current);
pollIntervalRef.current = null;
}
}, []);
(0, import_react4.useEffect)(() => {
const attemptAutoConnect = async () => {
if (localStorage.getItem("midnight-hasExplicitlyDisconnected") === "true") {
setIsInitializing(false);
return;
}
try {
const alreadyEnabled = await isEnabled();
if (alreadyEnabled) {
const preflightApi = await connect();
const state = await preflightApi.state();
setApi(preflightApi);
setAddress(state.address);
}
} catch (err) {
import_contracts_ui_builder_utils7.logger.warn("MidnightWalletProvider", "Auto-reconnect failed:", err);
} finally {
setIsInitializing(false);
}
};
attemptAutoConnect();
}, []);
const handleConnect = (0, import_react4.useCallback)(async () => {
if (isConnecting || isInitializing) return;
localStorage.removeItem("midnight-hasExplicitlyDisconnected");
setIsConnecting(true);
setError(null);
try {
const preflightApi = await connect();
pollIntervalRef.current = setInterval(async () => {
try {
const state = await preflightApi.state();
cleanupTimer();
setApi(preflightApi);
setAddress(state.address);
setIsConnecting(false);
} catch {
}
}, 2e3);
setTimeout(() => {
if (pollIntervalRef.current) {
cleanupTimer();
setError(new Error("Connection timed out. Please try again."));
setIsConnecting(false);
}
}, 9e4);
} catch (initialError) {
setError(
initialError instanceof Error ? initialError : new Error("Failed to initiate connection.")
);
setIsConnecting(false);
}
}, [isConnecting, isInitializing, cleanupTimer]);
const handleDisconnect = (0, import_react4.useCallback)(async () => {
disconnect();
setApi(null);
setAddress(void 0);
setError(null);
cleanupTimer();
localStorage.setItem("midnight-hasExplicitlyDisconnected", "true");
}, [cleanupTimer]);
(0, import_react4.useEffect)(() => {
return cleanupTimer;
}, [cleanupTimer]);
(0, import_react4.useEffect)(() => {
if (api && typeof api.onAccountChange === "function") {
const handleAccountChange = (addresses) => {
setAddress(addresses[0]);
};
api.onAccountChange(handleAccountChange);
return () => {
if (typeof api.offAccountChange === "function") {
api.offAccountChange(handleAccountChange);
}
};
}
}, [api]);
const contextValue = (0, import_react4.useMemo)(
() => ({
isConnected,
isConnecting: isConnecting || isInitializing,
isConnectPending: isConnecting || isInitializing,
address,
api,
error,
connect: handleConnect,
disconnect: handleDisconnect
}),
[
isConnected,
isConnecting,
isInitializing,
address,
api,
error,
handleConnect,
handleDisconnect
]
);
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MidnightWalletContext.Provider, { value: contextValue, children });
};
// src/wallet/connection.ts
var supportsMidnightWalletConnection = () => {
return typeof window !== "undefined" && !!window.midnight?.mnLace;
};
var getMidnightAvailableConnectors = async () => {
if (!supportsMidnightWalletConnection()) {
return [];
}
return [{ id: "mnLace", name: "Lace (Midnight)" }];
};
async function disconnectMidnightWallet() {
return { disconnected: true };
}
// src/adapter.ts
var MidnightAdapter = class {
constructor(networkConfig) {
__publicField(this, "networkConfig");
__publicField(this, "initialAppServiceKitName");
__publicField(this, "artifacts", null);
if (!(0, import_contracts_ui_builder_types.isMidnightNetworkConfig)(networkConfig)) {
throw new Error("MidnightAdapter requires a valid Midnight network configuration.");
}
this.networkConfig = networkConfig;
this.initialAppServiceKitName = "custom";
import_contracts_ui_builder_utils8.logger.info(
"MidnightAdapter",
`Adapter initialized for network: ${networkConfig.name} (ID: ${networkConfig.id})`
);
}
getEcosystemReactUiContextProvider() {
return MidnightWalletProvider;
}
getEcosystemReactHooks() {
return midnightFacadeHooks;
}
getEcosystemWalletComponents() {
return {
ConnectButton,
AccountDisplay: CustomAccountDisplay
};
}
supportsWalletConnection() {
return supportsMidnightWalletConnection();
}
async getAvailableConnectors() {
return getMidnightAvailableConnectors();
}
connectWallet(_connectorId) {
import_contracts_ui_builder_utils8.logger.warn(
"MidnightAdapter",
"The `connectWallet` method is not supported. Use the `ConnectButton` component from `getEcosystemWalletComponents()` instead."
);
return Promise.resolve({ connected: false, error: "Method not supported." });
}
disconnectWallet() {
return disconnectMidnightWallet();
}
getWalletConnectionStatus() {
return {
isConnected: false,
address: void 0,
chainId: this.networkConfig.id
};
}
getContractDefinitionInputs() {
return [
{
id: "contractAddress",
name: "contractAddress",
label: "Contract Address",
type: "blockchain-address",
validation: { required: true },
placeholder: "ct1q8ej4px...",
helperText: "Enter the deployed Midnight contract address (Bech32m format)."
},
{
id: "privateStateId",
name: "privateStateId",
label: "Private State ID",
type: "text",
validation: { required: true },
placeholder: "my-unique-state-id",
helperText: "A unique identifier for your private state instance. This ID is used to manage your personal encrypted data."
},
{
id: "contractSchema",
name: "contractSchema",
label: "Contract Interface (.d.ts)",
type: "code-editor",
validation: { required: true },
placeholder: "export interface MyContract {\n myMethod(param: string): Promise<void>;\n // ... other methods\n}",
helperText: "Paste the TypeScript interface definition from your contract.d.ts file. This defines the contract's available methods.",
codeEditorProps: {
language: "typescript",
placeholder: "Paste your contract interface here...",
maxHeight: "400px"
}
},
{
id: "contractModule",
name: "contractModule",
label: "Compiled Contract Module (.cjs)",
type: "textarea",
validation: { required: true },
placeholder: "module.exports = { /* compiled contract code */ };",
helperText: "Paste the compiled contract code from your contract.cjs file. This contains the contract's implementation."
},
{
id: "witnessCode",
name: "witnessCode",
label: "Witness Functions (Optional)",
type: "textarea",
validation: { required: false },
placeholder: "// Define witness functions for zero-knowledge proofs\nexport const witnesses = {\n myWitness: (ctx) => {\n return [ctx.privateState.myField, []];\n }\n};",
helperText: "Optional: Define witness functions that generate zero-knowledge proofs for your contract interactions. These functions determine what private data is used in proofs."
}
];
}
async loadContract(source) {
const artifacts = validateAndConvertMidnightArtifacts(source);
this.artifacts = artifacts;
import_contracts_ui_builder_utils8.logger.info("MidnightAdapter", "Contract artifacts stored.", this.artifacts);
const { functions, events } = parseMidnightContractInterface(artifacts.contractSchema);
const schema = {
name: "MyMidnightContract",
// TODO: Extract from artifacts if possible
ecosystem: "midnight",
address: artifacts.contractAddress,
functions,
events
};
return schema;
}
getWritableFunctions(contractSchema) {
return contractSchema.functions.filter((fn) => fn.modifiesState);
}
mapParameterTypeToFieldType(_parameterType) {
return "text";
}
getCompatibleFieldTypes(_parameterType) {
return ["text"];
}
generateDefaultField(parameter) {
return {
id: parameter.name,
name: parameter.name,
label: parameter.name,
type: this.mapParameterTypeToFieldType(parameter.type),
validation: {}
};
}
formatTransactionData(_contractSchema, _functionId, _submittedInputs, _fields) {
throw new Error("formatTransactionData not implemented for MidnightAdapter.");
}
async signAndBroadcast(_transactionData, _executionConfig) {
throw new Error("signAndBroadcast not implemented for MidnightAdapter.");
}
isViewFunction(functionDetails) {
return !functionDetails.modifiesState;
}
async queryViewFunction(_contractAddress, _functionId, _params, _contractSchema) {
throw new Error("queryViewFunction not implemented for MidnightAdapter.");
}
formatFunctionResult(decodedValue) {
return JSON.stringify(decodedValue, null, 2);
}
async getSupportedExecutionMethods() {
return [];
}
async validateExecutionConfig(_config) {
return true;
}
getExplorerUrl(_address) {
return null;
}
getExplorerTxUrl(_txHash) {
return null;
}
isValidAddress(_address) {
return true;
}
async getAvailableUiKits() {
return [
{
id: "custom",
name: "OpenZeppelin Custom",
configFields: []
}
];
}
async getRelayers(_serviceUrl, _accessToken) {
import_contracts_ui_builder_utils8.logger.warn("MidnightAdapter", "getRelayers is not implemented for the Midnight adapter yet.");
return Promise.resolve([]);
}
async getRelayer(_serviceUrl, _accessToken, _relayerId) {
import_contracts_ui_builder_utils8.logger.warn("MidnightAdapter", "getRelayer is not implemented for the Midnight adapter yet.");
return Promise.resolve({});
}
/**
* @inheritdoc
*/
async validateRpcEndpoint(rpcConfig) {
return validateMidnightRpcEndpoint(rpcConfig);
}
/**
* @inheritdoc
*/
async testRpcConnection(rpcConfig) {
return testMidnightRpcConnection(rpcConfig);
}
};
var adapter_default = MidnightAdapter;
// src/networks/testnet.ts
var midnightTestnet = {
id: "midnight-testnet",
exportConstName: "midnightTestnet",
name: "Midnight Testnet",
ecosystem: "midnight",
network: "midnight-testnet",
type: "testnet",
isTestnet: true
// Add Midnight-specific fields here when known
// explorerUrl: '...',
// apiUrl: '...',
};
// src/networks/index.ts
var midnightTestnetNetworks = [midnightTestnet];
var midnightNetworks = [...midnightTestnetNetworks];
// src/config.ts
var midnightAdapterConfig = {
/**
* Default app name to display in the wallet connection UI.
*/
appName: "OpenZeppelin Contracts UI Builder",
/**
* Dependencies required by the Midnight adapter
* These will be included in exported projects that use this adapter
*/
dependencies: {
// TODO: Review and update with real, verified dependencies and versions before production release
// Runtime dependencies
runtime: {
// Core Midnight protocol libraries
"@midnight-protocol/sdk": "^0.8.2",
"@midnight-protocol/client": "^0.7.0",
// Encryption and privacy utilities
"libsodium-wrappers": "^0.7.11",
"@openzeppelin/contracts-upgradeable": "^4.9.3",
// Additional utilities for Midnight
"js-sha256": "^0.9.0",
"bn.js": "^5.2.1",
"@midnight-ntwrk/dapp-connector-api": "^3.0.0"
},
// Development dependencies
dev: {
// Testing utilities for Midnight
"@midnight-protocol/testing": "^0.5.0",
// Type definitions
"@types/libsodium-wrappers": "^0.7.10",
"@types/bn.js": "^5.1.1"
}
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
MidnightAdapter,
isMidnightContractArtifacts,
midnightAdapterConfig,
midnightNetworks,
midnightTestnet,
midnightTestnetNetworks
});
//# sourceMappingURL=index.cjs.map
;