Real XMR pilot
This commit is contained in:
@@ -21,8 +21,36 @@ test('default testnet v6 manifest is unchanged and unknown network profiles fail
|
||||
assert.equal(GENESIS_TIME, 1_792_411_200);
|
||||
assert.equal(CHAIN_ID, hash(JSON.stringify(['wikideck-randomx-testnet-6', CONSENSUS, 1_792_411_200, MAX_TARGET])));
|
||||
assert.equal(networkProfile(undefined), 'testnet');
|
||||
assert.equal(networkProfile('pilot'), 'pilot');
|
||||
assert.throws(() => networkProfile('production')); assert.throws(() => networkProfile(''));
|
||||
});
|
||||
test('private pilot is a separate deterministic chain with an explicit mock-only startup gate', () => {
|
||||
const output = JSON.parse(script(`
|
||||
import { NETWORK, NETWORK_GENESIS_TIME, NETWORK_LABEL } from './shared/network.ts';
|
||||
import { CHAIN_ID, GENESIS_HASH, GENESIS_TIME } from './server/testnet/consensus.ts';
|
||||
import { launchManifest, assertLaunchAllowed } from './server/launch.ts';
|
||||
const allowed = (env) => { try { assertLaunchAllowed(env); return true; } catch { return false; } };
|
||||
console.log(JSON.stringify({ NETWORK, NETWORK_GENESIS_TIME, NETWORK_LABEL, CHAIN_ID, GENESIS_HASH, GENESIS_TIME,
|
||||
manifest:launchManifest(), missing:allowed({}), approved:allowed({WIKIDECK_PILOT_MODE:'private-mock-only'}),
|
||||
livePayment:allowed({WIKIDECK_PILOT_MODE:'private-mock-only',WIKIDECK_PAYMENT_MODE:'live'}) }));
|
||||
`, { WIKIDECK_NETWORK: 'pilot' }));
|
||||
assert.equal(output.NETWORK, 'wikideck-randomx-pilot-1');
|
||||
assert.equal(output.GENESIS_TIME, 1_792_627_200);
|
||||
assert.equal(output.NETWORK_LABEL, 'PRIVATE PILOT');
|
||||
assert.equal(output.manifest.launchStatus, 'private-pilot-mock-only');
|
||||
assert.equal(output.manifest.paymentMode, 'mock');
|
||||
assert.equal(output.missing, false);
|
||||
assert.equal(output.approved, true);
|
||||
assert.equal(output.livePayment, false);
|
||||
assert.notEqual(output.CHAIN_ID, CHAIN_ID);
|
||||
assert.notEqual(output.GENESIS_HASH, GENESIS_HASH);
|
||||
const missingMode = spawnSync(process.execPath, ['--experimental-strip-types', 'server/index.ts'], {
|
||||
env: { ...process.env, WIKIDECK_NETWORK: 'pilot', WIKIDECK_PILOT_MODE: '' },
|
||||
encoding: 'utf8', timeout: 30000,
|
||||
});
|
||||
assert.notEqual(missingMode.status, 0);
|
||||
assert.match(missingMode.stderr, /Private pilot requires WIKIDECK_PILOT_MODE/);
|
||||
});
|
||||
test('mainnet candidate has distinct deterministic genesis, signatures and strict transaction schemas', () => {
|
||||
const output = JSON.parse(script(`
|
||||
import { NETWORK, nftTransferMessage } from './shared/testnet.ts';
|
||||
@@ -86,6 +114,24 @@ test('mainnet ledger and market files use isolated folders; testnet backup heade
|
||||
} finally { await rm(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('pilot ledger and market files use their own profile directory', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'wikideck-pilot-network-'));
|
||||
try {
|
||||
const result = JSON.parse(script(`
|
||||
import { Ledger } from './server/testnet/ledger.ts';
|
||||
import { Market } from './server/market/store.ts';
|
||||
import { existsSync } from 'node:fs'; import { join } from 'node:path';
|
||||
const ledger=await Ledger.open(process.env.PROFILE_TEST_DIR,{hash:async()=>{throw Error('unused')},close(){}});
|
||||
const market=await Market.open(process.env.PROFILE_TEST_DIR,ledger,undefined,Date.now,{worker:false});
|
||||
const result={ledger:existsSync(join(process.env.PROFILE_TEST_DIR,'pilot','ledger.sqlite')),
|
||||
market:existsSync(join(process.env.PROFILE_TEST_DIR,'pilot','market.sqlite')),
|
||||
testnet:existsSync(join(process.env.PROFILE_TEST_DIR,'testnet'))};
|
||||
market.close();ledger.close();console.log(JSON.stringify(result));
|
||||
`, { WIKIDECK_NETWORK: 'pilot', WIKIDECK_PILOT_MODE: 'private-mock-only', PROFILE_TEST_DIR: dir }));
|
||||
assert.deepEqual(result, { ledger: true, market: true, testnet: false });
|
||||
} finally { await rm(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('operator preflight is read-only, fails closed, and does not disclose credentials', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'wikideck-preflight-'));
|
||||
try {
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
|
||||
test('private pilot Compose stack is loopback-bound, isolated, and mock-only', async () => {
|
||||
const compose = (await readFile(new URL('../compose.custody-pilot.yaml', import.meta.url), 'utf8')).replaceAll('\r\n', '\n');
|
||||
assert.match(compose, /WIKIDECK_NETWORK: pilot/);
|
||||
assert.match(compose, /WIKIDECK_PILOT_MODE: private-mock-only/);
|
||||
assert.match(compose, /WIKIDECK_PAYMENT_MODE: mock/);
|
||||
assert.match(compose, /WIKIDECK_CUSTODY_STORAGE: postgres/);
|
||||
assert.match(compose, /WIKIDECK_CUSTODY_MODE: sandbox/);
|
||||
assert.match(compose, /WIKIDECK_LOCAL_PG_BOOTSTRAP: sandbox-only/);
|
||||
assert.match(compose, /127\.0\.0\.1:\$\{WIKIDECK_PILOT_PORT:-3423\}:3001/);
|
||||
assert.match(compose, /financial: \{internal: true\}/);
|
||||
assert.match(compose, /pg-runtime:\/secrets\/runtime:ro/);
|
||||
assert.doesNotMatch(compose, /POSTGRES_PASSWORD:\s|5432:5432/i);
|
||||
assert.doesNotMatch(compose, /^\s+(?:monero|wallet-rpc|observer):/im);
|
||||
const database = compose.split(' database:')[1].split(' migrate:')[0];
|
||||
assert.doesNotMatch(database, /ports:/);
|
||||
const app = compose.split(' wikideck:')[1].split('networks:\n financial:')[0];
|
||||
assert.doesNotMatch(app, /pg-admin:|pg-owner:|pg-tls:/);
|
||||
});
|
||||
@@ -10,17 +10,21 @@ test('project overview distinguishes mining rewards, peer markets, planned TCGs
|
||||
assert.match(readme,/custom games hosted by peers.*planned/);
|
||||
assert.match(readme,/configurable hosting fee/);
|
||||
assert.match(readme,/hardcoded \*\*1% author fee\*\*/);
|
||||
assert.match(readme,/checkout is mock-only/);
|
||||
assert.match(readme,/Checkout, fees and payouts are simulated/);
|
||||
assert.match(readme,/new fixed-price listings and timed auctions use native XMR amounts/);
|
||||
assert.match(readme,/does not yet contain a project LICENSE file/);
|
||||
assert.doesNotMatch(readme,/## Mine only by explicit choice/);
|
||||
});
|
||||
test('homepage explains the roadmap without opt-in marketing or implying live XMR checkout',async()=>{
|
||||
test('homepage sells the collector vision while disclosing mining and market limits',async()=>{
|
||||
const app=await readFile(new URL('../src/App.tsx',import.meta.url),'utf8');
|
||||
assert.match(app,/Mine a block\. Earn a Wikipedia NFT card/);
|
||||
assert.match(app,/ON THE ROADMAP · NOT PLAYABLE YET/);
|
||||
assert.match(app,/peer-hosted custom TCGs are planned/);
|
||||
assert.match(app,/today payments and fees are simulated/);
|
||||
assert.doesNotMatch(app,/EXPLICIT OPT-IN|opt-in RandomX|No browser mining|Only by choice/);
|
||||
assert.match(app,/Mine with your CPU/);
|
||||
assert.match(app,/Build a deck that feels like yours/);
|
||||
assert.match(app,/designed to resist specialized ASICs/);
|
||||
assert.match(app,/ASIC resistance is a design goal, not a guarantee/);
|
||||
assert.match(app,/New listings are priced in XMR, but all checkout, fees and payouts are simulated today/);
|
||||
assert.match(app,/Playable TCGs, match systems, deck rules and peer-hosted custom games are not implemented yet/);
|
||||
assert.match(app,/<details className="mining-details"><summary>Want to run a miner\? Setup & safety details/);
|
||||
assert.doesNotMatch(app,/Prices are in USD with XMR cryptocurrency settlement planned/);
|
||||
assert.match(app,/--consent/); // Documentation-only change: runnable miner invocation keeps its existing required flag.
|
||||
});
|
||||
test('market transparency explains real controls without promising escrow, refunds or live payments',async()=>{
|
||||
|
||||
Reference in New Issue
Block a user