bulletin-deploy 0.7.6 → 0.7.7
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/bin/bulletin-deploy +6 -0
- package/dist/bug-report.js +4 -4
- package/dist/{chunk-A2J6R5PD.js → chunk-77SWQOPW.js} +21 -12
- package/dist/{chunk-EECNTEAE.js → chunk-BEAOHOTJ.js} +1 -1
- package/dist/{chunk-YX62STIA.js → chunk-D3SJZTE2.js} +2 -2
- package/dist/{chunk-G6CVI6U2.js → chunk-EOCLCWCS.js} +227 -14
- package/dist/{chunk-2Q2WSKFD.js → chunk-HOTQDYHD.js} +11 -5
- package/dist/{chunk-Y6CTPQS2.js → chunk-LNFD7QP6.js} +7 -2
- package/dist/{chunk-WIBZPZSY.js → chunk-RP4YJYNB.js} +6 -1
- package/dist/{chunk-HHY32NGJ.js → chunk-VKADME5F.js} +2 -2
- package/dist/deploy.d.ts +11 -1
- package/dist/deploy.js +10 -8
- package/dist/dotns.d.ts +24 -1
- package/dist/dotns.js +8 -4
- package/dist/gh-pages-mirror.d.ts +2 -1
- package/dist/gh-pages-mirror.js +3 -1
- package/dist/index.js +8 -8
- package/dist/memory-report.js +2 -2
- package/dist/pool.d.ts +2 -1
- package/dist/pool.js +3 -1
- package/dist/run-state.js +1 -1
- package/dist/telemetry.js +2 -2
- package/dist/version-check.js +3 -3
- package/package.json +2 -2
package/bin/bulletin-deploy
CHANGED
|
@@ -24,6 +24,8 @@ for (let i = 0; i < args.length; i++) {
|
|
|
24
24
|
else if (args[i] === "--password") { flags.password = args[++i]; }
|
|
25
25
|
else if (args[i] === "--js-merkle") { flags.jsMerkle = true; }
|
|
26
26
|
else if (args[i] === "--tag") { flags.tag = args[++i]; }
|
|
27
|
+
else if (args[i] === "--name") { flags.name = args[++i]; }
|
|
28
|
+
else if (args[i] === "--description") { flags.description = args[++i]; }
|
|
27
29
|
else if (args[i] === "--gh-pages-mirror") { flags.ghPagesMirror = true; }
|
|
28
30
|
else if (args[i] === "--version" || args[i] === "-V") { flags.version = true; }
|
|
29
31
|
else if (args[i] === "--help" || args[i] === "-h") { flags.help = true; }
|
|
@@ -54,6 +56,8 @@ Options:
|
|
|
54
56
|
--password "..." Encrypt SPA content (users will be prompted to decrypt)
|
|
55
57
|
--js-merkle Use pure-JS merkleization (no IPFS Kubo binary required)
|
|
56
58
|
--tag "..." Label deploy in telemetry (or set DEPLOY_TAG env var); see Telemetry in README
|
|
59
|
+
--name "..." Optional. Sets the "name" text record on the domain.
|
|
60
|
+
--description "..." Optional. Sets the "description" text record (≤100 chars recommended).
|
|
57
61
|
--gh-pages-mirror After deploy, push the CAR to the current repo's gh-pages branch
|
|
58
62
|
at bulletin/<domain>.dot.car (opt-in; also set GH_PAGES_MIRROR=1)
|
|
59
63
|
--version Show version
|
|
@@ -185,6 +189,8 @@ try {
|
|
|
185
189
|
jsMerkle: flags.jsMerkle,
|
|
186
190
|
tag: flags.tag,
|
|
187
191
|
ghPagesMirror: flags.ghPagesMirror,
|
|
192
|
+
name: flags.name,
|
|
193
|
+
description: flags.description,
|
|
188
194
|
});
|
|
189
195
|
|
|
190
196
|
const output = process.env.GITHUB_OUTPUT;
|
package/dist/bug-report.js
CHANGED
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
offerBugReport,
|
|
10
10
|
scrubSecrets,
|
|
11
11
|
setDeployContext
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-D3SJZTE2.js";
|
|
13
|
+
import "./chunk-BEAOHOTJ.js";
|
|
14
|
+
import "./chunk-LNFD7QP6.js";
|
|
15
|
+
import "./chunk-VKADME5F.js";
|
|
16
16
|
import "./chunk-QGM4M3NI.js";
|
|
17
17
|
export {
|
|
18
18
|
buildCliFlagsSummary,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
setDeployContext
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-D3SJZTE2.js";
|
|
4
4
|
import {
|
|
5
5
|
DotNS,
|
|
6
6
|
TX_TIMEOUT_MS,
|
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
parseDomainName,
|
|
9
9
|
popStatusName,
|
|
10
10
|
verifyNonceAdvanced
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EOCLCWCS.js";
|
|
12
12
|
import {
|
|
13
13
|
MirrorSkipped,
|
|
14
14
|
mirrorToGitHubPages,
|
|
15
15
|
pollMirrorFreshness
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-HOTQDYHD.js";
|
|
17
17
|
import {
|
|
18
18
|
VERSION,
|
|
19
19
|
captureWarning,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
truncateAddress,
|
|
28
28
|
withDeploySpan,
|
|
29
29
|
withSpan
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LNFD7QP6.js";
|
|
31
31
|
import {
|
|
32
32
|
merkleizeJS
|
|
33
33
|
} from "./chunk-B7GUYYAN.js";
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
fetchPoolAuthorizations,
|
|
39
39
|
selectAccount,
|
|
40
40
|
topUpBy
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-RP4YJYNB.js";
|
|
42
42
|
|
|
43
43
|
// src/deploy.ts
|
|
44
44
|
import { Buffer } from "buffer";
|
|
@@ -648,6 +648,12 @@ async function storeDirectory(directoryPath, providerOrOptions = {}, password, j
|
|
|
648
648
|
}
|
|
649
649
|
return { storageCid, ipfsCid, carBytes: carContent };
|
|
650
650
|
}
|
|
651
|
+
function resolveDotnsConnectOptions(options) {
|
|
652
|
+
if (options.signer && options.signerAddress) {
|
|
653
|
+
return { signer: options.signer, signerAddress: options.signerAddress };
|
|
654
|
+
}
|
|
655
|
+
return { mnemonic: options.mnemonic, derivationPath: options.derivationPath };
|
|
656
|
+
}
|
|
651
657
|
async function estimateUploadBytes(content) {
|
|
652
658
|
try {
|
|
653
659
|
if (Array.isArray(content)) {
|
|
@@ -702,14 +708,13 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
702
708
|
if (options.password) console.log(` Encrypted: yes`);
|
|
703
709
|
let provider;
|
|
704
710
|
const reconnect = options.mnemonic ? () => getDirectProvider(options.mnemonic, options.derivationPath) : () => getProvider();
|
|
711
|
+
let dotnsPreflight = null;
|
|
705
712
|
try {
|
|
706
713
|
console.log("\n" + "=".repeat(60));
|
|
707
714
|
console.log("Preflight");
|
|
708
715
|
console.log("=".repeat(60));
|
|
709
716
|
const preflight = new DotNS();
|
|
710
|
-
await preflight.connect(
|
|
711
|
-
options.signer && options.signerAddress ? { signer: options.signer, signerAddress: options.signerAddress } : options.mnemonic ? { mnemonic: options.mnemonic, derivationPath: options.derivationPath } : {}
|
|
712
|
-
);
|
|
717
|
+
await preflight.connect(resolveDotnsConnectOptions(options));
|
|
713
718
|
if (parsed?.isSubdomain) {
|
|
714
719
|
try {
|
|
715
720
|
const { owned: subOwned } = await preflight.checkSubdomainOwnership(parsed.sublabel, parsed.parentLabel);
|
|
@@ -726,7 +731,6 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
726
731
|
}
|
|
727
732
|
console.log(` Mode: subdomain (parent ${parsed.parentLabel}.dot owned by signer)`);
|
|
728
733
|
} else {
|
|
729
|
-
let dotnsPreflight;
|
|
730
734
|
try {
|
|
731
735
|
dotnsPreflight = await preflight.preflight(name);
|
|
732
736
|
} finally {
|
|
@@ -859,9 +863,7 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
859
863
|
console.log("=".repeat(60));
|
|
860
864
|
await withSpan("deploy.dotns", "2. dotns", { "deploy.domain": name, "deploy.subdomain": String(parsed?.isSubdomain ?? false) }, async () => {
|
|
861
865
|
const dotns = new DotNS();
|
|
862
|
-
await dotns.connect(
|
|
863
|
-
options.signer && options.signerAddress ? { signer: options.signer, signerAddress: options.signerAddress } : options.mnemonic ? { mnemonic: options.mnemonic, derivationPath: options.derivationPath } : {}
|
|
864
|
-
);
|
|
866
|
+
await dotns.connect(resolveDotnsConnectOptions(options));
|
|
865
867
|
if (parsed?.isSubdomain) {
|
|
866
868
|
const { owned, owner } = await dotns.checkSubdomainOwnership(parsed.sublabel, parsed.parentLabel);
|
|
867
869
|
if (owned) {
|
|
@@ -879,12 +881,18 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
879
881
|
if (owned) {
|
|
880
882
|
console.log(` Status: Already owned`);
|
|
881
883
|
} else {
|
|
884
|
+
if (dotnsPreflight !== null && dotnsPreflight.needsPopUpgrade && dotnsPreflight.targetPopStatus !== void 0 && dotnsPreflight.isTestnet) {
|
|
885
|
+
await dotns.setUserPopStatus(dotnsPreflight.targetPopStatus);
|
|
886
|
+
}
|
|
882
887
|
console.log(` Status: Registering...`);
|
|
883
888
|
await dotns.register(name);
|
|
884
889
|
}
|
|
885
890
|
}
|
|
886
891
|
const contenthashHex = `0x${encodeContenthash(cid)}`;
|
|
887
892
|
await dotns.setContenthash(name, contenthashHex);
|
|
893
|
+
const textRecordTarget = parsed?.isSubdomain && parsed.sublabel && parsed.parentLabel ? `${parsed.sublabel}.${parsed.parentLabel}` : name;
|
|
894
|
+
if (options.name !== void 0) await dotns.setTextRecord(textRecordTarget, "name", options.name);
|
|
895
|
+
if (options.description !== void 0) await dotns.setTextRecord(textRecordTarget, "description", options.description);
|
|
888
896
|
dotns.disconnect();
|
|
889
897
|
});
|
|
890
898
|
if (options.ghPagesMirror) {
|
|
@@ -961,6 +969,7 @@ export {
|
|
|
961
969
|
merkleize,
|
|
962
970
|
computeStorageCid,
|
|
963
971
|
storeDirectory,
|
|
972
|
+
resolveDotnsConnectOptions,
|
|
964
973
|
estimateUploadBytes,
|
|
965
974
|
deploy
|
|
966
975
|
};
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
classifyErrorArea,
|
|
3
3
|
isInteractive,
|
|
4
4
|
promptYesNo
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BEAOHOTJ.js";
|
|
6
6
|
import {
|
|
7
7
|
VERSION,
|
|
8
8
|
getCurrentSentryTraceId
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LNFD7QP6.js";
|
|
10
10
|
|
|
11
11
|
// src/bug-report.ts
|
|
12
12
|
import { execSync, execFileSync } from "child_process";
|
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
captureWarning,
|
|
3
3
|
setDeployAttribute,
|
|
4
4
|
withSpan
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-LNFD7QP6.js";
|
|
6
6
|
import {
|
|
7
7
|
isTestnetSpecName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RP4YJYNB.js";
|
|
9
9
|
|
|
10
10
|
// src/dotns.ts
|
|
11
11
|
import { spawn } from "child_process";
|
|
12
12
|
import { readFileSync } from "fs";
|
|
13
13
|
import { dirname, join } from "path";
|
|
14
|
-
import { createClient } from "polkadot-api";
|
|
14
|
+
import { createClient, Enum } from "polkadot-api";
|
|
15
15
|
import { getPolkadotSigner } from "polkadot-api/signer";
|
|
16
16
|
import { getWsProvider } from "polkadot-api/ws-provider";
|
|
17
17
|
import { Keyring } from "@polkadot/keyring";
|
|
@@ -45,6 +45,19 @@ try {
|
|
|
45
45
|
_dotnsCliPath = "dotns";
|
|
46
46
|
console.warn(`[bulletin-deploy] @parity/dotns-cli not found in node_modules \u2014 falling back to "dotns" in PATH. Install with: npm install @parity/dotns-cli. Underlying: ${err.message}`);
|
|
47
47
|
}
|
|
48
|
+
var ONE_PAS = 10000000000n;
|
|
49
|
+
var FEE_FLOOR_OWNED = ONE_PAS / 100n;
|
|
50
|
+
var FEE_FLOOR_REGISTER = ONE_PAS / 10n;
|
|
51
|
+
var TOP_UP_TARGET = ONE_PAS / 2n;
|
|
52
|
+
var SOURCE_BUFFER = ONE_PAS;
|
|
53
|
+
var TOP_UP_TRANSFER_TIMEOUT_MS = 6e4;
|
|
54
|
+
var PASEO_FAUCET_URL = "https://faucet.polkadot.io";
|
|
55
|
+
function fmtPas(plancks) {
|
|
56
|
+
return (Number(plancks) / Number(ONE_PAS)).toFixed(4);
|
|
57
|
+
}
|
|
58
|
+
function feeFloorFor(plannedAction) {
|
|
59
|
+
return plannedAction === "already-owned-by-us" ? FEE_FLOOR_OWNED : FEE_FLOOR_REGISTER;
|
|
60
|
+
}
|
|
48
61
|
var RPC_ENDPOINTS = [
|
|
49
62
|
"wss://asset-hub-paseo.dotters.network",
|
|
50
63
|
"wss://sys.ibp.network/asset-hub-paseo",
|
|
@@ -282,12 +295,13 @@ function canRegister(requiredStatus, userStatus, trailingDigits) {
|
|
|
282
295
|
function simulateUserStatus(currentStatus, requiredStatus, options) {
|
|
283
296
|
const max = (a, b) => a > b ? a : b;
|
|
284
297
|
if (options.explicitStatus !== void 0) {
|
|
285
|
-
return max(currentStatus, options.explicitStatus);
|
|
298
|
+
if (options.isTestnet) return max(currentStatus, options.explicitStatus);
|
|
299
|
+
return currentStatus;
|
|
286
300
|
}
|
|
287
301
|
if (requiredStatus === ProofOfPersonhoodStatus.NoStatus && currentStatus === ProofOfPersonhoodStatus.ProofOfPersonhoodLite && options.isTestnet) {
|
|
288
302
|
return ProofOfPersonhoodStatus.ProofOfPersonhoodFull;
|
|
289
303
|
}
|
|
290
|
-
if (requiredStatus !== ProofOfPersonhoodStatus.NoStatus) {
|
|
304
|
+
if (requiredStatus !== ProofOfPersonhoodStatus.NoStatus && options.isTestnet) {
|
|
291
305
|
return max(currentStatus, requiredStatus);
|
|
292
306
|
}
|
|
293
307
|
return currentStatus;
|
|
@@ -520,6 +534,129 @@ var DotNS = class {
|
|
|
520
534
|
this._testnetCache = isTestnetSpecName(rpc) || rpc.includes("paseo") || rpc.includes("westend") || rpc.includes("rococo");
|
|
521
535
|
return this._testnetCache;
|
|
522
536
|
}
|
|
537
|
+
// Free PAS balance for a substrate address on the connected DotNS chain.
|
|
538
|
+
// Used by preflight to gate the deploy on whether the signer can pay tx
|
|
539
|
+
// fees before the chunk upload runs. Returns 0n if the account doesn't
|
|
540
|
+
// exist on chain.
|
|
541
|
+
async readFreeBalance(ss58) {
|
|
542
|
+
this.ensureConnected();
|
|
543
|
+
if (!this.clientWrapper) throw new Error("readFreeBalance: polkadot-api client not available");
|
|
544
|
+
const acc = await this.clientWrapper.client.query.System.Account.getValue(ss58);
|
|
545
|
+
return BigInt(acc?.data?.free ?? 0n);
|
|
546
|
+
}
|
|
547
|
+
// Testnet-only: try to top the deploy signer up from the well-known dev
|
|
548
|
+
// phrase's Alice (root) or Bob (//Bob) account. Each candidate is read,
|
|
549
|
+
// skipped if it can't spare the transfer, and otherwise used to send
|
|
550
|
+
// `targetAmount` to `recipientSs58`. Returns the source label + amount on
|
|
551
|
+
// success, or null if neither candidate had the funds. The dev phrase is
|
|
552
|
+
// hardcoded on purpose — this only fires on testnet (gated by caller) and
|
|
553
|
+
// runs against accounts every Substrate-Polkadot tester can fund.
|
|
554
|
+
async attemptTestnetTopUp(recipientSs58, targetAmount) {
|
|
555
|
+
this.ensureConnected();
|
|
556
|
+
if (!this.clientWrapper) throw new Error("attemptTestnetTopUp: polkadot-api client not available");
|
|
557
|
+
await cryptoWaitReady();
|
|
558
|
+
const keyring = new Keyring({ type: "sr25519" });
|
|
559
|
+
const sources = [
|
|
560
|
+
{ label: "Alice", uri: DEFAULT_MNEMONIC },
|
|
561
|
+
{ label: "Bob", uri: `${DEFAULT_MNEMONIC}//Bob` }
|
|
562
|
+
];
|
|
563
|
+
for (const src of sources) {
|
|
564
|
+
const account = keyring.addFromUri(src.uri);
|
|
565
|
+
if (account.address === recipientSs58) continue;
|
|
566
|
+
const sourceBalance = await this.readFreeBalance(account.address);
|
|
567
|
+
if (sourceBalance < targetAmount + SOURCE_BUFFER) {
|
|
568
|
+
console.log(` ${src.label} (${account.address.slice(0, 8)}...) low: ${fmtPas(sourceBalance)} PAS \u2014 skipping`);
|
|
569
|
+
captureWarning(`DotNS auto-top-up: ${src.label} insufficient`, {
|
|
570
|
+
source: src.label,
|
|
571
|
+
sourceAddress: account.address,
|
|
572
|
+
free: sourceBalance.toString(),
|
|
573
|
+
required: (targetAmount + SOURCE_BUFFER).toString()
|
|
574
|
+
});
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
const signer = getPolkadotSigner(
|
|
578
|
+
account.publicKey,
|
|
579
|
+
"Sr25519",
|
|
580
|
+
async (input) => account.sign(input)
|
|
581
|
+
);
|
|
582
|
+
console.log(` Trying ${src.label} (${account.address.slice(0, 8)}...): transferring ${fmtPas(targetAmount)} PAS to ${recipientSs58.slice(0, 8)}...`);
|
|
583
|
+
try {
|
|
584
|
+
await withTimeout(
|
|
585
|
+
this.submitTransfer(signer, recipientSs58, targetAmount),
|
|
586
|
+
TOP_UP_TRANSFER_TIMEOUT_MS,
|
|
587
|
+
`Balances.transfer_allow_death from ${src.label}`
|
|
588
|
+
);
|
|
589
|
+
return { source: src.label, transferred: targetAmount };
|
|
590
|
+
} catch (e) {
|
|
591
|
+
console.log(` Top-up via ${src.label} failed: ${e.message?.slice(0, 200)}`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
// Helper: submit a Balances.transfer_allow_death tx and resolve only after
|
|
597
|
+
// GRANDPA finalization (not best-block inclusion). Auto-top-up writes to
|
|
598
|
+
// the deploy signer's balance; if a re-org rolls back a best-block credit
|
|
599
|
+
// before the deploy's next tx, preflight reports success but setContenthash
|
|
600
|
+
// / register fail with Insufficient funds again. Waiting for finalization
|
|
601
|
+
// adds ~18s on Asset Hub Paseo but eliminates the re-org window.
|
|
602
|
+
// Logs a per-block-progress line so the operator sees the wait isn't a hang.
|
|
603
|
+
// Note: Enum("Id", ss58) is required to decode the SS58 to AccountId32;
|
|
604
|
+
// the structural literal { type: "Id", value } encodes wrong.
|
|
605
|
+
// Companion in tools/setup-e2e-derivation-signers.mjs uses best-block only;
|
|
606
|
+
// that's a one-time setup script, not a runtime gate, so the trade-off there
|
|
607
|
+
// is different.
|
|
608
|
+
submitTransfer(signer, destSubstrate, valueRaw) {
|
|
609
|
+
const api = this.clientWrapper.client;
|
|
610
|
+
const tx = api.tx.Balances.transfer_allow_death({
|
|
611
|
+
dest: Enum("Id", destSubstrate),
|
|
612
|
+
value: valueRaw
|
|
613
|
+
});
|
|
614
|
+
return new Promise((resolve, reject) => {
|
|
615
|
+
let settled = false;
|
|
616
|
+
let bestBlockSeen = false;
|
|
617
|
+
const sub = tx.signSubmitAndWatch(signer).subscribe({
|
|
618
|
+
next: (event) => {
|
|
619
|
+
if (settled) return;
|
|
620
|
+
if (event.type === "txBestBlocksState" && event.found && !bestBlockSeen) {
|
|
621
|
+
bestBlockSeen = true;
|
|
622
|
+
if (!event.ok) {
|
|
623
|
+
settled = true;
|
|
624
|
+
try {
|
|
625
|
+
sub.unsubscribe();
|
|
626
|
+
} catch {
|
|
627
|
+
}
|
|
628
|
+
reject(new Error("Balances.transfer_allow_death dispatch error"));
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
console.log(` Tx in best block \u2014 waiting for finalization...`);
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
if (event.type === "finalized") {
|
|
635
|
+
settled = true;
|
|
636
|
+
try {
|
|
637
|
+
sub.unsubscribe();
|
|
638
|
+
} catch {
|
|
639
|
+
}
|
|
640
|
+
if (event.ok === false) reject(new Error("Balances.transfer_allow_death finalization error"));
|
|
641
|
+
else resolve();
|
|
642
|
+
}
|
|
643
|
+
},
|
|
644
|
+
error: (e) => {
|
|
645
|
+
if (settled) return;
|
|
646
|
+
settled = true;
|
|
647
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
648
|
+
},
|
|
649
|
+
// Defensive: papi can complete the stream after a network drop without
|
|
650
|
+
// emitting finalized. Without this, the promise hangs forever and
|
|
651
|
+
// preflight stalls. Reject so the caller falls back to Bob.
|
|
652
|
+
complete: () => {
|
|
653
|
+
if (settled) return;
|
|
654
|
+
settled = true;
|
|
655
|
+
reject(new Error("transfer subscription closed without finalization"));
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
});
|
|
659
|
+
}
|
|
523
660
|
async contractCall(contractAddress, contractAbi, functionName, args = []) {
|
|
524
661
|
this.ensureConnected();
|
|
525
662
|
if (!this.clientWrapper) throw new Error("contractCall: polkadot-api client not available");
|
|
@@ -650,6 +787,30 @@ var DotNS = class {
|
|
|
650
787
|
return { node };
|
|
651
788
|
});
|
|
652
789
|
}
|
|
790
|
+
async setTextRecord(domainName, key, value, _cli = runDotnsCli) {
|
|
791
|
+
return withSpan("deploy.dotns.set-text", `2c. set-text ${key}`, {}, async () => {
|
|
792
|
+
this.ensureConnected();
|
|
793
|
+
console.log(` Setting text[${key}]: ${value}`);
|
|
794
|
+
const authEnv = buildAuthEnv({ mnemonic: this._mnemonic ?? void 0, keyUri: this._keyUri ?? void 0 });
|
|
795
|
+
const setResult = await _cli(
|
|
796
|
+
["text", "set", domainName, key, value, "--json", ...rpcFlag(this.rpc)],
|
|
797
|
+
authEnv
|
|
798
|
+
);
|
|
799
|
+
console.log(` Tx: ${setResult.txHash}`);
|
|
800
|
+
const viewResult = await _cli(
|
|
801
|
+
["text", "view", domainName, key, "--json", ...rpcFlag(this.rpc)]
|
|
802
|
+
);
|
|
803
|
+
const onChain = viewResult.value ?? "";
|
|
804
|
+
if (onChain !== value) {
|
|
805
|
+
throw new Error(
|
|
806
|
+
`Post-set verification failed for text[${key}] on ${domainName}.dot: on-chain value is ${JSON.stringify(onChain)}, not ${JSON.stringify(value)} we just wrote. The setText tx may have silently failed, or another writer overwrote the record.`
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
console.log(` Verified text[${key}]: ${onChain}
|
|
810
|
+
`);
|
|
811
|
+
return { value, txHash: setResult.txHash };
|
|
812
|
+
});
|
|
813
|
+
}
|
|
653
814
|
async getContenthash(domainName) {
|
|
654
815
|
this.ensureConnected();
|
|
655
816
|
const result = await runDotnsCli(
|
|
@@ -687,11 +848,12 @@ var DotNS = class {
|
|
|
687
848
|
};
|
|
688
849
|
}
|
|
689
850
|
const baseName = stripTrailingDigits(validated);
|
|
690
|
-
const [userStatus, baseReservation, ownership, isTestnet] = await Promise.all([
|
|
851
|
+
const [userStatus, baseReservation, ownership, isTestnet, signerFreeBalance] = await Promise.all([
|
|
691
852
|
this.getUserPopStatus(),
|
|
692
853
|
withTimeout(this.contractCall(CONTRACTS.POP_RULES, POP_RULES_ABI, "isBaseNameReserved", [baseName]), 3e4, "isBaseNameReserved"),
|
|
693
854
|
this.checkOwnership(validated),
|
|
694
|
-
this.isTestnet()
|
|
855
|
+
this.isTestnet(),
|
|
856
|
+
this.readFreeBalance(this.substrateAddress)
|
|
695
857
|
]);
|
|
696
858
|
const [isReserved, reservationOwnerRaw] = baseReservation;
|
|
697
859
|
const reservationOwner = isReserved ? reservationOwnerRaw.toLowerCase() : null;
|
|
@@ -713,11 +875,12 @@ var DotNS = class {
|
|
|
713
875
|
canProceed: false,
|
|
714
876
|
reason: `Domain ${validated}.dot is already owned by ${existingOwner}.`,
|
|
715
877
|
plannedAction: "abort",
|
|
716
|
-
needsPopUpgrade: false
|
|
878
|
+
needsPopUpgrade: false,
|
|
879
|
+
signerFreeBalance
|
|
717
880
|
};
|
|
718
881
|
}
|
|
719
882
|
if (existingOwner !== null && existingOwner === selfAddress) {
|
|
720
|
-
return {
|
|
883
|
+
return await this.gateOnFeeBalance({
|
|
721
884
|
label: validated,
|
|
722
885
|
classification,
|
|
723
886
|
userStatus,
|
|
@@ -731,7 +894,7 @@ var DotNS = class {
|
|
|
731
894
|
canProceed: true,
|
|
732
895
|
plannedAction: "already-owned-by-us",
|
|
733
896
|
needsPopUpgrade: false
|
|
734
|
-
};
|
|
897
|
+
}, signerFreeBalance, isTestnet);
|
|
735
898
|
}
|
|
736
899
|
if (isReserved && reservationOwner !== selfAddress) {
|
|
737
900
|
return {
|
|
@@ -748,7 +911,8 @@ var DotNS = class {
|
|
|
748
911
|
canProceed: false,
|
|
749
912
|
reason: `Base name ${baseName} is reserved for ${reservationOwner}.`,
|
|
750
913
|
plannedAction: "abort",
|
|
751
|
-
needsPopUpgrade: false
|
|
914
|
+
needsPopUpgrade: false,
|
|
915
|
+
signerFreeBalance
|
|
752
916
|
};
|
|
753
917
|
}
|
|
754
918
|
const explicitStatus = explicitStatusOverride ?? process.env.DOTNS_STATUS;
|
|
@@ -771,10 +935,11 @@ var DotNS = class {
|
|
|
771
935
|
reason: `${validated}.dot classifies as ${className}; this signer cannot register it (PopRules.priceWithCheck gate). Remediations: use a signer with Full PoP, or pick a base name of 6-8 chars + trailing 00 (which classifies as PopLite).`,
|
|
772
936
|
plannedAction: "abort",
|
|
773
937
|
needsPopUpgrade: false,
|
|
774
|
-
targetPopStatus
|
|
938
|
+
targetPopStatus,
|
|
939
|
+
signerFreeBalance
|
|
775
940
|
};
|
|
776
941
|
}
|
|
777
|
-
return {
|
|
942
|
+
return await this.gateOnFeeBalance({
|
|
778
943
|
label: validated,
|
|
779
944
|
classification,
|
|
780
945
|
userStatus,
|
|
@@ -789,9 +954,55 @@ var DotNS = class {
|
|
|
789
954
|
plannedAction: "register",
|
|
790
955
|
needsPopUpgrade: targetPopStatus !== userStatus,
|
|
791
956
|
targetPopStatus
|
|
792
|
-
};
|
|
957
|
+
}, signerFreeBalance, isTestnet);
|
|
793
958
|
});
|
|
794
959
|
}
|
|
960
|
+
// Final preflight stage: check the DotNS signer can pay tx fees on the
|
|
961
|
+
// connected fee chain (Asset Hub Paseo for testnet, Asset Hub Polkadot for
|
|
962
|
+
// mainnet). On testnet, attempts a one-shot auto-top-up from the dev
|
|
963
|
+
// phrase's Alice or Bob if the signer is short. Replaces the original
|
|
964
|
+
// canProceed:true result with an actionable canProceed:false when even the
|
|
965
|
+
// top-up can't get the signer above the threshold.
|
|
966
|
+
async gateOnFeeBalance(candidate, signerFreeBalance, isTestnet) {
|
|
967
|
+
const feeFloor = feeFloorFor(candidate.plannedAction);
|
|
968
|
+
let effectiveBalance = signerFreeBalance;
|
|
969
|
+
let toppedUp;
|
|
970
|
+
if (effectiveBalance < feeFloor && isTestnet) {
|
|
971
|
+
setDeployAttribute("deploy.dotns.signer_below_floor", "true");
|
|
972
|
+
console.log(` DotNS signer ${this.substrateAddress?.slice(0, 8)}... balance ${fmtPas(effectiveBalance)} PAS < ${fmtPas(feeFloor)} PAS floor \u2014 attempting testnet auto top-up...`);
|
|
973
|
+
const result = await this.attemptTestnetTopUp(this.substrateAddress, TOP_UP_TARGET);
|
|
974
|
+
if (result) {
|
|
975
|
+
console.log(` Topped up ${fmtPas(result.transferred)} PAS from ${result.source}`);
|
|
976
|
+
effectiveBalance += result.transferred;
|
|
977
|
+
toppedUp = result;
|
|
978
|
+
setDeployAttribute("deploy.dotns.toppedup", "true");
|
|
979
|
+
setDeployAttribute("deploy.dotns.toppedup_source", result.source);
|
|
980
|
+
}
|
|
981
|
+
} else if (effectiveBalance < feeFloor) {
|
|
982
|
+
setDeployAttribute("deploy.dotns.signer_below_floor", "true");
|
|
983
|
+
}
|
|
984
|
+
if (effectiveBalance < feeFloor) {
|
|
985
|
+
const op = candidate.plannedAction === "already-owned-by-us" ? "setContenthash" : "register";
|
|
986
|
+
const tail = isTestnet ? ` Testnet auto-top-up via Alice/Bob failed (both also low). Top up at ${PASEO_FAUCET_URL}.` : ` Top up the signer's balance and re-deploy.`;
|
|
987
|
+
captureWarning("DotNS preflight balance gate: signer cannot pay fees", {
|
|
988
|
+
signer: this.substrateAddress,
|
|
989
|
+
free: effectiveBalance.toString(),
|
|
990
|
+
floor: feeFloor.toString(),
|
|
991
|
+
plannedAction: candidate.plannedAction,
|
|
992
|
+
isTestnet: String(isTestnet),
|
|
993
|
+
autoTopUpAttempted: String(isTestnet)
|
|
994
|
+
});
|
|
995
|
+
return {
|
|
996
|
+
...candidate,
|
|
997
|
+
canProceed: false,
|
|
998
|
+
plannedAction: "abort",
|
|
999
|
+
reason: `DotNS signer ${this.substrateAddress} has ${fmtPas(effectiveBalance)} PAS free; needs \u2265${fmtPas(feeFloor)} PAS for ${op}.${tail}`,
|
|
1000
|
+
signerFreeBalance: effectiveBalance,
|
|
1001
|
+
feeFloor
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
return { ...candidate, signerFreeBalance: effectiveBalance, feeFloor, toppedUp };
|
|
1005
|
+
}
|
|
795
1006
|
async register(label, options = {}) {
|
|
796
1007
|
return withSpan("deploy.dotns.register", `2a. register ${label}.dot`, {}, async () => {
|
|
797
1008
|
if (!this.connected) await this.connect(options);
|
|
@@ -859,6 +1070,8 @@ var DotNS = class {
|
|
|
859
1070
|
var dotns = new DotNS();
|
|
860
1071
|
|
|
861
1072
|
export {
|
|
1073
|
+
fmtPas,
|
|
1074
|
+
feeFloorFor,
|
|
862
1075
|
RPC_ENDPOINTS,
|
|
863
1076
|
CONTRACTS,
|
|
864
1077
|
DECIMALS,
|
|
@@ -108,6 +108,14 @@ function runGit(args, cwd, extraEnv = {}) {
|
|
|
108
108
|
env: { ...process.env, ...extraEnv }
|
|
109
109
|
}).trim();
|
|
110
110
|
}
|
|
111
|
+
var MIRROR_BOT_GIT_OVERRIDES = [
|
|
112
|
+
"-c",
|
|
113
|
+
"user.email=bulletin-deploy@noreply.github.com",
|
|
114
|
+
"-c",
|
|
115
|
+
"user.name=bulletin-deploy",
|
|
116
|
+
"-c",
|
|
117
|
+
"commit.gpgsign=false"
|
|
118
|
+
];
|
|
111
119
|
function pushRemoteUrl(owner, repo, token) {
|
|
112
120
|
const authedOwner = token ? `x-access-token:${token}@github.com` : "github.com";
|
|
113
121
|
return `https://${authedOwner}/${owner}/${repo}.git`;
|
|
@@ -154,7 +162,7 @@ async function mirrorToGitHubPages(input) {
|
|
|
154
162
|
const manifestPath = path.join(mirrorDir, `${domainFilename}.json`);
|
|
155
163
|
fs.writeFileSync(carPath, input.carBytes);
|
|
156
164
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
|
|
157
|
-
runGit([
|
|
165
|
+
runGit([...MIRROR_BOT_GIT_OVERRIDES, "add", GH_PAGES_MIRROR_DIR], workTree);
|
|
158
166
|
const status = runGit(["status", "--porcelain"], workTree);
|
|
159
167
|
if (status.length === 0) {
|
|
160
168
|
return {
|
|
@@ -167,10 +175,7 @@ async function mirrorToGitHubPages(input) {
|
|
|
167
175
|
}
|
|
168
176
|
runGit(
|
|
169
177
|
[
|
|
170
|
-
|
|
171
|
-
"user.email=bulletin-deploy@noreply.github.com",
|
|
172
|
-
"-c",
|
|
173
|
-
"user.name=bulletin-deploy",
|
|
178
|
+
...MIRROR_BOT_GIT_OVERRIDES,
|
|
174
179
|
"commit",
|
|
175
180
|
"-m",
|
|
176
181
|
`"mirror(bulletin): ${domainFilename} @ ${input.cid.slice(0, 12)}"`
|
|
@@ -209,5 +214,6 @@ export {
|
|
|
209
214
|
normalizeDomainFilename,
|
|
210
215
|
mirrorUrl,
|
|
211
216
|
buildManifest,
|
|
217
|
+
MIRROR_BOT_GIT_OVERRIDES,
|
|
212
218
|
mirrorToGitHubPages
|
|
213
219
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
package_default,
|
|
3
3
|
writeRunState
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VKADME5F.js";
|
|
5
5
|
|
|
6
6
|
// src/memory-report.ts
|
|
7
7
|
import * as fs2 from "fs";
|
|
@@ -203,7 +203,12 @@ function getDeployAttributes(domain) {
|
|
|
203
203
|
// Seed "false" so every span carries the attribute (boolean-both-values rule).
|
|
204
204
|
// Flipped to "true" by getWsProvider's onStatusChanged when papi connects to a
|
|
205
205
|
// non-primary endpoint, and flushed again in deploy()'s finally block.
|
|
206
|
-
"deploy.rpc.failed_over": "false"
|
|
206
|
+
"deploy.rpc.failed_over": "false",
|
|
207
|
+
// DotNS preflight balance gate. Seeded "false" so successful spans form the
|
|
208
|
+
// denominator for "% of deploys hitting the floor" and "% recovered via
|
|
209
|
+
// testnet auto-top-up" metrics. Flipped by gateOnFeeBalance.
|
|
210
|
+
"deploy.dotns.signer_below_floor": "false",
|
|
211
|
+
"deploy.dotns.toppedup": "false"
|
|
207
212
|
};
|
|
208
213
|
if (hostApp) attrs["deploy.host_app"] = hostApp;
|
|
209
214
|
return attrs;
|
|
@@ -7,6 +7,10 @@ import { getWsProvider } from "polkadot-api/ws-provider";
|
|
|
7
7
|
import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat";
|
|
8
8
|
import { Keyring } from "@polkadot/keyring";
|
|
9
9
|
import { cryptoWaitReady } from "@polkadot/util-crypto";
|
|
10
|
+
var PAS_DECIMALS_DIVISOR = 1e10;
|
|
11
|
+
function formatPasBalance(plancks) {
|
|
12
|
+
return (Number(plancks) / PAS_DECIMALS_DIVISOR).toFixed(4);
|
|
13
|
+
}
|
|
10
14
|
var DEPLOY_PATH_PREFIX = "//deploy";
|
|
11
15
|
var TOPUP_TRANSACTIONS = 1e3;
|
|
12
16
|
var TOPUP_BYTES = 100000000n;
|
|
@@ -198,7 +202,7 @@ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
|
|
|
198
202
|
const aliceSigner = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
|
|
199
203
|
const aliceAccount = await api.query.System.Account.getValue(alice.address);
|
|
200
204
|
const aliceBalance = BigInt(aliceAccount.data.free);
|
|
201
|
-
console.log(`Alice balance: ${(
|
|
205
|
+
console.log(`Alice balance: ${formatPasBalance(aliceBalance)} PAS
|
|
202
206
|
`);
|
|
203
207
|
for (const account of accounts) {
|
|
204
208
|
console.log(`Account ${account.index}: ${account.address}`);
|
|
@@ -239,6 +243,7 @@ async function bootstrapPool(bulletinRpc, poolSize = 10, mnemonic) {
|
|
|
239
243
|
}
|
|
240
244
|
|
|
241
245
|
export {
|
|
246
|
+
formatPasBalance,
|
|
242
247
|
derivePoolAccounts,
|
|
243
248
|
selectAccount,
|
|
244
249
|
fetchPoolAuthorizations,
|
|
@@ -6,7 +6,7 @@ import * as path from "path";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "bulletin-deploy",
|
|
9
|
-
version: "0.7.
|
|
9
|
+
version: "0.7.7",
|
|
10
10
|
private: false,
|
|
11
11
|
repository: {
|
|
12
12
|
type: "git",
|
|
@@ -48,7 +48,7 @@ var package_default = {
|
|
|
48
48
|
"@ipld/car": "^5.4.3",
|
|
49
49
|
"@ipld/dag-pb": "^4.1.3",
|
|
50
50
|
"@noble/hashes": "^1.7.2",
|
|
51
|
-
"@parity/dotns-cli": "0.
|
|
51
|
+
"@parity/dotns-cli": "^0.6.0",
|
|
52
52
|
"@polkadot-api/substrate-bindings": "^0.16.5",
|
|
53
53
|
"@polkadot-labs/hdkd": "^0.0.25",
|
|
54
54
|
"@polkadot-labs/hdkd-helpers": "^0.0.26",
|
package/dist/deploy.d.ts
CHANGED
|
@@ -101,8 +101,18 @@ interface DeployOptions {
|
|
|
101
101
|
* caveat.
|
|
102
102
|
*/
|
|
103
103
|
ghPagesMirror?: boolean;
|
|
104
|
+
/** When set, writes the "name" text record on the domain after contenthash. */
|
|
105
|
+
name?: string;
|
|
106
|
+
/** When set, writes the "description" text record. ≤100 chars recommended for host-app cards. */
|
|
107
|
+
description?: string;
|
|
104
108
|
}
|
|
109
|
+
declare function resolveDotnsConnectOptions(options: Pick<DeployOptions, "mnemonic" | "derivationPath" | "signer" | "signerAddress">): {
|
|
110
|
+
signer?: PolkadotSigner;
|
|
111
|
+
signerAddress?: string;
|
|
112
|
+
mnemonic?: string;
|
|
113
|
+
derivationPath?: string;
|
|
114
|
+
};
|
|
105
115
|
declare function estimateUploadBytes(content: DeployContent): Promise<number | null>;
|
|
106
116
|
declare function deploy(content: DeployContent, domainName?: string | null, options?: DeployOptions): Promise<DeployResult>;
|
|
107
117
|
|
|
108
|
-
export { CHUNK_MORTALITY_PERIOD, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, EXIT_CODE_NO_RETRY, NonRetryableError, type StoreDirectoryOptions, chunk, computeStorageCid, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, estimateUploadBytes, friendlyChainError, hasIPFS, isConnectionError, merkleize, storeChunkedContent, storeDirectory, storeFile };
|
|
118
|
+
export { CHUNK_MORTALITY_PERIOD, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, type DeployContent, type DeployOptions, type DeployResult, ENCRYPT_KEY_LEN, ENCRYPT_MAGIC, ENCRYPT_NONCE_LEN, ENCRYPT_PBKDF2_ITERATIONS, ENCRYPT_SALT_LEN, ENCRYPT_TAG_LEN, EXIT_CODE_NO_RETRY, NonRetryableError, type StoreDirectoryOptions, chunk, computeStorageCid, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, estimateUploadBytes, friendlyChainError, hasIPFS, isConnectionError, merkleize, resolveDotnsConnectOptions, storeChunkedContent, storeDirectory, storeFile };
|
package/dist/deploy.js
CHANGED
|
@@ -22,18 +22,19 @@ import {
|
|
|
22
22
|
hasIPFS,
|
|
23
23
|
isConnectionError,
|
|
24
24
|
merkleize,
|
|
25
|
+
resolveDotnsConnectOptions,
|
|
25
26
|
storeChunkedContent,
|
|
26
27
|
storeDirectory,
|
|
27
28
|
storeFile
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
34
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-77SWQOPW.js";
|
|
30
|
+
import "./chunk-D3SJZTE2.js";
|
|
31
|
+
import "./chunk-BEAOHOTJ.js";
|
|
32
|
+
import "./chunk-EOCLCWCS.js";
|
|
33
|
+
import "./chunk-HOTQDYHD.js";
|
|
34
|
+
import "./chunk-LNFD7QP6.js";
|
|
35
|
+
import "./chunk-VKADME5F.js";
|
|
35
36
|
import "./chunk-B7GUYYAN.js";
|
|
36
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-RP4YJYNB.js";
|
|
37
38
|
import "./chunk-QGM4M3NI.js";
|
|
38
39
|
export {
|
|
39
40
|
CHUNK_MORTALITY_PERIOD,
|
|
@@ -59,6 +60,7 @@ export {
|
|
|
59
60
|
hasIPFS,
|
|
60
61
|
isConnectionError,
|
|
61
62
|
merkleize,
|
|
63
|
+
resolveDotnsConnectOptions,
|
|
62
64
|
storeChunkedContent,
|
|
63
65
|
storeDirectory,
|
|
64
66
|
storeFile
|
package/dist/dotns.d.ts
CHANGED
|
@@ -44,7 +44,19 @@ interface DotnsPreflightResult {
|
|
|
44
44
|
plannedAction: "register" | "already-owned-by-us" | "abort";
|
|
45
45
|
needsPopUpgrade: boolean;
|
|
46
46
|
targetPopStatus?: number;
|
|
47
|
+
/** Free PAS balance of the DotNS signer at preflight time, in plancks (10 decimals). */
|
|
48
|
+
signerFreeBalance?: bigint;
|
|
49
|
+
/** Threshold the signer must clear; depends on plannedAction. */
|
|
50
|
+
feeFloor?: bigint;
|
|
51
|
+
/** Set when an auto-top-up was attempted on testnet; describes the source and amount. */
|
|
52
|
+
toppedUp?: {
|
|
53
|
+
source: "Alice" | "Bob";
|
|
54
|
+
transferred: bigint;
|
|
55
|
+
};
|
|
47
56
|
}
|
|
57
|
+
declare function fmtPas(plancks: bigint): string;
|
|
58
|
+
type DotnsSuccessAction = Exclude<DotnsPreflightResult["plannedAction"], "abort">;
|
|
59
|
+
declare function feeFloorFor(plannedAction: DotnsSuccessAction): bigint;
|
|
48
60
|
declare const RPC_ENDPOINTS: string[];
|
|
49
61
|
declare const CONTRACTS: {
|
|
50
62
|
readonly DOTNS_REGISTRAR: "0x329aAA5b6bEa94E750b2dacBa74Bf41291E6c2BD";
|
|
@@ -130,6 +142,12 @@ declare class DotNS {
|
|
|
130
142
|
ensureConnected(): void;
|
|
131
143
|
private _testnetCache;
|
|
132
144
|
isTestnet(): Promise<boolean>;
|
|
145
|
+
readFreeBalance(ss58: string): Promise<bigint>;
|
|
146
|
+
attemptTestnetTopUp(recipientSs58: string, targetAmount: bigint): Promise<{
|
|
147
|
+
source: "Alice" | "Bob";
|
|
148
|
+
transferred: bigint;
|
|
149
|
+
} | null>;
|
|
150
|
+
private submitTransfer;
|
|
133
151
|
contractCall(contractAddress: string, contractAbi: readonly any[], functionName: string, args?: any[]): Promise<any>;
|
|
134
152
|
checkOwnership(label: string, ownerAddress?: string | null): Promise<OwnershipResult>;
|
|
135
153
|
getUserPopStatus(ownerAddress?: string | null): Promise<number>;
|
|
@@ -143,8 +161,13 @@ declare class DotNS {
|
|
|
143
161
|
setContenthash(domainName: string, contenthashHex: string): Promise<{
|
|
144
162
|
node: string;
|
|
145
163
|
}>;
|
|
164
|
+
setTextRecord(domainName: string, key: string, value: string, _cli?: (argv: string[], env?: Record<string, string>) => Promise<unknown>): Promise<{
|
|
165
|
+
value: string;
|
|
166
|
+
txHash: string;
|
|
167
|
+
}>;
|
|
146
168
|
getContenthash(domainName: string): Promise<string>;
|
|
147
169
|
preflight(label: string, explicitStatusOverride?: string): Promise<DotnsPreflightResult>;
|
|
170
|
+
private gateOnFeeBalance;
|
|
148
171
|
register(label: string, options?: DotNSConnectOptions & {
|
|
149
172
|
status?: string;
|
|
150
173
|
reverse?: boolean;
|
|
@@ -156,4 +179,4 @@ declare class DotNS {
|
|
|
156
179
|
}
|
|
157
180
|
declare const dotns: DotNS;
|
|
158
181
|
|
|
159
|
-
export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, fetchNonce, isCommitmentMature, isExplicitCommitmentBuffer, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, runDotnsCli, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
|
|
182
|
+
export { CONNECTION_TIMEOUT_MS, CONTRACTS, DECIMALS, DEFAULT_MNEMONIC, DOTNS_TX_MAX_ATTEMPTS, DOT_NODE, DotNS, type DotNSConnectOptions, type DotnsPreflightResult, type DotnsSuccessAction, NATIVE_TO_ETH_RATIO, OPERATION_TIMEOUT_MS, type OwnershipResult, type ParsedDomainName, type PriceValidationResult, ProofOfPersonhoodStatus, RPC_ENDPOINTS, TX_CHAIN_TIME_BUDGET_MS, TX_TIMEOUT_MS, TX_WALL_CLOCK_CEILING_MS, WS_HEARTBEAT_TIMEOUT_MS, canRegister, classifyDotnsLabel, classifyTxRetryDecision, computeDomainTokenId, convertWeiToNative, countTrailingDigits, dotns, feeFloorFor, fetchNonce, fmtPas, isCommitmentMature, isExplicitCommitmentBuffer, parseDomainName, parseProofOfPersonhoodStatus, popStatusName, runDotnsCli, sanitizeDomainLabel, simulateUserStatus, stripTrailingDigits, validateDomainLabel, verifyNonceAdvanced };
|
package/dist/dotns.js
CHANGED
|
@@ -21,7 +21,9 @@ import {
|
|
|
21
21
|
convertWeiToNative,
|
|
22
22
|
countTrailingDigits,
|
|
23
23
|
dotns,
|
|
24
|
+
feeFloorFor,
|
|
24
25
|
fetchNonce,
|
|
26
|
+
fmtPas,
|
|
25
27
|
isCommitmentMature,
|
|
26
28
|
isExplicitCommitmentBuffer,
|
|
27
29
|
parseDomainName,
|
|
@@ -33,10 +35,10 @@ import {
|
|
|
33
35
|
stripTrailingDigits,
|
|
34
36
|
validateDomainLabel,
|
|
35
37
|
verifyNonceAdvanced
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
39
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-EOCLCWCS.js";
|
|
39
|
+
import "./chunk-LNFD7QP6.js";
|
|
40
|
+
import "./chunk-VKADME5F.js";
|
|
41
|
+
import "./chunk-RP4YJYNB.js";
|
|
40
42
|
import "./chunk-QGM4M3NI.js";
|
|
41
43
|
export {
|
|
42
44
|
CONNECTION_TIMEOUT_MS,
|
|
@@ -61,7 +63,9 @@ export {
|
|
|
61
63
|
convertWeiToNative,
|
|
62
64
|
countTrailingDigits,
|
|
63
65
|
dotns,
|
|
66
|
+
feeFloorFor,
|
|
64
67
|
fetchNonce,
|
|
68
|
+
fmtPas,
|
|
65
69
|
isCommitmentMature,
|
|
66
70
|
isExplicitCommitmentBuffer,
|
|
67
71
|
parseDomainName,
|
|
@@ -70,6 +70,7 @@ declare function resolveSourceCommit(repoPath: string): string | undefined;
|
|
|
70
70
|
declare function normalizeDomainFilename(domain: string): string;
|
|
71
71
|
declare function mirrorUrl(owner: string, repo: string, domainFilename: string): string;
|
|
72
72
|
declare function buildManifest(input: Omit<MirrorInput, "carBytes" | "repoPath" | "githubToken">): MirrorManifest;
|
|
73
|
+
declare const MIRROR_BOT_GIT_OVERRIDES: readonly string[];
|
|
73
74
|
declare function mirrorToGitHubPages(input: MirrorInput): Promise<MirrorResult>;
|
|
74
75
|
|
|
75
|
-
export { type FreshnessPollResult, GH_PAGES_MIRROR_BRANCH, GH_PAGES_MIRROR_DIR, GH_PAGES_MIRROR_MAX_BYTES, type MirrorInput, type MirrorManifest, type MirrorResult, MirrorSkipped, buildManifest, mirrorToGitHubPages, mirrorUrl, normalizeDomainFilename, parseGitRemoteUrl, pollMirrorFreshness, resolveOwnerRepo, resolveSourceCommit };
|
|
76
|
+
export { type FreshnessPollResult, GH_PAGES_MIRROR_BRANCH, GH_PAGES_MIRROR_DIR, GH_PAGES_MIRROR_MAX_BYTES, MIRROR_BOT_GIT_OVERRIDES, type MirrorInput, type MirrorManifest, type MirrorResult, MirrorSkipped, buildManifest, mirrorToGitHubPages, mirrorUrl, normalizeDomainFilename, parseGitRemoteUrl, pollMirrorFreshness, resolveOwnerRepo, resolveSourceCommit };
|
package/dist/gh-pages-mirror.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
GH_PAGES_MIRROR_BRANCH,
|
|
3
3
|
GH_PAGES_MIRROR_DIR,
|
|
4
4
|
GH_PAGES_MIRROR_MAX_BYTES,
|
|
5
|
+
MIRROR_BOT_GIT_OVERRIDES,
|
|
5
6
|
MirrorSkipped,
|
|
6
7
|
buildManifest,
|
|
7
8
|
mirrorToGitHubPages,
|
|
@@ -11,12 +12,13 @@ import {
|
|
|
11
12
|
pollMirrorFreshness,
|
|
12
13
|
resolveOwnerRepo,
|
|
13
14
|
resolveSourceCommit
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-HOTQDYHD.js";
|
|
15
16
|
import "./chunk-QGM4M3NI.js";
|
|
16
17
|
export {
|
|
17
18
|
GH_PAGES_MIRROR_BRANCH,
|
|
18
19
|
GH_PAGES_MIRROR_DIR,
|
|
19
20
|
GH_PAGES_MIRROR_MAX_BYTES,
|
|
21
|
+
MIRROR_BOT_GIT_OVERRIDES,
|
|
20
22
|
MirrorSkipped,
|
|
21
23
|
buildManifest,
|
|
22
24
|
mirrorToGitHubPages,
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-77SWQOPW.js";
|
|
4
|
+
import "./chunk-D3SJZTE2.js";
|
|
5
|
+
import "./chunk-BEAOHOTJ.js";
|
|
6
6
|
import {
|
|
7
7
|
DotNS,
|
|
8
8
|
parseDomainName
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-EOCLCWCS.js";
|
|
10
|
+
import "./chunk-HOTQDYHD.js";
|
|
11
|
+
import "./chunk-LNFD7QP6.js";
|
|
12
12
|
import {
|
|
13
13
|
VERSION,
|
|
14
14
|
loadRunState,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
shouldSkipStaleWarning,
|
|
19
19
|
stateFilePath,
|
|
20
20
|
writeRunState
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VKADME5F.js";
|
|
22
22
|
import {
|
|
23
23
|
merkleizeJS
|
|
24
24
|
} from "./chunk-B7GUYYAN.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
ensureAuthorized,
|
|
29
29
|
fetchPoolAuthorizations,
|
|
30
30
|
selectAccount
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-RP4YJYNB.js";
|
|
32
32
|
import "./chunk-QGM4M3NI.js";
|
|
33
33
|
export {
|
|
34
34
|
DotNS,
|
package/dist/memory-report.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
maybeWriteMemoryReport,
|
|
6
6
|
safeHeap,
|
|
7
7
|
sampleFromBytes
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-LNFD7QP6.js";
|
|
9
|
+
import "./chunk-VKADME5F.js";
|
|
10
10
|
import "./chunk-QGM4M3NI.js";
|
|
11
11
|
export {
|
|
12
12
|
DEFAULT_THRESHOLD_MB,
|
package/dist/pool.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PolkadotSigner } from 'polkadot-api';
|
|
2
2
|
|
|
3
|
+
declare function formatPasBalance(plancks: bigint): string;
|
|
3
4
|
interface PoolAccount {
|
|
4
5
|
index: number;
|
|
5
6
|
path: string;
|
|
@@ -34,4 +35,4 @@ declare function ensureAuthorized(api: any, address: string, label?: string, min
|
|
|
34
35
|
declare function topUpBy(api: any, address: string, needs: AuthorizationNeeds, label?: string): Promise<void>;
|
|
35
36
|
declare function bootstrapPool(bulletinRpc: string, poolSize?: number, mnemonic?: string): Promise<void>;
|
|
36
37
|
|
|
37
|
-
export { type AuthorizationNeeds, type PoolAccount, type PoolAuthorization, type TxRetryDecision, _resetTestnetCacheForTests, bootstrapPool, classifyAliceTxError, computeTopUpTarget, derivePoolAccounts, detectTestnet, ensureAuthorized, fetchPoolAuthorizations, isTestnetSpecName, selectAccount, topUpBy };
|
|
38
|
+
export { type AuthorizationNeeds, type PoolAccount, type PoolAuthorization, type TxRetryDecision, _resetTestnetCacheForTests, bootstrapPool, classifyAliceTxError, computeTopUpTarget, derivePoolAccounts, detectTestnet, ensureAuthorized, fetchPoolAuthorizations, formatPasBalance, isTestnetSpecName, selectAccount, topUpBy };
|
package/dist/pool.js
CHANGED
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
detectTestnet,
|
|
8
8
|
ensureAuthorized,
|
|
9
9
|
fetchPoolAuthorizations,
|
|
10
|
+
formatPasBalance,
|
|
10
11
|
isTestnetSpecName,
|
|
11
12
|
selectAccount,
|
|
12
13
|
topUpBy
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RP4YJYNB.js";
|
|
14
15
|
import "./chunk-QGM4M3NI.js";
|
|
15
16
|
export {
|
|
16
17
|
_resetTestnetCacheForTests,
|
|
@@ -21,6 +22,7 @@ export {
|
|
|
21
22
|
detectTestnet,
|
|
22
23
|
ensureAuthorized,
|
|
23
24
|
fetchPoolAuthorizations,
|
|
25
|
+
formatPasBalance,
|
|
24
26
|
isTestnetSpecName,
|
|
25
27
|
selectAccount,
|
|
26
28
|
topUpBy
|
package/dist/run-state.js
CHANGED
package/dist/telemetry.js
CHANGED
package/dist/version-check.js
CHANGED
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
isPreReleaseVersion,
|
|
9
9
|
preReleaseWarning,
|
|
10
10
|
promptYesNo
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-BEAOHOTJ.js";
|
|
12
|
+
import "./chunk-LNFD7QP6.js";
|
|
13
|
+
import "./chunk-VKADME5F.js";
|
|
14
14
|
import "./chunk-QGM4M3NI.js";
|
|
15
15
|
export {
|
|
16
16
|
assessVersion,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bulletin-deploy",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@ipld/car": "^5.4.3",
|
|
43
43
|
"@ipld/dag-pb": "^4.1.3",
|
|
44
44
|
"@noble/hashes": "^1.7.2",
|
|
45
|
-
"@parity/dotns-cli": "0.
|
|
45
|
+
"@parity/dotns-cli": "^0.6.0",
|
|
46
46
|
"@polkadot-api/substrate-bindings": "^0.16.5",
|
|
47
47
|
"@polkadot-labs/hdkd": "^0.0.25",
|
|
48
48
|
"@polkadot-labs/hdkd-helpers": "^0.0.26",
|