@sig-net/midnight-contract-deploy 0.0.3
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/deploy-signet-contract.d.ts +24 -0
- package/dist/deploy-signet-contract.d.ts.map +1 -0
- package/dist/deploy-signet-contract.js +47 -0
- package/dist/deploy-signet-contract.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/plumbing/deploy.d.ts +82 -0
- package/dist/plumbing/deploy.d.ts.map +1 -0
- package/dist/plumbing/deploy.js +125 -0
- package/dist/plumbing/deploy.js.map +1 -0
- package/dist/plumbing/midnight-node-config.d.ts +33 -0
- package/dist/plumbing/midnight-node-config.d.ts.map +1 -0
- package/dist/plumbing/midnight-node-config.js +72 -0
- package/dist/plumbing/midnight-node-config.js.map +1 -0
- package/dist/plumbing/network-id.d.ts +5 -0
- package/dist/plumbing/network-id.d.ts.map +1 -0
- package/dist/plumbing/network-id.js +8 -0
- package/dist/plumbing/network-id.js.map +1 -0
- package/dist/plumbing/seed.d.ts +44 -0
- package/dist/plumbing/seed.d.ts.map +1 -0
- package/dist/plumbing/seed.js +77 -0
- package/dist/plumbing/seed.js.map +1 -0
- package/dist/plumbing/wallet.d.ts +90 -0
- package/dist/plumbing/wallet.d.ts.map +1 -0
- package/dist/plumbing/wallet.js +171 -0
- package/dist/plumbing/wallet.js.map +1 -0
- package/dist/signet-contract-binding.d.ts +11 -0
- package/dist/signet-contract-binding.d.ts.map +1 -0
- package/dist/signet-contract-binding.js +30 -0
- package/dist/signet-contract-binding.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type TransactionIdentifier } from "./plumbing/wallet.ts";
|
|
2
|
+
/** The outcome of a successful signet-contract deployment. */
|
|
3
|
+
export interface SignetContractDeployment {
|
|
4
|
+
/** Address of the deployed signet contract on Midnight. */
|
|
5
|
+
contractAddress: string;
|
|
6
|
+
/** Identifier of the submitted deploy transaction. */
|
|
7
|
+
txId: TransactionIdentifier;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deploy the signet contract: read config from `env`, build and prove the
|
|
11
|
+
* deploy transaction and submit it through a synced wallet. Progress is
|
|
12
|
+
* logged to the console. The one constructor argument is the MPC attestation
|
|
13
|
+
* key (`MPC_JUBJUB_PK`, "x,y" decimal or 0x-hex field coordinates),
|
|
14
|
+
* whose hash the contract seals — remote execution responses must be signed
|
|
15
|
+
* by it. Any funded wallet can deploy; nothing about the deployer is sealed.
|
|
16
|
+
*
|
|
17
|
+
* @param env - Environment map providing `DEPLOYER_SEED`,
|
|
18
|
+
* `MPC_JUBJUB_PK` and the shared Midnight node configuration (see `getMidnightNodeConfig`).
|
|
19
|
+
* @returns The deployed contract address and deploy transaction id.
|
|
20
|
+
* @throws If `MPC_JUBJUB_PK` is missing/malformed, the deployer
|
|
21
|
+
* wallet holds no funds, or submission fails.
|
|
22
|
+
*/
|
|
23
|
+
export declare function deploySignetContract(env?: Record<string, string | undefined>): Promise<SignetContractDeployment>;
|
|
24
|
+
//# sourceMappingURL=deploy-signet-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-signet-contract.d.ts","sourceRoot":"","sources":["../src/deploy-signet-contract.ts"],"names":[],"mappings":"AAaA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAC;AAM9B,8DAA8D;AAC9D,MAAM,WAAW,wBAAwB;IACvC,2DAA2D;IAC3D,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,IAAI,EAAE,qBAAqB,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,OAAO,CAAC,wBAAwB,CAAC,CA2CnC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Signet-contract deploy flow: builds, balances, proves and submits the
|
|
2
|
+
// contract's deploy transaction using the generic plumbing in ./plumbing.
|
|
3
|
+
// Everything contract-specific lives HERE: the MPC attestation key
|
|
4
|
+
// constructor arg and the (empty) private state. Requires the contract
|
|
5
|
+
// package's compiled assets to carry keys (its published dist/managed
|
|
6
|
+
// always does; an in-repo checkout needs `yarn compile:zk`).
|
|
7
|
+
import { parseJubjubPublicKey } from "@sig-net/midnight";
|
|
8
|
+
import { assertDeployerFunded, buildDeployTransaction, getDeployConfig, } from "./plumbing/deploy.js";
|
|
9
|
+
import { deriveAccountKeys, submitUnprovenTransaction, withSyncedWalletFacade, } from "./plumbing/wallet.js";
|
|
10
|
+
import { createSignetContractPrivateState, signetContractCompiledContract, } from "./signet-contract-binding.js";
|
|
11
|
+
/**
|
|
12
|
+
* Deploy the signet contract: read config from `env`, build and prove the
|
|
13
|
+
* deploy transaction and submit it through a synced wallet. Progress is
|
|
14
|
+
* logged to the console. The one constructor argument is the MPC attestation
|
|
15
|
+
* key (`MPC_JUBJUB_PK`, "x,y" decimal or 0x-hex field coordinates),
|
|
16
|
+
* whose hash the contract seals — remote execution responses must be signed
|
|
17
|
+
* by it. Any funded wallet can deploy; nothing about the deployer is sealed.
|
|
18
|
+
*
|
|
19
|
+
* @param env - Environment map providing `DEPLOYER_SEED`,
|
|
20
|
+
* `MPC_JUBJUB_PK` and the shared Midnight node configuration (see `getMidnightNodeConfig`).
|
|
21
|
+
* @returns The deployed contract address and deploy transaction id.
|
|
22
|
+
* @throws If `MPC_JUBJUB_PK` is missing/malformed, the deployer
|
|
23
|
+
* wallet holds no funds, or submission fails.
|
|
24
|
+
*/
|
|
25
|
+
export async function deploySignetContract(env = process.env) {
|
|
26
|
+
const deployConfig = getDeployConfig(env);
|
|
27
|
+
const { networkId } = deployConfig.midnightNodeConfig;
|
|
28
|
+
const mpcPkRaw = env.MPC_JUBJUB_PK?.trim();
|
|
29
|
+
if (!mpcPkRaw) {
|
|
30
|
+
throw new Error("MPC_JUBJUB_PK is required (the MPC attestation key, as \"x,y\")");
|
|
31
|
+
}
|
|
32
|
+
const mpcPk = parseJubjubPublicKey(mpcPkRaw);
|
|
33
|
+
const accountKeys = deriveAccountKeys(deployConfig.deployerSeed, networkId);
|
|
34
|
+
console.log(`deploying signet-contract to ${networkId} (${deployConfig.midnightNodeConfig.nodeUrl})`);
|
|
35
|
+
console.log(`mpc attestation key: x=${mpcPk.x} y=${mpcPk.y}`);
|
|
36
|
+
const { contractAddress, txId } = await withSyncedWalletFacade(accountKeys, deployConfig.midnightNodeConfig, async (facade, state) => {
|
|
37
|
+
assertDeployerFunded(state);
|
|
38
|
+
const deployTransaction = await buildDeployTransaction(signetContractCompiledContract, networkId, accountKeys.shieldedSecretKeys.coinPublicKey, createSignetContractPrivateState(), mpcPk);
|
|
39
|
+
console.log(`contract address (pre-submit): ${deployTransaction.contractAddress}`);
|
|
40
|
+
const submittedTxId = await submitUnprovenTransaction(facade, accountKeys, deployTransaction.serializedTransaction);
|
|
41
|
+
return { contractAddress: deployTransaction.contractAddress, txId: submittedTxId };
|
|
42
|
+
});
|
|
43
|
+
console.log(`submitted deploy tx ${txId}`);
|
|
44
|
+
console.log(`deployed signet-contract at ${contractAddress}`);
|
|
45
|
+
return { contractAddress, txId };
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=deploy-signet-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-signet-contract.js","sourceRoot":"","sources":["../src/deploy-signet-contract.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,0EAA0E;AAC1E,mEAAmE;AACnE,uEAAuE;AACvE,sEAAsE;AACtE,6DAA6D;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,GAEvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,8BAA8B,CAAC;AAUtC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,kBAAkB,CAAC;IAEtD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,KAAK,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,iBAAiB,CAAC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAE5E,OAAO,CAAC,GAAG,CAAC,gCAAgC,SAAS,KAAK,YAAY,CAAC,kBAAkB,CAAC,OAAO,GAAG,CAAC,CAAC;IACtG,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAE9D,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,MAAM,sBAAsB,CAC5D,WAAW,EACX,YAAY,CAAC,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;QACtB,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAE5B,MAAM,iBAAiB,GAAG,MAAM,sBAAsB,CACpD,8BAA8B,EAC9B,SAAS,EACT,WAAW,CAAC,kBAAkB,CAAC,aAAa,EAC5C,gCAAgC,EAAE,EAClC,KAAK,CACN,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,kCAAkC,iBAAiB,CAAC,eAAe,EAAE,CAAC,CAAC;QAEnF,MAAM,aAAa,GAAG,MAAM,yBAAyB,CACnD,MAAM,EACN,WAAW,EACX,iBAAiB,CAAC,qBAAqB,CACxC,CAAC;QACF,OAAO,EAAE,eAAe,EAAE,iBAAiB,CAAC,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACrF,CAAC,CACF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,+BAA+B,eAAe,EAAE,CAAC,CAAC;IAE9D,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./deploy-signet-contract.ts";
|
|
2
|
+
export * from "./signet-contract-binding.ts";
|
|
3
|
+
export * from "./plumbing/network-id.ts";
|
|
4
|
+
export * from "./plumbing/midnight-node-config.ts";
|
|
5
|
+
export * from "./plumbing/seed.ts";
|
|
6
|
+
export * from "./plumbing/wallet.ts";
|
|
7
|
+
export * from "./plumbing/deploy.ts";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Deploy tooling for the central signet contract, self-contained for npm:
|
|
2
|
+
// the operator deploy flow, the Node binding of @sig-net/midnight-contract
|
|
3
|
+
// to its compiled assets, and the generic Midnight deploy/wallet plumbing
|
|
4
|
+
// (config, seed parsing, key derivation, wallet facade, unproven-tx
|
|
5
|
+
// build/submit) the flow is built from. The plumbing is generic on purpose —
|
|
6
|
+
// any contract package's deploy script composes it.
|
|
7
|
+
export * from "./deploy-signet-contract.js";
|
|
8
|
+
export * from "./signet-contract-binding.js";
|
|
9
|
+
export * from "./plumbing/network-id.js";
|
|
10
|
+
export * from "./plumbing/midnight-node-config.js";
|
|
11
|
+
export * from "./plumbing/seed.js";
|
|
12
|
+
export * from "./plumbing/wallet.js";
|
|
13
|
+
export * from "./plumbing/deploy.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,oEAAoE;AACpE,6EAA6E;AAC7E,oDAAoD;AAEpD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,oCAAoC,CAAC;AACnD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { CompiledContract, Contract } from "@midnight-ntwrk/compact-js/effect";
|
|
2
|
+
import type { FacadeState } from "@midnightntwrk/wallet-sdk-facade";
|
|
3
|
+
import { type Types } from "effect";
|
|
4
|
+
import { type MidnightNodeConfig } from "./midnight-node-config.ts";
|
|
5
|
+
import type { NetworkId } from "./network-id.ts";
|
|
6
|
+
/** Everything needed to perform a contract deploy: which stack to target, and which wallet pays for it. */
|
|
7
|
+
export interface DeployConfig {
|
|
8
|
+
/** The stack (node/indexer/proof-server endpoints + network id) to deploy to. */
|
|
9
|
+
readonly midnightNodeConfig: MidnightNodeConfig;
|
|
10
|
+
/** Seed (hex or mnemonic) of the wallet that funds & signs the deploy. */
|
|
11
|
+
readonly deployerSeed: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read a {@link DeployConfig} from the environment. Every variable is
|
|
15
|
+
* optional: node config per {@link getMidnightNodeConfig}, plus
|
|
16
|
+
* `DEPLOYER_SEED` (hex or mnemonic) defaulting to the genesis mint wallet.
|
|
17
|
+
*
|
|
18
|
+
* @param env - The environment to read from; defaults to `process.env`.
|
|
19
|
+
* @returns The resolved deploy configuration.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getDeployConfig(env?: Record<string, string | undefined>): DeployConfig;
|
|
22
|
+
/** An unproven contract-deploy transaction, ready to balance/sign/prove/submit via a wallet. */
|
|
23
|
+
export interface DeployTransaction {
|
|
24
|
+
/** The contract address this deployment will create, known before submission. */
|
|
25
|
+
readonly contractAddress: string;
|
|
26
|
+
/** The serialized unproven transaction — see `submitUnprovenTransaction` in wallet.ts. */
|
|
27
|
+
readonly serializedTransaction: Uint8Array;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Bind a generated Compact contract to its witnesses and compiled assets.
|
|
31
|
+
*
|
|
32
|
+
* Thin typed wrapper over the compact-js `CompiledContract` combinators so
|
|
33
|
+
* contract packages need no direct compact-js dependency. Chained data-first
|
|
34
|
+
* on purpose: the witness/asset combinators rebuild the binding via object
|
|
35
|
+
* spread, which drops the prototype carrying `.pipe`.
|
|
36
|
+
*
|
|
37
|
+
* @param tag - Identifier for the binding (not the on-chain address), e.g. the contract name.
|
|
38
|
+
* @param ctor - The `Contract` class exported by the generated `managed/contract` module.
|
|
39
|
+
* @param witnesses - The contract's real witness implementations (from the package's `witnesses.ts`).
|
|
40
|
+
* @param managedDirPath - Absolute path to the compiler output dir (`contract/`, `zkir/`, `keys/`, `compiler/`).
|
|
41
|
+
* @returns The fully-bound {@link CompiledContract.CompiledContract}, ready for {@link buildDeployTransaction}.
|
|
42
|
+
*/
|
|
43
|
+
export declare function makeCompiledContract<C extends Contract.Contract<PS>, PS>(tag: string, ctor: Types.Ctor<C>, witnesses: Contract.Contract.Witnesses<C>, managedDirPath: string): CompiledContract.CompiledContract<C, PS>;
|
|
44
|
+
/**
|
|
45
|
+
* Bind a generated Compact contract that declares NO witnesses to its
|
|
46
|
+
* compiled assets. Counterpart to {@link makeCompiledContract}: compact-js
|
|
47
|
+
* types `Contract.Witnesses<C>` as `never` when the generated witness shape
|
|
48
|
+
* is empty, so witness-less contracts must bind via `withVacantWitnesses`
|
|
49
|
+
* rather than passing an empty object.
|
|
50
|
+
*
|
|
51
|
+
* @param tag - Identifier for the binding (not the on-chain address), e.g. the contract name.
|
|
52
|
+
* @param ctor - The `Contract` class exported by the generated `managed/contract` module.
|
|
53
|
+
* @param managedDirPath - Absolute path to the compiler output dir (`contract/`, `zkir/`, `keys/`, `compiler/`).
|
|
54
|
+
* @returns The fully-bound {@link CompiledContract.CompiledContract}, ready for {@link buildDeployTransaction}.
|
|
55
|
+
*/
|
|
56
|
+
export declare function makeVacantCompiledContract<C extends Contract.Contract<PS>, PS>(tag: string, ctor: Types.Ctor<C>, managedDirPath: string): CompiledContract.CompiledContract<C, PS>;
|
|
57
|
+
/**
|
|
58
|
+
* Build an UNPROVEN contract-deploy transaction: run the Compact constructor
|
|
59
|
+
* with `constructorArgs`, attach the verifier keys from the compiled assets,
|
|
60
|
+
* and wrap the resulting contract state in a deploy intent. Touches no
|
|
61
|
+
* network and no wallet — the only wallet-derived input is the deployer's
|
|
62
|
+
* coin public key, which feeds the constructor's context.
|
|
63
|
+
*
|
|
64
|
+
* @param compiledContract - The bound contract, from {@link makeCompiledContract}.
|
|
65
|
+
* @param networkId - The network the transaction targets.
|
|
66
|
+
* @param coinPublicKeyHex - The deploying wallet's Zswap coin public key (hex).
|
|
67
|
+
* @param initialPrivateState - The private state the constructor (and its witnesses, if any) runs against.
|
|
68
|
+
* @param constructorArgs - The contract's constructor arguments, statically typed per contract.
|
|
69
|
+
* @returns The deterministic contract address plus the serialized unproven transaction.
|
|
70
|
+
* @throws If the constructor traps, or the verifier keys are missing from the
|
|
71
|
+
* compiled assets (run `compile:zk` — the default `--skip-zk` output has none).
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildDeployTransaction<C extends Contract.Contract<PS>, PS>(compiledContract: CompiledContract.CompiledContract<C, PS>, networkId: NetworkId, coinPublicKeyHex: string, initialPrivateState: PS, ...constructorArgs: Contract.Contract.InitializeParameters<C>): Promise<DeployTransaction>;
|
|
74
|
+
/**
|
|
75
|
+
* Fail fast when the deployer wallet cannot pay for a transaction: fees are
|
|
76
|
+
* paid in DUST, which only generates on NIGHT registered for dust generation.
|
|
77
|
+
*
|
|
78
|
+
* @param state - The synced facade state to inspect (see `withSyncedWalletFacade` in wallet.ts).
|
|
79
|
+
* @throws If the deployer's spendable DUST balance is zero.
|
|
80
|
+
*/
|
|
81
|
+
export declare function assertDeployerFunded(state: FacadeState): void;
|
|
82
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/plumbing/deploy.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAsB,MAAM,mCAAmC,CAAC;AAKnG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE3D,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,2GAA2G;AAC3G,MAAM,WAAW,YAAY;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAChD,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAMD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,YAAY,CAKnG;AAED,gGAAgG;AAChG,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,qBAAqB,EAAE,UAAU,CAAC;CAC5C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EACtE,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EACzC,cAAc,EAAE,MAAM,GACrB,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAI1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAC5E,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EACnB,cAAc,EAAE,MAAM,GACrB,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,CAI1C;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,SAAS,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,EAC9E,gBAAgB,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,CAAC,EAC1D,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,EAAE,EACvB,GAAG,eAAe,EAAE,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,GAC5D,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAQ7D"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Contract-deploy plumbing shared by every contract package's deploy script
|
|
2
|
+
// (ported from midday app/ui/lib/actions/buildDeployTransaction.ts): the
|
|
3
|
+
// deploy config, the compiled-contract binding, and building the unproven
|
|
4
|
+
// deploy transaction. Everything contract-SPECIFIC — constructor args, witness
|
|
5
|
+
// implementations, initial private state — stays in the contract package's own
|
|
6
|
+
// deploy.ts and arrives here through the type parameters.
|
|
7
|
+
import { NodeContext } from "@effect/platform-node";
|
|
8
|
+
import { CompiledContract, Contract, ContractExecutable } from "@midnight-ntwrk/compact-js/effect";
|
|
9
|
+
import { ZKFileConfiguration } from "@midnight-ntwrk/compact-js-node/effect";
|
|
10
|
+
import * as ledger from "@midnightntwrk/ledger-v9";
|
|
11
|
+
import * as Configuration from "@midnight-ntwrk/platform-js/effect/Configuration";
|
|
12
|
+
import * as CoinPublicKey from "@midnight-ntwrk/platform-js/effect/CoinPublicKey";
|
|
13
|
+
import { Effect, Layer, Option } from "effect";
|
|
14
|
+
import { getMidnightNodeConfig } from "./midnight-node-config.js";
|
|
15
|
+
// Pre-funded genesis wallet of the local standalone stack — the default
|
|
16
|
+
// deployer for development.
|
|
17
|
+
const GENESIS_MINT_WALLET_SEED = "0000000000000000000000000000000000000000000000000000000000000001";
|
|
18
|
+
/**
|
|
19
|
+
* Read a {@link DeployConfig} from the environment. Every variable is
|
|
20
|
+
* optional: node config per {@link getMidnightNodeConfig}, plus
|
|
21
|
+
* `DEPLOYER_SEED` (hex or mnemonic) defaulting to the genesis mint wallet.
|
|
22
|
+
*
|
|
23
|
+
* @param env - The environment to read from; defaults to `process.env`.
|
|
24
|
+
* @returns The resolved deploy configuration.
|
|
25
|
+
*/
|
|
26
|
+
export function getDeployConfig(env = process.env) {
|
|
27
|
+
return {
|
|
28
|
+
midnightNodeConfig: getMidnightNodeConfig(env),
|
|
29
|
+
deployerSeed: env.DEPLOYER_SEED?.trim() || GENESIS_MINT_WALLET_SEED,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Bind a generated Compact contract to its witnesses and compiled assets.
|
|
34
|
+
*
|
|
35
|
+
* Thin typed wrapper over the compact-js `CompiledContract` combinators so
|
|
36
|
+
* contract packages need no direct compact-js dependency. Chained data-first
|
|
37
|
+
* on purpose: the witness/asset combinators rebuild the binding via object
|
|
38
|
+
* spread, which drops the prototype carrying `.pipe`.
|
|
39
|
+
*
|
|
40
|
+
* @param tag - Identifier for the binding (not the on-chain address), e.g. the contract name.
|
|
41
|
+
* @param ctor - The `Contract` class exported by the generated `managed/contract` module.
|
|
42
|
+
* @param witnesses - The contract's real witness implementations (from the package's `witnesses.ts`).
|
|
43
|
+
* @param managedDirPath - Absolute path to the compiler output dir (`contract/`, `zkir/`, `keys/`, `compiler/`).
|
|
44
|
+
* @returns The fully-bound {@link CompiledContract.CompiledContract}, ready for {@link buildDeployTransaction}.
|
|
45
|
+
*/
|
|
46
|
+
export function makeCompiledContract(tag, ctor, witnesses, managedDirPath) {
|
|
47
|
+
const base = CompiledContract.make(tag, ctor);
|
|
48
|
+
const withWitnesses = CompiledContract.withWitnesses(base, witnesses);
|
|
49
|
+
return CompiledContract.withCompiledFileAssets(withWitnesses, managedDirPath);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Bind a generated Compact contract that declares NO witnesses to its
|
|
53
|
+
* compiled assets. Counterpart to {@link makeCompiledContract}: compact-js
|
|
54
|
+
* types `Contract.Witnesses<C>` as `never` when the generated witness shape
|
|
55
|
+
* is empty, so witness-less contracts must bind via `withVacantWitnesses`
|
|
56
|
+
* rather than passing an empty object.
|
|
57
|
+
*
|
|
58
|
+
* @param tag - Identifier for the binding (not the on-chain address), e.g. the contract name.
|
|
59
|
+
* @param ctor - The `Contract` class exported by the generated `managed/contract` module.
|
|
60
|
+
* @param managedDirPath - Absolute path to the compiler output dir (`contract/`, `zkir/`, `keys/`, `compiler/`).
|
|
61
|
+
* @returns The fully-bound {@link CompiledContract.CompiledContract}, ready for {@link buildDeployTransaction}.
|
|
62
|
+
*/
|
|
63
|
+
export function makeVacantCompiledContract(tag, ctor, managedDirPath) {
|
|
64
|
+
const base = CompiledContract.make(tag, ctor);
|
|
65
|
+
const vacant = CompiledContract.withVacantWitnesses(base);
|
|
66
|
+
return CompiledContract.withCompiledFileAssets(vacant, managedDirPath);
|
|
67
|
+
}
|
|
68
|
+
// How long the deploy intent stays valid before it must be re-built.
|
|
69
|
+
const DEPLOY_TTL_MS = 30 * 60 * 1000;
|
|
70
|
+
/**
|
|
71
|
+
* Build an UNPROVEN contract-deploy transaction: run the Compact constructor
|
|
72
|
+
* with `constructorArgs`, attach the verifier keys from the compiled assets,
|
|
73
|
+
* and wrap the resulting contract state in a deploy intent. Touches no
|
|
74
|
+
* network and no wallet — the only wallet-derived input is the deployer's
|
|
75
|
+
* coin public key, which feeds the constructor's context.
|
|
76
|
+
*
|
|
77
|
+
* @param compiledContract - The bound contract, from {@link makeCompiledContract}.
|
|
78
|
+
* @param networkId - The network the transaction targets.
|
|
79
|
+
* @param coinPublicKeyHex - The deploying wallet's Zswap coin public key (hex).
|
|
80
|
+
* @param initialPrivateState - The private state the constructor (and its witnesses, if any) runs against.
|
|
81
|
+
* @param constructorArgs - The contract's constructor arguments, statically typed per contract.
|
|
82
|
+
* @returns The deterministic contract address plus the serialized unproven transaction.
|
|
83
|
+
* @throws If the constructor traps, or the verifier keys are missing from the
|
|
84
|
+
* compiled assets (run `compile:zk` — the default `--skip-zk` output has none).
|
|
85
|
+
*/
|
|
86
|
+
export async function buildDeployTransaction(compiledContract, networkId, coinPublicKeyHex, initialPrivateState, ...constructorArgs) {
|
|
87
|
+
// initialize() needs the deployer's coin public key (for the constructor
|
|
88
|
+
// context) and a signing key for the contract maintenance authority.
|
|
89
|
+
// Option.none() makes the SDK sample a fresh CMA key (discarded — the
|
|
90
|
+
// contract can't be maintained later, which is fine for now).
|
|
91
|
+
const keysLayer = Layer.succeed(Configuration.Keys, {
|
|
92
|
+
coinPublicKey: CoinPublicKey.Hex(coinPublicKeyHex),
|
|
93
|
+
getSigningKey: () => Option.none(),
|
|
94
|
+
});
|
|
95
|
+
// Run the contract constructor and attach verifier keys → initial ContractState.
|
|
96
|
+
const deployResult = await Effect.runPromise(ContractExecutable.make(compiledContract)
|
|
97
|
+
.initialize(initialPrivateState, ...constructorArgs)
|
|
98
|
+
.pipe(Effect.provide(ZKFileConfiguration.layer(CompiledContract.getCompiledAssetsPath(compiledContract))), Effect.provide(NodeContext.layer), Effect.provide(keysLayer)));
|
|
99
|
+
// `initialize` yields an onchain-runtime ContractState; bridge it to the
|
|
100
|
+
// ledger's ContractState (separate package/type) via its serialized form.
|
|
101
|
+
const contractState = ledger.ContractState.deserialize(deployResult.public.contractState.serialize());
|
|
102
|
+
const deploy = new ledger.ContractDeploy(contractState);
|
|
103
|
+
const intent = ledger.Intent.new(new Date(Date.now() + DEPLOY_TTL_MS)).addDeploy(deploy);
|
|
104
|
+
const transaction = ledger.Transaction.fromPartsRandomized(networkId, undefined, undefined, intent);
|
|
105
|
+
return {
|
|
106
|
+
contractAddress: deploy.address,
|
|
107
|
+
serializedTransaction: transaction.serialize(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Fail fast when the deployer wallet cannot pay for a transaction: fees are
|
|
112
|
+
* paid in DUST, which only generates on NIGHT registered for dust generation.
|
|
113
|
+
*
|
|
114
|
+
* @param state - The synced facade state to inspect (see `withSyncedWalletFacade` in wallet.ts).
|
|
115
|
+
* @throws If the deployer's spendable DUST balance is zero.
|
|
116
|
+
*/
|
|
117
|
+
export function assertDeployerFunded(state) {
|
|
118
|
+
const dust = state.dust.balance(new Date());
|
|
119
|
+
if (dust > 0n)
|
|
120
|
+
return;
|
|
121
|
+
const night = Object.values(state.unshielded.balances).reduce((sum, value) => sum + value, 0n);
|
|
122
|
+
throw new Error(`deployer wallet has no DUST to pay fees (NIGHT balance: ${night}). ` +
|
|
123
|
+
"Fund the wallet with NIGHT and register it for dust generation, then retry.");
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/plumbing/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type NetworkId } from "./network-id.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The set of endpoints (+ network id) needed to reach the chain. Plain data,
|
|
4
|
+
* so it can be handed to domain classes/functions by argument rather than
|
|
5
|
+
* having them reach for a global. A seed is intentionally NOT part of this:
|
|
6
|
+
* this config describes a *network*, while a seed identifies a *wallet*.
|
|
7
|
+
*/
|
|
8
|
+
export interface MidnightNodeConfig {
|
|
9
|
+
readonly indexerUrl: string;
|
|
10
|
+
readonly indexerWsUrl: string;
|
|
11
|
+
readonly nodeUrl: string;
|
|
12
|
+
readonly proofServerUrl: string;
|
|
13
|
+
readonly networkId: NetworkId;
|
|
14
|
+
}
|
|
15
|
+
export type Endpoints = Omit<MidnightNodeConfig, "networkId">;
|
|
16
|
+
export declare const LOCAL_PROOF_SERVER = "http://127.0.0.1:6300";
|
|
17
|
+
export declare const DEFAULT_ENDPOINTS: Record<NetworkId, Endpoints>;
|
|
18
|
+
export declare function indexerWsUrlFromIndexerUrl(indexerUrl: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Read a {@link MidnightNodeConfig} from the environment. Every variable is
|
|
21
|
+
* optional — with nothing set this yields the local "undeployed" stack.
|
|
22
|
+
*
|
|
23
|
+
* Parse flow:
|
|
24
|
+
* 1. `NETWORK_ID` (default "undeployed", validated against {@link NETWORK_IDS})
|
|
25
|
+
* selects the {@link DEFAULT_ENDPOINTS} baseline.
|
|
26
|
+
* 2. Per-URL overrides then replace individual baseline endpoints:
|
|
27
|
+
* `MIDNIGHT_NODE_URL`, `MIDNIGHT_NODE_INDEXER_URL`,
|
|
28
|
+
* `MIDNIGHT_NODE_INDEXER_WS_URL`, `MIDNIGHT_NODE_PROOF_SERVER_URL`.
|
|
29
|
+
* When the indexer URL is overridden without a WS override, the WS URL is
|
|
30
|
+
* derived from it instead of keeping the baseline host.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getMidnightNodeConfig(env?: Record<string, string | undefined>): MidnightNodeConfig;
|
|
33
|
+
//# sourceMappingURL=midnight-node-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midnight-node-config.d.ts","sourceRoot":"","sources":["../../src/plumbing/midnight-node-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;AAI9D,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAI1D,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAyB1D,CAAC;AAIF,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,kBAAkB,CAmBpB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Midnight node connection config — everything needed to talk to one Midnight
|
|
2
|
+
import { NETWORK_IDS } from "./network-id.js";
|
|
3
|
+
// The proof server sees private witness data, so it is always run locally
|
|
4
|
+
// rather than against a remote host.
|
|
5
|
+
export const LOCAL_PROOF_SERVER = "http://127.0.0.1:6300";
|
|
6
|
+
// Default endpoints per network. Undeployed is the local standalone stack
|
|
7
|
+
// (Docker containers) run during development.
|
|
8
|
+
export const DEFAULT_ENDPOINTS = {
|
|
9
|
+
["undeployed"]: {
|
|
10
|
+
indexerUrl: "http://127.0.0.1:8088/api/v3/graphql",
|
|
11
|
+
indexerWsUrl: "ws://127.0.0.1:8088/api/v3/graphql/ws",
|
|
12
|
+
nodeUrl: "http://127.0.0.1:9944",
|
|
13
|
+
proofServerUrl: LOCAL_PROOF_SERVER,
|
|
14
|
+
},
|
|
15
|
+
["preview"]: {
|
|
16
|
+
indexerUrl: "https://indexer.preview.midnight.network/api/v3/graphql",
|
|
17
|
+
indexerWsUrl: "wss://indexer.preview.midnight.network/api/v3/graphql/ws",
|
|
18
|
+
nodeUrl: "https://rpc.preview.midnight.network",
|
|
19
|
+
proofServerUrl: LOCAL_PROOF_SERVER,
|
|
20
|
+
},
|
|
21
|
+
["preprod"]: {
|
|
22
|
+
indexerUrl: "https://indexer.preprod.midnight.network/api/v3/graphql",
|
|
23
|
+
indexerWsUrl: "wss://indexer.preprod.midnight.network/api/v3/graphql/ws",
|
|
24
|
+
nodeUrl: "https://rpc.preprod.midnight.network",
|
|
25
|
+
proofServerUrl: LOCAL_PROOF_SERVER,
|
|
26
|
+
},
|
|
27
|
+
["mainnet"]: {
|
|
28
|
+
indexerUrl: "https://indexer.mainnet.midnight.network/api/v3/graphql",
|
|
29
|
+
indexerWsUrl: "wss://indexer.mainnet.midnight.network/api/v3/graphql/ws",
|
|
30
|
+
nodeUrl: "https://rpc.mainnet.midnight.network",
|
|
31
|
+
proofServerUrl: LOCAL_PROOF_SERVER,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
// Derive the indexer WebSocket URL from the indexer HTTP URL: swap the scheme
|
|
35
|
+
// to ws(s) and append the "/ws" path segment the indexer expects.
|
|
36
|
+
export function indexerWsUrlFromIndexerUrl(indexerUrl) {
|
|
37
|
+
const url = new URL(indexerUrl);
|
|
38
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
39
|
+
url.pathname = `${url.pathname.replace(/\/$/, "")}/ws`;
|
|
40
|
+
return url.toString();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Read a {@link MidnightNodeConfig} from the environment. Every variable is
|
|
44
|
+
* optional — with nothing set this yields the local "undeployed" stack.
|
|
45
|
+
*
|
|
46
|
+
* Parse flow:
|
|
47
|
+
* 1. `NETWORK_ID` (default "undeployed", validated against {@link NETWORK_IDS})
|
|
48
|
+
* selects the {@link DEFAULT_ENDPOINTS} baseline.
|
|
49
|
+
* 2. Per-URL overrides then replace individual baseline endpoints:
|
|
50
|
+
* `MIDNIGHT_NODE_URL`, `MIDNIGHT_NODE_INDEXER_URL`,
|
|
51
|
+
* `MIDNIGHT_NODE_INDEXER_WS_URL`, `MIDNIGHT_NODE_PROOF_SERVER_URL`.
|
|
52
|
+
* When the indexer URL is overridden without a WS override, the WS URL is
|
|
53
|
+
* derived from it instead of keeping the baseline host.
|
|
54
|
+
*/
|
|
55
|
+
export function getMidnightNodeConfig(env = process.env) {
|
|
56
|
+
const networkId = env.NETWORK_ID?.trim() || "undeployed";
|
|
57
|
+
if (!NETWORK_IDS.includes(networkId)) {
|
|
58
|
+
throw new Error(`Invalid NETWORK_ID "${networkId}" — expected one of: ${NETWORK_IDS.join(", ")}.`);
|
|
59
|
+
}
|
|
60
|
+
const defaults = DEFAULT_ENDPOINTS[networkId];
|
|
61
|
+
const indexerUrl = env.MIDNIGHT_NODE_INDEXER_URL || defaults.indexerUrl;
|
|
62
|
+
const indexerWsUrl = env.MIDNIGHT_NODE_INDEXER_WS_URL ||
|
|
63
|
+
(env.MIDNIGHT_NODE_INDEXER_URL ? indexerWsUrlFromIndexerUrl(indexerUrl) : defaults.indexerWsUrl);
|
|
64
|
+
return {
|
|
65
|
+
networkId,
|
|
66
|
+
indexerUrl,
|
|
67
|
+
indexerWsUrl,
|
|
68
|
+
nodeUrl: env.MIDNIGHT_NODE_URL || defaults.nodeUrl,
|
|
69
|
+
proofServerUrl: env.MIDNIGHT_NODE_PROOF_SERVER_URL || defaults.proofServerUrl,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=midnight-node-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"midnight-node-config.js","sourceRoot":"","sources":["../../src/plumbing/midnight-node-config.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,WAAW,EAAkB,MAAM,iBAAiB,CAAC;AAkB9D,0EAA0E;AAC1E,qCAAqC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAE1D,0EAA0E;AAC1E,8CAA8C;AAC9C,MAAM,CAAC,MAAM,iBAAiB,GAAiC;IAC7D,CAAC,YAAY,CAAC,EAAE;QACd,UAAU,EAAE,sCAAsC;QAClD,YAAY,EAAE,uCAAuC;QACrD,OAAO,EAAE,uBAAuB;QAChC,cAAc,EAAE,kBAAkB;KACnC;IACD,CAAC,SAAS,CAAC,EAAE;QACX,UAAU,EAAE,yDAAyD;QACrE,YAAY,EAAE,0DAA0D;QACxE,OAAO,EAAE,sCAAsC;QAC/C,cAAc,EAAE,kBAAkB;KACnC;IACD,CAAC,SAAS,CAAC,EAAE;QACX,UAAU,EAAE,yDAAyD;QACrE,YAAY,EAAE,0DAA0D;QACxE,OAAO,EAAE,sCAAsC;QAC/C,cAAc,EAAE,kBAAkB;KACnC;IACD,CAAC,SAAS,CAAC,EAAE;QACX,UAAU,EAAE,yDAAyD;QACrE,YAAY,EAAE,0DAA0D;QACxE,OAAO,EAAE,sCAAsC;QAC/C,cAAc,EAAE,kBAAkB;KACnC;CACF,CAAC;AAEF,8EAA8E;AAC9E,kEAAkE;AAClE,MAAM,UAAU,0BAA0B,CAAC,UAAkB;IAC3D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAChC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,GAAG,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;IACvD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,SAAS,GAAc,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,YAAY,CAAC;IACpE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,wBAAwB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrG,CAAC;IAED,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,GAAG,CAAC,yBAAyB,IAAI,QAAQ,CAAC,UAAU,CAAC;IACxE,MAAM,YAAY,GAChB,GAAG,CAAC,4BAA4B;QAChC,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEnG,OAAO;QACL,SAAS;QACT,UAAU;QACV,YAAY;QACZ,OAAO,EAAE,GAAG,CAAC,iBAAiB,IAAI,QAAQ,CAAC,OAAO;QAClD,cAAc,EAAE,GAAG,CAAC,8BAA8B,IAAI,QAAQ,CAAC,cAAc;KAC9E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NetworkId as MidnightSDKNetworkId } from "@midnight-ntwrk/midnight-js/network-id";
|
|
2
|
+
/** A Midnight network id: the SDK's bare-string type plus our known named networks. */
|
|
3
|
+
export type NetworkId = MidnightSDKNetworkId | "undeployed" | "preview" | "preprod" | "mainnet";
|
|
4
|
+
export declare const NETWORK_IDS: readonly NetworkId[];
|
|
5
|
+
//# sourceMappingURL=network-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-id.d.ts","sourceRoot":"","sources":["../../src/plumbing/network-id.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,IAAI,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAEhG,uFAAuF;AACvF,MAAM,MAAM,SAAS,GAEjB,oBAAoB,GAEpB,YAAY,GAEZ,SAAS,GAET,SAAS,GAET,SAAS,CAAC;AAGd,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAK3C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-id.js","sourceRoot":"","sources":["../../src/plumbing/network-id.ts"],"names":[],"mappings":"AAoBA,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC7C,YAAY;IACZ,SAAS;IACT,SAAS;IACT,SAAS;CACZ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** How the input seed was supplied. (Const object + union — see network.ts.) */
|
|
2
|
+
export declare const SeedFormat: {
|
|
3
|
+
readonly Mnemonic: "mnemonic";
|
|
4
|
+
readonly Hex: "hex";
|
|
5
|
+
};
|
|
6
|
+
export type SeedFormat = (typeof SeedFormat)[keyof typeof SeedFormat];
|
|
7
|
+
/** Where a parsed seed came from, including its normalised hex form. */
|
|
8
|
+
export interface DerivationSource {
|
|
9
|
+
format: SeedFormat;
|
|
10
|
+
/** Word count, when the input was a mnemonic. */
|
|
11
|
+
words?: number;
|
|
12
|
+
/** The normalised hex of the seed bytes — the stable dedup key. */
|
|
13
|
+
seedHex: string;
|
|
14
|
+
seedBytes: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class ParseError extends Error {
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse `input` as a hex seed (16–64 bytes, optional 0x prefix) or a BIP-39
|
|
20
|
+
* mnemonic (run through PBKDF2 to its 64-byte seed). Throws {@link ParseError}
|
|
21
|
+
* when it is neither.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseSeed(input: string): {
|
|
24
|
+
seed: Uint8Array;
|
|
25
|
+
source: DerivationSource;
|
|
26
|
+
};
|
|
27
|
+
/** Generate a fresh random 24-word BIP-39 mnemonic (256 bits of entropy). */
|
|
28
|
+
export declare function generateMnemonic(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a 32-byte identity secret key from the environment: `env[envVar]`
|
|
31
|
+
* (hex, optional 0x prefix) when set, else the bytes of `fallbackSeed` (the
|
|
32
|
+
* wallet seed doubling as the identity). Contract packages use this for the
|
|
33
|
+
* secret whose commitment gates a circuit (e.g. the vault deployer identity),
|
|
34
|
+
* and clients use it for the caller identity answering a secret-key witness.
|
|
35
|
+
*
|
|
36
|
+
* @param envVar - Name of the environment variable holding the hex secret.
|
|
37
|
+
* @param env - The environment to read from.
|
|
38
|
+
* @param fallbackSeed - The wallet seed (hex or mnemonic) used as the identity when `env[envVar]` is unset.
|
|
39
|
+
* @returns The 32-byte secret key.
|
|
40
|
+
* @throws If `env[envVar]` is set but not 32 bytes of hex, or if it is unset
|
|
41
|
+
* and `fallbackSeed` does not parse to exactly 32 bytes (e.g. a mnemonic).
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseIdentitySecretKey(envVar: string, env: Record<string, string | undefined>, fallbackSeed: string): Uint8Array;
|
|
44
|
+
//# sourceMappingURL=seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/plumbing/seed.ts"],"names":[],"mappings":"AAQA,gFAAgF;AAChF,eAAO,MAAM,UAAU;;;CAGb,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAEtE,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAW,SAAQ,KAAK;CAAG;AAExC;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAyBvF;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,YAAY,EAAE,MAAM,GACnB,UAAU,CAiBZ"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Seed parsing — turns user input (a BIP-39 mnemonic or a raw hex seed) into
|
|
2
|
+
// the seed bytes the HD wallet derives from, plus a record of how it was
|
|
3
|
+
// supplied (so the normalised hex form can be used as a stable identifier).
|
|
4
|
+
import * as bip39 from "@scure/bip39";
|
|
5
|
+
import { wordlist as english } from "@scure/bip39/wordlists/english.js";
|
|
6
|
+
const toHex = (bytes) => Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
7
|
+
/** How the input seed was supplied. (Const object + union — see network.ts.) */
|
|
8
|
+
export const SeedFormat = {
|
|
9
|
+
Mnemonic: "mnemonic",
|
|
10
|
+
Hex: "hex",
|
|
11
|
+
};
|
|
12
|
+
export class ParseError extends Error {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Parse `input` as a hex seed (16–64 bytes, optional 0x prefix) or a BIP-39
|
|
16
|
+
* mnemonic (run through PBKDF2 to its 64-byte seed). Throws {@link ParseError}
|
|
17
|
+
* when it is neither.
|
|
18
|
+
*/
|
|
19
|
+
export function parseSeed(input) {
|
|
20
|
+
const trimmed = input.trim();
|
|
21
|
+
if (!trimmed)
|
|
22
|
+
throw new ParseError("Nothing to parse — generate or paste a seed first.");
|
|
23
|
+
const compact = trimmed.replace(/^0x/i, "");
|
|
24
|
+
const looksHex = /^[0-9a-fA-F]+$/.test(compact) && compact.length % 2 === 0;
|
|
25
|
+
if (looksHex) {
|
|
26
|
+
const bytes = compact.length / 2;
|
|
27
|
+
if (bytes < 16 || bytes > 64) {
|
|
28
|
+
throw new ParseError(`Hex seed must be 16–64 bytes; got ${bytes}.`);
|
|
29
|
+
}
|
|
30
|
+
const seed = Uint8Array.from(compact.match(/.{2}/g).map((h) => parseInt(h, 16)));
|
|
31
|
+
return { seed, source: { format: SeedFormat.Hex, seedHex: compact.toLowerCase(), seedBytes: bytes } };
|
|
32
|
+
}
|
|
33
|
+
const words = trimmed.split(/\s+/);
|
|
34
|
+
if (!bip39.validateMnemonic(words.join(" "), english)) {
|
|
35
|
+
throw new ParseError("Not a valid BIP-39 mnemonic (and not valid hex).");
|
|
36
|
+
}
|
|
37
|
+
const seed = bip39.mnemonicToSeedSync(words.join(" "));
|
|
38
|
+
return {
|
|
39
|
+
seed,
|
|
40
|
+
source: { format: SeedFormat.Mnemonic, words: words.length, seedHex: toHex(seed), seedBytes: seed.length },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Generate a fresh random 24-word BIP-39 mnemonic (256 bits of entropy). */
|
|
44
|
+
export function generateMnemonic() {
|
|
45
|
+
return bip39.generateMnemonic(english, 256);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a 32-byte identity secret key from the environment: `env[envVar]`
|
|
49
|
+
* (hex, optional 0x prefix) when set, else the bytes of `fallbackSeed` (the
|
|
50
|
+
* wallet seed doubling as the identity). Contract packages use this for the
|
|
51
|
+
* secret whose commitment gates a circuit (e.g. the vault deployer identity),
|
|
52
|
+
* and clients use it for the caller identity answering a secret-key witness.
|
|
53
|
+
*
|
|
54
|
+
* @param envVar - Name of the environment variable holding the hex secret.
|
|
55
|
+
* @param env - The environment to read from.
|
|
56
|
+
* @param fallbackSeed - The wallet seed (hex or mnemonic) used as the identity when `env[envVar]` is unset.
|
|
57
|
+
* @returns The 32-byte secret key.
|
|
58
|
+
* @throws If `env[envVar]` is set but not 32 bytes of hex, or if it is unset
|
|
59
|
+
* and `fallbackSeed` does not parse to exactly 32 bytes (e.g. a mnemonic).
|
|
60
|
+
*/
|
|
61
|
+
export function parseIdentitySecretKey(envVar, env, fallbackSeed) {
|
|
62
|
+
const raw = env[envVar]?.trim();
|
|
63
|
+
if (raw) {
|
|
64
|
+
const hex = raw.replace(/^0x/i, "");
|
|
65
|
+
if (!/^[0-9a-fA-F]{64}$/.test(hex)) {
|
|
66
|
+
throw new ParseError(`${envVar} must be exactly 32 bytes of hex`);
|
|
67
|
+
}
|
|
68
|
+
return Uint8Array.from(hex.match(/.{2}/g).map((byte) => parseInt(byte, 16)));
|
|
69
|
+
}
|
|
70
|
+
const { seed } = parseSeed(fallbackSeed);
|
|
71
|
+
if (seed.length !== 32) {
|
|
72
|
+
throw new ParseError(`The fallback seed parses to ${seed.length} bytes; the identity secret needs exactly 32. ` +
|
|
73
|
+
`Set ${envVar} explicitly.`);
|
|
74
|
+
}
|
|
75
|
+
return seed;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/plumbing/seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as ledger from "@midnightntwrk/ledger-v9";
|
|
2
|
+
import { WalletFacade, type FacadeState, type TransactionIdentifier } from "@midnightntwrk/wallet-sdk-facade";
|
|
3
|
+
import { type UnshieldedKeystore } from "@midnightntwrk/wallet-sdk-unshielded-wallet";
|
|
4
|
+
import type { MidnightNodeConfig } from "./midnight-node-config.ts";
|
|
5
|
+
import type { NetworkId } from "./network-id.ts";
|
|
6
|
+
export type { FacadeState, TransactionIdentifier, WalletFacade } from "@midnightntwrk/wallet-sdk-facade";
|
|
7
|
+
export type { EncPublicKey } from "@midnightntwrk/ledger-v9";
|
|
8
|
+
/** The live key material for one account. Reused for signing / balancing. */
|
|
9
|
+
export interface AccountKeys {
|
|
10
|
+
shieldedSecretKeys: ledger.ZswapSecretKeys;
|
|
11
|
+
dustSecretKey: ledger.DustSecretKey;
|
|
12
|
+
unshieldedKeystore: UnshieldedKeystore;
|
|
13
|
+
}
|
|
14
|
+
/** A wallet's three Midnight addresses, as bech32m strings. */
|
|
15
|
+
export interface WalletAddresses {
|
|
16
|
+
unshielded: string;
|
|
17
|
+
shielded: string;
|
|
18
|
+
dust: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The fee settings the facade balances transactions with: it burns
|
|
22
|
+
* `feesWithMargin(params, feeBlocksMargin) + additionalFeeOverhead` per
|
|
23
|
+
* transaction.
|
|
24
|
+
*/
|
|
25
|
+
export declare const COST_PARAMETERS: {
|
|
26
|
+
readonly additionalFeeOverhead: bigint;
|
|
27
|
+
readonly feeBlocksMargin: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Parse a seed and derive the three role keys (Zswap / NightExternal / Dust).
|
|
31
|
+
* Pure crypto — no network. This is the step that exercises the ledger WASM.
|
|
32
|
+
*/
|
|
33
|
+
export declare function deriveAccountKeys(seed: string, networkId: NetworkId): AccountKeys;
|
|
34
|
+
/** Compute the three bech32m addresses from the keys. Pure — no network. */
|
|
35
|
+
export declare function deriveAddresses(keys: AccountKeys, networkId: NetworkId): WalletAddresses;
|
|
36
|
+
/**
|
|
37
|
+
* Wire up the WalletFacade for the given keys + connection config. This only
|
|
38
|
+
* constructs the three sub-wallets — it does NOT start syncing.
|
|
39
|
+
*/
|
|
40
|
+
export declare function initialiseWalletFacade(keys: AccountKeys, config: MidnightNodeConfig): Promise<WalletFacade>;
|
|
41
|
+
/**
|
|
42
|
+
* Balance, sign, prove and submit a serialized unproven transaction (e.g. a
|
|
43
|
+
* contract deploy built by `buildDeployTransaction` in deploy.ts). Proving
|
|
44
|
+
* happens in `finalizeRecipe` via the facade's configured proof server.
|
|
45
|
+
*
|
|
46
|
+
* @param facade - A started (and synced) wallet facade that pays for and submits the transaction.
|
|
47
|
+
* @param keys - The key material of the same wallet, for balancing and signing.
|
|
48
|
+
* @param serializedTransaction - The unproven transaction bytes.
|
|
49
|
+
* @returns The submitted transaction's identifier.
|
|
50
|
+
* @throws If the wallet cannot cover fees, proving fails, or the node rejects the transaction.
|
|
51
|
+
*/
|
|
52
|
+
export declare function submitUnprovenTransaction(facade: WalletFacade, keys: AccountKeys, serializedTransaction: Uint8Array): Promise<TransactionIdentifier>;
|
|
53
|
+
/**
|
|
54
|
+
* Register every NIGHT UTXO not yet registered for dust generation, so the
|
|
55
|
+
* wallet can pay transaction fees (fees are paid in DUST, which only
|
|
56
|
+
* generates on registered NIGHT). Registers ONLY unregistered UTXOs — the
|
|
57
|
+
* node rejects a re-registration of an already-registered one — and submits
|
|
58
|
+
* nothing when there is nothing new to register.
|
|
59
|
+
*
|
|
60
|
+
* @param facade - A started wallet facade for `keys` (builds, proves and submits the registration).
|
|
61
|
+
* @param keys - The key material of the same wallet; its unshielded keystore signs the registration.
|
|
62
|
+
* @param state - The synced facade state to read the NIGHT UTXOs from.
|
|
63
|
+
* @returns How many NIGHT UTXOs this call registered (0 = nothing unregistered, including no NIGHT at all).
|
|
64
|
+
* @throws If the node rejects the registration transaction.
|
|
65
|
+
*/
|
|
66
|
+
export declare function registerNightForDustGeneration(facade: WalletFacade, keys: AccountKeys, state: FacadeState): Promise<number>;
|
|
67
|
+
/**
|
|
68
|
+
* Wait until the wallet's spendable DUST (fee) balance is positive, polling
|
|
69
|
+
* the synced facade state. Pair with {@link registerNightForDustGeneration}:
|
|
70
|
+
* a wallet whose NIGHT was just registered has no dust for a few blocks.
|
|
71
|
+
*
|
|
72
|
+
* @param facade - A started wallet facade.
|
|
73
|
+
* @param timeoutMs - Give-up deadline in milliseconds.
|
|
74
|
+
* @returns The first positive dust balance observed.
|
|
75
|
+
* @throws If no dust appears within `timeoutMs`.
|
|
76
|
+
*/
|
|
77
|
+
export declare function waitForSpendableDust(facade: WalletFacade, timeoutMs?: number): Promise<bigint>;
|
|
78
|
+
/**
|
|
79
|
+
* Run `fn` against a started-and-synced {@link WalletFacade}, then stop the
|
|
80
|
+
* facade — even when `fn` throws. The one place the start / wait-for-sync /
|
|
81
|
+
* stop boilerplate lives.
|
|
82
|
+
*
|
|
83
|
+
* @param keys - The account to open the facade for (see {@link deriveAccountKeys}).
|
|
84
|
+
* @param config - The stack the facade connects to.
|
|
85
|
+
* @param fn - Work to run with the live facade; receives the synced state for balance checks.
|
|
86
|
+
* @returns Whatever `fn` returns.
|
|
87
|
+
* @throws Whatever {@link initialiseWalletFacade}, the facade start/sync, or `fn` throws.
|
|
88
|
+
*/
|
|
89
|
+
export declare function withSyncedWalletFacade<T>(keys: AccountKeys, config: MidnightNodeConfig, fn: (facade: WalletFacade, state: FacadeState) => Promise<T>): Promise<T>;
|
|
90
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/plumbing/wallet.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAGL,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC3B,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,6CAA6C,CAAC;AAUrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKjD,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAIzG,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,MAAM,CAAC,eAAe,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;IACpC,kBAAkB,EAAE,kBAAkB,CAAC;CACxC;AAED,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE;IAAE,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CAGvG,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,WAAW,CAqBjF;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,eAAe,CAUxF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoB3G;AAKD;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,WAAW,EACjB,qBAAqB,EAAE,UAAU,GAChC,OAAO,CAAC,qBAAqB,CAAC,CAkBhC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,GAAE,MAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAa7G;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,kBAAkB,EAC1B,EAAE,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3D,OAAO,CAAC,CAAC,CAAC,CASZ"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// Seed → account construction utilities shared by every wallet host (the UI's
|
|
2
|
+
// SeedWallet and the integration tests' buildWallet): key derivation, address
|
|
3
|
+
// encoding and WalletFacade wiring. Pure crypto + facade construction — no
|
|
4
|
+
// network I/O happens here (the facade connects only when started).
|
|
5
|
+
import * as ledger from "@midnightntwrk/ledger-v9";
|
|
6
|
+
import { HDWallet, Roles } from "@midnightntwrk/wallet-sdk-hd";
|
|
7
|
+
import { mergeWalletEntries, WalletEntrySchema, WalletFacade, } from "@midnightntwrk/wallet-sdk-facade";
|
|
8
|
+
import { ShieldedWallet } from "@midnightntwrk/wallet-sdk-shielded";
|
|
9
|
+
import { DustWallet } from "@midnightntwrk/wallet-sdk-dust-wallet";
|
|
10
|
+
import { createKeystore, PublicKey as UnshieldedPublicKey, UnshieldedWallet, } from "@midnightntwrk/wallet-sdk-unshielded-wallet";
|
|
11
|
+
import { InMemoryTransactionHistoryStorage } from "@midnightntwrk/wallet-sdk-abstractions";
|
|
12
|
+
import { DustAddress, MidnightBech32m, ShieldedAddress, ShieldedCoinPublicKey, ShieldedEncryptionPublicKey, } from "@midnightntwrk/wallet-sdk-address-format";
|
|
13
|
+
import { parseSeed } from "./seed.js";
|
|
14
|
+
/**
|
|
15
|
+
* The fee settings the facade balances transactions with: it burns
|
|
16
|
+
* `feesWithMargin(params, feeBlocksMargin) + additionalFeeOverhead` per
|
|
17
|
+
* transaction.
|
|
18
|
+
*/
|
|
19
|
+
export const COST_PARAMETERS = {
|
|
20
|
+
additionalFeeOverhead: 300000000000n,
|
|
21
|
+
feeBlocksMargin: 5,
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Parse a seed and derive the three role keys (Zswap / NightExternal / Dust).
|
|
25
|
+
* Pure crypto — no network. This is the step that exercises the ledger WASM.
|
|
26
|
+
*/
|
|
27
|
+
export function deriveAccountKeys(seed, networkId) {
|
|
28
|
+
const { seed: seedBytes } = parseSeed(seed);
|
|
29
|
+
const hd = HDWallet.fromSeed(seedBytes);
|
|
30
|
+
if (hd.type !== "seedOk")
|
|
31
|
+
throw new Error("HDWallet.fromSeed failed (seedError).");
|
|
32
|
+
const derived = hd.hdWallet
|
|
33
|
+
.selectAccount(0)
|
|
34
|
+
.selectRoles([Roles.Zswap, Roles.NightExternal, Roles.Dust])
|
|
35
|
+
.deriveKeysAt(0);
|
|
36
|
+
if (derived.type !== "keysDerived")
|
|
37
|
+
throw new Error("deriveKeysAt failed (keyOutOfBounds).");
|
|
38
|
+
hd.hdWallet.clear();
|
|
39
|
+
const shieldedSecretKeys = ledger.ZswapSecretKeys.fromSeed(derived.keys[Roles.Zswap]);
|
|
40
|
+
const dustSecretKey = ledger.DustSecretKey.fromSeed(derived.keys[Roles.Dust]);
|
|
41
|
+
const unshieldedKeystore = createKeystore({ kind: "schnorr", secret: derived.keys[Roles.NightExternal] }, networkId);
|
|
42
|
+
return { shieldedSecretKeys, dustSecretKey, unshieldedKeystore };
|
|
43
|
+
}
|
|
44
|
+
/** Compute the three bech32m addresses from the keys. Pure — no network. */
|
|
45
|
+
export function deriveAddresses(keys, networkId) {
|
|
46
|
+
const shieldedAddr = new ShieldedAddress(ShieldedCoinPublicKey.fromHexString(keys.shieldedSecretKeys.coinPublicKey), ShieldedEncryptionPublicKey.fromHexString(keys.shieldedSecretKeys.encryptionPublicKey));
|
|
47
|
+
return {
|
|
48
|
+
unshielded: keys.unshieldedKeystore.getBech32Address().asString(),
|
|
49
|
+
shielded: MidnightBech32m.encode(networkId, shieldedAddr).asString(),
|
|
50
|
+
dust: DustAddress.encodePublicKey(networkId, keys.dustSecretKey.publicKey),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Wire up the WalletFacade for the given keys + connection config. This only
|
|
55
|
+
* constructs the three sub-wallets — it does NOT start syncing.
|
|
56
|
+
*/
|
|
57
|
+
export function initialiseWalletFacade(keys, config) {
|
|
58
|
+
return WalletFacade.init({
|
|
59
|
+
configuration: {
|
|
60
|
+
networkId: config.networkId,
|
|
61
|
+
indexerClientConnection: {
|
|
62
|
+
indexerHttpUrl: config.indexerUrl,
|
|
63
|
+
indexerWsUrl: config.indexerWsUrl,
|
|
64
|
+
},
|
|
65
|
+
provingServerUrl: new URL(config.proofServerUrl),
|
|
66
|
+
// The facade talks to the node over WebSocket, so flip http(s) -> ws(s).
|
|
67
|
+
relayURL: new URL(config.nodeUrl.replace(/^http/, "ws")),
|
|
68
|
+
costParameters: COST_PARAMETERS,
|
|
69
|
+
txHistoryStorage: new InMemoryTransactionHistoryStorage(WalletEntrySchema, mergeWalletEntries),
|
|
70
|
+
},
|
|
71
|
+
shielded: (cfg) => ShieldedWallet(cfg).startWithSecretKeys(keys.shieldedSecretKeys),
|
|
72
|
+
unshielded: (cfg) => UnshieldedWallet(cfg).startWithPublicKey(UnshieldedPublicKey.fromKeyStore(keys.unshieldedKeystore)),
|
|
73
|
+
dust: (cfg) => DustWallet(cfg).startWithSecretKey(keys.dustSecretKey, ledger.LedgerParameters.initialParameters().dust),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Recipes (balancing plans for submitted transactions) expire 30 min out.
|
|
77
|
+
const RECIPE_TTL_MS = 30 * 60 * 1000;
|
|
78
|
+
/**
|
|
79
|
+
* Balance, sign, prove and submit a serialized unproven transaction (e.g. a
|
|
80
|
+
* contract deploy built by `buildDeployTransaction` in deploy.ts). Proving
|
|
81
|
+
* happens in `finalizeRecipe` via the facade's configured proof server.
|
|
82
|
+
*
|
|
83
|
+
* @param facade - A started (and synced) wallet facade that pays for and submits the transaction.
|
|
84
|
+
* @param keys - The key material of the same wallet, for balancing and signing.
|
|
85
|
+
* @param serializedTransaction - The unproven transaction bytes.
|
|
86
|
+
* @returns The submitted transaction's identifier.
|
|
87
|
+
* @throws If the wallet cannot cover fees, proving fails, or the node rejects the transaction.
|
|
88
|
+
*/
|
|
89
|
+
export async function submitUnprovenTransaction(facade, keys, serializedTransaction) {
|
|
90
|
+
// Deserialize back into the ledger UnprovenTransaction the facade balances.
|
|
91
|
+
const tx = ledger.Transaction.deserialize("signature", "pre-proof", "pre-binding", serializedTransaction);
|
|
92
|
+
// Balance (add dust/fee inputs) → sign those inputs → finalize (prove) → submit.
|
|
93
|
+
const recipe = await facade.balanceUnprovenTransaction(tx, { shieldedSecretKeys: keys.shieldedSecretKeys, dustSecretKey: keys.dustSecretKey }, { ttl: new Date(Date.now() + RECIPE_TTL_MS) });
|
|
94
|
+
const signed = await facade.signRecipe(recipe, keys.unshieldedKeystore.signDataAsync);
|
|
95
|
+
const finalized = await facade.finalizeRecipe(signed);
|
|
96
|
+
return facade.submitTransaction(finalized);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Register every NIGHT UTXO not yet registered for dust generation, so the
|
|
100
|
+
* wallet can pay transaction fees (fees are paid in DUST, which only
|
|
101
|
+
* generates on registered NIGHT). Registers ONLY unregistered UTXOs — the
|
|
102
|
+
* node rejects a re-registration of an already-registered one — and submits
|
|
103
|
+
* nothing when there is nothing new to register.
|
|
104
|
+
*
|
|
105
|
+
* @param facade - A started wallet facade for `keys` (builds, proves and submits the registration).
|
|
106
|
+
* @param keys - The key material of the same wallet; its unshielded keystore signs the registration.
|
|
107
|
+
* @param state - The synced facade state to read the NIGHT UTXOs from.
|
|
108
|
+
* @returns How many NIGHT UTXOs this call registered (0 = nothing unregistered, including no NIGHT at all).
|
|
109
|
+
* @throws If the node rejects the registration transaction.
|
|
110
|
+
*/
|
|
111
|
+
export async function registerNightForDustGeneration(facade, keys, state) {
|
|
112
|
+
const unregistered = state.unshielded.availableCoins.filter((coin) => !coin.meta.registeredForDustGeneration);
|
|
113
|
+
if (unregistered.length === 0)
|
|
114
|
+
return 0;
|
|
115
|
+
// Register → finalize (prove) → submit. The registration segments are
|
|
116
|
+
// signed inside registerNightUtxosForDustGeneration via the keystore
|
|
117
|
+
// callback; no separate signRecipe step.
|
|
118
|
+
const recipe = await facade.registerNightUtxosForDustGeneration(unregistered, keys.unshieldedKeystore.getPublicKey(), keys.unshieldedKeystore.signDataAsync);
|
|
119
|
+
const finalized = await facade.finalizeRecipe(recipe);
|
|
120
|
+
await facade.submitTransaction(finalized);
|
|
121
|
+
return unregistered.length;
|
|
122
|
+
}
|
|
123
|
+
// Dust generates continuously once NIGHT is registered, but a fresh
|
|
124
|
+
// registration takes a few blocks before a spendable balance appears.
|
|
125
|
+
const DUST_POLL_INTERVAL_MS = 5_000;
|
|
126
|
+
/**
|
|
127
|
+
* Wait until the wallet's spendable DUST (fee) balance is positive, polling
|
|
128
|
+
* the synced facade state. Pair with {@link registerNightForDustGeneration}:
|
|
129
|
+
* a wallet whose NIGHT was just registered has no dust for a few blocks.
|
|
130
|
+
*
|
|
131
|
+
* @param facade - A started wallet facade.
|
|
132
|
+
* @param timeoutMs - Give-up deadline in milliseconds.
|
|
133
|
+
* @returns The first positive dust balance observed.
|
|
134
|
+
* @throws If no dust appears within `timeoutMs`.
|
|
135
|
+
*/
|
|
136
|
+
export async function waitForSpendableDust(facade, timeoutMs = 300_000) {
|
|
137
|
+
const deadline = Date.now() + timeoutMs;
|
|
138
|
+
for (;;) {
|
|
139
|
+
const state = await facade.waitForSyncedState();
|
|
140
|
+
const dust = state.dust.balance(new Date());
|
|
141
|
+
if (dust > 0n)
|
|
142
|
+
return dust;
|
|
143
|
+
if (Date.now() >= deadline) {
|
|
144
|
+
throw new Error(`no spendable DUST after ${timeoutMs} ms — is the wallet's NIGHT registered for dust generation?`);
|
|
145
|
+
}
|
|
146
|
+
await new Promise((resolve) => setTimeout(resolve, DUST_POLL_INTERVAL_MS));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Run `fn` against a started-and-synced {@link WalletFacade}, then stop the
|
|
151
|
+
* facade — even when `fn` throws. The one place the start / wait-for-sync /
|
|
152
|
+
* stop boilerplate lives.
|
|
153
|
+
*
|
|
154
|
+
* @param keys - The account to open the facade for (see {@link deriveAccountKeys}).
|
|
155
|
+
* @param config - The stack the facade connects to.
|
|
156
|
+
* @param fn - Work to run with the live facade; receives the synced state for balance checks.
|
|
157
|
+
* @returns Whatever `fn` returns.
|
|
158
|
+
* @throws Whatever {@link initialiseWalletFacade}, the facade start/sync, or `fn` throws.
|
|
159
|
+
*/
|
|
160
|
+
export async function withSyncedWalletFacade(keys, config, fn) {
|
|
161
|
+
const facade = await initialiseWalletFacade(keys, config);
|
|
162
|
+
await facade.start(keys.shieldedSecretKeys, keys.dustSecretKey);
|
|
163
|
+
try {
|
|
164
|
+
const state = await facade.waitForSyncedState();
|
|
165
|
+
return await fn(facade, state);
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
await facade.stop().catch(() => { });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/plumbing/wallet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Contract, createSignetContractPrivateState, type SignetContractPrivateState } from "@sig-net/midnight-contract";
|
|
2
|
+
export declare const signetContractManagedPath: string;
|
|
3
|
+
/**
|
|
4
|
+
* The signet-contract compact-js compiled-contract binding: generated module
|
|
5
|
+
* (the contract declares no witnesses) and the compiled assets on disk.
|
|
6
|
+
* Consumed by deploy tooling (and `findDeployedContract`, should a Node
|
|
7
|
+
* client ever join the deployed contract).
|
|
8
|
+
*/
|
|
9
|
+
export declare const signetContractCompiledContract: import("@midnight-ntwrk/compact-js/effect/CompiledContract").CompiledContract<Contract<SignetContractPrivateState, import("@sig-net/midnight-contract").Witnesses<SignetContractPrivateState>>, SignetContractPrivateState, never>;
|
|
10
|
+
export { createSignetContractPrivateState };
|
|
11
|
+
//# sourceMappingURL=signet-contract-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signet-contract-binding.d.ts","sourceRoot":"","sources":["../src/signet-contract-binding.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,QAAQ,EACR,gCAAgC,EAChC,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AAapC,eAAO,MAAM,yBAAyB,QAGrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,oOAO1C,CAAC;AAIF,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// The NODE binding of the signet contract to its compiled assets — the
|
|
2
|
+
// environment-specific half that @sig-net/midnight-contract deliberately
|
|
3
|
+
// does not ship (it assumes Node + fs + assets on disk). Consumers each
|
|
4
|
+
// declare their own; this is the deploy package's.
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { Contract, createSignetContractPrivateState, } from "@sig-net/midnight-contract";
|
|
8
|
+
import { makeVacantCompiledContract } from "./plumbing/deploy.js";
|
|
9
|
+
// The contract package's compiler output dir (contract/, keys/, zkir/) — the
|
|
10
|
+
// "zk config root" deploy tooling reads proving/verifier keys from. Resolved
|
|
11
|
+
// THROUGH THE PACKAGE SPECIFIER, never a workspace-relative path, so the same
|
|
12
|
+
// code works in-repo and from the npm tarball: the managed/ dir sits beside
|
|
13
|
+
// the entry module in both layouts (src/index.ts + src/managed in the repo,
|
|
14
|
+
// dist/index.js + dist/managed in the published package — the tarball ships
|
|
15
|
+
// prover keys, its build refuses to emit without them; an in-repo checkout
|
|
16
|
+
// needs `yarn compile:zk` output first). createRequire rather than
|
|
17
|
+
// `import.meta.resolve` because vitest's module runner does not implement
|
|
18
|
+
// the latter; the CJS resolver honors the same exports map.
|
|
19
|
+
export const signetContractManagedPath = join(dirname(createRequire(import.meta.url).resolve("@sig-net/midnight-contract")), "managed");
|
|
20
|
+
/**
|
|
21
|
+
* The signet-contract compact-js compiled-contract binding: generated module
|
|
22
|
+
* (the contract declares no witnesses) and the compiled assets on disk.
|
|
23
|
+
* Consumed by deploy tooling (and `findDeployedContract`, should a Node
|
|
24
|
+
* client ever join the deployed contract).
|
|
25
|
+
*/
|
|
26
|
+
export const signetContractCompiledContract = makeVacantCompiledContract("signet-contract", Contract, signetContractManagedPath);
|
|
27
|
+
// Re-exported so deploy-side callers get the private state builder from the
|
|
28
|
+
// same module as the binding it pairs with.
|
|
29
|
+
export { createSignetContractPrivateState };
|
|
30
|
+
//# sourceMappingURL=signet-contract-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signet-contract-binding.js","sourceRoot":"","sources":["../src/signet-contract-binding.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yEAAyE;AACzE,wEAAwE;AACxE,mDAAmD;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EACL,QAAQ,EACR,gCAAgC,GAEjC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,mEAAmE;AACnE,0EAA0E;AAC1E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAC3C,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,EAC7E,SAAS,CACV,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,0BAA0B,CAItE,iBAAiB,EACjB,QAAQ,EACR,yBAAyB,CAC1B,CAAC;AAEF,4EAA4E;AAC5E,4CAA4C;AAC5C,OAAO,EAAE,gCAAgC,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sig-net/midnight-contract-deploy",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Deploy tooling for the central signet contract on Midnight: the operator deploy flow, the Node binding of @sig-net/midnight-contract to its compiled assets, and the generic deploy/wallet plumbing (node config, seed parsing, key derivation, wallet facade, unproven-tx build/submit) any Compact contract's deploy script composes.",
|
|
6
|
+
"//exports": "Local dev consumes raw TS source. `publishConfig.exports` below swaps this to the emitted ./dist at publish time, so npm consumers get JS + .d.ts while the monorepo keeps resolving to src.",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "rm -rf dist && tsc -p tsconfig.json && tsc -p tsconfig.build.json",
|
|
18
|
+
"prepack": "yarn build",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"deploy": "tsx deploy.ts"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"default": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@effect/platform-node": "^0.107.0",
|
|
35
|
+
"@midnight-ntwrk/compact-js": "2.5.5-rc.5",
|
|
36
|
+
"@midnight-ntwrk/compact-js-node": "2.5.5-rc.5",
|
|
37
|
+
"@midnight-ntwrk/midnight-js": "5.0.0-beta.3",
|
|
38
|
+
"@midnight-ntwrk/platform-js": "^3.0.0",
|
|
39
|
+
"@midnightntwrk/ledger-v9": "1.0.0-rc.3",
|
|
40
|
+
"@midnightntwrk/wallet-sdk-abstractions": "3.0.0-beta.0",
|
|
41
|
+
"@midnightntwrk/wallet-sdk-address-format": "4.0.0-beta.2",
|
|
42
|
+
"@midnightntwrk/wallet-sdk-dust-wallet": "5.0.0-beta.2",
|
|
43
|
+
"@midnightntwrk/wallet-sdk-facade": "5.0.0-beta.2",
|
|
44
|
+
"@midnightntwrk/wallet-sdk-hd": "3.1.0-beta.1",
|
|
45
|
+
"@midnightntwrk/wallet-sdk-shielded": "4.0.0-beta.2",
|
|
46
|
+
"@midnightntwrk/wallet-sdk-unshielded-wallet": "4.0.0-beta.2",
|
|
47
|
+
"@scure/bip39": "^2.2.0",
|
|
48
|
+
"@sig-net/midnight": "^0.0.3",
|
|
49
|
+
"@sig-net/midnight-contract": "^0.0.3",
|
|
50
|
+
"effect": "^3.21.4"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^26.1.0",
|
|
54
|
+
"tsx": "^4.23.0",
|
|
55
|
+
"typescript": "^6.0.3",
|
|
56
|
+
"vitest": "^4.1.9"
|
|
57
|
+
},
|
|
58
|
+
"main": "./dist/index.js",
|
|
59
|
+
"types": "./dist/index.d.ts"
|
|
60
|
+
}
|