@midnight-ntwrk/compact-js-command
v2.3.0
Published
Command line utilities for working with smart contracts compiled with the Compact language
Downloads
95
Readme
Compact.js (Command Line Utilities)
Introduction
Provides an opinionated command line interface for Compact.js, allowing compactc compiled contracts to be
executed from the command line. The package exports commands that can be used programmatically within other
command line tools, or executed directly in its own process through its own CLI.
Commands
Prerequisites & Configuration
Since Compact.js commands operate over Compact compiled contracts, we need the following prerequisites in order to execute them:
- A
.compactcontract that has been compiled using thecompactccompiler.
The Compact compiler generates a JavaScript based contract executable that will be the target of the invocations made by the commands present in Compact.js. It also generates other assets that are required in order to fulfill contract deployment and execution. Specifically, these are the TypeScript declaration file that describes the contract, and the ZK file assets including prover and verifier keys. - With the above in place, we also need a configuration file (written in TypeScript), that:
- Imports the contract executable and makes it invocable via the
CompiledContractandContractExecutabletypes present in Compact.js, - Provides a type for private state, and a function that creates its initial value,
- Provides the implementation of the Witnesses required by the contract, and,
- Optionally provides some default configuration that can be set for all Compact.js commands.
- Imports the contract executable and makes it invocable via the
An example configuration file for the canonical "Counter" contract is shown below:
import { CompiledContract, type Contract, ContractExecutable } from '@midnight-ntwrk/compact-js/effect';
import { Contract as C_ } from './<path>/managed/counter/contract/index.cjs';
// The type of private state to use in contract execution.
type PrivateState = {
count: number;
};
type CounterContract = C_<PrivateState>;
const CounterContract = C_;
// An implementation of the required Witnesses.
const witnesses: Contract.Contract.Witnesses<CounterContract> = {
private_increment: ({ privateState }) => [{ count: privateState.count + 1 }, []]
}
// A function that creates the initial private state given to the contract when an instance is
// being deployed.
const createInitialPrivateState: () => PrivateState = () => ({
count: 0
});
// The default export that describes the binding to the Contract.
export default {
// Creates an executable from the imported contract, along with the assets it will require at runtime.
contractExecutable: CompiledContract.make<CounterContract>('CounterContract', CounterContract).pipe(
CompiledContract.withWitnesses(witnesses),
CompiledContract.withCompiledFileAssets('./<path>/managed/counter'),
ContractExecutable.make
),
createInitialPrivateState,
config: {
keys: {
coinPublic: '...',
signing: '...'
},
network: 'undeployed'
}
}Note: The config property is entirely optional along with its keys. The values can also be provided (or
overridden via precedence), via environment variables, or through the command line options documented below.
Global Options
The following options can be used with all commands:
-c | --config pathToConfig. The file path to the previously mentioned Contract Configuration file.
Defaults to'contract.config.ts'in the current working folder.-p | --coin-public key. The user public key capable of receiving Zswap coins.
The string can be hex or Bech32m encoded. Its value can also be specified using an environment variable namedKEYS_COIN_PUBLIC.-n | --network networkId. An optional network identifier.
Defaults to the Midnight MainNet if not specified. Its value can also be specified using an environment variable namedNETWORK.
deploy Command
<binName> deploy [-c ...]
[-p ...]
[-n ...]
[-s | --signing ...]
[--output ...]
[--output-ps ...]
[--output-zswap ...]
...argsThis command executes the contract constructor and generates a serialized Intent describing a contract deployment.
The constructor is executed with the given ...args, and the serialized Intent is written to the --output file
path. The private state and Zswap local state is written to the --output-ps and --output-zswap file paths
respectively, both formatted as JSON.
Options
-s | --signing key. An optional public BIP-340 signing key, hex encoded.
If not provided, a sample signing key is used in order to create a valid Contract Maintenance Authority (CMA) but it will not be available for use in future maintenance operations. Its value can also be specified using an environment variable namedKEYS_SIGNING.--output pathToStateOutput. The file path to where the serializedIntentdata should be written.
Defaults to'output.bin'in the current working folder.--output-ps pathToPrivateStateOutput. The file path to where the private state data should be written.
Defaults to'output.ps.json'in the current working folder.--output-zswap pathToZswapLocalStateOutput. The file path to where the the local Zswap state data should be written.
Defaults to'zswap.json'in the current working folder.
circuit Command
<binName> circuit [-c ...]
[-p ...]
[-n ...]
--input ...
--input-ps ...
[--input-zswap ...]
[--output ...]
[--output-ps ...]
[--output-zswap ...]
contractAddress,
circuitId,
...argsExecutes a circuit on the contract and generates a serialized Intent describing a contract call. The circuit is
executed with the given ...args in the context of some prior state provided by the --input file path, and private
state found in the --input-ps file path. Optionally, Zswap data describing coins can be provided via a JSON file
via the --input-ps file path.
As with the previously described 'deploy' command, the --output-* options provide file paths to the outputs in
the same way.
Options
--input pathToStateInput. The required file path to the serialized state data.
The state data is provided as part of the context given to the executing circuit.--input-ps pathToPrivateStateInput. The required file path to the private state data.
Private state is provided to the associated Witness implementations.--input-zswap pathToZswapLocalStateInput. The file path to the the local Zswap state data.
If not provided, then empty Zswap local state data will be provided to the circuit.--output pathToStateOutput. The file path to where the serializedIntentdata should be written.
Defaults to'output.bin'in the current working folder.--output-ps pathToPrivateStateOutput. The file path to where the private state data should be written.
Defaults to'output.ps.json'in the current working folder.--output-zswap pathToZswapLocalStateOutput. The file path to where the the local Zswap state data should be written.
Defaults to'zswap.json'in the current working folder.
Contract Arguments
Compact allows contract constructors and circuits to receive arguments. As described in the
Compact Language Reference
Compact types are mapped to TypeScript equivalents, and each command attempts to process its ...args based on
the associated TypeScript type. Internally, the previously mentioned TypeScript declaration file (generated by
compactc), is reflected over to determine the required TypeScript argument types. Each argument provided in
...args is then parsed according to its TypeScript type before being presented to the Compact runtime.
Tuples & Objects
Tuples and object literals (Compact structs) can be written by enclosing them in quotes:
... "[100n, 200n, true]" ...... "{a: 100n, b: 200n, c: false}" ...
Nested tuples and nested object literals are supported:
... "[100n, [200n, 300n], true]" ...... "{a: 100n, b: {bx: true, by: false}, c: false}" ...... "[100n, {a: 200n, b: false}, true]" ...... "{a: 100n, b: [true, false], c: false}" ...
Strings
Since command line arguments are implicitly string types, you can pass them as is. Obviously, if the string has to contain whitespace then it should be enclosed in quotes as it would for any command line argument:
... AString ...... "A longer string" ...
When used in Tuple types or object literals, since the enclosing type requires enclosing quotes, strings should be enclosed in single quotes:
... "[100n, 'AString']" ...... "[100n, 'A longer string']" ...... "{a: 100n, b: 'AString'}" ...... "{a: 100n, b: 'A longer string'}" ...
