create-mn-app 0.3.26 → 0.3.27

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mn-app",
3
- "version": "0.3.26",
3
+ "version": "0.3.27",
4
4
  "description": "Create Midnight Network applications with zero configuration",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -18,24 +18,24 @@
18
18
  "test": "echo \"Error: no test specified\" && exit 1"
19
19
  },
20
20
  "dependencies": {
21
- "@midnight-ntwrk/compact-runtime": "0.14.0",
22
- "@midnight-ntwrk/compact-js": "2.4.0",
23
- "@midnight-ntwrk/ledger-v7": "7.0.0",
24
- "@midnight-ntwrk/midnight-js-contracts": "3.0.0",
25
- "@midnight-ntwrk/midnight-js-http-client-proof-provider": "3.0.0",
26
- "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "3.0.0",
27
- "@midnight-ntwrk/midnight-js-level-private-state-provider": "3.0.0",
28
- "@midnight-ntwrk/midnight-js-node-zk-config-provider": "3.0.0",
29
- "@midnight-ntwrk/midnight-js-network-id": "3.0.0",
30
- "@midnight-ntwrk/midnight-js-types": "3.0.0",
31
- "@midnight-ntwrk/midnight-js-utils": "3.0.0",
32
- "@midnight-ntwrk/wallet-sdk-facade": "1.0.0",
33
- "@midnight-ntwrk/wallet-sdk-hd": "3.0.0",
34
- "@midnight-ntwrk/wallet-sdk-shielded": "1.0.0",
35
- "@midnight-ntwrk/wallet-sdk-unshielded-wallet": "1.0.0",
36
- "@midnight-ntwrk/wallet-sdk-dust-wallet": "1.0.0",
37
- "ws": "^8.19.0",
38
- "rxjs": "^7.8.0"
21
+ "@midnight-ntwrk/compact-js": "2.5.0",
22
+ "rxjs": "^7.8.1",
23
+ "@midnight-ntwrk/compact-runtime": "0.15.0",
24
+ "@midnight-ntwrk/ledger-v8": "8.0.3",
25
+ "@midnight-ntwrk/midnight-js-contracts": "4.0.2",
26
+ "@midnight-ntwrk/midnight-js-http-client-proof-provider": "4.0.2",
27
+ "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "4.0.2",
28
+ "@midnight-ntwrk/midnight-js-level-private-state-provider": "4.0.2",
29
+ "@midnight-ntwrk/midnight-js-network-id": "4.0.2",
30
+ "@midnight-ntwrk/midnight-js-node-zk-config-provider": "4.0.2",
31
+ "@midnight-ntwrk/midnight-js-types": "4.0.2",
32
+ "@midnight-ntwrk/midnight-js-utils": "4.0.2",
33
+ "@midnight-ntwrk/wallet-sdk-dust-wallet": "3.0.0",
34
+ "@midnight-ntwrk/wallet-sdk-facade": "3.0.0",
35
+ "@midnight-ntwrk/wallet-sdk-hd": "3.0.1",
36
+ "@midnight-ntwrk/wallet-sdk-shielded": "2.1.0",
37
+ "@midnight-ntwrk/wallet-sdk-unshielded-wallet": "2.1.0",
38
+ "ws": "^8.19.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^22.0.0",
@@ -8,8 +8,8 @@ import { Buffer } from 'buffer';
8
8
 
9
9
  // Midnight SDK imports
10
10
  import { setNetworkId, getNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
11
- import * as ledger from '@midnight-ntwrk/ledger-v7';
12
- import { unshieldedToken } from '@midnight-ntwrk/ledger-v7';
11
+ import * as ledger from '@midnight-ntwrk/ledger-v8';
12
+ import { unshieldedToken } from '@midnight-ntwrk/ledger-v8';
13
13
  import { WalletFacade } from '@midnight-ntwrk/wallet-sdk-facade';
14
14
  import { DustWallet } from '@midnight-ntwrk/wallet-sdk-dust-wallet';
15
15
  import { HDWallet, Roles } from '@midnight-ntwrk/wallet-sdk-hd';
@@ -55,20 +55,17 @@ async function createWallet(seed: string) {
55
55
  indexerClientConnection: { indexerHttpUrl: CONFIG.indexer, indexerWsUrl: CONFIG.indexerWS },
56
56
  provingServerUrl: new URL(CONFIG.proofServer),
57
57
  relayURL: new URL(CONFIG.node.replace(/^http/, 'ws')),
58
- };
59
-
60
- const shieldedWallet = ShieldedWallet(walletConfig).startWithSecretKeys(shieldedSecretKeys);
61
- const unshieldedWallet = UnshieldedWallet({
62
- networkId,
63
- indexerClientConnection: walletConfig.indexerClientConnection,
64
58
  txHistoryStorage: new InMemoryTransactionHistoryStorage(),
65
- }).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore));
66
- const dustWallet = DustWallet({
67
- ...walletConfig,
68
59
  costParameters: { additionalFeeOverhead: 300_000_000_000_000n, feeBlocksMargin: 5 },
69
- }).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust);
60
+ };
61
+
62
+ const wallet = await WalletFacade.init({
63
+ configuration: walletConfig,
64
+ shielded: async (config) => ShieldedWallet(config).startWithSecretKeys(shieldedSecretKeys),
65
+ unshielded: async (config) => UnshieldedWallet(config).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore)),
66
+ dust: async (config) => DustWallet(config).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust),
67
+ });
70
68
 
71
- const wallet = new WalletFacade(shieldedWallet, unshieldedWallet, dustWallet);
72
69
  await wallet.start(shieldedSecretKeys, dustSecretKey);
73
70
 
74
71
  return { wallet, unshieldedKeystore };
@@ -100,13 +97,11 @@ async function main() {
100
97
  const { wallet, unshieldedKeystore } = await createWallet(seed);
101
98
 
102
99
  console.log(' Syncing with network...');
103
- const state = await Rx.firstValueFrom(
104
- wallet.state().pipe(Rx.throttleTime(5000), Rx.filter((s) => s.isSynced)),
105
- );
100
+ const state = await wallet.waitForSyncedState();
106
101
 
107
102
  const address = unshieldedKeystore.getBech32Address();
108
103
  const tNightBalance = state.unshielded.balances[unshieldedToken().raw] ?? 0n;
109
- const dustBalance = state.dust.walletBalance(new Date());
104
+ const dustBalance = state.dust.balance(new Date());
110
105
 
111
106
  console.log('\n─── Wallet Details ─────────────────────────────────────────────\n');
112
107
  console.log(` Address: ${address}`);
@@ -17,8 +17,8 @@ import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-p
17
17
  import { levelPrivateStateProvider } from '@midnight-ntwrk/midnight-js-level-private-state-provider';
18
18
  import { NodeZkConfigProvider } from '@midnight-ntwrk/midnight-js-node-zk-config-provider';
19
19
  import { setNetworkId, getNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
20
- import * as ledger from '@midnight-ntwrk/ledger-v7';
21
- import { unshieldedToken } from '@midnight-ntwrk/ledger-v7';
20
+ import * as ledger from '@midnight-ntwrk/ledger-v8';
21
+ import { unshieldedToken } from '@midnight-ntwrk/ledger-v8';
22
22
  import { WalletFacade } from '@midnight-ntwrk/wallet-sdk-facade';
23
23
  import { DustWallet } from '@midnight-ntwrk/wallet-sdk-dust-wallet';
24
24
  import { HDWallet, Roles } from '@midnight-ntwrk/wallet-sdk-hd';
@@ -83,48 +83,26 @@ async function createWallet(seed: string) {
83
83
  indexerClientConnection: { indexerHttpUrl: CONFIG.indexer, indexerWsUrl: CONFIG.indexerWS },
84
84
  provingServerUrl: new URL(CONFIG.proofServer),
85
85
  relayURL: new URL(CONFIG.node.replace(/^http/, 'ws')),
86
- };
87
-
88
- const shieldedWallet = ShieldedWallet(walletConfig).startWithSecretKeys(shieldedSecretKeys);
89
- const unshieldedWallet = UnshieldedWallet({
90
- networkId,
91
- indexerClientConnection: walletConfig.indexerClientConnection,
92
86
  txHistoryStorage: new InMemoryTransactionHistoryStorage(),
93
- }).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore));
94
- const dustWallet = DustWallet({
95
- ...walletConfig,
96
87
  costParameters: { additionalFeeOverhead: 300_000_000_000_000n, feeBlocksMargin: 5 },
97
- }).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust);
88
+ };
89
+
90
+ const wallet = await WalletFacade.init({
91
+ configuration: walletConfig,
92
+ shielded: async (config) => ShieldedWallet(config).startWithSecretKeys(shieldedSecretKeys),
93
+ unshielded: async (config) => UnshieldedWallet(config).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore)),
94
+ dust: async (config) => DustWallet(config).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust),
95
+ });
98
96
 
99
- const wallet = new WalletFacade(shieldedWallet, unshieldedWallet, dustWallet);
100
97
  await wallet.start(shieldedSecretKeys, dustSecretKey);
101
98
 
102
99
  return { wallet, shieldedSecretKeys, dustSecretKey, unshieldedKeystore };
103
100
  }
104
101
 
105
- // Workaround for wallet SDK signRecipe bug
106
- function signTransactionIntents(tx: { intents?: Map<number, any> }, signFn: (payload: Uint8Array) => ledger.Signature, proofMarker: 'proof' | 'pre-proof'): void {
107
- if (!tx.intents || tx.intents.size === 0) return;
108
- for (const segment of tx.intents.keys()) {
109
- const intent = tx.intents.get(segment);
110
- if (!intent) continue;
111
- const cloned = ledger.Intent.deserialize<ledger.SignatureEnabled, ledger.Proofish, ledger.PreBinding>('signature', proofMarker, 'pre-binding', intent.serialize());
112
- const sigData = cloned.signatureData(segment);
113
- const signature = signFn(sigData);
114
- if (cloned.fallibleUnshieldedOffer) {
115
- const sigs = cloned.fallibleUnshieldedOffer.inputs.map((_: any, i: number) => cloned.fallibleUnshieldedOffer!.signatures.at(i) ?? signature);
116
- cloned.fallibleUnshieldedOffer = cloned.fallibleUnshieldedOffer.addSignatures(sigs);
117
- }
118
- if (cloned.guaranteedUnshieldedOffer) {
119
- const sigs = cloned.guaranteedUnshieldedOffer.inputs.map((_: any, i: number) => cloned.guaranteedUnshieldedOffer!.signatures.at(i) ?? signature);
120
- cloned.guaranteedUnshieldedOffer = cloned.guaranteedUnshieldedOffer.addSignatures(sigs);
121
- }
122
- tx.intents.set(segment, cloned);
123
- }
124
- }
125
-
126
102
  async function createProviders(walletCtx: ReturnType<typeof createWallet> extends Promise<infer T> ? T : never) {
127
- const state = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.filter((s) => s.isSynced)));
103
+ const privateStatePassword = process.env.PRIVATE_STATE_PASSWORD?.trim() || 'development';
104
+
105
+ const state = await walletCtx.wallet.waitForSyncedState();
128
106
 
129
107
  const walletProvider = {
130
108
  getCoinPublicKey: () => state.shielded.coinPublicKey.toHexString(),
@@ -135,18 +113,23 @@ async function createProviders(walletCtx: ReturnType<typeof createWallet> extend
135
113
  { shieldedSecretKeys: walletCtx.shieldedSecretKeys, dustSecretKey: walletCtx.dustSecretKey },
136
114
  { ttl: ttl ?? new Date(Date.now() + 30 * 60 * 1000) },
137
115
  );
138
- const signFn = (payload: Uint8Array) => walletCtx.unshieldedKeystore.signData(payload);
139
- signTransactionIntents(recipe.baseTransaction, signFn, 'proof');
140
- if (recipe.balancingTransaction) signTransactionIntents(recipe.balancingTransaction, signFn, 'pre-proof');
141
- return walletCtx.wallet.finalizeRecipe(recipe);
116
+ const signedRecipe = await walletCtx.wallet.signRecipe(recipe, (payload) =>
117
+ walletCtx.unshieldedKeystore.signData(payload),
118
+ );
119
+ return walletCtx.wallet.finalizeRecipe(signedRecipe);
142
120
  },
143
121
  submitTx: (tx: any) => walletCtx.wallet.submitTransaction(tx) as any,
144
122
  };
145
123
 
146
124
  const zkConfigProvider = new NodeZkConfigProvider(zkConfigPath);
125
+ const accountId = walletCtx.unshieldedKeystore.getBech32Address().toString();
147
126
 
148
127
  return {
149
- privateStateProvider: levelPrivateStateProvider({ privateStateStoreName: 'hello-world-state', walletProvider }),
128
+ privateStateProvider: levelPrivateStateProvider({
129
+ privateStateStoreName: 'hello-world-state',
130
+ accountId,
131
+ privateStoragePasswordProvider: () => privateStatePassword,
132
+ }),
150
133
  publicDataProvider: indexerPublicDataProvider(CONFIG.indexer, CONFIG.indexerWS),
151
134
  zkConfigProvider,
152
135
  proofProvider: httpClientProofProvider(CONFIG.proofServer, zkConfigProvider),
@@ -186,7 +169,7 @@ async function main() {
186
169
  const walletCtx = await createWallet(seed);
187
170
 
188
171
  console.log(' Syncing with network...');
189
- const state = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.throttleTime(5000), Rx.filter((s) => s.isSynced)));
172
+ const state = await walletCtx.wallet.waitForSyncedState();
190
173
  const balance = state.unshielded.balances[unshieldedToken().raw] ?? 0n;
191
174
  console.log(` Balance: ${balance.toLocaleString()} tNight\n`);
192
175
 
@@ -195,10 +178,8 @@ async function main() {
195
178
  const providers = await createProviders(walletCtx);
196
179
 
197
180
  const deployed: any = await findDeployedContract(providers, {
198
- compiledContract,
181
+ compiledContract: compiledContract as any,
199
182
  contractAddress: deployment.contractAddress,
200
- privateStateId: 'helloWorldState',
201
- initialPrivateState: {},
202
183
  });
203
184
 
204
185
  console.log(' ✅ Connected!\n');
@@ -248,9 +229,9 @@ async function main() {
248
229
 
249
230
  case '3': {
250
231
  console.log('\n Checking balance...');
251
- const currentState = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.filter((s) => s.isSynced)));
232
+ const currentState = await walletCtx.wallet.waitForSyncedState();
252
233
  const currentBalance = currentState.unshielded.balances[unshieldedToken().raw] ?? 0n;
253
- const dustBalance = currentState.dust.walletBalance(new Date());
234
+ const dustBalance = currentState.dust.balance(new Date());
254
235
  console.log(`\n tNight: ${currentBalance.toLocaleString()}`);
255
236
  console.log(` DUST: ${dustBalance.toLocaleString()}\n`);
256
237
  break;
@@ -18,8 +18,8 @@ import { levelPrivateStateProvider } from '@midnight-ntwrk/midnight-js-level-pri
18
18
  import { NodeZkConfigProvider } from '@midnight-ntwrk/midnight-js-node-zk-config-provider';
19
19
  import { setNetworkId, getNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
20
20
  import { toHex } from '@midnight-ntwrk/midnight-js-utils';
21
- import * as ledger from '@midnight-ntwrk/ledger-v7';
22
- import { unshieldedToken } from '@midnight-ntwrk/ledger-v7';
21
+ import * as ledger from '@midnight-ntwrk/ledger-v8';
22
+ import { unshieldedToken } from '@midnight-ntwrk/ledger-v8';
23
23
  import { WalletFacade } from '@midnight-ntwrk/wallet-sdk-facade';
24
24
  import { DustWallet } from '@midnight-ntwrk/wallet-sdk-dust-wallet';
25
25
  import { HDWallet, Roles, generateRandomSeed } from '@midnight-ntwrk/wallet-sdk-hd';
@@ -114,48 +114,26 @@ async function createWallet(seed: string) {
114
114
  indexerClientConnection: { indexerHttpUrl: CONFIG.indexer, indexerWsUrl: CONFIG.indexerWS },
115
115
  provingServerUrl: new URL(CONFIG.proofServer),
116
116
  relayURL: new URL(CONFIG.node.replace(/^http/, 'ws')),
117
- };
118
-
119
- const shieldedWallet = ShieldedWallet(walletConfig).startWithSecretKeys(shieldedSecretKeys);
120
- const unshieldedWallet = UnshieldedWallet({
121
- networkId,
122
- indexerClientConnection: walletConfig.indexerClientConnection,
123
117
  txHistoryStorage: new InMemoryTransactionHistoryStorage(),
124
- }).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore));
125
- const dustWallet = DustWallet({
126
- ...walletConfig,
127
118
  costParameters: { additionalFeeOverhead: 300_000_000_000_000n, feeBlocksMargin: 5 },
128
- }).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust);
119
+ };
120
+
121
+ const wallet = await WalletFacade.init({
122
+ configuration: walletConfig,
123
+ shielded: async (config) => ShieldedWallet(config).startWithSecretKeys(shieldedSecretKeys),
124
+ unshielded: async (config) => UnshieldedWallet(config).startWithPublicKey(PublicKey.fromKeyStore(unshieldedKeystore)),
125
+ dust: async (config) => DustWallet(config).startWithSecretKey(dustSecretKey, ledger.LedgerParameters.initialParameters().dust),
126
+ });
129
127
 
130
- const wallet = new WalletFacade(shieldedWallet, unshieldedWallet, dustWallet);
131
128
  await wallet.start(shieldedSecretKeys, dustSecretKey);
132
129
 
133
130
  return { wallet, shieldedSecretKeys, dustSecretKey, unshieldedKeystore };
134
131
  }
135
132
 
136
- // Workaround for wallet SDK signRecipe bug
137
- function signTransactionIntents(tx: { intents?: Map<number, any> }, signFn: (payload: Uint8Array) => ledger.Signature, proofMarker: 'proof' | 'pre-proof'): void {
138
- if (!tx.intents || tx.intents.size === 0) return;
139
- for (const segment of tx.intents.keys()) {
140
- const intent = tx.intents.get(segment);
141
- if (!intent) continue;
142
- const cloned = ledger.Intent.deserialize<ledger.SignatureEnabled, ledger.Proofish, ledger.PreBinding>('signature', proofMarker, 'pre-binding', intent.serialize());
143
- const sigData = cloned.signatureData(segment);
144
- const signature = signFn(sigData);
145
- if (cloned.fallibleUnshieldedOffer) {
146
- const sigs = cloned.fallibleUnshieldedOffer.inputs.map((_: any, i: number) => cloned.fallibleUnshieldedOffer!.signatures.at(i) ?? signature);
147
- cloned.fallibleUnshieldedOffer = cloned.fallibleUnshieldedOffer.addSignatures(sigs);
148
- }
149
- if (cloned.guaranteedUnshieldedOffer) {
150
- const sigs = cloned.guaranteedUnshieldedOffer.inputs.map((_: any, i: number) => cloned.guaranteedUnshieldedOffer!.signatures.at(i) ?? signature);
151
- cloned.guaranteedUnshieldedOffer = cloned.guaranteedUnshieldedOffer.addSignatures(sigs);
152
- }
153
- tx.intents.set(segment, cloned);
154
- }
155
- }
156
-
157
133
  async function createProviders(walletCtx: ReturnType<typeof createWallet> extends Promise<infer T> ? T : never) {
158
- const state = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.filter((s) => s.isSynced)));
134
+ const privateStatePassword = process.env.PRIVATE_STATE_PASSWORD?.trim() || 'development';
135
+
136
+ const state = await walletCtx.wallet.waitForSyncedState();
159
137
 
160
138
  const walletProvider = {
161
139
  getCoinPublicKey: () => state.shielded.coinPublicKey.toHexString(),
@@ -166,18 +144,23 @@ async function createProviders(walletCtx: ReturnType<typeof createWallet> extend
166
144
  { shieldedSecretKeys: walletCtx.shieldedSecretKeys, dustSecretKey: walletCtx.dustSecretKey },
167
145
  { ttl: ttl ?? new Date(Date.now() + 30 * 60 * 1000) },
168
146
  );
169
- const signFn = (payload: Uint8Array) => walletCtx.unshieldedKeystore.signData(payload);
170
- signTransactionIntents(recipe.baseTransaction, signFn, 'proof');
171
- if (recipe.balancingTransaction) signTransactionIntents(recipe.balancingTransaction, signFn, 'pre-proof');
172
- return walletCtx.wallet.finalizeRecipe(recipe);
147
+ const signedRecipe = await walletCtx.wallet.signRecipe(recipe, (payload) =>
148
+ walletCtx.unshieldedKeystore.signData(payload),
149
+ );
150
+ return walletCtx.wallet.finalizeRecipe(signedRecipe);
173
151
  },
174
152
  submitTx: (tx: any) => walletCtx.wallet.submitTransaction(tx) as any,
175
153
  };
176
154
 
177
155
  const zkConfigProvider = new NodeZkConfigProvider(zkConfigPath);
156
+ const accountId = walletCtx.unshieldedKeystore.getBech32Address().toString();
178
157
 
179
158
  return {
180
- privateStateProvider: levelPrivateStateProvider({ privateStateStoreName: 'hello-world-state', walletProvider }),
159
+ privateStateProvider: levelPrivateStateProvider({
160
+ privateStateStoreName: 'hello-world-state',
161
+ accountId,
162
+ privateStoragePasswordProvider: () => privateStatePassword,
163
+ }),
181
164
  publicDataProvider: indexerPublicDataProvider(CONFIG.indexer, CONFIG.indexerWS),
182
165
  zkConfigProvider,
183
166
  proofProvider: httpClientProofProvider(CONFIG.proofServer, zkConfigProvider),
@@ -272,7 +255,7 @@ async function main() {
272
255
  const walletCtx = await createWallet(seed.trim());
273
256
 
274
257
  console.log(' Syncing with network...');
275
- const state = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.throttleTime(5000), Rx.filter((s) => s.isSynced)));
258
+ const state = await walletCtx.wallet.waitForSyncedState();
276
259
  const address = walletCtx.unshieldedKeystore.getBech32Address();
277
260
  const balance = state.unshielded.balances[unshieldedToken().raw] ?? 0n;
278
261
 
@@ -301,7 +284,7 @@ async function main() {
301
284
  console.log('─── Step 3: DUST Token Setup ───────────────────────────────────\n');
302
285
  const dustState = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.filter((s) => s.isSynced)));
303
286
 
304
- if (dustState.dust.walletBalance(new Date()) === 0n) {
287
+ if (dustState.dust.balance(new Date()) === 0n) {
305
288
  const nightUtxos = dustState.unshielded.availableCoins.filter((c: any) => !c.meta?.registeredForDustGeneration);
306
289
  if (nightUtxos.length > 0) {
307
290
  console.log(' Registering for DUST generation...');
@@ -310,12 +293,13 @@ async function main() {
310
293
  walletCtx.unshieldedKeystore.getPublicKey(),
311
294
  (payload) => walletCtx.unshieldedKeystore.signData(payload),
312
295
  );
313
- await walletCtx.wallet.submitTransaction(await walletCtx.wallet.finalizeRecipe(recipe));
296
+ const signedRecipe = await walletCtx.wallet.signRecipe(recipe, (payload) => walletCtx.unshieldedKeystore.signData(payload));
297
+ await walletCtx.wallet.submitTransaction(await walletCtx.wallet.finalizeRecipe(signedRecipe));
314
298
  }
315
299
 
316
300
  console.log(' Waiting for DUST tokens...');
317
301
  await Rx.firstValueFrom(
318
- walletCtx.wallet.state().pipe(Rx.throttleTime(5000), Rx.filter((s) => s.isSynced), Rx.filter((s) => s.dust.walletBalance(new Date()) > 0n)),
302
+ walletCtx.wallet.state().pipe(Rx.throttleTime(5000), Rx.filter((s) => s.isSynced), Rx.filter((s) => s.dust.balance(new Date()) > 0n)),
319
303
  );
320
304
  }
321
305
  console.log(' DUST tokens ready!\n');
@@ -360,11 +344,10 @@ async function main() {
360
344
 
361
345
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
362
346
  try {
363
- deployed = await deployContract(providers, {
364
- compiledContract,
365
- privateStateId: 'helloWorldState',
366
- initialPrivateState: {},
367
- });
347
+ deployed = await deployContract(providers, {
348
+ compiledContract: compiledContract as any,
349
+ args: [],
350
+ });
368
351
  break; // Success - exit retry loop
369
352
  } catch (err: any) {
370
353
  const errMsg = err?.message || err?.toString() || '';
@@ -397,8 +380,8 @@ async function main() {
397
380
  // Check if it's a DUST-related error (must check "Not enough Dust" specifically)
398
381
  if (fullError.includes('Not enough Dust')) {
399
382
  // Get current DUST balance
400
- const currentState = await Rx.firstValueFrom(walletCtx.wallet.state().pipe(Rx.filter((s) => s.isSynced)));
401
- const dustBalance = currentState.dust.walletBalance(new Date());
383
+ const currentState = await walletCtx.wallet.waitForSyncedState();
384
+ const dustBalance = currentState.dust.balance(new Date());
402
385
 
403
386
  if (attempt < MAX_RETRIES) {
404
387
  console.log(` ⏳ DUST balance: ${dustBalance.toLocaleString()} (need more for tx fees)`);
@@ -422,7 +405,7 @@ async function main() {
422
405
  console.log(' │ (DUST accumulates as blocks are produced) │');
423
406
  console.log(' │ │');
424
407
  console.log(' │ [2] Send DUST from existing wallet to this address: │');
425
- console.log(` │ ${address.slice(0, 50)}... │`);
408
+ console.log(` │ ${address.toString().slice(0, 50)}... │`);
426
409
  console.log(' │ │');
427
410
  console.log(' │ [3] Import wallet with DUST (choose option 2 on retry) │');
428
411
  console.log(' │ │');