@etherna/docker 0.0.0-stage → 1.7.2

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`}function Me(e){return e.trim().replace(/\/+$/,``)}function Ne(){return[`proxy`,`start`,`--no-tls`,`--unprivileged`]}function Pe(e=process.env){return{...e,PORTLESS_UNPRIVILEGED:`1`}}function Fe(){return[`proxy`,`stop`]}function Ie(e,t,n=!1){let r=[`alias`,e,String(t)];return n&&r.push(`--force`),r}function Le(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`],env:Pe()}),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 Re(){try{return(await N([`--version`])).code===0}catch{return!1}}async function ze(){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 Be(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 Ve(e,t){let n=Be(t),r=await N(Ie(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 He(e){for(let t of e)await N(Le(t))}async function Ue(){await N(Fe())}const We=1633,Ge=1634,P=9545,Ke=4020,qe=`0xCEeE442a149784faa65C35e328CCd64d874F9a02`,Je=[`POSTAGE_PRICE`],Ye=32650,F=`shkeeper`;function Xe(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:${We}`,g=n&&i?Me(i):Qe(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:Ye},"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:${Ye}`,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:${Ye}`,"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:Ke},"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:Ke,BEE_FULL_NODE:`true`,BEE_PORT:We,BEE_P2P_PORT:Ge,BEE_API_ADDR:`0.0.0.0:${We}`,BEE_P2P_ADDR:`0.0.0.0:${Ge}`,BEE_CORS_ALLOWED_ORIGINS:`*`,BEE_ALLOW_PRIVATE_CIDRS:`true`,BEE_BOOTNODE_MODE:``,BEE_BOOTNODE:``}}}function Ze(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 Qe(e,t,n,r){return n?M(r):L(e,t)}const R=(e,t)=>Xe(t)[e]??null;function $e(e){let t=new Set(Je);return Object.fromEntries(Object.entries(e).filter(([e])=>!t.has(e)))}function et(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 tt=[`elastic`,`mongo`,`bee`,`sso`,`index`,`gateway`,`credit`,`beehive`,`shkeeper`];function nt(e){return typeof e==`object`&&e?e.enabled!==!1:e!==!1}function rt(e){return e===!0?!0:typeof e==`object`&&e?e.enabled!==!1:!1}function it(e){let t={};for(let n of tt)t[n]=n===`shkeeper`?rt(e[n]):nt(e[n]);t.blockchain=t.bee;let n={enabled:t,detached:et(e),portless:e.portless??!1,mode:e.mode??`http`,installSignalHandlers:e.installSignalHandlers??!0};return e.appPort!==void 0&&(n.appPort=e.appPort),n}function at(e){return new Promise(t=>setTimeout(t,e))}async function ot(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 st(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 at(i)}return null}function st(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 ct(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 lt(...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 ut(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 dt(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 ft(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)),ft(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 pt=`etherna-`;function H(e){return e.startsWith(pt)?e:`${pt}${e}`}const mt=`https://docs.docker.com/get-docker/`,ht=3e4;function U(e,t){(0,d.spawn)(e,t,{detached:!0,stdio:`ignore`}).unref()}function gt(){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 _t(){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 vt(){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 yt(e){return new Promise(t=>setTimeout(t,e))}async function bt(){if(await _t()||(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(mt)}`),process.exit(1)),await gt())return;console.log(` ${k.yellow(`➜`)} ${k.bold(`docker`)}: ${k.yellow(`Docker daemon is not running. Starting it…`)}`),vt();let e=Date.now()+ht;for(;Date.now()<e;)if(await yt(2e3),await gt()){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 ${ht/1e3}s. Start Docker manually and run the dev server again.`)}`),console.error(` Install or troubleshoot: ${k.cyan.underline(mt)}`),process.exit(1)}async function W({containerName:e,imageName:t,args:n=[],cmd:r=[],detached:i=!1}){let a=H(e);if(!i)await xt(a)&&await St(a);else{if(await Ct(a))return null;await xt(a)&&await wt(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)&&ut(a),/Error response from daemon/gm.test(t)&&V(a,t)}),i&&s.unref(),s}async function xt(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 St(e){let t=(0,d.spawn)(`docker`,[`stop`,H(e)]);await new Promise(e=>{t.on(`close`,()=>{e()})})}async function Ct(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 wt(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 Tt(e){let t=(0,d.spawn)(`docker`,[`network`,`create`,e]);await new Promise(e=>{t.on(`close`,()=>{e()})})}const Et={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 Dt(e){return Et[e]}async function Ot(e){let t=[...new Set(e.flatMap(Dt))];await Promise.all(t.map(e=>St(e)))}async function kt(e){await Ot(Object.keys(e).filter(t=>e[t]))}async function At(e){await dt(`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=${lt(`.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 At(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 jt(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 Mt(e){if(e<0n)throw Error(`Cannot encode negative uint param: ${e}`);return e.toString(16).padStart(64,`0`)}function Nt(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 Pt(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 Ft(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 jt(r)}throw Error(`Transaction ${t} was not mined within ${n}ms`)}async function It(e,t){return await q(e,`eth_getCode`,[t,`latest`]).then(e=>e??`0x`)}async function Lt(e){let t=await q(e,`eth_blockNumber`,[]);return Number.parseInt(t??`0x0`,16)}function Rt(e){return e!==`0x`&&e.length>2}async function zt(e,t,n=`pending`){return Y(await q(e,`eth_getTransactionCount`,[t,n]))}async function Bt(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 Vt(...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 Ht(e,t){if(e<56)return Uint8Array.of(t+e);let n=Q(BigInt(e));return Vt(Uint8Array.of(t+55+n.length),n)}function Ut(e){if(e instanceof Uint8Array)return e.length===1&&e[0]<128?e:Vt(Ht(e.length,128),e);let t=Vt(...e.map(Ut));return Vt(Ht(t.length,192),t)}function Wt(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 Gt(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)(Ut([...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=Ut([...n,Q(l),Q(s),Q(c)]);return{rawTx:`0x`+Z(u),hash:`0x`+Z((0,h.keccak_256)(u))}}async function Kt(e,t,n,r){let i=Wt(t),[a,o,s]=await Promise.all([q(e,`eth_chainId`,[]),zt(e,i,`pending`),Bt(e)]),{rawTx:c,hash:l}=Gt({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 Ft(e,l,r.timeoutMs,r.pollMs);if(u.status!==`0x1`)throw Error(r.onRevert?.(l)??`Transaction ${l} reverted (status ${u.status}).`);return l}const qt=`etherna_bee_network`,Jt=[`BEE_SWAP_FACTORY_ADDRESS`,`BEE_POSTAGE_STAMP_ADDRESS`,`BEE_PRICE_ORACLE_ADDRESS`,`BEE_REDISTRIBUTION_ADDRESS`,`BEE_STAKING_ADDRESS`],Yt=3e4,Xt=2e5;let Zt=!1,Qt,$t=Promise.resolve();function en(){Zt=!0,$t=new Promise(e=>{Qt=e})}function $(){Zt&&(Zt=!1,Qt?.(),Qt=void 0)}function tn(){return Zt}function nn(){return $t}function rn(e){return new Promise(t=>setTimeout(t,e))}async function an({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=Wt(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=Pt(m),g=Nt(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 Kt(e,n,{to:t,data:l+h+g,gasLimit:BigInt(Xt)},{timeoutMs:Yt,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 Kt(e,n,{to:t,data:s+Mt(r),gasLimit:BigInt(Xt)},{timeoutMs:Yt,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 on(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 sn(e,t,n){let r=Date.now()+3e4,i=null;for(;Date.now()<r;){let[r,a]=await Promise.all([Lt(e).catch(()=>null),Promise.all(t.map(t=>It(e,t).catch(()=>null)))]);if(r!=null&&a.every(e=>e!=null)){if(i===null&&(i=r),a.every(e=>Rt(e)))return;if(r>=10||r-i>=2)throw on(n)}await rn(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 cn(e){let t=e.serviceCtx,n=e.getServiceEnv(`bee`),r=`etherna-blockchain`,i=`etherna_blockchain-volume`,a=e.detached,o=$e({...R(r,t)??{},...n}),s=Number(o.BLOCKCHAIN_PORT);if(a&&await Ct(r))return B(r,`http`,String(s)),null;en(),await Tt(qt),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=$e({...R(r,t)??{},...n}),g={...R(`etherna-bee`,t)??{},...n},_=Number(h.BLOCKCHAIN_PORT),v=Jt.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`,qt,`-p`,`${_}:${_}`,`-p`,`${_+1}:${_+1}`,`--mount`,`type=volume,source=${i},target=/root/.ethereum`,`--mount`,`type=bind,source=${lt(`.ethereum`)},target=/root/extra`],detached:a,cmd:[`--allow-insecure-unlock`,`--unlock=${qe}`,`--password=/root/extra/password`,`--mine`,`--miner.etherbase=${qe}`,`--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,sn(`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),St(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 ln(e){let t=e.serviceCtx,n=e.getServiceEnv(`bee`),r=`etherna-bee`,i=await un(e,r),a=await ft(`http://localhost:${R(`etherna-bee`,t)?.BEE_PORT??`1633`}`),[o]=await Promise.all([un(e,r,1,a)]);try{let e={...R(`etherna-bee`,t)??{},...n};await an({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 un(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=$e({...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`,qt,`-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 dn(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 fn(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 pn(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 mn=`vsyshost/shkeeper:2.5.12`,hn=`vsyshost/ethereum-shkeeper:1.2.3`,gn=`etherna`;function _n(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 vn(e){let{tag:t}=_n(mn);return e?`${gn}/shkeeper:${t}`:mn}function yn(e){let{tag:t}=_n(hn);return e?`${gn}/ethereum-shkeeper:${t}`:hn}async function bn(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 xn(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 Sn(e,t){return z(e,`${t.replace(/[^a-z0-9._-]+/gi,`-`)}-${Date.now()}`)}async function Cn(e,t,n){let r=Sn(t,n);f.default.mkdirSync(r,{recursive:!0});let i=p.default.join(r,`clone`);return await xn(`git`,[`clone`,`--depth`,`1`,`--branch`,n,`https://github.com/${e}.git`,i]),{cleanupPath:r,contextPath:i,dockerfilePath:p.default.join(i,`Dockerfile`)}}async function wn(e){let{logLabel:t,imageName:n,sourceRepo:r,workspacePrefix:i,gitRef:a}=e;if(await bn(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 Cn(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 Tn(e){let t=e?.trim();return t&&t.length>0?t:`main`}async function En(e,t){await wn({logLabel:`shkeeper`,imageName:vn(e),sourceRepo:e??`vsys-host/shkeeper.io`,workspacePrefix:`.shkeeper-build`,gitRef:e?Tn(t):_n(mn).tag})}async function Dn(e,t){e&&await wn({logLabel:`ethereum-shkeeper`,imageName:yn(e),sourceRepo:e,workspacePrefix:`.ethereum-shkeeper-build`,gitRef:Tn(t)})}const On=`etherna_shkeeper_network`;async function kn({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 An({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 jn(e=On,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 Mn(e=On,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 Nn({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 Pn(e){let t=e.serviceCtx,n=e.detached,r=e.getShkeeperConfig(),i=e.getShkeeperBuild(),a={imageName:vn(i.githubRepo)},o=r.ethereum?.githubRepo?.trim()||void 0,s=r.ethereum?.githubBranch?.trim()||void 0,c=`host`,l=[];try{await En(i.githubRepo,i.githubBranch),await Dn(o,s);let u=yn(o),[d,f]=await Promise.all([jn(c,{detached:n}),Mn(c,{detached:n})]);l.push(d,f);let[p,m]=await Promise.all([An({context:t,envs:r.ethereum?.env,networkName:c,imageName:u,detached:n}),Nn({context:t,envs:r.ethereum?.env,networkName:c,imageName:u,detached:n})]);l.push(p,m);let h=await kn({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 Fn(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 In(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 Ot(t)}function Ln(e){return typeof e==`object`&&e?e.env??{}:{}}function Rn(e){return e===!0?{}:typeof e==`object`&&e?e:{}}async function zn(e={}){let t=it(e);await bt();let n=ct(`PORTLESS_URL`)?.trim(),r=t.appPort??Ze(t.mode).appPort,i={mode:t.mode,portless:t.portless,appPort:r,...t.portless&&n?{portlessAppPublicUrl:Me(n)}:{}},a=Fn({detached:t.detached,enabledServices:t.enabled,stopContainersForEnabled:kt,addPortlessAlias:(e,t)=>Ve(e,t),removePortlessAliases:e=>He(e),stopPortlessProxy:Ue,isBlockchainBootstrapInProgress:tn,waitForBlockchainBootstrapToSettle:nn,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 Bn(a,i,n);let o=t.portless?Xe(i):void 0,s=t=>Ln(e[t]),c=dn({detached:t.detached,serviceCtx:i,getServiceEnv:s,pushSpawn:(...e)=>{a.pushSpawn(...e.filter(e=>e!=null))},isShutdownRequested:()=>a.isShutdownRequested(),getShkeeperConfig:()=>Rn(e.shkeeper),getShkeeperBuild:()=>{let t=Rn(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 ot();t&&(e={...e,"Payments:ShKeeper:ApiKey":t})}await K(c,`etherna-credit`,`etherna/etherna-credit:latest`,e)},d={"bee-blockchain":()=>l(()=>cn(c)),"bee-nodes":()=>l(()=>ln(c)),shkeeper:()=>l(()=>Pn(c)),mongo:()=>l(()=>pn(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(()=>fn(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 kt(t.enabled),await a.shutdown({killTrackedSpawns:!0})),{shutdown:e=>a.shutdown(e)}}async function Bn(e,t,n){await Re()||(console.error(k.red(` portless: CLI not found. Install globally (recommended): npm install -g portless`)),process.exit(1));try{let{startedByUs:t}=await ze();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 Vn(e){return e===`all`||xe.includes(e)||e===`shkeeper`}function Hn(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 Un(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 Wn(e){return e.length===0||e.includes(`all`)}function Gn(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 Kn(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=Gn(n[e],`--app-port`);continue}if(t.startsWith(`--app-port=`)){a.appPort=Gn(t.slice(11),`--app-port`);continue}if(t.startsWith(`-`))throw Error(`Unknown option "${t}".`);if(!Vn(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 qn(e){let t=Te(Hn(e));return Wn(e)&&!e.includes(`shkeeper`)&&(t.shkeeper=!1),t}function Jn(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 Yn(){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 Xn(e=process.argv.slice(2)){try{let t=Kn(e);if(t.command===`help`){console.log(Yn());return}if(t.command===`stop`){await In(Un(t.services));return}let n=Jn(qn(t.services),t.options);await zn(n),n.detached&&process.exit(0)}catch(e){console.error(k.red(e instanceof Error?e.message:String(e))),console.error(``),console.error(Yn()),process.exitCode=1}}Xn();
29
+ //# sourceMappingURL=bin.cjs.map