bulletin-deploy 0.6.5 → 0.6.6-rc.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/bin/bulletin-deploy +4 -3
- package/dist/{chunk-BR35ORSD.js → chunk-3MATO55H.js} +4 -4
- package/dist/{chunk-QB7UH3NR.js → chunk-BDJLYUP6.js} +53 -11
- package/dist/{chunk-S7ZSIIY4.js → chunk-DEUNAION.js} +1 -1
- package/dist/{chunk-AIHW2WLO.js → chunk-LGPTJYA3.js} +4 -4
- package/dist/deploy.d.ts +5 -1
- package/dist/deploy.js +8 -4
- package/dist/dotns.js +2 -2
- package/dist/index.js +4 -4
- package/dist/pool.d.ts +1 -1
- package/dist/pool.js +1 -1
- package/dist/telemetry.js +1 -1
- package/package.json +1 -1
package/bin/bulletin-deploy
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE } from "../dist/deploy.js";
|
|
3
|
+
import { deploy, DEFAULT_BULLETIN_RPC, DEFAULT_POOL_SIZE, NonRetryableError, EXIT_CODE_NO_RETRY } from "../dist/deploy.js";
|
|
4
4
|
import { bootstrapPool } from "../dist/pool.js";
|
|
5
5
|
import { VERSION } from "../dist/telemetry.js";
|
|
6
6
|
import * as fs from "fs";
|
|
@@ -74,6 +74,7 @@ try {
|
|
|
74
74
|
}
|
|
75
75
|
process.exit(0);
|
|
76
76
|
} catch (error) {
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const noRetry = error instanceof NonRetryableError;
|
|
78
|
+
console.error(`Deployment failed${noRetry ? " (not retryable)" : ""}:`, error.message);
|
|
79
|
+
process.exit(noRetry ? EXIT_CODE_NO_RETRY : 1);
|
|
79
80
|
}
|
|
@@ -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.6.
|
|
9
|
+
version: "0.6.6-rc.0",
|
|
10
10
|
private: false,
|
|
11
11
|
repository: {
|
|
12
12
|
type: "git",
|
|
@@ -65,7 +65,7 @@ var package_default = {
|
|
|
65
65
|
|
|
66
66
|
// src/telemetry.ts
|
|
67
67
|
var VERSION = package_default.version;
|
|
68
|
-
var DEFAULT_DSN = "https://e021c025d79c4c3ade2862a11f13c40b@
|
|
68
|
+
var DEFAULT_DSN = "https://e021c025d79c4c3ade2862a11f13c40b@o4511059872841728.ingest.de.sentry.io/4511093597405264";
|
|
69
69
|
var DISABLED = process.env.BULLETIN_DEPLOY_TELEMETRY === "0";
|
|
70
70
|
var Sentry = null;
|
|
71
71
|
if (!DISABLED) {
|
|
@@ -87,7 +87,7 @@ function extractRepoSlug(url) {
|
|
|
87
87
|
}
|
|
88
88
|
function tryGitRemote() {
|
|
89
89
|
try {
|
|
90
|
-
return extractRepoSlug(execSync("git remote get-url origin", { encoding: "utf-8" }).trim());
|
|
90
|
+
return extractRepoSlug(execSync("git remote get-url origin", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim());
|
|
91
91
|
} catch {
|
|
92
92
|
return void 0;
|
|
93
93
|
}
|
|
@@ -106,7 +106,7 @@ function resolveRepo(domain) {
|
|
|
106
106
|
}
|
|
107
107
|
function tryGitBranch() {
|
|
108
108
|
try {
|
|
109
|
-
return execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
|
|
109
|
+
return execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
110
110
|
} catch {
|
|
111
111
|
return "unknown";
|
|
112
112
|
}
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
TX_TIMEOUT_MS,
|
|
5
5
|
fetchNonce,
|
|
6
6
|
validateDomainLabel
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DEUNAION.js";
|
|
8
8
|
import {
|
|
9
9
|
derivePoolAccounts,
|
|
10
10
|
ensureAuthorized,
|
|
11
11
|
fetchPoolAuthorizations,
|
|
12
12
|
selectAccount
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LGPTJYA3.js";
|
|
14
14
|
import {
|
|
15
15
|
VERSION,
|
|
16
16
|
captureWarning,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
setDeployAttribute,
|
|
19
19
|
withDeploySpan,
|
|
20
20
|
withSpan
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-3MATO55H.js";
|
|
22
22
|
|
|
23
23
|
// src/deploy.ts
|
|
24
24
|
import { Buffer } from "buffer";
|
|
@@ -294,6 +294,13 @@ var cdm_default = {
|
|
|
294
294
|
};
|
|
295
295
|
|
|
296
296
|
// src/deploy.ts
|
|
297
|
+
var NonRetryableError = class extends Error {
|
|
298
|
+
constructor(message) {
|
|
299
|
+
super(message);
|
|
300
|
+
this.name = "NonRetryableError";
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
var EXIT_CODE_NO_RETRY = 78;
|
|
297
304
|
var DEFAULT_BULLETIN_RPC = "wss://paseo-bulletin-rpc.polkadot.io";
|
|
298
305
|
var DEFAULT_POOL_SIZE = 10;
|
|
299
306
|
var BULLETIN_RPC = DEFAULT_BULLETIN_RPC;
|
|
@@ -301,7 +308,7 @@ var POOL_SIZE = DEFAULT_POOL_SIZE;
|
|
|
301
308
|
var CHUNK_SIZE = 1 * 1024 * 1024;
|
|
302
309
|
var MAX_FILE_SIZE = 8 * 1024 * 1024;
|
|
303
310
|
var MAX_RECONNECTIONS = parseInt(process.env.BULLETIN_MAX_RECONNECTIONS ?? "3", 10);
|
|
304
|
-
var CHUNK_TIMEOUT_MS =
|
|
311
|
+
var CHUNK_TIMEOUT_MS = parseInt(process.env.BULLETIN_CHUNK_TIMEOUT_MS ?? "60000", 10);
|
|
305
312
|
var RETRY_BASE_DELAY_MS = 2e3;
|
|
306
313
|
var RETRY_MAX_DELAY_MS = 15e3;
|
|
307
314
|
function isConnectionError(error) {
|
|
@@ -395,10 +402,10 @@ async function getProvider() {
|
|
|
395
402
|
if (!selected) {
|
|
396
403
|
const best = authorizations.reduce((a, b) => a.transactions > b.transactions ? a : b);
|
|
397
404
|
console.log(` All pool accounts low on capacity, auto-authorizing account ${best.index}...`);
|
|
398
|
-
await ensureAuthorized(unsafeApi, best, BULLETIN_RPC);
|
|
405
|
+
await ensureAuthorized(unsafeApi, best.address, BULLETIN_RPC, `pool account ${best.index}`);
|
|
399
406
|
selected = best;
|
|
400
407
|
} else {
|
|
401
|
-
await ensureAuthorized(unsafeApi, selected, BULLETIN_RPC);
|
|
408
|
+
await ensureAuthorized(unsafeApi, selected.address, BULLETIN_RPC, `pool account ${selected.index}`);
|
|
402
409
|
}
|
|
403
410
|
console.log(` Using pool account ${selected.index}: ${selected.address}`);
|
|
404
411
|
setDeployAttribute("deploy.signer.mode", "pool");
|
|
@@ -423,7 +430,7 @@ async function getDirectProvider(mnemonic) {
|
|
|
423
430
|
const bytesRemaining = auth ? auth.extent.bytes : 0n;
|
|
424
431
|
if (txsRemaining === 0n && bytesRemaining === 0n) {
|
|
425
432
|
client.destroy();
|
|
426
|
-
throw new
|
|
433
|
+
throw new NonRetryableError(`Account ${ss58} is not authorized for Bulletin storage.`);
|
|
427
434
|
}
|
|
428
435
|
console.log(` Authorization: ${txsRemaining} txs, ${Number(bytesRemaining) / 1e6}MB remaining`);
|
|
429
436
|
setDeployAttribute("deploy.signer.mode", "direct");
|
|
@@ -561,6 +568,23 @@ async function storeChunkedContent(chunks, { client: existingClient, unsafeApi:
|
|
|
561
568
|
ss58 = provider.ss58;
|
|
562
569
|
ownsClient = true;
|
|
563
570
|
}
|
|
571
|
+
const requiredTxs = BigInt(chunks.length + 1);
|
|
572
|
+
const auth = await unsafeApi.query.TransactionStorage.Authorizations.getValue(
|
|
573
|
+
Enum("Account", ss58)
|
|
574
|
+
);
|
|
575
|
+
const txsRemaining = auth ? BigInt(auth.extent.transactions) : 0n;
|
|
576
|
+
const bytesRemaining = auth ? auth.extent.bytes : 0n;
|
|
577
|
+
if (txsRemaining < requiredTxs || bytesRemaining < BigInt(totalBytes)) {
|
|
578
|
+
console.log(`
|
|
579
|
+
Account has insufficient authorization for this upload (need ${requiredTxs} txs / ${(totalBytes / 1e6).toFixed(1)}MB, have ${txsRemaining} txs / ${Number(bytesRemaining) / 1e6}MB)`);
|
|
580
|
+
console.log(` Attempting to re-authorize with Alice...`);
|
|
581
|
+
try {
|
|
582
|
+
await ensureAuthorized(unsafeApi, ss58, BULLETIN_RPC);
|
|
583
|
+
console.log(` Re-authorization successful`);
|
|
584
|
+
} catch (e) {
|
|
585
|
+
throw new Error(`Re-authorization failed: ${e.message}`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
564
588
|
let reconnectionsUsed = 0;
|
|
565
589
|
async function doReconnect() {
|
|
566
590
|
if (!reconnect || reconnectionsUsed >= MAX_RECONNECTIONS) {
|
|
@@ -790,6 +814,24 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
790
814
|
let provider;
|
|
791
815
|
const reconnect = options.mnemonic ? () => getDirectProvider(options.mnemonic) : () => getProvider();
|
|
792
816
|
try {
|
|
817
|
+
console.log("\n" + "=".repeat(60));
|
|
818
|
+
console.log("Preflight");
|
|
819
|
+
console.log("=".repeat(60));
|
|
820
|
+
const preflight = new DotNS();
|
|
821
|
+
await preflight.connect(
|
|
822
|
+
options.signer && options.signerAddress ? { signer: options.signer, signerAddress: options.signerAddress } : options.mnemonic ? { mnemonic: options.mnemonic } : {}
|
|
823
|
+
);
|
|
824
|
+
const { owned, owner } = await preflight.checkOwnership(name);
|
|
825
|
+
if (owner && owner !== "0x0000000000000000000000000000000000000000" && !owned) {
|
|
826
|
+
preflight.disconnect();
|
|
827
|
+
throw new NonRetryableError(`Domain ${name}.dot is owned by a different account (${owner}). To fix, transfer it:
|
|
828
|
+
|
|
829
|
+
dotns lookup transfer ${name} -d ${preflight.evmAddress}
|
|
830
|
+
|
|
831
|
+
Or deploy with the original account, or use a different domain name.`);
|
|
832
|
+
}
|
|
833
|
+
console.log(` Domain: ${owned ? "owned by you" : "available"}`);
|
|
834
|
+
preflight.disconnect();
|
|
793
835
|
provider = await reconnect();
|
|
794
836
|
const providerWithReconnect = { ...provider, reconnect };
|
|
795
837
|
console.log("\n" + "=".repeat(60));
|
|
@@ -873,11 +915,9 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
873
915
|
await dotns.connect(
|
|
874
916
|
options.signer && options.signerAddress ? { signer: options.signer, signerAddress: options.signerAddress } : options.mnemonic ? { mnemonic: options.mnemonic } : {}
|
|
875
917
|
);
|
|
876
|
-
const { owned
|
|
877
|
-
if (
|
|
918
|
+
const { owned: owned2 } = await dotns.checkOwnership(name);
|
|
919
|
+
if (owned2) {
|
|
878
920
|
console.log(` Status: Already owned`);
|
|
879
|
-
} else if (owner && owner !== "0x0000000000000000000000000000000000000000") {
|
|
880
|
-
throw new Error(`Domain ${name}.dot is owned by ${owner}, not ${dotns.evmAddress}`);
|
|
881
921
|
} else {
|
|
882
922
|
console.log(` Status: Registering...`);
|
|
883
923
|
await dotns.register(name);
|
|
@@ -942,6 +982,8 @@ async function deploy(content, domainName = null, options = {}) {
|
|
|
942
982
|
}
|
|
943
983
|
|
|
944
984
|
export {
|
|
985
|
+
NonRetryableError,
|
|
986
|
+
EXIT_CODE_NO_RETRY,
|
|
945
987
|
DEFAULT_BULLETIN_RPC,
|
|
946
988
|
DEFAULT_POOL_SIZE,
|
|
947
989
|
isConnectionError,
|
|
@@ -55,16 +55,16 @@ async function fetchPoolAuthorizations(api, accounts) {
|
|
|
55
55
|
);
|
|
56
56
|
return results;
|
|
57
57
|
}
|
|
58
|
-
async function ensureAuthorized(api,
|
|
58
|
+
async function ensureAuthorized(api, address, bulletinRpc, label) {
|
|
59
59
|
const auth = await api.query.TransactionStorage.Authorizations.getValue(
|
|
60
|
-
Enum("Account",
|
|
60
|
+
Enum("Account", address)
|
|
61
61
|
);
|
|
62
62
|
const txsRemaining = auth ? BigInt(auth.extent.transactions) : 0n;
|
|
63
63
|
const bytesRemaining = auth ? auth.extent.bytes : 0n;
|
|
64
64
|
if (txsRemaining >= TOPUP_THRESHOLD_TXS && bytesRemaining >= TOPUP_THRESHOLD_BYTES) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
|
-
console.log(` Auto-authorizing
|
|
67
|
+
console.log(` Auto-authorizing ${label ?? "account"} (${address.slice(0, 8)}...)...`);
|
|
68
68
|
const aliceClient = createClient(withPolkadotSdkCompat(getWsProvider(bulletinRpc)));
|
|
69
69
|
const aliceApi = aliceClient.getUnsafeApi();
|
|
70
70
|
try {
|
|
@@ -72,7 +72,7 @@ async function ensureAuthorized(api, poolAccount, bulletinRpc) {
|
|
|
72
72
|
const alice = keyring.addFromUri("//Alice");
|
|
73
73
|
const aliceSigner = getPolkadotSigner(alice.publicKey, "Sr25519", (data) => alice.sign(data));
|
|
74
74
|
const tx = aliceApi.tx.TransactionStorage.authorize_account({
|
|
75
|
-
who:
|
|
75
|
+
who: address,
|
|
76
76
|
transactions: TOPUP_TRANSACTIONS,
|
|
77
77
|
bytes: TOPUP_BYTES
|
|
78
78
|
});
|
package/dist/deploy.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ interface DeployResult {
|
|
|
8
8
|
ipfsCid?: string;
|
|
9
9
|
}
|
|
10
10
|
type DeployContent = string | Uint8Array | Uint8Array[];
|
|
11
|
+
declare class NonRetryableError extends Error {
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
|
14
|
+
declare const EXIT_CODE_NO_RETRY = 78;
|
|
11
15
|
interface ProviderResult {
|
|
12
16
|
client: any;
|
|
13
17
|
unsafeApi: any;
|
|
@@ -62,4 +66,4 @@ interface DeployOptions {
|
|
|
62
66
|
}
|
|
63
67
|
declare function deploy(content: DeployContent, domainName?: string | null, options?: DeployOptions): Promise<DeployResult>;
|
|
64
68
|
|
|
65
|
-
export { 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, chunk, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, hasIPFS, isConnectionError, merkleize, storeChunkedContent, storeDirectory, storeFile };
|
|
69
|
+
export { 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, chunk, createCID, deploy, deriveRootSigner, encodeContenthash, encryptContent, hasIPFS, isConnectionError, merkleize, storeChunkedContent, storeDirectory, storeFile };
|
package/dist/deploy.js
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
ENCRYPT_PBKDF2_ITERATIONS,
|
|
8
8
|
ENCRYPT_SALT_LEN,
|
|
9
9
|
ENCRYPT_TAG_LEN,
|
|
10
|
+
EXIT_CODE_NO_RETRY,
|
|
11
|
+
NonRetryableError,
|
|
10
12
|
chunk,
|
|
11
13
|
createCID,
|
|
12
14
|
deploy,
|
|
@@ -19,10 +21,10 @@ import {
|
|
|
19
21
|
storeChunkedContent,
|
|
20
22
|
storeDirectory,
|
|
21
23
|
storeFile
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-BDJLYUP6.js";
|
|
25
|
+
import "./chunk-DEUNAION.js";
|
|
26
|
+
import "./chunk-LGPTJYA3.js";
|
|
27
|
+
import "./chunk-3MATO55H.js";
|
|
26
28
|
import "./chunk-QGM4M3NI.js";
|
|
27
29
|
export {
|
|
28
30
|
DEFAULT_BULLETIN_RPC,
|
|
@@ -33,6 +35,8 @@ export {
|
|
|
33
35
|
ENCRYPT_PBKDF2_ITERATIONS,
|
|
34
36
|
ENCRYPT_SALT_LEN,
|
|
35
37
|
ENCRYPT_TAG_LEN,
|
|
38
|
+
EXIT_CODE_NO_RETRY,
|
|
39
|
+
NonRetryableError,
|
|
36
40
|
chunk,
|
|
37
41
|
createCID,
|
|
38
42
|
deploy,
|
package/dist/dotns.js
CHANGED
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
sanitizeDomainLabel,
|
|
20
20
|
stripTrailingDigits,
|
|
21
21
|
validateDomainLabel
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-DEUNAION.js";
|
|
23
|
+
import "./chunk-3MATO55H.js";
|
|
24
24
|
import "./chunk-QGM4M3NI.js";
|
|
25
25
|
export {
|
|
26
26
|
CONNECTION_TIMEOUT_MS,
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BDJLYUP6.js";
|
|
4
4
|
import {
|
|
5
5
|
DotNS
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DEUNAION.js";
|
|
7
7
|
import {
|
|
8
8
|
bootstrapPool,
|
|
9
9
|
derivePoolAccounts,
|
|
10
10
|
ensureAuthorized,
|
|
11
11
|
fetchPoolAuthorizations,
|
|
12
12
|
selectAccount
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-LGPTJYA3.js";
|
|
14
|
+
import "./chunk-3MATO55H.js";
|
|
15
15
|
import "./chunk-QGM4M3NI.js";
|
|
16
16
|
export {
|
|
17
17
|
DotNS,
|
package/dist/pool.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ interface PoolAuthorization extends PoolAccount {
|
|
|
14
14
|
declare function derivePoolAccounts(poolSize?: number, mnemonic?: string): PoolAccount[];
|
|
15
15
|
declare function selectAccount(authorizations: PoolAuthorization[]): PoolAuthorization | null;
|
|
16
16
|
declare function fetchPoolAuthorizations(api: any, accounts: PoolAccount[]): Promise<PoolAuthorization[]>;
|
|
17
|
-
declare function ensureAuthorized(api: any,
|
|
17
|
+
declare function ensureAuthorized(api: any, address: string, bulletinRpc: string, label?: string): Promise<void>;
|
|
18
18
|
declare function bootstrapPool(bulletinRpc: string, poolSize?: number, mnemonic?: string): Promise<void>;
|
|
19
19
|
|
|
20
20
|
export { type PoolAccount, type PoolAuthorization, bootstrapPool, derivePoolAccounts, ensureAuthorized, fetchPoolAuthorizations, selectAccount };
|
package/dist/pool.js
CHANGED
package/dist/telemetry.js
CHANGED