create-mn-app 1.0.0
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/README.md +45 -0
- package/bin/create-midnight-app.js +47 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/create-app.d.ts +10 -0
- package/dist/create-app.d.ts.map +1 -0
- package/dist/create-app.js +169 -0
- package/dist/create-app.js.map +1 -0
- package/dist/installers/package-installer.d.ts +8 -0
- package/dist/installers/package-installer.d.ts.map +1 -0
- package/dist/installers/package-installer.js +62 -0
- package/dist/installers/package-installer.js.map +1 -0
- package/dist/installers/proof-server-setup.d.ts +6 -0
- package/dist/installers/proof-server-setup.d.ts.map +1 -0
- package/dist/installers/proof-server-setup.js +54 -0
- package/dist/installers/proof-server-setup.js.map +1 -0
- package/dist/installers/wallet-generator.d.ts +4 -0
- package/dist/installers/wallet-generator.d.ts.map +1 -0
- package/dist/installers/wallet-generator.js +64 -0
- package/dist/installers/wallet-generator.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +53 -0
- package/dist/test.js.map +1 -0
- package/dist/utils/git-utils.d.ts +6 -0
- package/dist/utils/git-utils.d.ts.map +1 -0
- package/dist/utils/git-utils.js +51 -0
- package/dist/utils/git-utils.js.map +1 -0
- package/dist/utils/template-manager.d.ts +7 -0
- package/dist/utils/template-manager.d.ts.map +1 -0
- package/dist/utils/template-manager.js +61 -0
- package/dist/utils/template-manager.js.map +1 -0
- package/dist/utils/validation.d.ts +6 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +32 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +60 -0
- package/templates/hello-world/README.md.template +100 -0
- package/templates/hello-world/_env.template +0 -0
- package/templates/hello-world/_gitignore +52 -0
- package/templates/hello-world/contracts/hello-world.compact.template +12 -0
- package/templates/hello-world/nodemon.json.template +7 -0
- package/templates/hello-world/package.json.template +49 -0
- package/templates/hello-world/src/cli.ts.template +194 -0
- package/templates/hello-world/src/deploy.ts.template +181 -0
- package/templates/hello-world/src/providers/midnight-providers.ts.template +46 -0
- package/templates/hello-world/src/utils/environment.ts.template +51 -0
- package/templates/hello-world/tsconfig.json.template +20 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { WalletBuilder } from "@midnight-ntwrk/wallet";
|
|
3
|
+
import { deployContract } from "@midnight-ntwrk/midnight-js-contracts";
|
|
4
|
+
import { httpClientProofProvider } from "@midnight-ntwrk/midnight-js-http-client-proof-provider";
|
|
5
|
+
import { indexerPublicDataProvider } from "@midnight-ntwrk/midnight-js-indexer-public-data-provider";
|
|
6
|
+
import { NodeZkConfigProvider } from "@midnight-ntwrk/midnight-js-node-zk-config-provider";
|
|
7
|
+
import { levelPrivateStateProvider } from "@midnight-ntwrk/midnight-js-level-private-state-provider";
|
|
8
|
+
import {
|
|
9
|
+
NetworkId,
|
|
10
|
+
setNetworkId,
|
|
11
|
+
getZswapNetworkId,
|
|
12
|
+
getLedgerNetworkId,
|
|
13
|
+
} from "@midnight-ntwrk/midnight-js-network-id";
|
|
14
|
+
import { createBalancedTx } from "@midnight-ntwrk/midnight-js-types";
|
|
15
|
+
import { nativeToken, Transaction } from "@midnight-ntwrk/ledger";
|
|
16
|
+
import { Transaction as ZswapTransaction } from "@midnight-ntwrk/zswap";
|
|
17
|
+
import { WebSocket } from "ws";
|
|
18
|
+
import * as fs from "fs";
|
|
19
|
+
import * as path from "path";
|
|
20
|
+
import * as Rx from "rxjs";
|
|
21
|
+
import { type Wallet } from "@midnight-ntwrk/wallet-api";
|
|
22
|
+
import { MidnightProviders } from "./providers/midnight-providers";
|
|
23
|
+
import { EnvironmentManager } from "./utils/environment";
|
|
24
|
+
|
|
25
|
+
// Fix WebSocket for Node.js environment
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
globalThis.WebSocket = WebSocket;
|
|
28
|
+
|
|
29
|
+
// Configure for Midnight Testnet
|
|
30
|
+
setNetworkId(NetworkId.TestNet);
|
|
31
|
+
|
|
32
|
+
const waitForFunds = (wallet: Wallet) =>
|
|
33
|
+
Rx.firstValueFrom(
|
|
34
|
+
wallet.state().pipe(
|
|
35
|
+
Rx.tap((state) => {
|
|
36
|
+
if (state.syncProgress) {
|
|
37
|
+
console.log(
|
|
38
|
+
`Sync progress: synced=${state.syncProgress.synced}, sourceGap=${state.syncProgress.lag.sourceGap}, applyGap=${state.syncProgress.lag.applyGap}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
Rx.filter((state) => state.syncProgress?.synced === true),
|
|
43
|
+
Rx.map((s) => s.balances[nativeToken()] ?? 0n),
|
|
44
|
+
Rx.filter((balance) => balance > 0n),
|
|
45
|
+
Rx.tap((balance) => console.log(`Wallet funded with balance: ${balance}`))
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
async function main() {
|
|
50
|
+
console.log("š {{projectName}} Deployment\n");
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
// Validate environment
|
|
54
|
+
EnvironmentManager.validateEnvironment();
|
|
55
|
+
|
|
56
|
+
const networkConfig = EnvironmentManager.getNetworkConfig();
|
|
57
|
+
const contractName = process.env.CONTRACT_NAME || "hello-world";
|
|
58
|
+
|
|
59
|
+
// Check if contract is compiled
|
|
60
|
+
if (!EnvironmentManager.checkContractCompiled(contractName)) {
|
|
61
|
+
console.error("ā Contract not compiled! Run: npm run compile");
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const walletSeed = process.env.WALLET_SEED!;
|
|
66
|
+
|
|
67
|
+
// Build wallet from seed
|
|
68
|
+
console.log("Building wallet...");
|
|
69
|
+
const wallet = await WalletBuilder.buildFromSeed(
|
|
70
|
+
networkConfig.indexer,
|
|
71
|
+
networkConfig.indexerWS,
|
|
72
|
+
networkConfig.proofServer,
|
|
73
|
+
networkConfig.node,
|
|
74
|
+
walletSeed,
|
|
75
|
+
getZswapNetworkId(),
|
|
76
|
+
"info"
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
wallet.start();
|
|
80
|
+
const state = await Rx.firstValueFrom(wallet.state());
|
|
81
|
+
|
|
82
|
+
console.log(`Your wallet address is: ${state.address}`);
|
|
83
|
+
|
|
84
|
+
let balance = state.balances[nativeToken()] || 0n;
|
|
85
|
+
|
|
86
|
+
if (balance === 0n) {
|
|
87
|
+
console.log(`Your wallet balance is: 0`);
|
|
88
|
+
console.log(
|
|
89
|
+
"Visit: https://midnight.network/test-faucet to get some funds."
|
|
90
|
+
);
|
|
91
|
+
console.log(`Waiting to receive tokens...`);
|
|
92
|
+
balance = await waitForFunds(wallet);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log(`Balance: ${balance}`);
|
|
96
|
+
|
|
97
|
+
// Load compiled contract files
|
|
98
|
+
console.log("Loading contract...");
|
|
99
|
+
const contractPath = path.join(process.cwd(), "contracts");
|
|
100
|
+
const contractModulePath = path.join(
|
|
101
|
+
contractPath,
|
|
102
|
+
"managed",
|
|
103
|
+
contractName,
|
|
104
|
+
"contract",
|
|
105
|
+
"index.cjs"
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const HelloWorldModule = await import(contractModulePath);
|
|
109
|
+
const contractInstance = new HelloWorldModule.Contract({});
|
|
110
|
+
|
|
111
|
+
// Create wallet provider for transactions
|
|
112
|
+
const walletState = await Rx.firstValueFrom(wallet.state());
|
|
113
|
+
|
|
114
|
+
const walletProvider = {
|
|
115
|
+
coinPublicKey: walletState.coinPublicKey,
|
|
116
|
+
encryptionPublicKey: walletState.encryptionPublicKey,
|
|
117
|
+
balanceTx(tx: any, newCoins: any) {
|
|
118
|
+
return wallet
|
|
119
|
+
.balanceTransaction(
|
|
120
|
+
ZswapTransaction.deserialize(
|
|
121
|
+
tx.serialize(getLedgerNetworkId()),
|
|
122
|
+
getZswapNetworkId()
|
|
123
|
+
),
|
|
124
|
+
newCoins
|
|
125
|
+
)
|
|
126
|
+
.then((tx) => wallet.proveTransaction(tx))
|
|
127
|
+
.then((zswapTx) =>
|
|
128
|
+
Transaction.deserialize(
|
|
129
|
+
zswapTx.serialize(getZswapNetworkId()),
|
|
130
|
+
getLedgerNetworkId()
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
.then(createBalancedTx);
|
|
134
|
+
},
|
|
135
|
+
submitTx(tx: any) {
|
|
136
|
+
return wallet.submitTransaction(tx);
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Configure all required providers
|
|
141
|
+
console.log("Setting up providers...");
|
|
142
|
+
const providers = MidnightProviders.create({
|
|
143
|
+
contractName,
|
|
144
|
+
walletProvider,
|
|
145
|
+
networkConfig,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Deploy contract to blockchain
|
|
149
|
+
console.log("Deploying contract (30-60 seconds)...");
|
|
150
|
+
|
|
151
|
+
const deployed = await deployContract(providers, {
|
|
152
|
+
contract: contractInstance,
|
|
153
|
+
privateStateId: "helloWorldState",
|
|
154
|
+
initialPrivateState: {},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const contractAddress = deployed.deployTxData.public.contractAddress;
|
|
158
|
+
|
|
159
|
+
// Save deployment information
|
|
160
|
+
console.log("\nš DEPLOYED!");
|
|
161
|
+
console.log(`Contract: ${contractAddress}\n`);
|
|
162
|
+
|
|
163
|
+
const info = {
|
|
164
|
+
contractAddress,
|
|
165
|
+
deployedAt: new Date().toISOString(),
|
|
166
|
+
network: networkConfig.name,
|
|
167
|
+
contractName,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
fs.writeFileSync("deployment.json", JSON.stringify(info, null, 2));
|
|
171
|
+
console.log("ā
Saved to deployment.json");
|
|
172
|
+
|
|
173
|
+
// Close wallet connection
|
|
174
|
+
await wallet.close();
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error("ā Failed:", error);
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { levelPrivateStateProvider } from "@midnight-ntwrk/midnight-js-level-private-state-provider";
|
|
3
|
+
import { indexerPublicDataProvider } from "@midnight-ntwrk/midnight-js-indexer-public-data-provider";
|
|
4
|
+
import { NodeZkConfigProvider } from "@midnight-ntwrk/midnight-js-node-zk-config-provider";
|
|
5
|
+
import { httpClientProofProvider } from "@midnight-ntwrk/midnight-js-http-client-proof-provider";
|
|
6
|
+
|
|
7
|
+
export interface NetworkConfig {
|
|
8
|
+
indexer: string;
|
|
9
|
+
indexerWS: string;
|
|
10
|
+
node: string;
|
|
11
|
+
proofServer: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProviderConfig {
|
|
16
|
+
contractName: string;
|
|
17
|
+
walletProvider: any;
|
|
18
|
+
networkConfig: NetworkConfig;
|
|
19
|
+
privateStateStoreName?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class MidnightProviders {
|
|
23
|
+
static create(config: ProviderConfig) {
|
|
24
|
+
const contractPath = path.join(process.cwd(), "contracts");
|
|
25
|
+
const zkConfigPath = path.join(
|
|
26
|
+
contractPath,
|
|
27
|
+
"managed",
|
|
28
|
+
config.contractName
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
privateStateProvider: levelPrivateStateProvider({
|
|
33
|
+
privateStateStoreName:
|
|
34
|
+
config.privateStateStoreName || `${config.contractName}-state`,
|
|
35
|
+
}),
|
|
36
|
+
publicDataProvider: indexerPublicDataProvider(
|
|
37
|
+
config.networkConfig.indexer,
|
|
38
|
+
config.networkConfig.indexerWS
|
|
39
|
+
),
|
|
40
|
+
zkConfigProvider: new NodeZkConfigProvider(zkConfigPath),
|
|
41
|
+
proofProvider: httpClientProofProvider(config.networkConfig.proofServer),
|
|
42
|
+
walletProvider: config.walletProvider,
|
|
43
|
+
midnightProvider: config.walletProvider,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { NetworkConfig } from "../providers/midnight-providers";
|
|
4
|
+
|
|
5
|
+
export class EnvironmentManager {
|
|
6
|
+
static getNetworkConfig(): NetworkConfig {
|
|
7
|
+
const network = process.env.MIDNIGHT_NETWORK || "testnet";
|
|
8
|
+
|
|
9
|
+
const networks = {
|
|
10
|
+
testnet: {
|
|
11
|
+
indexer: "https://indexer.testnet-02.midnight.network/api/v1/graphql",
|
|
12
|
+
indexerWS:
|
|
13
|
+
"wss://indexer.testnet-02.midnight.network/api/v1/graphql/ws",
|
|
14
|
+
node: "https://rpc.testnet-02.midnight.network",
|
|
15
|
+
proofServer: process.env.PROOF_SERVER_URL || "http://127.0.0.1:6300",
|
|
16
|
+
name: "Testnet",
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
return networks[network as keyof typeof networks] || networks.testnet;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static validateEnvironment(): void {
|
|
24
|
+
const required = ["WALLET_SEED"];
|
|
25
|
+
const missing = required.filter((key) => !process.env[key]);
|
|
26
|
+
|
|
27
|
+
if (missing.length > 0) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`Missing required environment variables: ${missing.join(", ")}`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const walletSeed = process.env.WALLET_SEED!;
|
|
34
|
+
if (!/^[a-fA-F0-9]{64}$/.test(walletSeed)) {
|
|
35
|
+
throw new Error("WALLET_SEED must be a 64-character hexadecimal string");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static checkContractCompiled(contractName: string): boolean {
|
|
40
|
+
const contractPath = path.join(
|
|
41
|
+
process.cwd(),
|
|
42
|
+
"contracts",
|
|
43
|
+
"managed",
|
|
44
|
+
contractName
|
|
45
|
+
);
|
|
46
|
+
const keysPath = path.join(contractPath, "keys");
|
|
47
|
+
const contractModulePath = path.join(contractPath, "contract", "index.cjs");
|
|
48
|
+
|
|
49
|
+
return fs.existsSync(keysPath) && fs.existsSync(contractModulePath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"allowSyntheticDefaultImports": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist", "contracts/managed"]
|
|
20
|
+
}
|