@etherna/docker 1.7.1 → 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/dist/bin.cjs CHANGED
@@ -3,11 +3,11 @@ var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=
3
3
  `:`
4
4
  `)+n,i=r+1,r=e.indexOf(`
5
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(`
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
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:
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
11
  etherna start [services...] [options]
12
12
  etherna stop <services...>
13
13
 
@@ -25,5 +25,5 @@ Options:
25
25
  Examples:
26
26
  etherna start sso gateway
27
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();
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
29
  //# sourceMappingURL=bin.cjs.map