@kuiralabs/midnight-account-chain 0.1.0 → 0.2.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/dist/cli/owner.d.ts +2 -2
- package/dist/cli/owner.js +4 -3
- package/dist/driver.d.ts +1 -1
- package/dist/driver.js +7 -4
- package/dist/scripts/completeDeploy.js +2 -1
- package/dist/scripts/deploy.js +3 -1
- package/dist/src/agent.d.ts +1 -30
- package/dist/src/agent.js +1 -5
- package/dist/src/artefacts.d.ts +13 -0
- package/dist/src/artefacts.js +257 -0
- package/dist/src/connect.d.ts +1 -12
- package/dist/src/connect.js +0 -16
- package/dist/src/localnet.d.ts +12 -2
- package/dist/src/profile.d.ts +2 -1
- package/dist/src/profile.js +14 -15
- package/dist/src/providers.d.ts +2 -1
- package/dist/src/providers.js +1 -1
- package/dist/src/seedWallets.d.ts +75 -0
- package/dist/src/seedWallets.js +31 -0
- package/dist/src/session.d.ts +1 -33
- package/dist/src/session.js +1 -6
- package/package.json +2 -2
package/dist/cli/owner.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Session } from '../src/session.ts';
|
|
2
2
|
export type Out = (text: string) => void;
|
|
3
|
-
export declare const runOwner: (argv: readonly string[], open
|
|
3
|
+
export declare const runOwner: (argv: readonly string[], open: () => Promise<Session>, out?: Out) => Promise<number>;
|
package/dist/cli/owner.js
CHANGED
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
import { randomBytes } from 'node:crypto';
|
|
19
19
|
import { grantRequestFromLink, hexOf, sealedResponseLink } from '@kuiralabs/midnight-account';
|
|
20
20
|
import { DEFAULT_LIMITS, exhaustedGrants, issueReadGrant, listRoster, revokeEveryGrant, revokeReadGrant, revokeReadGrants, termsFor } from "../src/issuance.js";
|
|
21
|
-
import { openSession } from "../src/session.js";
|
|
22
21
|
const EXIT_OK = 0;
|
|
23
22
|
const EXIT_FAILED = 1;
|
|
24
23
|
const EXIT_USAGE = 2;
|
|
@@ -216,7 +215,7 @@ const COMMANDS = {
|
|
|
216
215
|
};
|
|
217
216
|
// Runs one command and returns its exit code. The session is opened only
|
|
218
217
|
// once the command line is known to be well formed, and always closed.
|
|
219
|
-
export const runOwner = async (argv, open
|
|
218
|
+
export const runOwner = async (argv, open, out = console.log) => {
|
|
220
219
|
let flags;
|
|
221
220
|
try {
|
|
222
221
|
flags = parse(argv);
|
|
@@ -255,5 +254,7 @@ export const runOwner = async (argv, open = openSession, out = console.log) => {
|
|
|
255
254
|
await session?.close();
|
|
256
255
|
}
|
|
257
256
|
};
|
|
257
|
+
// Run as a command, the genesis wallet pays: its module is loaded only then, so
|
|
258
|
+
// the driver, which brings its own wallet, never loads testkit-js.
|
|
258
259
|
if (import.meta.main)
|
|
259
|
-
process.exitCode = await runOwner(process.argv.slice(2));
|
|
260
|
+
process.exitCode = await runOwner(process.argv.slice(2), (await import("../src/seedWallets.js")).openSession);
|
package/dist/driver.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Arm } from '@kuiralabs/midnight-account';
|
|
2
2
|
import { type Out } from './cli/owner.ts';
|
|
3
3
|
import { type FeeWallet } from './src/providers.ts';
|
|
4
|
-
export declare const DRIVER_VERSION =
|
|
4
|
+
export declare const DRIVER_VERSION = 4;
|
|
5
5
|
export declare const accountOnRecord: () => {
|
|
6
6
|
readonly address: string;
|
|
7
7
|
readonly arm: Arm;
|
package/dist/driver.js
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
// MIDNIGHT_ACCOUNT_NODE_URL the node, http(s)
|
|
9
9
|
// MIDNIGHT_ACCOUNT_INDEXER_URL the indexer's GraphQL endpoint, http(s)
|
|
10
10
|
// MIDNIGHT_ACCOUNT_PROOF_SERVER_URL the proof server, http(s)
|
|
11
|
-
// MIDNIGHT_ACCOUNT_ARTEFACTS_DIR
|
|
12
|
-
//
|
|
13
|
-
// running from the
|
|
11
|
+
// MIDNIGHT_ACCOUNT_ARTEFACTS_DIR a directory to cache the proving artefacts in, each
|
|
12
|
+
// fetched as it is first needed and checked against this
|
|
13
|
+
// package's manifest; required when running from the
|
|
14
|
+
// published package, which carries none (src/artefacts.ts)
|
|
15
|
+
// MIDNIGHT_ACCOUNT_ARTEFACTS_SOURCE optional: where they are fetched from, this build's
|
|
16
|
+
// release by default
|
|
14
17
|
// and runs with the working directory where the private-state stores should
|
|
15
18
|
// live (they are LevelDB directories under it).
|
|
16
19
|
import { existsSync, renameSync, statSync } from 'node:fs';
|
|
@@ -23,7 +26,7 @@ import { OWNER_PATHS, stateFile } from "./src/profile.js";
|
|
|
23
26
|
import { accountProviders } from "./src/providers.js";
|
|
24
27
|
import { OWNER_RECORD, openSessionOver, readOwner } from "./src/session.js";
|
|
25
28
|
// Bumped when what this module offers or expects changes in a way a caller must know.
|
|
26
|
-
export const DRIVER_VERSION =
|
|
29
|
+
export const DRIVER_VERSION = 4;
|
|
27
30
|
// A margin over the deploy transaction's validity before a deploy that has
|
|
28
31
|
// not landed is taken as one that never will.
|
|
29
32
|
const UNLANDED_MARGIN_MS = 5 * 60 * 1000;
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// resumes where it stopped.
|
|
7
7
|
import { readFileSync } from 'node:fs';
|
|
8
8
|
import { findDeployedContract } from '@midnight-ntwrk/midnight-js-contracts';
|
|
9
|
-
import { MidnightWalletProvider, createDefaultTestLogger } from '@midnight-ntwrk/testkit-js';
|
|
10
9
|
import { ACCOUNT_CIRCUITS, compiledAccount } from "../src/account.js";
|
|
11
10
|
import { GENESIS_SEED, LOCALNET } from "../src/localnet.js";
|
|
12
11
|
import { insertMissingVerifierKeys } from "../src/maintenance.js";
|
|
@@ -26,7 +25,9 @@ export const completeDeploy = async (providers, address) => {
|
|
|
26
25
|
throw new Error('the maintenance authority was not retired');
|
|
27
26
|
console.log(`all ${ACCOUNT_CIRCUITS.length} verifier keys on chain match the build; the maintenance authority is retired (counter ${authority.counter})`);
|
|
28
27
|
};
|
|
28
|
+
// Run as a script, the genesis wallet pays; testkit-js is loaded only then.
|
|
29
29
|
if (import.meta.main) {
|
|
30
|
+
const { MidnightWalletProvider, createDefaultTestLogger } = await import('@midnight-ntwrk/testkit-js');
|
|
30
31
|
const owner = JSON.parse(readFileSync(stateFile('owner.json'), 'utf8'));
|
|
31
32
|
const wallet = await MidnightWalletProvider.build(createDefaultTestLogger(), LOCALNET, GENESIS_SEED);
|
|
32
33
|
await wallet.start(true);
|
package/dist/scripts/deploy.js
CHANGED
|
@@ -28,7 +28,6 @@ import { getNetworkId } from '@midnight-ntwrk/midnight-js-network-id';
|
|
|
28
28
|
import { sampleSigningKey } from '@midnight-ntwrk/midnight-js-protocol/compact-runtime';
|
|
29
29
|
import { ContractDeploy, ContractState, Intent, Transaction } from '@midnight-ntwrk/midnight-js-protocol/ledger';
|
|
30
30
|
import { SucceedEntirely } from '@midnight-ntwrk/midnight-js-types';
|
|
31
|
-
import { MidnightWalletProvider, createDefaultTestLogger } from '@midnight-ntwrk/testkit-js';
|
|
32
31
|
import { ARMS, accountEncryptionKeyPair, bootCommitmentPreimage, fromHex, hexOf, k1PublicKey, k1SecretKey, sha256, v1PublicKey, v1SecretKey } from '@kuiralabs/midnight-account';
|
|
33
32
|
import { EMPTY_PRIVATE_STATE, compiledAccount } from "../src/account.js";
|
|
34
33
|
import { GENESIS_SEED, LOCALNET } from "../src/localnet.js";
|
|
@@ -118,7 +117,10 @@ export const deployAccount = async (providers, arm, device = freshDevice(arm)) =
|
|
|
118
117
|
await completeDeploy(providers, address);
|
|
119
118
|
return address;
|
|
120
119
|
};
|
|
120
|
+
// Run as a script, the genesis wallet pays. testkit-js is loaded only then, so
|
|
121
|
+
// the driver, which imports deployAccount with its own wallet, never loads it.
|
|
121
122
|
if (import.meta.main) {
|
|
123
|
+
const { MidnightWalletProvider, createDefaultTestLogger } = await import('@midnight-ntwrk/testkit-js');
|
|
122
124
|
const armArgument = process.argv[2] ?? 'v1';
|
|
123
125
|
const arm = ARMS.find((candidate) => candidate === armArgument);
|
|
124
126
|
if (arm === undefined)
|
package/dist/src/agent.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type Arm, type Bytes32, type GrantRequest, type SealedResponse, type Pa
|
|
|
2
2
|
import { type VersionedFinalizedTransaction } from '@midnight-ntwrk/midnight-js-types';
|
|
3
3
|
import { type DiscoveredCoin } from './coins.ts';
|
|
4
4
|
import { type UnprovenCall } from './compose.ts';
|
|
5
|
-
import {
|
|
5
|
+
import type { Connection, ShieldedAddress } from './connect.ts';
|
|
6
6
|
import { type Grantee } from './grantee.ts';
|
|
7
7
|
import { type FeeWallet } from './providers.ts';
|
|
8
8
|
export declare const AGENT_VAULT: URL;
|
|
@@ -25,35 +25,6 @@ export type AgentOptions = {
|
|
|
25
25
|
readonly mailboxOnly?: boolean;
|
|
26
26
|
};
|
|
27
27
|
export declare const agentAccount: () => string;
|
|
28
|
-
export declare const openAgent: (slot: number, options?: AgentOptions) => Promise<{
|
|
29
|
-
grantee: Grantee;
|
|
30
|
-
grantId: Bytes32;
|
|
31
|
-
payContract: (coin: DiscoveredCoin, payee: string, amount: bigint) => Promise<{
|
|
32
|
-
finalized: import("@midnight-ntwrk/midnight-js-types").FinalizedTxData;
|
|
33
|
-
sent: SealedCoin;
|
|
34
|
-
change: SealedCoin | undefined;
|
|
35
|
-
}>;
|
|
36
|
-
unprovenContractSpend: (coin: DiscoveredCoin, payee: Bytes32, amount: bigint) => Promise<UnprovenCall & {
|
|
37
|
-
readonly change: SealedCoin | undefined;
|
|
38
|
-
}>;
|
|
39
|
-
scope: import("@kuiralabs/midnight-account").GrantScope;
|
|
40
|
-
source: () => "mailbox" | "response file";
|
|
41
|
-
spent: () => bigint;
|
|
42
|
-
readCoins: () => Promise<readonly DiscoveredCoin[]>;
|
|
43
|
-
spendShielded: (coin: DiscoveredCoin, merchant: ShieldedAddress, amount: bigint) => Promise<{
|
|
44
|
-
result: import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_grant_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_grant_k256">;
|
|
45
|
-
change: SealedCoin | undefined;
|
|
46
|
-
}>;
|
|
47
|
-
proveShieldedSpend: (coin: DiscoveredCoin, merchant: ShieldedAddress, amount: bigint) => Promise<ProvedSpend>;
|
|
48
|
-
submitProved: ({ tx, amount }: ProvedSpend) => Promise<import("@midnight-ntwrk/midnight-js-types").VersionedFinalizedTxData>;
|
|
49
|
-
address: string;
|
|
50
|
-
providers: import("./providers.ts").AccountProviders;
|
|
51
|
-
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
52
|
-
self: Bytes32;
|
|
53
|
-
readLedger: () => Promise<import("../managed/Account/contract/index.js").Ledger>;
|
|
54
|
-
close: () => Promise<void>;
|
|
55
|
-
wallet: FeeWallet;
|
|
56
|
-
}>;
|
|
57
28
|
export declare const openAgentOver: (connection: Connection & {
|
|
58
29
|
readonly wallet: FeeWallet;
|
|
59
30
|
}, slot: number, { mailboxOnly }?: AgentOptions) => Promise<{
|
package/dist/src/agent.js
CHANGED
|
@@ -14,10 +14,8 @@ import { compiledAccount } from "./account.js";
|
|
|
14
14
|
import { grantFromMessages, readMailbox } from "./mailbox.js";
|
|
15
15
|
import { changeCoinOf, readAccountZswap, sentCoinOf, walkInbox } from "./coins.js";
|
|
16
16
|
import { payeeProviders, submitComposed, withClaim } from "./compose.js";
|
|
17
|
-
import { connect } from "./connect.js";
|
|
18
17
|
import { freshGrantee, granteeFromVault } from "./grantee.js";
|
|
19
|
-
import {
|
|
20
|
-
import { AGENT_PATHS, PAYEE_PATHS, ensureStateDir, stateFile } from "./profile.js";
|
|
18
|
+
import { PAYEE_PATHS, ensureStateDir, stateFile } from "./profile.js";
|
|
21
19
|
import { PRIVATE_STATE_ID } from "./providers.js";
|
|
22
20
|
export const AGENT_VAULT = stateFile('agent.json');
|
|
23
21
|
export const GRANT_REQUEST = stateFile('grant-request.json');
|
|
@@ -67,8 +65,6 @@ export const requestGrant = (account, clientId, slot, payTo, payToKind, arm) =>
|
|
|
67
65
|
};
|
|
68
66
|
// The account the agent's vault names, which its connection must be to.
|
|
69
67
|
export const agentAccount = () => readVault().account;
|
|
70
|
-
// The agent's session over its own fee wallet.
|
|
71
|
-
export const openAgent = async (slot, options = {}) => openAgentOver(await connect(agentAccount(), AGENT_FEE_SEED, AGENT_PATHS), slot, options);
|
|
72
68
|
// The agent's session over a connection the caller made to the vault's
|
|
73
69
|
// account, with the wallet that pays its fees: the grantee key, the read
|
|
74
70
|
// secret and the running spend are the vault's, whoever pays.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ZKConfigProvider } from '@midnight-ntwrk/midnight-js-types';
|
|
2
|
+
export declare const ACCOUNT_BUILD_ID: string;
|
|
3
|
+
export declare const BUILD_RELEASE: string;
|
|
4
|
+
export type ArtefactCache = {
|
|
5
|
+
readonly directory: string;
|
|
6
|
+
readonly ensure: (circuits: readonly string[]) => Promise<void>;
|
|
7
|
+
readonly provider: <K extends string>() => ZKConfigProvider<K>;
|
|
8
|
+
};
|
|
9
|
+
export type ArtefactCacheOptions = {
|
|
10
|
+
readonly source?: string;
|
|
11
|
+
readonly stallMs?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare const artefactCache: (root: string, { source, stallMs }?: ArtefactCacheOptions) => ArtefactCache;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// The account's proving artefacts for a client of this package, which ships
|
|
2
|
+
// none (a proving key is up to a quarter of a gigabyte): fetched one circuit's
|
|
3
|
+
// file at a time, when midnight-js first asks for it, into a cache kept per
|
|
4
|
+
// build, and kept only when it matches this package's manifest.
|
|
5
|
+
//
|
|
6
|
+
// The trust chain: the manifest this package carries (compactc's, beside the
|
|
7
|
+
// compiled contract) lists a SHA-256 and a size for every key and ZKIR file. A
|
|
8
|
+
// fetched file is kept only if it matches, so a key is as trusted as this
|
|
9
|
+
// package, wherever it came from. The cache is laid out as compactc's output,
|
|
10
|
+
// manifest included, so midnight-js's own provider checks every file again as
|
|
11
|
+
// it reads it. A wrong proving key could not spend anything anyway: the node
|
|
12
|
+
// verifies every proof against the verifier key the account holds on chain.
|
|
13
|
+
//
|
|
14
|
+
// Where from: the build's release in kuiralabs/midnight-account-artifacts by
|
|
15
|
+
// default, or a source the caller names:
|
|
16
|
+
// - an http(s) URL laid out as a release, every file under its own name
|
|
17
|
+
// (<source>/<circuit>.prover, .verifier, .bzkir). Its query string is kept
|
|
18
|
+
// for every file, so a URL signed for the whole prefix works; one signed for
|
|
19
|
+
// a single object cannot.
|
|
20
|
+
// - an absolute directory (or file: URL) laid out as compactc's output
|
|
21
|
+
// (<source>/keys/<circuit>.prover, ...), as a local build of the contract is.
|
|
22
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
23
|
+
import { createReadStream, createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { copyFile } from 'node:fs/promises';
|
|
25
|
+
import { dirname, isAbsolute, join } from 'node:path';
|
|
26
|
+
import { pipeline } from 'node:stream/promises';
|
|
27
|
+
import { fileURLToPath } from 'node:url';
|
|
28
|
+
import { NodeZkConfigProvider } from '@midnight-ntwrk/midnight-js-node-zk-config-provider';
|
|
29
|
+
import { ZKConfigProvider } from '@midnight-ntwrk/midnight-js-types';
|
|
30
|
+
import { ACCOUNT_BUILD } from "./account.js";
|
|
31
|
+
// Where each build's release is: its tag is `build-` and the build's id.
|
|
32
|
+
const ARTEFACT_RELEASES = 'https://github.com/kuiralabs/midnight-account-artifacts/releases/download/';
|
|
33
|
+
// A fetch is abandoned when no bytes arrive for this long.
|
|
34
|
+
const FETCH_STALL_MS = 60_000;
|
|
35
|
+
// A build's id: this many hex digits of its manifest's SHA-256.
|
|
36
|
+
const BUILD_ID_HEX_DIGITS = 16;
|
|
37
|
+
const KEYS = 'keys';
|
|
38
|
+
const ZKIR_DIRECTORY = 'zkir';
|
|
39
|
+
const COMPILER = 'compiler';
|
|
40
|
+
const MANIFEST = 'contract-manifest.json';
|
|
41
|
+
const CONTRACT_INFO = 'contract-info.json';
|
|
42
|
+
const ARTEFACT_DIRECTORIES = [KEYS, ZKIR_DIRECTORY];
|
|
43
|
+
const manifestBytes = () => readFileSync(join(ACCOUNT_BUILD, COMPILER, MANIFEST));
|
|
44
|
+
// This package's build of the account, by the hash of its manifest.
|
|
45
|
+
export const ACCOUNT_BUILD_ID = createHash('sha256').update(manifestBytes()).digest('hex').slice(0, BUILD_ID_HEX_DIGITS);
|
|
46
|
+
// This build's release, the source when none is named.
|
|
47
|
+
export const BUILD_RELEASE = `${ARTEFACT_RELEASES}build-${ACCOUNT_BUILD_ID}/`;
|
|
48
|
+
const MANIFEST_ENTRIES = JSON.parse(manifestBytes().toString('utf8'));
|
|
49
|
+
const entryOf = (directory, name) => {
|
|
50
|
+
const entry = MANIFEST_ENTRIES[directory][name];
|
|
51
|
+
if (entry?.type !== 'file')
|
|
52
|
+
throw new Error(`this build of the account has no ${directory}/${name}`);
|
|
53
|
+
return entry;
|
|
54
|
+
};
|
|
55
|
+
const proverKeyFile = (circuit) => [KEYS, `${circuit}.prover`];
|
|
56
|
+
const verifierKeyFile = (circuit) => [KEYS, `${circuit}.verifier`];
|
|
57
|
+
const zkirFile = (circuit) => [ZKIR_DIRECTORY, `${circuit}.bzkir`];
|
|
58
|
+
const hasCode = (error, code) => error instanceof Error && 'code' in error && error.code === code;
|
|
59
|
+
// A temporary file beside `path`, named for the process writing it, so a run
|
|
60
|
+
// can tell a dead process's leftovers from a live one's.
|
|
61
|
+
const TEMPORARY_RANDOM_BYTES = 6;
|
|
62
|
+
const temporaryPath = (path) => `${path}.${process.pid}.${randomBytes(TEMPORARY_RANDOM_BYTES).toString('hex')}.tmp`;
|
|
63
|
+
const TEMPORARY_NAME = new RegExp(`\\.(\\d+)\\.[0-9a-f]{${TEMPORARY_RANDOM_BYTES * 2}}\\.tmp$`);
|
|
64
|
+
const isRunning = (pid) => {
|
|
65
|
+
try {
|
|
66
|
+
process.kill(pid, 0);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
catch (cause) {
|
|
70
|
+
return hasCode(cause, 'EPERM');
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
// Removes a file another process may be removing at the same moment.
|
|
74
|
+
const removeIfThere = (path) => {
|
|
75
|
+
try {
|
|
76
|
+
unlinkSync(path);
|
|
77
|
+
}
|
|
78
|
+
catch (cause) {
|
|
79
|
+
if (!hasCode(cause, 'ENOENT'))
|
|
80
|
+
throw cause;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const sizeOf = (path) => {
|
|
84
|
+
try {
|
|
85
|
+
return statSync(path).size;
|
|
86
|
+
}
|
|
87
|
+
catch (cause) {
|
|
88
|
+
if (hasCode(cause, 'ENOENT'))
|
|
89
|
+
return undefined;
|
|
90
|
+
throw cause;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const sha256Of = async (path) => {
|
|
94
|
+
const hash = createHash('sha256');
|
|
95
|
+
for await (const chunk of createReadStream(path))
|
|
96
|
+
hash.update(chunk);
|
|
97
|
+
return hash.digest('hex');
|
|
98
|
+
};
|
|
99
|
+
const matches = async (path, entry) => sizeOf(path) === entry.size && (await sha256Of(path)) === entry.hash;
|
|
100
|
+
const sourceOf = (source) => {
|
|
101
|
+
if (/^https?:\/\//.test(source))
|
|
102
|
+
return { kind: 'url', base: new URL(source) };
|
|
103
|
+
const path = source.startsWith('file://') ? fileURLToPath(source) : source;
|
|
104
|
+
if (!isAbsolute(path))
|
|
105
|
+
throw new Error(`the source of the proving artefacts must be an http(s) URL or an absolute directory, not ${JSON.stringify(source)}`);
|
|
106
|
+
return { kind: 'directory', path };
|
|
107
|
+
};
|
|
108
|
+
// `name` under the base URL's path, keeping its query string.
|
|
109
|
+
const urlOf = (base, name) => {
|
|
110
|
+
const url = new URL(base);
|
|
111
|
+
url.pathname = `${url.pathname.replace(/\/?$/, '/')}${name}`;
|
|
112
|
+
return url;
|
|
113
|
+
};
|
|
114
|
+
// Streams `url` into `temporary`, refusing more bytes than the manifest's size
|
|
115
|
+
// and giving up when the server stalls for `stallMs`. The request is aborted
|
|
116
|
+
// once done either way, so a refused response's body never holds a socket open.
|
|
117
|
+
const download = async (url, temporary, entry, stallMs) => {
|
|
118
|
+
const controller = new AbortController();
|
|
119
|
+
const stall = setTimeout(() => controller.abort(new Error(`no data for ${stallMs / 1000} s`)), stallMs);
|
|
120
|
+
try {
|
|
121
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
122
|
+
const body = response.body;
|
|
123
|
+
if (!response.ok || body === null)
|
|
124
|
+
throw new Error(`HTTP ${response.status}`);
|
|
125
|
+
let received = 0;
|
|
126
|
+
await pipeline(async function* () {
|
|
127
|
+
for await (const chunk of body) {
|
|
128
|
+
received += chunk.length;
|
|
129
|
+
if (received > entry.size)
|
|
130
|
+
throw new Error(`more than the manifest's ${entry.size} bytes`);
|
|
131
|
+
stall.refresh();
|
|
132
|
+
yield chunk;
|
|
133
|
+
}
|
|
134
|
+
}, createWriteStream(temporary));
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
clearTimeout(stall);
|
|
138
|
+
controller.abort();
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
// The cache for this build under `root` (its own directory there, named by the
|
|
142
|
+
// build's id, so two builds' files never mix): the manifest is placed in it,
|
|
143
|
+
// and what a killed fetch left is removed.
|
|
144
|
+
export const artefactCache = (root, { source = BUILD_RELEASE, stallMs = FETCH_STALL_MS } = {}) => {
|
|
145
|
+
if (!isAbsolute(root))
|
|
146
|
+
throw new Error(`the proving artefacts' cache must be an absolute path, not ${JSON.stringify(root)}`);
|
|
147
|
+
const from = sourceOf(source);
|
|
148
|
+
const directory = join(root, ACCOUNT_BUILD_ID);
|
|
149
|
+
placeCompilerFiles(directory);
|
|
150
|
+
removeAbandoned(directory);
|
|
151
|
+
// One fetch per file at a time: a second ask waits for the first.
|
|
152
|
+
const inFlight = new Map();
|
|
153
|
+
const ensureFile = ([folder, name]) => {
|
|
154
|
+
const relative = `${folder}/${name}`;
|
|
155
|
+
const running = inFlight.get(relative);
|
|
156
|
+
if (running !== undefined)
|
|
157
|
+
return running;
|
|
158
|
+
const fetching = (async () => {
|
|
159
|
+
const target = join(directory, folder, name);
|
|
160
|
+
const entry = entryOf(folder, name);
|
|
161
|
+
if (!(await matches(target, entry)))
|
|
162
|
+
await fetchInto(from, folder, name, target, entry, stallMs);
|
|
163
|
+
})().finally(() => inFlight.delete(relative));
|
|
164
|
+
inFlight.set(relative, fetching);
|
|
165
|
+
return fetching;
|
|
166
|
+
};
|
|
167
|
+
const ensure = async (circuits) => {
|
|
168
|
+
for (const circuit of circuits)
|
|
169
|
+
for (const file of [proverKeyFile(circuit), verifierKeyFile(circuit), zkirFile(circuit)])
|
|
170
|
+
await ensureFile(file);
|
|
171
|
+
};
|
|
172
|
+
const provider = () => new FetchingZkConfigProvider(new NodeZkConfigProvider(directory), ensureFile);
|
|
173
|
+
return { directory, ensure, provider };
|
|
174
|
+
};
|
|
175
|
+
// midnight-js's provider over the cache, each file fetched before it is read.
|
|
176
|
+
class FetchingZkConfigProvider extends ZKConfigProvider {
|
|
177
|
+
cached;
|
|
178
|
+
ensureFile;
|
|
179
|
+
constructor(cached, ensureFile) {
|
|
180
|
+
super();
|
|
181
|
+
this.cached = cached;
|
|
182
|
+
this.ensureFile = ensureFile;
|
|
183
|
+
}
|
|
184
|
+
getArtifactRuntimeVersion() {
|
|
185
|
+
return this.cached.getArtifactRuntimeVersion();
|
|
186
|
+
}
|
|
187
|
+
async getProverKey(circuitId) {
|
|
188
|
+
await this.ensureFile(proverKeyFile(circuitId));
|
|
189
|
+
return this.cached.getProverKey(circuitId);
|
|
190
|
+
}
|
|
191
|
+
async getVerifierKey(circuitId) {
|
|
192
|
+
await this.ensureFile(verifierKeyFile(circuitId));
|
|
193
|
+
return this.cached.getVerifierKey(circuitId);
|
|
194
|
+
}
|
|
195
|
+
async getZKIR(circuitId) {
|
|
196
|
+
await this.ensureFile(zkirFile(circuitId));
|
|
197
|
+
return this.cached.getZKIR(circuitId);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Writes this build's compiler files into the cache, atomically, unless the
|
|
201
|
+
// same ones are there; a cache holding another build's is refused.
|
|
202
|
+
const placeCompilerFiles = (directory) => {
|
|
203
|
+
mkdirSync(join(directory, COMPILER), { recursive: true });
|
|
204
|
+
for (const name of [MANIFEST, CONTRACT_INFO]) {
|
|
205
|
+
const ours = readFileSync(join(ACCOUNT_BUILD, COMPILER, name));
|
|
206
|
+
const target = join(directory, COMPILER, name);
|
|
207
|
+
if (existsSync(target)) {
|
|
208
|
+
if (readFileSync(target).equals(ours))
|
|
209
|
+
continue;
|
|
210
|
+
throw new Error(`${target} is another build's: the cache ${directory} is not this build's`);
|
|
211
|
+
}
|
|
212
|
+
const temporary = temporaryPath(target);
|
|
213
|
+
writeFileSync(temporary, ours);
|
|
214
|
+
renameSync(temporary, target);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
// Removes the temporary files of fetches whose process is gone (killed
|
|
218
|
+
// mid-download); a running process's own are left alone.
|
|
219
|
+
const removeAbandoned = (directory) => {
|
|
220
|
+
for (const folder of ARTEFACT_DIRECTORIES) {
|
|
221
|
+
const path = join(directory, folder);
|
|
222
|
+
if (!existsSync(path))
|
|
223
|
+
continue;
|
|
224
|
+
for (const name of readdirSync(path)) {
|
|
225
|
+
const pid = TEMPORARY_NAME.exec(name)?.[1];
|
|
226
|
+
if (pid !== undefined && !isRunning(Number(pid)))
|
|
227
|
+
removeIfThere(join(path, name));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
// Fetches one file to a temporary path beside `target`, checks it against its
|
|
232
|
+
// manifest entry, and only then moves it into place. A URL serves it under its
|
|
233
|
+
// own name, a directory under its compactc directory.
|
|
234
|
+
const fetchInto = async (source, folder, name, target, entry, stallMs) => {
|
|
235
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
236
|
+
const temporary = temporaryPath(target);
|
|
237
|
+
const from = source.kind === 'url' ? urlOf(source.base, name).href : join(source.path, folder, name);
|
|
238
|
+
try {
|
|
239
|
+
if (source.kind === 'url') {
|
|
240
|
+
await download(new URL(from), temporary, entry, stallMs);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
if (!existsSync(from))
|
|
244
|
+
throw new Error('not found');
|
|
245
|
+
await copyFile(from, temporary);
|
|
246
|
+
}
|
|
247
|
+
if (!(await matches(temporary, entry)))
|
|
248
|
+
throw new Error("not this build's file: refused");
|
|
249
|
+
renameSync(temporary, target);
|
|
250
|
+
}
|
|
251
|
+
catch (cause) {
|
|
252
|
+
throw new Error(`${folder}/${name} from ${from}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
removeIfThere(temporary);
|
|
256
|
+
}
|
|
257
|
+
};
|
package/dist/src/connect.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { MidnightWalletProvider } from '@midnight-ntwrk/testkit-js';
|
|
1
|
+
import type { EncPublicKey } from '@midnight-ntwrk/midnight-js-protocol/ledger';
|
|
3
2
|
import { type Bytes32 } from '@kuiralabs/midnight-account';
|
|
4
3
|
import { type Ledger } from '../managed/Account/contract/index.js';
|
|
5
4
|
import { type FeeWallet, type ProviderPaths } from './providers.ts';
|
|
@@ -12,18 +11,8 @@ export declare const connectOver: (address: string, wallet: FeeWallet, paths: Pr
|
|
|
12
11
|
readLedger: () => Promise<Ledger>;
|
|
13
12
|
close: () => Promise<void>;
|
|
14
13
|
}>;
|
|
15
|
-
export declare const connect: (address: string, walletSeed: string, paths: ProviderPaths) => Promise<{
|
|
16
|
-
wallet: MidnightWalletProvider;
|
|
17
|
-
address: string;
|
|
18
|
-
providers: import("./providers.ts").AccountProviders;
|
|
19
|
-
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
20
|
-
self: Bytes32;
|
|
21
|
-
readLedger: () => Promise<Ledger>;
|
|
22
|
-
close: () => Promise<void>;
|
|
23
|
-
}>;
|
|
24
14
|
export declare const timed: <T>(label: string, run: () => Promise<T>) => Promise<T>;
|
|
25
15
|
export type ShieldedAddress = {
|
|
26
16
|
readonly coinPublicKey: Bytes32;
|
|
27
17
|
readonly encryptionPublicKey: EncPublicKey;
|
|
28
18
|
};
|
|
29
|
-
export declare const shieldedAddressOf: (walletSeed: string) => ShieldedAddress;
|
package/dist/src/connect.js
CHANGED
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
// providers and private-state store, the found contract, and reads of the
|
|
3
3
|
// account's public state.
|
|
4
4
|
import { findDeployedContract } from '@midnight-ntwrk/midnight-js-contracts';
|
|
5
|
-
import { ZswapSecretKeys } from '@midnight-ntwrk/midnight-js-protocol/ledger';
|
|
6
|
-
import { MidnightWalletProvider, createDefaultTestLogger, getShieldedSeed } from '@midnight-ntwrk/testkit-js';
|
|
7
5
|
import { fromHex } from '@kuiralabs/midnight-account';
|
|
8
6
|
import { ledger } from '../managed/Account/contract/index.js';
|
|
9
7
|
import { EMPTY_PRIVATE_STATE, compiledAccount } from "./account.js";
|
|
10
|
-
import { LOCALNET } from "./localnet.js";
|
|
11
8
|
import { PRIVATE_STATE_ID, accountProviders } from "./providers.js";
|
|
12
9
|
// A connection over a wallet the caller brings and will close: the account's
|
|
13
10
|
// calls need only that it balances and submits (FeeWallet).
|
|
@@ -31,13 +28,6 @@ export const connectOver = async (address, wallet, paths, close) => {
|
|
|
31
28
|
};
|
|
32
29
|
return { address, providers, account, self, readLedger, close };
|
|
33
30
|
};
|
|
34
|
-
// A connection over the testkit wallet of a seed, which it starts and stops.
|
|
35
|
-
// The scripts that move the wallet's own funds reach it as `wallet`.
|
|
36
|
-
export const connect = async (address, walletSeed, paths) => {
|
|
37
|
-
const wallet = await MidnightWalletProvider.build(createDefaultTestLogger(), LOCALNET, walletSeed);
|
|
38
|
-
await wallet.start(true);
|
|
39
|
-
return { ...(await connectOver(address, wallet, paths, () => wallet.stop())), wallet };
|
|
40
|
-
};
|
|
41
31
|
// Times one on-chain step and reports it.
|
|
42
32
|
export const timed = async (label, run) => {
|
|
43
33
|
const startedAt = Date.now();
|
|
@@ -45,9 +35,3 @@ export const timed = async (label, run) => {
|
|
|
45
35
|
console.log(`${label}: ${((Date.now() - startedAt) / 1000).toFixed(1)} s`);
|
|
46
36
|
return result;
|
|
47
37
|
};
|
|
48
|
-
// A wallet seed's shielded address, derived as the wallet derives it (the
|
|
49
|
-
// Zswap role of account 0, key 0), without syncing that wallet.
|
|
50
|
-
export const shieldedAddressOf = (walletSeed) => {
|
|
51
|
-
const keys = ZswapSecretKeys.fromSeed(getShieldedSeed(walletSeed));
|
|
52
|
-
return { coinPublicKey: fromHex(keys.coinPublicKey, 32), encryptionPublicKey: keys.encryptionPublicKey };
|
|
53
|
-
};
|
package/dist/src/localnet.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NetworkId } from '@midnightntwrk/wallet-sdk';
|
|
2
2
|
export declare const NETWORK_ID = "undeployed";
|
|
3
3
|
export declare const GENESIS_SEED = "0000000000000000000000000000000000000000000000000000000000000001";
|
|
4
4
|
export declare const AGENT_FEE_SEED = "0000000000000000000000000000000000000000000000000000000000000002";
|
|
5
5
|
export declare const MERCHANT_SEED = "0000000000000000000000000000000000000000000000000000000000000003";
|
|
6
|
-
export
|
|
6
|
+
export type Network = {
|
|
7
|
+
readonly networkId: string;
|
|
8
|
+
readonly walletNetworkId: NetworkId.NetworkId;
|
|
9
|
+
readonly node: string;
|
|
10
|
+
readonly nodeWS: string;
|
|
11
|
+
readonly indexer: string;
|
|
12
|
+
readonly indexerWS: string;
|
|
13
|
+
readonly proofServer: string;
|
|
14
|
+
readonly faucet: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
export declare const LOCALNET: Network;
|
package/dist/src/profile.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { type ArtefactCache } from './artefacts.ts';
|
|
1
2
|
import type { ProviderPaths } from './providers.ts';
|
|
2
3
|
export declare const PROFILE: string | undefined;
|
|
3
4
|
export declare const STATE_DIR: URL;
|
|
4
5
|
export declare const stateFile: (name: string) => URL;
|
|
5
6
|
export declare const ensureStateDir: () => void;
|
|
6
|
-
export declare const ARTEFACTS: string;
|
|
7
|
+
export declare const ARTEFACTS: string | ArtefactCache;
|
|
7
8
|
export declare const OWNER_PATHS: ProviderPaths;
|
|
8
9
|
export declare const AGENT_PATHS: ProviderPaths;
|
|
9
10
|
export declare const PAYEE_PATHS: ProviderPaths;
|
package/dist/src/profile.js
CHANGED
|
@@ -10,13 +10,16 @@
|
|
|
10
10
|
// profiles then live under it the same way.
|
|
11
11
|
//
|
|
12
12
|
// The proving artefacts are the repo's own build. The package as published
|
|
13
|
-
// carries none (they are
|
|
14
|
-
//
|
|
15
|
-
// as
|
|
16
|
-
|
|
13
|
+
// carries none (they are gigabytes), so a caller running from it names a
|
|
14
|
+
// directory to cache them in with MIDNIGHT_ACCOUNT_ARTEFACTS_DIR: each file is
|
|
15
|
+
// fetched as it is first needed, from this build's release or from
|
|
16
|
+
// MIDNIGHT_ACCOUNT_ARTEFACTS_SOURCE, and kept only if it matches this
|
|
17
|
+
// package's manifest (artefacts.ts).
|
|
18
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
17
19
|
import { isAbsolute, join } from 'node:path';
|
|
18
20
|
import { pathToFileURL } from 'node:url';
|
|
19
21
|
import { ACCOUNT_BUILD } from "./account.js";
|
|
22
|
+
import { artefactCache } from "./artefacts.js";
|
|
20
23
|
// A profile name is a plain directory name, so it can neither escape
|
|
21
24
|
// .state/ nor alias the default profile's directory.
|
|
22
25
|
const PROFILE_NAME = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
@@ -45,26 +48,22 @@ export const ensureStateDir = () => {
|
|
|
45
48
|
};
|
|
46
49
|
// A private-state store name for this profile.
|
|
47
50
|
const profileStore = (base) => (PROFILE === undefined ? base : `${base}-${PROFILE}`);
|
|
48
|
-
const MANIFEST = join('compiler', 'contract-manifest.json');
|
|
49
51
|
const KEYS = 'keys';
|
|
50
|
-
// The proving artefacts every party proves with: the directory the
|
|
51
|
-
// names,
|
|
52
|
-
// holds them.
|
|
52
|
+
// The proving artefacts every party proves with: a cache in the directory the
|
|
53
|
+
// caller names, else this package's own build, if it holds them.
|
|
53
54
|
const artefactsFromEnvironment = () => {
|
|
54
55
|
const directory = process.env.MIDNIGHT_ACCOUNT_ARTEFACTS_DIR;
|
|
56
|
+
const source = process.env.MIDNIGHT_ACCOUNT_ARTEFACTS_SOURCE;
|
|
55
57
|
if (directory === undefined) {
|
|
58
|
+
if (source !== undefined)
|
|
59
|
+
throw new Error('MIDNIGHT_ACCOUNT_ARTEFACTS_SOURCE needs MIDNIGHT_ACCOUNT_ARTEFACTS_DIR: name the directory to cache the proving artefacts in');
|
|
56
60
|
if (!existsSync(join(ACCOUNT_BUILD, KEYS)))
|
|
57
|
-
throw new Error('this build of the account carries no proving keys: name a directory
|
|
61
|
+
throw new Error('this build of the account carries no proving keys: name a directory to cache them in with MIDNIGHT_ACCOUNT_ARTEFACTS_DIR');
|
|
58
62
|
return ACCOUNT_BUILD;
|
|
59
63
|
}
|
|
60
64
|
if (!isAbsolute(directory))
|
|
61
65
|
throw new Error(`MIDNIGHT_ACCOUNT_ARTEFACTS_DIR must be an absolute path: ${JSON.stringify(directory)}`);
|
|
62
|
-
|
|
63
|
-
if (!existsSync(manifest))
|
|
64
|
-
throw new Error(`MIDNIGHT_ACCOUNT_ARTEFACTS_DIR holds no ${MANIFEST}: ${directory}`);
|
|
65
|
-
if (!readFileSync(manifest).equals(readFileSync(join(ACCOUNT_BUILD, MANIFEST))))
|
|
66
|
-
throw new Error(`MIDNIGHT_ACCOUNT_ARTEFACTS_DIR holds another build of the account than this package's: ${directory}`);
|
|
67
|
-
return directory;
|
|
66
|
+
return artefactCache(directory, source === undefined ? {} : { source });
|
|
68
67
|
};
|
|
69
68
|
export const ARTEFACTS = artefactsFromEnvironment();
|
|
70
69
|
// Each party's providers for this profile.
|
package/dist/src/providers.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { MidnightProvider, MidnightProviders, WalletProvider } from '@midnight-ntwrk/midnight-js-types';
|
|
2
2
|
import type { AccountCircuitId, AccountPrivateState } from './account.ts';
|
|
3
|
+
import type { ArtefactCache } from './artefacts.ts';
|
|
3
4
|
export declare const PRIVATE_STATE_ID = "account";
|
|
4
5
|
export type AccountProviders = MidnightProviders<AccountCircuitId, string, AccountPrivateState>;
|
|
5
6
|
export type ProviderPaths = {
|
|
6
7
|
readonly store: string;
|
|
7
|
-
readonly artefacts: string;
|
|
8
|
+
readonly artefacts: string | ArtefactCache;
|
|
8
9
|
};
|
|
9
10
|
export type FeeWallet = WalletProvider & MidnightProvider;
|
|
10
11
|
export declare const accountProviders: (wallet: FeeWallet, { store, artefacts }: ProviderPaths) => AccountProviders;
|
package/dist/src/providers.js
CHANGED
|
@@ -16,7 +16,7 @@ const STORE_PASSWORD = 'Answer to the Ultimate Question of Life, the Universe, a
|
|
|
16
16
|
// before this function existed are still found.
|
|
17
17
|
const storeAccountOf = (wallet) => Buffer.from(wallet.getCoinPublicKey()).toString('hex');
|
|
18
18
|
export const accountProviders = (wallet, { store, artefacts }) => {
|
|
19
|
-
const zkConfigProvider = new NodeZkConfigProvider(artefacts);
|
|
19
|
+
const zkConfigProvider = typeof artefacts === 'string' ? new NodeZkConfigProvider(artefacts) : artefacts.provider();
|
|
20
20
|
return {
|
|
21
21
|
privateStateProvider: levelPrivateStateProvider({
|
|
22
22
|
privateStateStoreName: store,
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { MidnightWalletProvider } from '@midnight-ntwrk/testkit-js';
|
|
2
|
+
import { type AgentOptions } from './agent.ts';
|
|
3
|
+
import { type ShieldedAddress } from './connect.ts';
|
|
4
|
+
import type { ProviderPaths } from './providers.ts';
|
|
5
|
+
export declare const connect: (address: string, walletSeed: string, paths: ProviderPaths) => Promise<{
|
|
6
|
+
wallet: MidnightWalletProvider;
|
|
7
|
+
address: string;
|
|
8
|
+
providers: import("./providers.ts").AccountProviders;
|
|
9
|
+
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
10
|
+
self: import("@kuiralabs/midnight-account").Bytes32;
|
|
11
|
+
readLedger: () => Promise<import("../managed/Account/contract/index.js").Ledger>;
|
|
12
|
+
close: () => Promise<void>;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const shieldedAddressOf: (walletSeed: string) => ShieldedAddress;
|
|
15
|
+
export declare const openSession: () => Promise<{
|
|
16
|
+
wallet: MidnightWalletProvider;
|
|
17
|
+
address: string;
|
|
18
|
+
providers: import("./providers.ts").AccountProviders;
|
|
19
|
+
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
20
|
+
self: import("@kuiralabs/midnight-account").Bytes32;
|
|
21
|
+
readLedger: () => Promise<import("../managed/Account/contract/index.js").Ledger>;
|
|
22
|
+
close: () => Promise<void>;
|
|
23
|
+
} & {
|
|
24
|
+
device: import("./device.ts").OwnerDevice;
|
|
25
|
+
bootSalt: Uint8Array<ArrayBufferLike>;
|
|
26
|
+
encSecret: () => import("@kuiralabs/midnight-account").Bytes32;
|
|
27
|
+
calls: {
|
|
28
|
+
activate: (bootSalt: import("@kuiralabs/midnight-account").Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "activate_initial_device_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "activate_initial_device_with_k256">>;
|
|
29
|
+
withdrawUnshielded: (color: import("@kuiralabs/midnight-account").Bytes32, amount: bigint, recipient: import("@kuiralabs/midnight-account").Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_unshielded_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_unshielded_with_k256">>;
|
|
30
|
+
withdrawShielded: (recipient: import("@kuiralabs/midnight-account").Bytes32, amount: bigint, coin: import("@kuiralabs/midnight-account").HeldCoin) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_k256">>;
|
|
31
|
+
unprovenWithdrawShieldedToContract: (recipient: import("@kuiralabs/midnight-account").Bytes32, amount: bigint, coin: import("@kuiralabs/midnight-account").HeldCoin) => Promise<import("./compose.ts").UnprovenCall & {
|
|
32
|
+
readonly landed: () => Promise<void>;
|
|
33
|
+
}>;
|
|
34
|
+
appendInbox: (entry: Uint8Array) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "append_inbox_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "append_inbox_with_k256">>;
|
|
35
|
+
rotateEncKey: (newKey: import("@kuiralabs/midnight-account").Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "rotate_enc_key_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "rotate_enc_key_with_k256">>;
|
|
36
|
+
addDevice: (newPk: import("@kuiralabs/midnight-account").Point) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "add_device_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "add_device_with_k256">>;
|
|
37
|
+
issueGrant: (grantId: import("@kuiralabs/midnight-account").Bytes32, scope: import("@kuiralabs/midnight-account").GrantScope) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "issue_grant_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "issue_grant_with_k256">>;
|
|
38
|
+
revokeGrant: (grantId: import("@kuiralabs/midnight-account").Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_grant_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_grant_with_k256">>;
|
|
39
|
+
revokeAllGrants: () => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_all_grants_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_all_grants_with_k256">>;
|
|
40
|
+
};
|
|
41
|
+
expectChange: (change: import("@kuiralabs/midnight-account").SealedCoin) => void;
|
|
42
|
+
settleChanges: () => Promise<number>;
|
|
43
|
+
refreshCoins: () => Promise<readonly import("./coins.ts").DiscoveredCoin[]>;
|
|
44
|
+
reencryptHoldings: () => Promise<number>;
|
|
45
|
+
rotateEncKey: () => Promise<number>;
|
|
46
|
+
}>;
|
|
47
|
+
export declare const openAgent: (slot: number, options?: AgentOptions) => Promise<{
|
|
48
|
+
grantee: import("./grantee.ts").Grantee;
|
|
49
|
+
grantId: import("@kuiralabs/midnight-account").Bytes32;
|
|
50
|
+
payContract: (coin: import("./coins.ts").DiscoveredCoin, payee: string, amount: bigint) => Promise<{
|
|
51
|
+
finalized: import("@midnight-ntwrk/midnight-js-types").FinalizedTxData;
|
|
52
|
+
sent: import("@kuiralabs/midnight-account").SealedCoin;
|
|
53
|
+
change: import("@kuiralabs/midnight-account").SealedCoin | undefined;
|
|
54
|
+
}>;
|
|
55
|
+
unprovenContractSpend: (coin: import("./coins.ts").DiscoveredCoin, payee: import("@kuiralabs/midnight-account").Bytes32, amount: bigint) => Promise<import("./compose.ts").UnprovenCall & {
|
|
56
|
+
readonly change: import("@kuiralabs/midnight-account").SealedCoin | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
scope: import("@kuiralabs/midnight-account").GrantScope;
|
|
59
|
+
source: () => "mailbox" | "response file";
|
|
60
|
+
spent: () => bigint;
|
|
61
|
+
readCoins: () => Promise<readonly import("./coins.ts").DiscoveredCoin[]>;
|
|
62
|
+
spendShielded: (coin: import("./coins.ts").DiscoveredCoin, merchant: ShieldedAddress, amount: bigint) => Promise<{
|
|
63
|
+
result: import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_grant_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_grant_k256">;
|
|
64
|
+
change: import("@kuiralabs/midnight-account").SealedCoin | undefined;
|
|
65
|
+
}>;
|
|
66
|
+
proveShieldedSpend: (coin: import("./coins.ts").DiscoveredCoin, merchant: ShieldedAddress, amount: bigint) => Promise<import("./agent.ts").ProvedSpend>;
|
|
67
|
+
submitProved: ({ tx, amount }: import("./agent.ts").ProvedSpend) => Promise<import("@midnight-ntwrk/midnight-js-types").VersionedFinalizedTxData>;
|
|
68
|
+
address: string;
|
|
69
|
+
providers: import("./providers.ts").AccountProviders;
|
|
70
|
+
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
71
|
+
self: import("@kuiralabs/midnight-account").Bytes32;
|
|
72
|
+
readLedger: () => Promise<import("../managed/Account/contract/index.js").Ledger>;
|
|
73
|
+
close: () => Promise<void>;
|
|
74
|
+
wallet: import("./providers.ts").FeeWallet;
|
|
75
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// The repository's own parties, each paid by the testkit wallet of a localnet
|
|
2
|
+
// seed: the owner by the genesis wallet, the agent by its fee wallet. Only the
|
|
3
|
+
// repository's scripts and command line use them, so they are not built, and
|
|
4
|
+
// nothing a client loads reaches testkit-js. A client brings its own wallet
|
|
5
|
+
// instead (connectOver, openSessionOver, openAgentOver).
|
|
6
|
+
import { ZswapSecretKeys } from '@midnight-ntwrk/midnight-js-protocol/ledger';
|
|
7
|
+
import { MidnightWalletProvider, createDefaultTestLogger, getShieldedSeed } from '@midnight-ntwrk/testkit-js';
|
|
8
|
+
import { fromHex } from '@kuiralabs/midnight-account';
|
|
9
|
+
import { agentAccount, openAgentOver } from "./agent.js";
|
|
10
|
+
import { connectOver } from "./connect.js";
|
|
11
|
+
import { AGENT_FEE_SEED, GENESIS_SEED, LOCALNET } from "./localnet.js";
|
|
12
|
+
import { AGENT_PATHS, OWNER_PATHS } from "./profile.js";
|
|
13
|
+
import { openSessionOver, readOwner } from "./session.js";
|
|
14
|
+
// A connection over the testkit wallet of a seed, which it starts and stops.
|
|
15
|
+
// The scripts that move the wallet's own funds reach it as `wallet`.
|
|
16
|
+
export const connect = async (address, walletSeed, paths) => {
|
|
17
|
+
const wallet = await MidnightWalletProvider.build(createDefaultTestLogger(), LOCALNET, walletSeed);
|
|
18
|
+
await wallet.start(true);
|
|
19
|
+
return { ...(await connectOver(address, wallet, paths, () => wallet.stop())), wallet };
|
|
20
|
+
};
|
|
21
|
+
// A wallet seed's shielded address, derived as the wallet derives it (the
|
|
22
|
+
// Zswap role of account 0, key 0), without syncing that wallet.
|
|
23
|
+
export const shieldedAddressOf = (walletSeed) => {
|
|
24
|
+
const keys = ZswapSecretKeys.fromSeed(getShieldedSeed(walletSeed));
|
|
25
|
+
return { coinPublicKey: fromHex(keys.coinPublicKey, 32), encryptionPublicKey: keys.encryptionPublicKey };
|
|
26
|
+
};
|
|
27
|
+
// The owner's session paid by the genesis wallet, which the scripts that move
|
|
28
|
+
// that wallet's own funds reach as `wallet`.
|
|
29
|
+
export const openSession = async () => openSessionOver(await connect(readOwner().contractAddress, GENESIS_SEED, OWNER_PATHS));
|
|
30
|
+
// The agent's session over its own fee wallet.
|
|
31
|
+
export const openAgent = async (slot, options = {}) => openAgentOver(await connect(agentAccount(), AGENT_FEE_SEED, AGENT_PATHS), slot, options);
|
package/dist/src/session.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Arm, type Bytes32, type SealedCoin } from '@kuiralabs/midnight-account';
|
|
2
2
|
import { type DiscoveredCoin } from './coins.ts';
|
|
3
|
-
import {
|
|
3
|
+
import type { Connection } from './connect.ts';
|
|
4
4
|
import { type OwnerDevice } from './device.ts';
|
|
5
5
|
export type OwnerRecord = {
|
|
6
6
|
readonly contractAddress: string;
|
|
@@ -44,36 +44,4 @@ export declare const openSessionOver: <C extends Connection>(connection: C) => P
|
|
|
44
44
|
reencryptHoldings: () => Promise<number>;
|
|
45
45
|
rotateEncKey: () => Promise<number>;
|
|
46
46
|
}>;
|
|
47
|
-
export declare const openSession: () => Promise<{
|
|
48
|
-
wallet: import("@midnight-ntwrk/testkit-js").MidnightWalletProvider;
|
|
49
|
-
address: string;
|
|
50
|
-
providers: import("./providers.ts").AccountProviders;
|
|
51
|
-
account: import("@midnight-ntwrk/midnight-js-contracts").FoundContract<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>>;
|
|
52
|
-
self: Bytes32;
|
|
53
|
-
readLedger: () => Promise<import("../managed/Account/contract/index.js").Ledger>;
|
|
54
|
-
close: () => Promise<void>;
|
|
55
|
-
} & {
|
|
56
|
-
device: OwnerDevice;
|
|
57
|
-
bootSalt: Uint8Array<ArrayBufferLike>;
|
|
58
|
-
encSecret: () => Bytes32;
|
|
59
|
-
calls: {
|
|
60
|
-
activate: (bootSalt: Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "activate_initial_device_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "activate_initial_device_with_k256">>;
|
|
61
|
-
withdrawUnshielded: (color: Bytes32, amount: bigint, recipient: Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_unshielded_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_unshielded_with_k256">>;
|
|
62
|
-
withdrawShielded: (recipient: Bytes32, amount: bigint, coin: import("@kuiralabs/midnight-account").HeldCoin) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "withdraw_shielded_with_k256">>;
|
|
63
|
-
unprovenWithdrawShieldedToContract: (recipient: Bytes32, amount: bigint, coin: import("@kuiralabs/midnight-account").HeldCoin) => Promise<import("./compose.ts").UnprovenCall & {
|
|
64
|
-
readonly landed: () => Promise<void>;
|
|
65
|
-
}>;
|
|
66
|
-
appendInbox: (entry: Uint8Array) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "append_inbox_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "append_inbox_with_k256">>;
|
|
67
|
-
rotateEncKey: (newKey: Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "rotate_enc_key_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "rotate_enc_key_with_k256">>;
|
|
68
|
-
addDevice: (newPk: import("@kuiralabs/midnight-account").Point) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "add_device_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "add_device_with_k256">>;
|
|
69
|
-
issueGrant: (grantId: Bytes32, scope: import("@kuiralabs/midnight-account").GrantScope) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "issue_grant_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "issue_grant_with_k256">>;
|
|
70
|
-
revokeGrant: (grantId: Bytes32) => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_grant_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_grant_with_k256">>;
|
|
71
|
-
revokeAllGrants: () => Promise<import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_all_grants_with_jubjub"> | import("@midnight-ntwrk/midnight-js-contracts").FinalizedCallTxData<import("../managed/Account/contract/index.js").Contract<import("./account.ts").AccountPrivateState, import("../managed/Account/contract/index.js").Witnesses<import("./account.ts").AccountPrivateState>>, "revoke_all_grants_with_k256">>;
|
|
72
|
-
};
|
|
73
|
-
expectChange: (change: SealedCoin) => void;
|
|
74
|
-
settleChanges: () => Promise<number>;
|
|
75
|
-
refreshCoins: () => Promise<readonly DiscoveredCoin[]>;
|
|
76
|
-
reencryptHoldings: () => Promise<number>;
|
|
77
|
-
rotateEncKey: () => Promise<number>;
|
|
78
|
-
}>;
|
|
79
47
|
export {};
|
package/dist/src/session.js
CHANGED
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
7
7
|
import { fromHex, hexOf, sealInboxEntry, x25519KeyPair, x25519PublicOf } from '@kuiralabs/midnight-account';
|
|
8
8
|
import { coinStore, contractCoinCommitment, readAccountZswap, walkInbox } from "./coins.js";
|
|
9
|
-
import { connect } from "./connect.js";
|
|
10
9
|
import { JubjubDevice, K256Device, recoverUseCounter } from "./device.js";
|
|
11
|
-
import {
|
|
12
|
-
import { OWNER_PATHS, stateFile } from "./profile.js";
|
|
10
|
+
import { stateFile } from "./profile.js";
|
|
13
11
|
import { ownerCalls } from "./ownerCalls.js";
|
|
14
12
|
import { PRIVATE_STATE_ID } from "./providers.js";
|
|
15
13
|
const changeToJson = (coin) => ({ nonce: hexOf(coin.nonce), color: hexOf(coin.color), value: coin.value.toString() });
|
|
@@ -133,6 +131,3 @@ export const openSessionOver = async (connection) => {
|
|
|
133
131
|
rotateEncKey,
|
|
134
132
|
};
|
|
135
133
|
};
|
|
136
|
-
// The owner's session paid by the genesis wallet, which the scripts that move
|
|
137
|
-
// that wallet's own funds reach as `wallet`.
|
|
138
|
-
export const openSession = async () => openSessionOver(await connect(readOwner().contractAddress, GENESIS_SEED, OWNER_PATHS));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kuiralabs/midnight-account-chain",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The account contract on a local ledger-9 network, over midnight-js 5: a wallet-free reader, connections, composed contract payments, devices and grantees, the grant mailbox and verifier-key maintenance.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"@midnight-ntwrk/midnight-js-node-zk-config-provider": "5.0.0-rc.1",
|
|
38
38
|
"@midnight-ntwrk/midnight-js-protocol": "5.0.0-rc.1",
|
|
39
39
|
"@midnight-ntwrk/midnight-js-types": "5.0.0-rc.1",
|
|
40
|
-
"@midnight-ntwrk/testkit-js": "5.0.0-rc.1",
|
|
41
40
|
"@midnightntwrk/ledger-v9": "1.0.0-rc.5",
|
|
42
41
|
"@midnightntwrk/wallet-sdk": "2.0.0-rc.0"
|
|
43
42
|
},
|
|
44
43
|
"devDependencies": {
|
|
44
|
+
"@midnight-ntwrk/testkit-js": "5.0.0-rc.1",
|
|
45
45
|
"@types/node": "24.13.2",
|
|
46
46
|
"typescript": "6.0.3"
|
|
47
47
|
},
|