@etherna/docker 0.0.0-stage → 1.7.1

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/README.md CHANGED
@@ -1,3 +1,36 @@
1
- # Temporary Holding Version
1
+ # @etherna/docker
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Orchestrate the Etherna Docker services (start/stop, dependency graph, Portless integration, SSL
4
+ trust) from Node or from the `etherna` CLI. No Vite dependency — use
5
+ [`@etherna/vite-plugin`](https://www.npmjs.com/package/@etherna/vite-plugin) instead if you're
6
+ running a Vite dev server.
7
+
8
+ See the [repository README](https://github.com/Etherna/etherna-vite-plugin#ethernadocker) for full
9
+ docs. Quick reference:
10
+
11
+ ## Node
12
+
13
+ ```ts
14
+ import { start, stop } from "@etherna/docker"
15
+
16
+ const session = await start({ mongo: true, gateway: { enabled: true } })
17
+ // ...
18
+ await session.shutdown()
19
+
20
+ await stop("gateway")
21
+ await stop(["mongo", "sso"])
22
+ ```
23
+
24
+ ## CLI
25
+
26
+ ```bash
27
+ npm install -g @etherna/docker
28
+ # or: pnpm add @etherna/docker / npx etherna ...
29
+
30
+ etherna start sso gateway --portless --app-port 5173
31
+ etherna stop mongo sso
32
+ etherna --help
33
+ ```
34
+
35
+ `etherna start` is detached by default (reuses/leaves running containers); pass `--attached` to stop
36
+ tracked containers when the process exits.
package/dist/bin.cjs ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("node:process");c=s(c,1);let l=require("node:os");l=s(l,1);let u=require("node:tty");u=s(u,1);let d=require("node:child_process"),f=require("node:fs");f=s(f,1);let p=require("node:path");p=s(p,1);let m=require("@noble/curves/secp256k1.js"),h=require("@noble/hashes/sha3.js");const g=(e=0)=>t=>`\u001B[${t+e}m`,_=(e=0)=>t=>`\u001B[${38+e};5;${t}m`,v=(e=0)=>(t,n,r)=>`\u001B[${38+e};2;${t};${n};${r}m`,y={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(y.modifier);const b=Object.keys(y.color),ee=Object.keys(y.bgColor);[...b,...ee];function te(){let e=new Map;for(let[t,n]of Object.entries(y)){for(let[t,r]of Object.entries(n))y[t]={open:`\u001B[${r[0]}m`,close:`\u001B[${r[1]}m`},n[t]=y[t],e.set(r[0],r[1]);Object.defineProperty(y,t,{value:n,enumerable:!1})}return Object.defineProperty(y,"codes",{value:e,enumerable:!1}),y.color.close=`\x1B[39m`,y.bgColor.close=`\x1B[49m`,y.color.ansi=g(),y.color.ansi256=_(),y.color.ansi16m=v(),y.bgColor.ansi=g(10),y.bgColor.ansi256=_(10),y.bgColor.ansi16m=v(10),Object.defineProperties(y,{rgbToAnsi256:{value(e,t,n){return e===t&&t===n?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(t/255*5)+Math.round(n/255*5)},enumerable:!1},hexToRgb:{value(e){let t=/[a-f\d]{6}|[a-f\d]{3}/i.exec(e.toString(16));if(!t)return[0,0,0];let[n]=t;n.length===3&&(n=[...n].map(e=>e+e).join(``));let r=Number.parseInt(n,16);return[r>>16&255,r>>8&255,r&255]},enumerable:!1},hexToAnsi256:{value:e=>y.rgbToAnsi256(...y.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value(e){if(e<8)return 30+e;if(e<16)return 90+(e-8);let t,n,r;if(e>=232)t=((e-232)*10+8)/255,n=t,r=t;else{e-=16;let i=e%36;t=Math.floor(e/36)/5,n=Math.floor(i/6)/5,r=i%6/5}let i=Math.max(t,n,r)*2;if(i===0)return 30;let a=30+(Math.round(r)<<2|Math.round(n)<<1|Math.round(t));return i===2&&(a+=60),a},enumerable:!1},rgbToAnsi:{value:(e,t,n)=>y.ansi256ToAnsi(y.rgbToAnsi256(e,t,n)),enumerable:!1},hexToAnsi:{value:e=>y.ansi256ToAnsi(y.hexToAnsi256(e)),enumerable:!1}}),y}const x=te();function S(e,t=globalThis.Deno?globalThis.Deno.args:c.default.argv){let n=e.startsWith(`-`)?``:e.length===1?`-`:`--`,r=t.indexOf(n+e),i=t.indexOf(`--`);return r!==-1&&(i===-1||r<i)}const{env:C}=c.default;let ne;S(`no-color`)||S(`no-colors`)||S(`color=false`)||S(`color=never`)?ne=0:(S(`color`)||S(`colors`)||S(`color=true`)||S(`color=always`))&&(ne=1);function re(){if(`FORCE_COLOR`in C)return C.FORCE_COLOR===`true`?1:C.FORCE_COLOR===`false`?0:C.FORCE_COLOR.length===0?1:Math.min(Number.parseInt(C.FORCE_COLOR,10),3)}function ie(e){return e!==0&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function ae(e,{streamIsTTY:t,sniffFlags:n=!0}={}){let r=re();r!==void 0&&(ne=r);let i=n?ne:r;if(i===0)return 0;if(n){if(S(`color=16m`)||S(`color=full`)||S(`color=truecolor`))return 3;if(S(`color=256`))return 2}if(`TF_BUILD`in C&&`AGENT_NAME`in C)return 1;if(e&&!t&&i===void 0)return 0;let a=i||0;if(C.TERM===`dumb`)return a;if(c.default.platform===`win32`){let e=l.default.release().split(`.`);return Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if(`CI`in C)return[`GITHUB_ACTIONS`,`GITEA_ACTIONS`,`CIRCLECI`].some(e=>e in C)?3:[`TRAVIS`,`APPVEYOR`,`GITLAB_CI`,`BUILDKITE`,`DRONE`].some(e=>e in C)||C.CI_NAME===`codeship`?1:a;if(`TEAMCITY_VERSION`in C)return+!!/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(C.TEAMCITY_VERSION);if(C.COLORTERM===`truecolor`||C.TERM===`xterm-kitty`||C.TERM===`xterm-ghostty`||C.TERM===`wezterm`)return 3;if(`TERM_PROGRAM`in C){let e=Number.parseInt((C.TERM_PROGRAM_VERSION||``).split(`.`)[0],10);switch(C.TERM_PROGRAM){case`iTerm.app`:return e>=3?3:2;case`Apple_Terminal`:return 2}}return/-256(color)?$/i.test(C.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(C.TERM)||`COLORTERM`in C?1:a}function oe(e,t={}){return ie(ae(e,{streamIsTTY:e&&e.isTTY,...t}))}const se={stdout:oe({isTTY:u.default.isatty(1)}),stderr:oe({isTTY:u.default.isatty(2)})};function ce(e,t,n){let r=e.indexOf(t);if(r===-1)return e;let i=t.length,a=0,o=``;do o+=e.slice(a,r)+t+n,a=r+i,r=e.indexOf(t,a);while(r!==-1);return o+=e.slice(a),o}function le(e,t,n,r){let i=0,a=``;do{let o=e[r-1]===`\r`;a+=e.slice(i,o?r-1:r)+t+(o?`\r
3
+ `:`
4
+ `)+n,i=r+1,r=e.indexOf(`
5
+ `,i)}while(r!==-1);return a+=e.slice(i),a}const{stdout:ue,stderr:de}=se,fe=Symbol(`GENERATOR`),w=Symbol(`STYLER`),T=Symbol(`IS_EMPTY`),pe=[`ansi`,`ansi`,`ansi256`,`ansi16m`],E=Object.create(null),me=(e,t={})=>{if(t.level&&!(Number.isInteger(t.level)&&t.level>=0&&t.level<=3))throw Error("The `level` option should be an integer from 0 to 3");let n=ue?ue.level:0;e.level=t.level===void 0?n:t.level},he=e=>{let t=(...e)=>e.join(` `);return me(t,e),Object.setPrototypeOf(t,D.prototype),t};function D(e){return he(e)}Object.setPrototypeOf(D.prototype,Function.prototype);for(let[e,t]of Object.entries(x))E[e]={get(){let n=O(this,ve(t.open,t.close,this[w]),this[T]);return Object.defineProperty(this,e,{value:n}),n}};E.visible={get(){let e=O(this,this[w],!0);return Object.defineProperty(this,"visible",{value:e}),e}};const ge=(e,t,n,...r)=>e===`rgb`?t===`ansi16m`?x[n].ansi16m(...r):t===`ansi256`?x[n].ansi256(x.rgbToAnsi256(...r)):x[n].ansi(x.rgbToAnsi(...r)):e===`hex`?ge(`rgb`,t,n,...x.hexToRgb(...r)):x[n][e](...r);for(let e of[`rgb`,`hex`,`ansi256`]){E[e]={get(){let{level:t}=this;return function(...n){let r=ve(ge(e,pe[t],`color`,...n),x.color.close,this[w]);return O(this,r,this[T])}}};let t=`bg`+e[0].toUpperCase()+e.slice(1);E[t]={get(){let{level:t}=this;return function(...n){let r=ve(ge(e,pe[t],`bgColor`,...n),x.bgColor.close,this[w]);return O(this,r,this[T])}}}}const _e=Object.defineProperties(()=>{},{...E,level:{enumerable:!0,get(){return this[fe].level},set(e){this[fe].level=e}}}),ve=(e,t,n)=>{let r,i;return n===void 0?(r=e,i=t):(r=n.openAll+e,i=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:i,parent:n}},O=(e,t,n)=>{let r=(...e)=>ye(r,e.length===1?``+e[0]:e.join(` `));return Object.setPrototypeOf(r,_e),r[fe]=e,r[w]=t,r[T]=n,r},ye=(e,t)=>{if(e.level<=0||!t)return e[T]?``:t;let n=e[w];if(n===void 0)return t;let{openAll:r,closeAll:i}=n;if(t.includes(`\x1B`))for(;n!==void 0;)t=ce(t,n.close,n.open),n=n.parent;let a=t.indexOf(`
6
+ `);return a!==-1&&(t=le(t,i,r,a)),r+t+i};Object.defineProperties(D.prototype,E);const k=D();D({level:de?de.level:0});const be={"bee-blockchain":{code:`bee-blockchain`,service:`bee`,dependencies:[],onFailure:`stop`},"bee-nodes":{code:`bee-nodes`,service:`bee`,dependencies:[`bee-blockchain`],onFailure:`stop`},shkeeper:{code:`shkeeper`,service:`shkeeper`,dependencies:[],onFailure:`stop`},mongo:{code:`mongo`,service:`mongo`,dependencies:[],onFailure:`stop`},sso:{code:`sso`,service:`sso`,dependencies:[`mongo`],onFailure:`stop`},index:{code:`index`,service:`index`,dependencies:[`mongo`],onFailure:`stop`},beehive:{code:`beehive`,service:`beehive`,dependencies:[`mongo`],onFailure:`stop`},gateway:{code:`gateway`,service:`gateway`,dependencies:[`mongo`,`sso`],onFailure:`stop`},credit:{code:`credit`,service:`credit`,dependencies:[`mongo`,`sso`,`shkeeper`],onFailure:`stop`},elastic:{code:`elastic`,service:`elastic`,dependencies:[],onFailure:`stop`}},A=[`blockchain`,`bee`,`beehive`,`credit`,`elastic`,`gateway`,`index`,`mongo`,`shkeeper`,`sso`],xe=A.filter(e=>e!==`shkeeper`);function Se(e){switch(e){case`blockchain`:return[`bee-blockchain`];case`bee`:return[`bee-blockchain`,`bee-nodes`];default:return[e]}}function Ce(e){let t=new Set;function n(e){if(!t.has(e)){t.add(e);for(let t of be[e].dependencies)n(t)}}for(let t of e)n(t);return t}function we(e,t){return e===`bee`?t.has(`bee-nodes`):e===`blockchain`?t.has(`bee-blockchain`):t.has(e)}function Te(e){let t=Ce(e.flatMap(Se)),n={};for(let e of A)n[e]=we(e,t);return n}var j=class extends Error{constructor(e){super(e),this.name=`DependencyTreeValidationError`}};function Ee(e){return e instanceof Error?e:Error(String(e))}function De(e,t){let n=new Set;for(let r=0;r<t.length;r++){let i=t[r];if(i.status!==`started`&&i.status!==`skipped`)if(i.status===`failed`)n.add(i.code);else{let t=i.blockedBy;if(t&&t.length>0)for(let e of t)n.add(e);else n.add(e[r])}}return[...n]}function Oe(e){let t=new Set;for(let n of e){if(t.has(n.code))throw new j(`Duplicate service code "${String(n.code)}".`);t.add(n.code)}for(let n of e){let e=n.dependencies??[];for(let r of e){if(r===n.code)throw new j(`Service "${String(n.code)}" cannot depend on itself.`);if(!t.has(r))throw new j(`Service "${String(n.code)}" depends on unknown service "${String(r)}".`)}}let n=new Set,r=new Set,i=new Map(e.map(e=>[e.code,e]));function a(e){if(r.has(e))return;if(n.has(e))throw new j(`Dependency cycle detected involving service "${String(e)}".`);n.add(e);let t=i.get(e);if(t){for(let e of t.dependencies??[])a(e);n.delete(e),r.add(e)}}for(let t of e)a(t.code)}function ke(e,t){Oe(e);let n=new Map(e.map(e=>[e.code,e])),r=new Map;function i(e){let a=r.get(e);if(a)return a;let o=n.get(e);if(!o)throw new j(`Unknown service code "${String(e)}".`);let s=(async()=>{let n=o.dependencies??[],r=await Promise.all(n.map(e=>i(e)));if(r.some(e=>e.status!==`started`&&e.status!==`skipped`))return{code:e,status:`blocked`,blockedBy:De(n,r)};if(o.enabled===!1)return{code:e,status:`skipped`};let a=o.onFailure??`stop`;try{if(o.beforeStartup&&await o.beforeStartup(),!await o.startupCallback()){let n=Error(`Service startup returned false`);return a===`log`&&t.logError(String(e),n.message),{code:e,status:`failed`,error:n}}return{code:e,status:`started`}}catch(n){let r=Ee(n);return a===`log`&&t.logError(String(e),r.message),{code:e,status:`failed`,error:r}}})();return r.set(e,s),s}return{start:async()=>{let t=await Promise.all(e.map(e=>i(e.code)));return{shouldStop:t.some(e=>e.status===`failed`&&(n.get(e.code)?.onFailure??`stop`)===`stop`),services:t}}}}const Ae=`/usr/local/share/ca-certificates`,je={"etherna-sso":`sso`,"etherna-index":`index`,"etherna-credit":`credit`,"etherna-gateway":`gateway`,"etherna-beehive":`beehive`};function M(e){return`http://${e}.localhost:1355`}function Me(e){return e.trim().replace(/\/+$/,``)}function Ne(){return[`proxy`,`start`,`-p`,`1355`,`--no-tls`]}function Pe(){return[`proxy`,`stop`]}function Fe(e,t,n=!1){let r=[`alias`,e,String(t)];return n&&r.push(`--force`),r}function Ie(e){return[`alias`,`--remove`,e]}async function N(e){return new Promise((t,n)=>{let r=(0,d.spawn)(`portless`,e,{stdio:[`ignore`,`pipe`,`pipe`]}),i=``,a=``;r.stdout?.on(`data`,e=>{i+=String(e)}),r.stderr?.on(`data`,e=>{a+=String(e)}),r.on(`error`,n),r.on(`exit`,e=>{t({code:e??1,stderr:a,stdout:i})})})}async function Le(){try{return(await N([`--version`])).code===0}catch{return!1}}async function Re(){let e=await N(Ne());if(e.code===0)return{startedByUs:!0};let t=`${e.stderr}\n${e.stdout}`;if(/already|in use|running|listen/i.test(t))return{startedByUs:!1};throw Error(`portless proxy start failed (exit ${e.code}): ${t.trim()||`(no output)`}`)}function ze(e){if(typeof e==`number`&&Number.isFinite(e))return e;let t=String(e).trim();if(t===``)throw Error(`Port value is empty`);let n=Number.parseInt(t,10);if(!Number.isFinite(n))throw Error(`Invalid port: ${String(e)}`);return n}async function Be(e,t){let n=ze(t),r=await N(Fe(e,n,!0));if(r.code!==0){let t=`${r.stderr}\n${r.stdout}`;throw Error(`portless alias ${e} ${n} failed: ${t.trim()}`)}}async function Ve(e){for(let t of e)await N(Ie(t))}async function He(){await N(Pe())}const Ue=1633,We=1634,P=9545,Ge=4020,Ke=`0xCEeE442a149784faa65C35e328CCd64d874F9a02`,qe=[`POSTAGE_PRICE`],Je=32650,F=`shkeeper`;function Ye(e){let{mode:t,portless:n,appPort:r,portlessAppPublicUrl:i}=e,a=t===`http`?32610:42610,o=t===`http`?32620:42620,s=t===`http`?32630:42630,c=t===`http`?32640:42640,l=`mongodb://localhost:27017`,u=L(t,a),d=L(t,o),f=L(t,s),p=L(t,c),m=L(t,12610),h=`http://localhost:${Ue}`,g=n&&i?Me(i):Ze(t,r,n,`app`),_={ASPNETCORE_ENVIRONMENT:`Development`,"Elastic:Urls:0":`http://localhost:9200`,...t===`https`?{ASPNETCORE_Kestrel__Certificates__Default__Path:`${Ae}/etherna.pfx`,ASPNETCORE_Kestrel__Certificates__Default__Password:``}:{}};return{app:{port:r},shkeeper:{port:Je},"shkeeper-core":{DEV_MODE:`1`,BTC_WALLET:`disabled`,LTC_WALLET:`disabled`,DOGE_WALLET:`disabled`,ETH_WALLET:`enabled`,ETH_USERNAME:`shkeeper`,ETH_PASSWORD:`shkeeper`,ETHEREUM_API_SERVER_HOST:`localhost`,ETHEREUM_SERVER_PORT:`6000`,SHKEEPER_BACKEND_KEY:F,SHKEEPER_BTC_BACKEND_KEY:F},"ethereum-shkeeper":{FULLNODE_URL:`http://localhost:${P}`,FULLNODE_TIMEOUT:`60`,CURRENT_ETH_NETWORK:`custom`,WEB3_ENABLE_POA_MIDDLEWARE:`1`,BLOCK_SCANNER_MAX_CATCHUP_BLOCKS:`64`,ETH_USERNAME:`shkeeper`,ETH_PASSWORD:`shkeeper`,SHKEEPER_BACKEND_KEY:F,SHKEEPER_HOST:`localhost:${Je}`,REDIS_HOST:`localhost`,SQLALCHEMY_DATABASE_URI:`mariadb+pymysql://root:shkeeper@localhost:3306/ethereum-shkeeper?charset=utf8mb4`,LAST_BLOCK_LOCKED:`FALSE`},elastic:{"discovery.type":`single-node`,"xpack.security.enabled":`false`,ES_JAVA_OPTS:`-Xms512m -Xmx512m`},"etherna-mongodb":{},"etherna-sso":{..._,ASPNETCORE_URLS:u,"IdServer:SsoServer:BaseUrl":u,"IdServer:SsoServer:AllowUnsafeConnection":`true`,"IdServer:Clients:EthernaCredit:BaseUrl":f,"IdServer:Clients:EthernaGateway:BaseUrls:0":p,"IdServer:Clients:EthernaIndex:BaseUrl":d,"IdServer:Clients:EthernaDapp:BaseUrl":g,"DbSeed:Clients:0:RedirectUris:0":`${g}/callback`,"DbSeed:Clients:0:PostLogoutRedirectUris:0":g,"DbSeed:Clients:0:AllowedCorsOrigins:0":g,"ConnectionStrings:DataProtectionDb":`${l}/ethernaSSODataProtectionDev`,"ConnectionStrings:HangfireDb":`${l}/ethernaSSOHangfireDev`,"ConnectionStrings:ServiceSharedDb":`${l}/ethernaServiceSharedDev`,"ConnectionStrings:SSOServerDb":`${l}/ethernaSSODev`},"etherna-index":{..._,ASPNETCORE_URLS:d,"Swarm:GatewayUrl":p,"SsoServer:BaseUrl":u,"SsoServer:AllowUnsafeConnection":`true`,"ConnectionStrings:DataProtectionDb":`${l}/ethernaSharedDataProtectionDev`,"ConnectionStrings:HangfireDb":`${l}/ethernaIndexHangfireDev`,"ConnectionStrings:IndexDb":`${l}/ethernaIndexDev`,"ConnectionStrings:ServiceSharedDb":`${l}/ethernaServiceSharedDev`},"etherna-credit":{..._,ASPNETCORE_URLS:f,"SsoServer:BaseUrl":u,"SsoServer:AllowUnsafeConnection":`true`,"ConnectionStrings:DataProtectionDb":`${l}/ethernaSharedDataProtectionDev`,"ConnectionStrings:HangfireDb":`${l}/ethernaCreditHangfireDev`,"ConnectionStrings:CreditDb":`${l}/ethernaCreditDev`,"ConnectionStrings:ServiceSharedDb":`${l}/ethernaServiceSharedDev`,DisableHttpsRedirection:`true`,"Payments:ShKeeper:Url":`http://localhost:${Je}`,"Payments:ShKeeper:ApiKey":F,"Payments:ShKeeper:CustomCallbackBaseUrl":f},"etherna-gateway":{..._,ASPNETCORE_URLS:p,"ForwardedHeaders:KnownNetworks:0":`0.0.0.0/0`,"SsoServer:BaseUrl":u,"SsoServer:Clients:Credit:BaseUrl":f,"SsoServer:Clients:Credit:Secret":`ethernaGatewayCreditClientSecret`,"SsoServer:Clients:Webapp:Secret":`ethernaGatewayWebappClientSecret`,"SsoServer:AllowUnsafeConnection":`true`,"Bee:CachedUrl":m,"Bee:DirectUrl":m,"Features:GarbageCollectPins":`false`,ForwardedAllowedHosts:`*`,"ConnectionStrings:DataProtectionDb":`${l}/ethernaSharedDataProtectionDev`,"ConnectionStrings:HangfireDb":`${l}/ethernaGatewayHangfireDev`,"ConnectionStrings:GatewayDb":`${l}/ethernaGatewayDev`,"ConnectionStrings:ServiceSharedDb":`${l}/ethernaServiceSharedDev`},"etherna-beehive":{..._,ASPNETCORE_URLS:m,"SeedDb:BeeNodes:0:Hostname":`localhost`,"ConnectionStrings:DataProtectionDb":`${l}/beehiveDataProtectionDev`,"ConnectionStrings:HangfireDb":`${l}/beehiveHangfireDev`,"ConnectionStrings:BeehiveDb":`${l}/beehiveDev`,"SeedDb:BeeNodes:0:ConnectionString":h,"SeedDb:BeeNodes:0:EnableBatchCreation":`true`},"etherna-blockchain":{BLOCKCHAIN_PORT:P,NETWORK_ID:Ge},"etherna-bee":{POSTAGE_PRICE:`24000`,BEE_WARMUP_TIME:`10s`,BEE_DEBUG_API_ENABLE:`true`,BEE_VERBOSITY:`4`,BEE_SWAP_ENABLE:`true`,BEE_MAINNET:`false`,BEE_SWAP_ENDPOINT:`http://etherna-blockchain:${P}`,BEE_BLOCKCHAIN_RPC_ENDPOINT:`http://etherna-blockchain:${P}`,BEE_PASSWORD:`password`,BEE_SWAP_FACTORY_ADDRESS:`0xCfEB869F69431e42cdB54A4F4f105C19C080A601`,BEE_POSTAGE_STAMP_ADDRESS:`0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B`,BEE_PRICE_ORACLE_ADDRESS:`0x5b1869D9A4C187F2EAa108f3062412ecf0526b24`,BEE_REDISTRIBUTION_ADDRESS:`0x9561C133DD8580860B6b7E504bC5Aa500f0f06a7`,BEE_STAKING_ADDRESS:`0xD833215cBcc3f914bD1C9ece3EE7BF8B14f841bb`,BEE_POSTAGE_STAMP_START_BLOCK:`1`,BEE_NETWORK_ID:Ge,BEE_FULL_NODE:`true`,BEE_PORT:Ue,BEE_P2P_PORT:We,BEE_API_ADDR:`0.0.0.0:${Ue}`,BEE_P2P_ADDR:`0.0.0.0:${We}`,BEE_CORS_ALLOWED_ORIGINS:`*`,BEE_ALLOW_PRIVATE_CIDRS:`true`,BEE_BOOTNODE_MODE:``,BEE_BOOTNODE:``}}}function Xe(e){return{mode:e,portless:!1,appPort:e===`http`?5173:5371}}function I(e){let t=e.split(`;`)[0]?.trim()??``;try{let e=new URL(t);return e.port?e.port:e.protocol===`https:`?`443`:`80`}catch{return t.split(`:`)[2]??`80`}}function L(e,t){return`${e}://localhost:${t}`}function Ze(e,t,n,r){return n?M(r):L(e,t)}const R=(e,t)=>Ye(t)[e]??null;function Qe(e){let t=new Set(qe);return Object.fromEntries(Object.entries(e).filter(([e])=>!t.has(e)))}function $e(e){if(typeof e.detached==`boolean`)return e.detached;let t=process.env.ETHERNA_DETACHED?.trim().toLowerCase();return t===`1`||t===`true`||t===`yes`}const et=[`elastic`,`mongo`,`bee`,`sso`,`index`,`gateway`,`credit`,`beehive`,`shkeeper`];function tt(e){return typeof e==`object`&&e?e.enabled!==!1:e!==!1}function nt(e){return e===!0?!0:typeof e==`object`&&e?e.enabled!==!1:!1}function rt(e){let t={};for(let n of et)t[n]=n===`shkeeper`?nt(e[n]):tt(e[n]);t.blockchain=t.bee;let n={enabled:t,detached:$e(e),portless:e.portless??!1,mode:e.mode??`http`,installSignalHandlers:e.installSignalHandlers??!0};return e.appPort!==void 0&&(n.appPort=e.appPort),n}function it(e){return new Promise(t=>setTimeout(t,e))}async function at(e){let t=e?.containerName??`shkeeper`,n=e?.sqlitePath??`/shkeeper.io/instance/shkeeper.sqlite`,r=e?.maxAttempts??120,i=e?.intervalMs??1e3;for(let e=0;e<r;e++){let a=await ot(t,n,`SELECT apikey FROM wallet WHERE apikey IS NOT NULL AND TRIM(COALESCE(apikey, '')) != '' LIMIT 1`);if(a)return a;e<r-1&&await it(i)}return null}function ot(e,t,n){return new Promise(r=>{let i=(0,d.spawn)(`docker`,[`exec`,e,`sqlite3`,t,n]),a=``;i.stdout?.on(`data`,e=>{a+=typeof e==`string`?e:e.toString(`utf8`)}),i.on(`error`,()=>{r(null)}),i.on(`close`,e=>{if(e!==0){r(null);return}let t=a.trim();r(t.length>0?t:null)})})}function st(e){let t=typeof process<`u`?process.env?.[e]:void 0;if(t!==void 0)return t;try{let t={}.env?.[e];return typeof t==`string`?t:void 0}catch{return}}function z(...e){return p.default.resolve(`node_modules/.vite`,...e)}function ct(...e){let t=z(...e);return process.platform===`win32`?t.replace(/\\/g,`/`):t}function B(e,t,n,r){if(r?.portlessUrl){let i=`${r.portlessUrl.replace(/\/$/,``)}/`,a=`${t}://localhost:${n}/`;console.log(` ${k.green(`➜`)} ${k.bold(e)}: ${k.cyan(i)} ${k.gray(`(${a})`)}`);return}let i=`${t}://localhost:${k.bold.cyanBright(n)}/`;console.log(` ${k.green(`➜`)} ${k.bold(e)}: ${k.cyan(i)}`)}function lt(e){console.log(` ${k.gray(`➜`)} ${k.bold(e)}: ${k.yellow(`Downloading image...`)}`)}function V(e,t){console.log(` ${k.red(`x`)} ${k.bold(e)}: ${k.red(t)}`)}async function ut(e,t,n){let r=(0,d.spawn)(e,t,n);return new Promise((e,t)=>{r.on(`error`,e=>{t(e)}),r.on(`exit`,()=>{e()})})}async function dt(e){let t=await fetch(`${e}/addresses`);if(!t.ok)throw Error(`Failed to fetch addresses from ${e}: ${t.statusText}`);let n=await t.json(),r=Array.isArray(n.underlay)?n.underlay:[];if(r.length===0)return await new Promise(e=>setTimeout(e,500)),dt(e);let i=r.find(e=>!e.includes(`127.0.0.1`));if(!i)throw Error(`No valid underlay address found in response from ${e}`);return i}const ft=`etherna-`;function H(e){return e.startsWith(ft)?e:`${ft}${e}`}const pt=`https://docs.docker.com/get-docker/`,mt=3e4;function U(e,t){(0,d.spawn)(e,t,{detached:!0,stdio:`ignore`}).unref()}function ht(){return new Promise(e=>{let t=(0,d.spawn)(`docker`,[`info`],{stdio:`ignore`});t.on(`error`,()=>e(!1)),t.on(`exit`,t=>e(t===0))})}function gt(){return new Promise(e=>{let t=(0,d.spawn)(`docker`,[`--version`],{stdio:`ignore`});t.on(`error`,()=>e(!1)),t.on(`exit`,t=>e(t===0))})}function _t(){let{platform:e}=process;if(e===`darwin`){U(`open`,[`-a`,`Docker`]);return}if(e===`win32`){let e=`C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe`;if(f.default.existsSync(e)){U(e,[]);return}U(`cmd`,[`/c`,`start`,``,`Docker Desktop`]);return}e===`linux`&&U(`systemctl`,[`--user`,`start`,`docker-desktop`])}function vt(e){return new Promise(t=>setTimeout(t,e))}async function yt(){if(await gt()||(console.error(` ${k.red(`x`)} ${k.bold(`docker`)}: ${k.red(`Docker is not installed or not on your PATH.`)}`),console.error(` Install Docker and try again: ${k.cyan.underline(pt)}`),process.exit(1)),await ht())return;console.log(` ${k.yellow(`➜`)} ${k.bold(`docker`)}: ${k.yellow(`Docker daemon is not running. Starting it…`)}`),_t();let e=Date.now()+mt;for(;Date.now()<e;)if(await vt(2e3),await ht()){console.log(` ${k.green(`➜`)} ${k.bold(`docker`)}: ${k.green(`Docker is ready.`)}`);return}console.error(` ${k.red(`x`)} ${k.bold(`docker`)}: ${k.red(`Docker did not become ready within ${mt/1e3}s. Start Docker manually and run the dev server again.`)}`),console.error(` Install or troubleshoot: ${k.cyan.underline(pt)}`),process.exit(1)}async function W({containerName:e,imageName:t,args:n=[],cmd:r=[],detached:i=!1}){let a=H(e);if(!i)await bt(a)&&await xt(a);else{if(await St(a))return null;await bt(a)&&await Ct(a)}let o=[`run`,`--rm`,`--name`,a,...n,t,...r],s=i?(0,d.spawn)(`docker`,[...o],{detached:!0,stdio:[`ignore`,`pipe`,`pipe`]}):(0,d.spawn)(`docker`,[...o]);return s.stdout?.on(`data`,e=>{let t=String(e);/Pulling from/gm.test(t)&&lt(a),/Error response from daemon/gm.test(t)&&V(a,t)}),i&&s.unref(),s}async function bt(e){let t=(0,d.spawn)(`docker`,[`ps`,`-a`,`--filter`,`name=${H(e)}`]);return(await new Promise(e=>{let n=``;t.stdout?.on(`data`,e=>{n+=String(e)}),t.on(`close`,()=>{e(n)})})).split(`
7
+ `).length>1}async function xt(e){let t=(0,d.spawn)(`docker`,[`stop`,H(e)]);await new Promise(e=>{t.on(`close`,()=>{e()})})}async function St(e){return new Promise(t=>{let n=(0,d.spawn)(`docker`,[`inspect`,`-f`,`{{.State.Running}}`,H(e)],{stdio:[`ignore`,`pipe`,`ignore`]}),r=``;n.stdout?.on(`data`,e=>{r+=String(e)}),n.on(`error`,()=>t(!1)),n.on(`close`,e=>{if(e!==0){t(!1);return}t(r.trim().toLowerCase()===`true`)})})}async function Ct(e){await new Promise(t=>{let n=(0,d.spawn)(`docker`,[`rm`,`-f`,H(e)],{stdio:`ignore`});n.on(`error`,()=>t()),n.on(`close`,()=>t())})}async function G(e){let t=(0,d.spawn)(`docker`,[`volume`,`create`,e]);await new Promise(e=>{t.on(`close`,()=>{e()})})}async function wt(e){let t=(0,d.spawn)(`docker`,[`network`,`create`,e]);await new Promise(e=>{t.on(`close`,()=>{e()})})}const Tt={blockchain:[`etherna-blockchain`],bee:[`etherna-blockchain`,`etherna-bee`,`etherna-bee_worker_1`],beehive:[`etherna-beehive`],credit:[`etherna-credit`],elastic:[`etherna-elastic`],gateway:[`etherna-gateway`],index:[`etherna-index`],mongo:[`etherna-mongodb`],shkeeper:[`ethereum-shkeeper-mariadb`,`ethereum-shkeeper-redis`,`ethereum-shkeeper`,`ethereum-tasks`,`shkeeper`],sso:[`etherna-sso`]};function Et(e){return Tt[e]}async function Dt(e){let t=[...new Set(e.flatMap(Et))];await Promise.all(t.map(e=>xt(e)))}async function Ot(e){await Dt(Object.keys(e).filter(t=>e[t]))}async function kt(e){await ut(`docker`,[`exec`,e,`update-ca-certificates`]).catch(t=>{console.error(k.red(`‼️ Error trusting certificate in container '${e}': ${t.message}`))})}async function K(e,t,n,r){let i,a=new Promise(e=>{i=e}),o,{mode:s}=e.serviceCtx,c={...R(t,e.serviceCtx)??{},...r},l=c.ASPNETCORE_URLS.split(`;`)[0]?.split(`:`)[2]??`80`,u=je[t],d=e.serviceCtx.portless&&u?M(u):void 0,f=await W({containerName:t,imageName:n,args:[...Object.entries(c).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),...s===`https`?[`--mount`,`type=bind,source=${ct(`.ssl`)},target=${Ae}/`]:[],`--network`,`host`],detached:e.detached});if(!f)return B(t,s,l,{portlessUrl:d}),null;e.pushSpawn(f);let p=async e=>{o=void 0;let n=String(e);/Now listening on: https?:\/\/(localhost|\[::\]):\d+/gm.test(n)&&(s===`https`&&await kt(t),B(t,s,l,{portlessUrl:d}),i?.());let r=[/Current db does not support change stream/gm,/is only supported on replica sets./gm,/Failed to process the job/gm],a=[/\[(ERR|FTL)\]/gm,/"LogLevel"\s*:\s*"(Error|Critical)"/gm,/\b(fail|crit):/gm,/<(2|3)>/gm].some(e=>e.test(n)),c=/\[(INF|WRN|DBG|VRB)\]/gm.test(n);a&&!c&&/Exception:.+/gm.test(n)&&!r.some(e=>e.test(n))?(V(t,n),i?.()):o=n};return f.stdout?.on(`data`,p),f.stdout?.on(`error`,e=>{V(t,`FATAL: `+e.message),i?.()}),f.stderr?.on(`data`,p),f.on(`close`,e=>{V(t,o||`Container closed with code ${e}`),i?.(),f.kill()}),await a,f}function At(e){return new Promise(t=>setTimeout(t,e))}async function q(e,t,n){let r=await fetch(e,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({jsonrpc:`2.0`,id:1,method:t,params:n})});if(!r.ok)throw Error(`RPC ${t} failed: ${r.status} ${r.statusText}`);let i=await r.json();if(i.error?.message)throw Error(`RPC ${t} error: ${i.error.message}`);return i.result}async function J(e,t){return(await q(e,`web3_sha3`,[`0x`+Buffer.from(t,`utf-8`).toString(`hex`)])).slice(0,10)}function jt(e){if(e<0n)throw Error(`Cannot encode negative uint param: ${e}`);return e.toString(16).padStart(64,`0`)}function Mt(e){let t=e.toLowerCase().startsWith(`0x`)?e.slice(2):e;if(t.length!==40)throw Error(`Invalid address (expected 20 bytes / 40 hex chars): ${e}`);return t.toLowerCase().padStart(64,`0`)}function Nt(e){let t=e.startsWith(`0x`)?e.slice(2):e;if(t.length!==64)throw Error(`Invalid bytes32 (expected 32 bytes / 64 hex chars): ${e}`);return t.toLowerCase()}function Y(e){let t=e.startsWith(`0x`)?e.slice(2):e;return t.length===0?0n:BigInt(`0x`+t)}async function Pt(e,t,n,r=500){let i=Date.now()+n;for(;Date.now()<i;){let n=await q(e,`eth_getTransactionReceipt`,[t]);if(n?.status)return{status:n.status,blockNumber:n.blockNumber};await At(r)}throw Error(`Transaction ${t} was not mined within ${n}ms`)}async function Ft(e,t){return await q(e,`eth_getCode`,[t,`latest`]).then(e=>e??`0x`)}async function It(e){let t=await q(e,`eth_blockNumber`,[]);return Number.parseInt(t??`0x0`,16)}function Lt(e){return e!==`0x`&&e.length>2}async function Rt(e,t,n=`pending`){return Y(await q(e,`eth_getTransactionCount`,[t,n]))}async function zt(e){return Y(await q(e,`eth_gasPrice`,[]))}function X(e){let t=e.startsWith(`0x`)?e.slice(2):e,n=t.length%2==0?t:`0`+t;return Uint8Array.from(Buffer.from(n,`hex`))}function Z(e){return Buffer.from(e).toString(`hex`)}function Q(e){if(e<0n)throw Error(`Cannot encode negative bigint: ${e}`);if(e===0n)return new Uint8Array;let t=e.toString(16);return t.length%2!=0&&(t=`0`+t),X(t)}function Bt(...e){let t=e.reduce((e,t)=>e+t.length,0),n=new Uint8Array(t),r=0;for(let t of e)n.set(t,r),r+=t.length;return n}function Vt(e,t){if(e<56)return Uint8Array.of(t+e);let n=Q(BigInt(e));return Bt(Uint8Array.of(t+55+n.length),n)}function Ht(e){if(e instanceof Uint8Array)return e.length===1&&e[0]<128?e:Bt(Vt(e.length,128),e);let t=Bt(...e.map(Ht));return Bt(Vt(t.length,192),t)}function Ut(e){let t=X(e);if(t.length!==32)throw Error(`Invalid private key length: expected 32 bytes, got ${t.length}`);return`0x`+Z((0,h.keccak_256)(m.secp256k1.getPublicKey(t,!1).slice(1)).slice(-20))}function Wt(e,t){if(!e.to.startsWith(`0x`)||e.to.length!==42)throw Error(`Invalid 'to' address: ${e.to}`);let n=[Q(e.nonce),Q(e.gasPrice),Q(e.gasLimit),X(e.to),Q(e.value),X(e.data)],r=(0,h.keccak_256)(Ht([...n,Q(e.chainId),new Uint8Array,new Uint8Array])),i=X(t),a=m.secp256k1.sign(r,i,{format:`recovered`,lowS:!0,prehash:!1}),o=a[0],s=Y(Z(a.subarray(1,33))),c=Y(Z(a.subarray(33,65))),l=BigInt(o)+35n+e.chainId*2n,u=Ht([...n,Q(l),Q(s),Q(c)]);return{rawTx:`0x`+Z(u),hash:`0x`+Z((0,h.keccak_256)(u))}}async function Gt(e,t,n,r){let i=Ut(t),[a,o,s]=await Promise.all([q(e,`eth_chainId`,[]),Rt(e,i,`pending`),zt(e)]),{rawTx:c,hash:l}=Wt({chainId:Y(a),nonce:o,gasPrice:s===0n?1n:s,gasLimit:n.gasLimit,to:n.to,value:n.value??0n,data:n.data},t);await q(e,`eth_sendRawTransaction`,[c]);let u=await Pt(e,l,r.timeoutMs,r.pollMs);if(u.status!==`0x1`)throw Error(r.onRevert?.(l)??`Transaction ${l} reverted (status ${u.status}).`);return l}const Kt=`etherna_bee_network`,qt=[`BEE_SWAP_FACTORY_ADDRESS`,`BEE_POSTAGE_STAMP_ADDRESS`,`BEE_PRICE_ORACLE_ADDRESS`,`BEE_REDISTRIBUTION_ADDRESS`,`BEE_STAKING_ADDRESS`],Jt=3e4,Yt=2e5;let Xt=!1,Zt,Qt=Promise.resolve();function $t(){Xt=!0,Qt=new Promise(e=>{Zt=e})}function $(){Xt&&(Xt=!1,Zt?.(),Zt=void 0)}function en(){return Xt}function tn(){return Qt}function nn(e){return new Promise(t=>setTimeout(t,e))}async function rn({rpcUrl:e,postageStampAddress:t,ownerPrivateKey:n,desiredPrice:r}){let i=`etherna-bee`,a=(1n<<64n)-1n;if(r<0n||r>a)throw Error(`POSTAGE_PRICE ${r} is out of range for uint64 (0..${a}).`);let[o,s,c,l,u]=await Promise.all([J(e,`lastPrice()`),J(e,`setPrice(uint256)`),J(e,`hasRole(bytes32,address)`),J(e,`grantRole(bytes32,address)`),J(e,`PRICE_ORACLE_ROLE()`)]),d=async()=>Y(await q(e,`eth_call`,[{to:t,data:o},`latest`])),f=await d();if(f===r)return;let p=Ut(n),m=await q(e,`eth_call`,[{to:t,data:u},`latest`]);if(!m||m===`0x`)throw Error(`PostageStamp.PRICE_ORACLE_ROLE() returned no data; ${t} may not be a PostageStamp contract.`);let h=Nt(m),g=Mt(p);if(Y(await q(e,`eth_call`,[{to:t,data:c+h+g},`latest`]))===0n){console.log(` ${k.yellow(`➜`)} ${k.bold(i)}: granting PRICE_ORACLE_ROLE on PostageStamp to ${k.gray(p)}`);let r=await Gt(e,n,{to:t,data:l+h+g,gasLimit:BigInt(Yt)},{timeoutMs:Jt,pollMs:500,onRevert:e=>`PostageStamp.grantRole(PRICE_ORACLE_ROLE, ${p}) reverted (tx ${e}). The owner likely lacks DEFAULT_ADMIN_ROLE on PostageStamp ${t}.`});console.log(` ${k.gray(` granted (tx ${r})`)}`)}console.log(` ${k.yellow(`➜`)} ${k.bold(i)}: updating postage price ${k.gray(String(f))} → ${k.cyan(String(r))} PLUR`);let _=await Gt(e,n,{to:t,data:s+jt(r),gasLimit:BigInt(Yt)},{timeoutMs:Jt,pollMs:500,onRevert:e=>`PostageStamp.setPrice(${r}) reverted (tx ${e}). The owner ${p} may lack PRICE_ORACLE_ROLE on PostageStamp ${t}.`}),v=await d();if(v!==r)throw Error(`PostageStamp.setPrice(${r}) succeeded (tx ${_}) but PostageStamp.lastPrice is ${v}.`);console.log(` ${k.green(`➜`)} ${k.bold(i)}: postage price set to ${k.cyan(String(r))} PLUR ${k.gray(`(tx ${_})`)}`)}function an(e){return Error([`Detected a stale or corrupted local blockchain state: Bee contracts are still missing even though the chain has already advanced.`,`Fix it by stopping the dev server, removing the persisted blockchain volume, and starting again:`,`1. Stop the dev server`,`2. Run: docker volume rm ${e}`,`3. Run: pnpm dev`].join(`
8
+ `))}async function on(e,t,n){let r=Date.now()+3e4,i=null;for(;Date.now()<r;){let[r,a]=await Promise.all([It(e).catch(()=>null),Promise.all(t.map(t=>Ft(e,t).catch(()=>null)))]);if(r!=null&&a.every(e=>e!=null)){if(i===null&&(i=r),a.every(e=>Lt(e)))return;if(r>=10||r-i>=2)throw an(n)}await nn(1e3)}throw Error(`Bee contracts were not deployed before the startup timeout elapsed. If this keeps happening, stop the dev server, run \`docker volume rm ${n}\`, and start again.`)}async function sn(e){let t=e.serviceCtx,n=e.getServiceEnv(`bee`),r=`etherna-blockchain`,i=`etherna_blockchain-volume`,a=e.detached,o=Qe({...R(r,t)??{},...n}),s=Number(o.BLOCKCHAIN_PORT);if(a&&await St(r))return B(r,`http`,String(s)),null;$t(),await wt(Kt),await G(i);let c,l,u,d=new Promise((e,t)=>{l=e,u=t}),p=!1,m=!1;f.default.existsSync(z(`.ethereum`))||f.default.mkdirSync(z(`.ethereum`),{recursive:!0,mode:511}),f.default.existsSync(z(`.ethereum`,`password`))||f.default.writeFileSync(z(`.ethereum`,`password`),`toTheSun`,{encoding:`utf-8`,mode:420});let h=Qe({...R(r,t)??{},...n}),g={...R(`etherna-bee`,t)??{},...n},_=Number(h.BLOCKCHAIN_PORT),v=qt.map(e=>String(g[e])),y=await W({containerName:r,imageName:`fairdatasociety/fdp-play-blockchain:latest`,args:[...Object.entries(h).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--network`,Kt,`-p`,`${_}:${_}`,`-p`,`${_+1}:${_+1}`,`--mount`,`type=volume,source=${i},target=/root/.ethereum`,`--mount`,`type=bind,source=${ct(`.ethereum`)},target=/root/extra`],detached:a,cmd:[`--allow-insecure-unlock`,`--unlock=${Ke}`,`--password=/root/extra/password`,`--mine`,`--miner.etherbase=${Ke}`,`--http`,`--http.api="debug,web3,eth,txpool,net,personal"`,`--http.corsdomain=*`,`--http.port=${_}`,`--http.addr=0.0.0.0`,`--http.vhosts=*`,`--ws`,`--ws.api="debug,web3,eth,txpool,net,personal"`,`--ws.port=${_+1}`,`--ws.origins=*`,`--maxpeers=0`,`--networkid=${h.NETWORK_ID}`,`--authrpc.vhosts=*`,`--authrpc.addr=0.0.0.0`]});if(!y)return $(),B(r,`http`,String(_)),null;e.pushSpawn(y);let b=e=>{c=void 0;let t=String(e);!p&&/HTTP server started/gm.test(t)&&(p=!0,on(`http://127.0.0.1:${_}`,v,i).then(()=>{m=!0,$(),l?.()}).catch(e=>{m=!0,$();let t=e instanceof Error?e.message:String(e);V(r,t),xt(r).finally(()=>{u?.(e)})})),/Error:.+/gm.test(t)?(V(r,t),l?.()):c=t};return y.stdout?.on(`data`,b),y.stdout?.on(`error`,e=>{$(),V(r,`FATAL: `+e.message),l?.()}),y.stderr?.on(`data`,b),y.on(`close`,e=>{$(),m||(V(r,c||`Container closed with code ${e}`),l?.()),y.kill()}),await d,y}async function cn(e){let t=e.serviceCtx,n=e.getServiceEnv(`bee`),r=`etherna-bee`,i=await ln(e,r),a=await dt(`http://localhost:${R(`etherna-bee`,t)?.BEE_PORT??`1633`}`),[o]=await Promise.all([ln(e,r,1,a)]);try{let e={...R(`etherna-bee`,t)??{},...n};await rn({rpcUrl:`http://127.0.0.1:${{...R(`etherna-blockchain`,t)??{},...n}.BLOCKCHAIN_PORT}`,postageStampAddress:String(e.BEE_POSTAGE_STAMP_ADDRESS),ownerPrivateKey:`0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d`,desiredPrice:BigInt(String(e.POSTAGE_PRICE??`24000`))})}catch(e){V(r,`Failed to sync postage price: ${e instanceof Error?e.message:String(e)}`)}return[i,o]}async function ln(e,t,n,r){let i=e.serviceCtx,a=e.getServiceEnv(`bee`),o=n?`etherna_bee_worker_${n}-volume`:`etherna_bee-volume`;await G(o);let s,c,l=new Promise(e=>{c=e}),{mode:u}=i,d=Qe({...R(t,i)??{},...a});n?(delete d.BEE_BOOTNODE_MODE,d.BEE_BOOTNODE=r):(delete d.BEE_BOOTNODE,d.BEE_BOOTNODE_MODE=`false`),n&&(t=`${t}_worker_${n}`);let f=await W({containerName:t,imageName:n?`fairdatasociety/fdp-play-worker-${n}`:`fairdatasociety/fdp-play-queen:latest`,args:[...Object.entries(d).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--mount`,`type=volume,source=${o},target=/home/bee/.bee`,`--network`,Kt,`-p`,`${n?parseInt(d.BEE_PORT??`1633`)+n*1e4:d.BEE_PORT}:${d.BEE_PORT}`,`-p`,`${n?parseInt(d.BEE_P2P_PORT??`1634`)+n*1e4:d.BEE_P2P_PORT}:${d.BEE_P2P_PORT}`],cmd:[`start`],detached:e.detached});if(!f){if(!n){let e=i.portless?M(`bee`):void 0;B(t,u,String(d.BEE_PORT??`1633`),{portlessUrl:e})}return null}e.pushSpawn(f);let p=e=>{s=void 0;let r=String(e);if(/"address"="\[::\]:\d+"/gm.test(r)){if(!n){let e=i.portless?M(`bee`):void 0;B(t,u,String(d.BEE_PORT??`1633`),{portlessUrl:e})}c?.()}let a=[/"logger"="node\/storageincentives"/gm],o=r.split(`
9
+ `).filter(e=>/"level"="(error|critical)"/.test(e)).join(`
10
+ `);o&&!a.some(e=>e.test(r))&&(V(t,o),c?.(),s=o)};return f.stdout?.on(`data`,p),f.stdout?.on(`error`,e=>{V(t,`FATAL: `+e.message),c?.()}),f.stderr?.on(`data`,p),f.on(`close`,e=>{V(t,s||`Container closed with code ${e}`),c?.(),f.kill()}),await l,f}function un(e){return{detached:e.detached??!1,serviceCtx:e.serviceCtx,getServiceEnv:e.getServiceEnv??(e=>({})),pushSpawn:e.pushSpawn??(()=>{}),isShutdownRequested:e.isShutdownRequested??(()=>!1),getShkeeperConfig:e.getShkeeperConfig??(()=>({})),getShkeeperBuild:e.getShkeeperBuild??(()=>({}))}}async function dn(e){let t=`elastic`,n=`etherna_${t}-data-volume`;await G(n);let r,i=new Promise(e=>{r=e}),a={...R(t,e.serviceCtx)??{},...e.getServiceEnv(`elastic`)},o=await W({containerName:t,imageName:`elasticsearch:7.17.24`,args:[...Object.entries(a).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--mount`,`type=volume,source=${n},target=/usr/share/elasticsearch/data`,`--network`,`host`,`--memory=512m`],cmd:[],detached:e.detached});if(!o)return B(t,`http`,`9200`),null;e.pushSpawn(o);let s=e=>{let n=String(e);/"message": "started"/gm.test(n)&&(B(t,`http`,`9200`),r?.())};return o.stdout?.on(`data`,s),o.stdout?.on(`error`,e=>{V(t,`FATAL: `+e.message),r?.()}),o.stderr?.on(`data`,s),o.on(`close`,e=>{V(t,`Container closed with code ${e}`),r?.(),o.kill()}),await i,o}async function fn(e){let t=`etherna-mongodb`,n=`etherna_${t}-db-volume`,r=`etherna_${t}-configdb-volume`;await Promise.all([G(n),G(r)]);let i,a=new Promise(e=>{i=e}),o={...R(t,e.serviceCtx)??{},...e.getServiceEnv(`mongo`)},s=await W({containerName:t,imageName:`mongo:latest`,args:[...Object.entries(o).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--mount`,`type=volume,source=${n},target=/data/db`,`--mount`,`type=volume,source=${r},target=/data/configdb`,`--network`,`host`],cmd:[],detached:e.detached});if(!s)return B(t,`mongodb`,`27017`),null;e.pushSpawn(s);let c=e=>{let n=String(e);/mongod startup complete/gm.test(n)&&(B(t,`mongodb`,`27017`),i?.())};return s.stdout?.on(`data`,c),s.stdout?.on(`error`,e=>{V(t,`FATAL: `+e.message),i?.()}),s.stderr?.on(`data`,c),s.on(`close`,e=>{V(t,`Container closed with code ${e}`),i?.(),s.kill()}),await a,s}const pn=`vsyshost/shkeeper:2.5.12`,mn=`vsyshost/ethereum-shkeeper:1.2.3`,hn=`etherna`;function gn(e){let t=e.lastIndexOf(`:`);return t===-1||e.slice(t+1).includes(`/`)?{repository:e,tag:`latest`}:{repository:e.slice(0,t),tag:e.slice(t+1)}}function _n(e){let{tag:t}=gn(pn);return e?`${hn}/shkeeper:${t}`:pn}function vn(e){let{tag:t}=gn(mn);return e?`${hn}/ethereum-shkeeper:${t}`:mn}async function yn(e){let t=(0,d.spawn)(`docker`,[`image`,`inspect`,e]);return await new Promise(e=>{t.on(`close`,t=>{e(t===0)}),t.on(`error`,()=>{e(!1)})})}async function bn(e,t){let n=(0,d.spawn)(e,t);await new Promise((r,i)=>{n.on(`close`,n=>{if(n===0){r();return}i(Error(`Command failed: ${e} ${t.join(` `)}`))}),n.on(`error`,i)})}function xn(e,t){return z(e,`${t.replace(/[^a-z0-9._-]+/gi,`-`)}-${Date.now()}`)}async function Sn(e,t,n){let r=xn(t,n);f.default.mkdirSync(r,{recursive:!0});let i=p.default.join(r,`clone`);return await bn(`git`,[`clone`,`--depth`,`1`,`--branch`,n,`https://github.com/${e}.git`,i]),{cleanupPath:r,contextPath:i,dockerfilePath:p.default.join(i,`Dockerfile`)}}async function Cn(e){let{logLabel:t,imageName:n,sourceRepo:r,workspacePrefix:i,gitRef:a}=e;if(await yn(n))return;console.log(` ${k.yellow(`➜`)} ${k.bold(t)}: ${k.yellow(`Building Docker image from GitHub (${r}@${a}) (first run may take a while)…`)}`);let o=await Sn(r,i,a),s=(0,d.spawn)(`docker`,[`build`,`-t`,n,`-f`,o.dockerfilePath,o.contextPath]);try{await new Promise((e,t)=>{s.on(`close`,r=>{if(r===0){e();return}t(Error(`Failed to build local Docker image ${n}`))}),s.on(`error`,t)})}catch(e){throw V(t,`Failed to build Docker image (${n}).`),o.cleanupPath?Error(`Failed to build local Docker image ${n}. Inspect cloned source at ${o.contextPath}`,{cause:e}):e}console.log(` ${k.yellow(`➜`)} ${k.bold(t)}: ${k.yellow(`Finished building Docker image.`)}`),o.cleanupPath&&f.default.rmSync(o.cleanupPath,{force:!0,recursive:!0})}function wn(e){let t=e?.trim();return t&&t.length>0?t:`main`}async function Tn(e,t){await Cn({logLabel:`shkeeper`,imageName:_n(e),sourceRepo:e??`vsys-host/shkeeper.io`,workspacePrefix:`.shkeeper-build`,gitRef:e?wn(t):gn(pn).tag})}async function En(e,t){e&&await Cn({logLabel:`ethereum-shkeeper`,imageName:vn(e),sourceRepo:e,workspacePrefix:`.ethereum-shkeeper-build`,gitRef:wn(t)})}const Dn=`etherna_shkeeper_network`;async function On({context:e,envs:t,build:n,networkName:r,detached:i=!1}){let a=`shkeeper`,o=`etherna_shkeeper-instance-volume`;await G(o);let s,c,l=new Promise((e,t)=>{s=e,c=t}),u,d=!1,f={...R(`shkeeper-core`,e)??{},...t},p=String(R(`shkeeper`,e)?.port??`32650`),m=r===`host`,h=m?p:`5000`,g=await W({containerName:a,imageName:n.imageName,args:[...Object.entries(f).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--mount`,`type=volume,source=${o},target=/shkeeper.io/instance`,`--network`,r,...m?[]:[`-p`,`${p}:5000`]],...m?{cmd:[`bash`,`-c`,`gunicorn --access-logfile=- --workers=1 --threads=16 --timeout=600 --bind=0.0.0.0:${p} 'shkeeper:create_app()'`]}:{},detached:i});if(!g)return B(a,`http`,p),s?.(),null;let _=e=>{u=void 0;let t=String(e);RegExp(`Listening at: http://.+:${h}`,`gm`).test(t)?(d=!0,B(a,`http`,p),s?.()):u=t};return g.stdout?.on(`data`,_),g.stdout?.on(`error`,e=>{V(a,`FATAL: `+e.message),d||c?.(e)}),g.stderr?.on(`data`,_),g.on(`close`,e=>{V(a,u||`Container closed with code ${e}`),d||c?.(Error(`Container closed with code ${e}`)),g.kill()}),await l,g}async function kn({context:e,envs:t,networkName:n,imageName:r,detached:i=!1}){let a=`ethereum-shkeeper`,o,s,c=new Promise((e,t)=>{o=e,s=t}),l,u=!1,d={...R(`ethereum-shkeeper`,e)??{},...t},f=await W({containerName:a,imageName:r,args:[...Object.entries(d).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--network`,n],cmd:[`bash`,`-c`,`sleep 30 && gunicorn --access-logfile=- --workers=1 --threads=16 --timeout=600 --bind=0.0.0.0:6000 run:server`],detached:i});if(!f)return o?.(),null;let p=e=>{l=void 0;let t=String(e);/Listening at: http:\/\/.+:6000/gm.test(t)?(u=!0,o?.()):l=t};return f.stdout?.on(`data`,p),f.stdout?.on(`error`,e=>{V(a,`FATAL: `+e.message),u||s?.(e)}),f.stderr?.on(`data`,p),f.on(`close`,e=>{V(a,l||`Container closed with code ${e}`),u||s?.(Error(`Container closed with code ${e}`)),f.kill()}),await c,f}async function An(e=Dn,t){let n=`ethereum-shkeeper-mariadb`,r=`etherna_shkeeper-mariadb-volume`;await G(r);let i,a,o=new Promise((e,t)=>{i=e,a=t}),s,c=!1,l=await W({containerName:n,imageName:`mariadb:10.9.3`,args:[`-e`,`MARIADB_ROOT_PASSWORD=shkeeper`,`-e`,`MARIADB_DATABASE=ethereum-shkeeper`,`--mount`,`type=volume,source=${r},target=/var/lib/mysql`,`--network`,e],detached:!!t?.detached});if(!l)return i?.(),null;let u=e=>{s=void 0;let t=String(e);/ready for connections/gim.test(t)?(c=!0,i?.()):s=t};return l.stdout?.on(`data`,u),l.stdout?.on(`error`,e=>{V(n,`FATAL: `+e.message),c||a?.(e)}),l.stderr?.on(`data`,u),l.on(`close`,e=>{V(n,s||`Container closed with code ${e}`),c||a?.(Error(`Container closed with code ${e}`)),l.kill()}),await o,l}async function jn(e=Dn,t){let n=`ethereum-shkeeper-redis`,r=`etherna_shkeeper-redis-volume`;await G(r);let i,a,o=new Promise((e,t)=>{i=e,a=t}),s,c=!1,l=await W({containerName:n,imageName:`redis:7`,args:[`--mount`,`type=volume,source=${r},target=/data`,`--network`,e],detached:!!t?.detached});if(!l)return i?.(),null;let u=e=>{s=void 0;let t=String(e);/Ready to accept connections/gm.test(t)?(c=!0,i?.()):s=t};return l.stdout?.on(`data`,u),l.stdout?.on(`error`,e=>{V(n,`FATAL: `+e.message),c||a?.(e)}),l.stderr?.on(`data`,u),l.on(`close`,e=>{V(n,s||`Container closed with code ${e}`),c||a?.(Error(`Container closed with code ${e}`)),l.kill()}),await o,l}async function Mn({context:e,envs:t,networkName:n,imageName:r,detached:i=!1}){let a=`ethereum-tasks`,o,s,c=new Promise((e,t)=>{o=e,s=t}),l,u=!1,d={...R(`ethereum-shkeeper`,e)??{},...t,C_FORCE_ROOT:`1`},f=await W({containerName:a,imageName:r,args:[...Object.entries(d).flatMap(([e,t])=>[`-e`,`${e}=${String(t)}`]),`--network`,n],cmd:[`bash`,`-c`,`sleep 30 && celery -A celery_worker.celery worker --loglevel=info -B`],detached:i});if(!f)return o?.(),null;let p=e=>{l=void 0;let t=String(e);/ready\./gim.test(t)?(u=!0,o?.()):l=t};return f.stdout?.on(`data`,p),f.stdout?.on(`error`,e=>{V(a,`FATAL: `+e.message),u||s?.(e)}),f.stderr?.on(`data`,p),f.on(`close`,e=>{V(a,l||`Container closed with code ${e}`),u||s?.(Error(`Container closed with code ${e}`)),f.kill()}),await c,f}async function Nn(e){let t=e.serviceCtx,n=e.detached,r=e.getShkeeperConfig(),i=e.getShkeeperBuild(),a={imageName:_n(i.githubRepo)},o=r.ethereum?.githubRepo?.trim()||void 0,s=r.ethereum?.githubBranch?.trim()||void 0,c=`host`,l=[];try{await Tn(i.githubRepo,i.githubBranch),await En(o,s);let u=vn(o),[d,f]=await Promise.all([An(c,{detached:n}),jn(c,{detached:n})]);l.push(d,f);let[p,m]=await Promise.all([kn({context:t,envs:r.ethereum?.env,networkName:c,imageName:u,detached:n}),Mn({context:t,envs:r.ethereum?.env,networkName:c,imageName:u,detached:n})]);l.push(p,m);let h=await On({context:t,envs:r.env,build:a,networkName:c,detached:n});return l.push(h),e.pushSpawn(...l),l}catch(e){for(let e of l)e?.kill();throw e}}function Pn(e){let t=e.detached,n=[],r=!1,i=[],a=!1,o=!1,s=e.isBlockchainBootstrapInProgress??(()=>!1),c=e.waitForBlockchainBootstrapToSettle??(()=>Promise.resolve()),l=e.onBlockchainShutdownWait??(()=>{}),u=e.addPortlessAlias??(async()=>{}),d=e.removePortlessAliases??(async()=>{}),f=e.stopPortlessProxy??(async()=>{}),p=e.exitProcess??(e=>process.exit(e)),m=()=>t,h=(...e)=>{n.push(...e)},g=()=>{for(let e of n)e.kill()},_=e=>{r=e},v=async(e,t)=>{await u(e,t),i.push(e)},y=async()=>{t||(i.length>0&&(await d([...i]),i.length=0),r&&await f(),r=!1)},b=async n=>{a=!0;let r=n?.force??!1;o&&!r||(o=!0,!r&&s()&&(l(),await c()),t||await e.stopContainersForEnabled(e.enabledServices),await y(),(n?.killTrackedSpawns??!t)&&g(),n?.exitProcess&&p(0))};return{isShutdownRequested:()=>a,pushSpawn:h,killSpawns:g,getDetached:m,setPortlessProxyStartedByUs:_,recordPortlessAlias:v,cleanupPortless:y,shutdown:b,installSignalHandlers:()=>{process.on(`SIGINT`,()=>{process.stdin.resume(),(async()=>{await b({exitProcess:!0,force:a})})()}),process.on(`SIGTERM`,()=>{(async()=>{await b({force:a})})()})}}}async function Fn(e){let t=Array.isArray(e)?e:[e];for(let e of t)if(!A.includes(e))throw TypeError(`Unknown Etherna service "${String(e)}". Valid services: ${A.join(`, `)}.`);await Dt(t)}function In(e){return typeof e==`object`&&e?e.env??{}:{}}function Ln(e){return e===!0?{}:typeof e==`object`&&e?e:{}}async function Rn(e={}){let t=rt(e);await yt();let n=st(`PORTLESS_URL`)?.trim(),r=t.appPort??Xe(t.mode).appPort,i={mode:t.mode,portless:t.portless,appPort:r,...t.portless&&n?{portlessAppPublicUrl:Me(n)}:{}},a=Pn({detached:t.detached,enabledServices:t.enabled,stopContainersForEnabled:Ot,addPortlessAlias:(e,t)=>Be(e,t),removePortlessAliases:e=>Ve(e),stopPortlessProxy:He,isBlockchainBootstrapInProgress:en,waitForBlockchainBootstrapToSettle:tn,onBlockchainShutdownWait:()=>{console.log(k.yellow(` ➜ ${k.bold(`etherna-blockchain`)}: Shutdown requested during blockchain initialization. Waiting for a safe shutdown point. Press Ctrl+C again to force exit.`))}});e.installSignalHandlers!==!1&&a.installSignalHandlers(),t.portless&&await zn(a,i,n);let o=t.portless?Ye(i):void 0,s=t=>In(e[t]),c=un({detached:t.detached,serviceCtx:i,getServiceEnv:s,pushSpawn:(...e)=>{a.pushSpawn(...e.filter(e=>e!=null))},isShutdownRequested:()=>a.isShutdownRequested(),getShkeeperConfig:()=>Ln(e.shkeeper),getShkeeperBuild:()=>{let t=Ln(e.shkeeper).build;return{githubRepo:t?.githubRepo?.trim()||void 0,githubBranch:t?.githubBranch?.trim()||void 0}}}),l=async e=>{try{return await e(),!a.isShutdownRequested()}catch(e){if(a.isShutdownRequested())return!1;throw e}},u=async()=>{let e=s(`credit`);if(t.enabled.shkeeper){let t=await at();t&&(e={...e,"Payments:ShKeeper:ApiKey":t})}await K(c,`etherna-credit`,`etherna/etherna-credit:latest`,e)},d={"bee-blockchain":()=>l(()=>sn(c)),"bee-nodes":()=>l(()=>cn(c)),shkeeper:()=>l(()=>Nn(c)),mongo:()=>l(()=>fn(c)),sso:()=>l(()=>K(c,`etherna-sso`,`etherna/etherna-sso:latest`,s(`sso`))),index:()=>l(()=>K(c,`etherna-index`,`etherna/etherna-index:latest`,s(`index`))),beehive:()=>l(()=>K(c,`etherna-beehive`,`etherna/beehive:latest`,s(`beehive`))),gateway:()=>l(()=>K(c,`etherna-gateway`,`etherna/etherna-gateway:latest`,s(`gateway`))),credit:()=>l(u),elastic:()=>l(()=>dn(c))},f=t.portless?{"bee-blockchain":async()=>{let e=R(`etherna-bee`,i)??{};await a.recordPortlessAlias(`bee`,{...e,...s(`bee`)}.BEE_PORT??1633)},shkeeper:async()=>{await a.recordPortlessAlias(`shkeeper`,R(`shkeeper`,i).port)},sso:async()=>{await a.recordPortlessAlias(`sso`,I(String(o?.[`etherna-sso`].ASPNETCORE_URLS)))},index:async()=>{await a.recordPortlessAlias(`index`,I(String(o?.[`etherna-index`].ASPNETCORE_URLS)))},beehive:async()=>{await a.recordPortlessAlias(`beehive`,I(String(o?.[`etherna-beehive`].ASPNETCORE_URLS)))},gateway:async()=>{await a.recordPortlessAlias(`gateway`,I(String(o?.[`etherna-gateway`].ASPNETCORE_URLS)))},credit:async()=>{await a.recordPortlessAlias(`credit`,I(String(o?.[`etherna-credit`].ASPNETCORE_URLS)))}}:{};return(await ke(Object.keys(be).map(e=>{let n=be[e],r=f[e];return{code:e,dependencies:n.dependencies,enabled:t.enabled[n.service],onFailure:n.onFailure,startupCallback:d[e],...r?{beforeStartup:r}:{}}}),{logError:V}).start()).shouldStop&&!a.isShutdownRequested()&&(await Ot(t.enabled),await a.shutdown({killTrackedSpawns:!0})),{shutdown:e=>a.shutdown(e)}}async function zn(e,t,n){await Le()||(console.error(k.red(` portless: CLI not found. Install globally (recommended): npm install -g portless`)),process.exit(1));try{let{startedByUs:t}=await Re();e.setPortlessProxyStartedByUs(t)}catch(e){console.error(k.red(` portless: failed to start proxy: ${e instanceof Error?e.message:String(e)}`)),process.exit(1)}if(!n)try{await e.recordPortlessAlias(`app`,t.appPort)}catch(t){console.error(k.red(` portless: failed to register aliases: ${t instanceof Error?t.message:String(t)}`)),await e.cleanupPortless(),process.exit(1)}let r=n!=null&&n!==``?`${Me(n)}/`:`${M(`app`)}/`;console.log(k.green(` ➜ ${k.bold(`app (portless)`)}: ${k.cyan(r)}`))}function Bn(e){return e===`all`||xe.includes(e)||e===`shkeeper`}function Vn(e){if(e.length===0)return[...xe];if(e.includes(`all`)){let t=new Set(xe);for(let n of e)n!==`all`&&t.add(n);return[...t]}return e}function Hn(e){if(e.includes(`all`)){let t=new Set(A);for(let n of e)n!==`all`&&t.add(n);return[...t]}return e}function Un(e){return e.length===0||e.includes(`all`)}function Wn(e,t){let n=Number(e);if(!Number.isInteger(n)||n<1||n>65535)throw Error(`${t} expects a TCP port between 1 and 65535.`);return n}function Gn(e){let[t,...n]=e,r=t===void 0||t===`help`||t===`--help`?`help`:t;if(r!==`start`&&r!==`stop`&&r!==`help`)throw Error(`Unknown command "${t}".`);let i=[],a={};for(let e=0;e<n.length;e++){let t=n[e];if(t===`--portless`){a.portless=!0;continue}if(t===`--no-portless`){a.portless=!1;continue}if(t===`--detached`){a.detached=!0;continue}if(t===`--attached`){a.detached=!1;continue}if(t===`--app-port`){e+=1,a.appPort=Wn(n[e],`--app-port`);continue}if(t.startsWith(`--app-port=`)){a.appPort=Wn(t.slice(11),`--app-port`);continue}if(t.startsWith(`-`))throw Error(`Unknown option "${t}".`);if(!Bn(t))throw Error(`Unknown service "${t}".`);i.push(t)}if(r===`stop`&&i.length===0)throw Error(`The "stop" command requires at least one service.`);return{command:r,services:i,options:a}}function Kn(e){let t=Te(Vn(e));return Un(e)&&!e.includes(`shkeeper`)&&(t.shkeeper=!1),t}function qn(e,t){return{detached:t.detached??!0,portless:t.portless,appPort:t.appPort,installSignalHandlers:!0,elastic:e.elastic,mongo:e.mongo,bee:e.bee,sso:e.sso,index:e.index,gateway:e.gateway,credit:e.credit,beehive:e.beehive,...e.shkeeper?{shkeeper:!0}:{}}}function Jn(){return`Usage:
11
+ etherna start [services...] [options]
12
+ etherna stop <services...>
13
+
14
+ Services:
15
+ all, blockchain, bee, beehive, credit, elastic, gateway, index, mongo, shkeeper, sso
16
+
17
+ Options:
18
+ --portless Start Portless proxy and register aliases
19
+ --no-portless Disable Portless aliases
20
+ --app-port <port> App port used for SSO client URLs and the app Portless alias
21
+ --detached Reuse already-running containers and leave services running (default)
22
+ --attached Stop tracked Docker processes when the CLI exits
23
+ --help Show this help
24
+
25
+ Examples:
26
+ etherna start sso gateway
27
+ etherna start sso gateway --portless --app-port 5173
28
+ etherna stop mongo sso`}async function Yn(e=process.argv.slice(2)){try{let t=Gn(e);if(t.command===`help`){console.log(Jn());return}if(t.command===`stop`){await Fn(Hn(t.services));return}let n=qn(Kn(t.services),t.options);await Rn(n),n.detached&&process.exit(0)}catch(e){console.error(k.red(e instanceof Error?e.message:String(e))),console.error(``),console.error(Jn()),process.exitCode=1}}Yn();
29
+ //# sourceMappingURL=bin.cjs.map