@tangle-network/sandbox-cli 0.22.112 → 0.22.114
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/account-K6n39T9G.mjs +1 -0
- package/dist/api-COxVvwlJ.mjs +1 -0
- package/dist/clone-CqxGeiso.mjs +1 -0
- package/dist/credential-store-BglYxKnr.mjs +1 -0
- package/dist/deployment-t_Jhgj4Q.mjs +1 -0
- package/dist/device-CYbYA3Ts.mjs +1 -0
- package/dist/dist-BFxZmL_S.mjs +1 -0
- package/dist/graph-campaign-state-BLsk-81-.mjs +1 -0
- package/dist/graph-dataset-V3HZEEry.mjs +1 -0
- package/dist/graph-learning-CZixMhev.mjs +1 -0
- package/dist/graph-operating-evidence-CUiPxcmh.mjs +2 -0
- package/dist/graph-view-DOQKwuvP.mjs +3 -0
- package/dist/index.mjs +31 -34
- package/dist/output-BqCeTtw4.mjs +1 -0
- package/dist/run-CEhYsWAB.mjs +1 -0
- package/dist/solve-checker-gdxdE3g4.mjs +1 -0
- package/dist/solve-signer-CcAle-Dv.mjs +1 -0
- package/dist/submit--rl0SmXb.mjs +1 -0
- package/dist/transactions-C3dKwqB0.mjs +1 -0
- package/dist/workspace-C-JZvGpv.mjs +1 -0
- package/package.json +5 -5
- /package/dist/{graph-native-Cl6SphYB.mjs → graph-native-Bv5gSn4b.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from"chalk";import t from"ora";let n=!1;function r(e){n=e}function i(...e){n?console.error(...e):console.log(...e)}function a(t){return t==null?e.dim(`-`):typeof t==`boolean`?t?e.green(`yes`):e.red(`no`):t instanceof Date?s(t):typeof t==`string`&&o(t)?s(new Date(t)):String(t)}function o(e){return/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e)}function s(e){let t=Date.now()-e.getTime();if(t<6e4)return`just now`;if(t<36e5)return`${Math.floor(t/6e4)} min ago`;if(t<864e5){let e=Math.floor(t/36e5);return`${e} hour${e>1?`s`:``} ago`}let n=Math.floor(t/864e5);return`${n} day${n>1?`s`:``} ago`}function c(t){switch(t){case`running`:return e.green(t);case`pending`:case`provisioning`:return e.yellow(t);case`stopped`:return e.gray(t);case`failed`:case`deleted`:return e.red(t);default:return t}}function l(e,t){let n=t.map(t=>{let n=t.header.length,r=Math.max(...e.map(e=>a(e[t.key]).length));return t.width??Math.max(n,r)+2}),r=e.map(e=>t.map(t=>t.key===`status`?c(String(e[t.key])):a(e[t.key])));x(t.map(e=>e.header),r,n)}function u(e){console.log(JSON.stringify(e,null,2))}function d(t){i(e.green(`✓`),t)}function f(t){console.error(e.red(`✗`),t)}function p(t){i(e.yellow(`!`),t)}function m(t){i(e.blue(`→`),t)}const h=new Set;function g(e){let r=t({text:e,color:`cyan`,isSilent:n});return h.add(r),r}function _(){for(let e of h)e.isSpinning&&e.stop();h.clear()}function v(t,n=0){let r=` `.repeat(n);for(let[n,i]of Object.entries(t))i!=null&&console.log(`${r}${e.dim(`${n}:`)} ${a(i)}`)}function y(e){let t=`${e.cpuCores} vCPU / ${e.memoryMB} MB / ${e.diskGB} GB`;return e.pool?`${t} (pool: ${e.pool})`:t}function b(t){if(console.log(),console.log(e.bold(`Sandbox Details`)),console.log(e.dim(`─`.repeat(40))),v({ID:t.id,Name:t.name,Status:c(t.status),Resources:t.resources?y(t.resources):void 0,Created:t.createdAt,Expires:t.expiresAt}),t.connection){if(console.log(),console.log(e.bold(`Connection`)),console.log(e.dim(`─`.repeat(40))),t.connection.ssh){let{ssh:e}=t.connection,n=process.platform===`win32`?`NUL`:`/dev/null`,r=`ssh -o ProxyCommand="${e.proxyCommand}" -o StrictHostKeyChecking=no -o UserKnownHostsFile=${n} -o GlobalKnownHostsFile=${n} -o LogLevel=ERROR -o ServerAliveInterval=15 -o ServerAliveCountMax=4 -o TCPKeepAlive=yes ${e.username}@localhost -p ${e.port}`;v({SSH:process.platform===`win32`?`$env:TANGLE_SSH_PROXY_AUTH_TOKEN='<token>'; ${r}`:`TANGLE_SSH_PROXY_AUTH_TOKEN='<token>' ${r}`})}t.connection.webTerminalUrl&&v({"Web Terminal":t.connection.webTerminalUrl}),t.connection.runtimeUrl&&v({"API URL":t.connection.runtimeUrl})}console.log()}function x(t,n,r){if(n.length===0){console.log(e.dim(`No items found.`));return}let i=r??t.map((e,t)=>{let r=Math.max(...n.map(e=>String(e[t]??``).length));return Math.max(e.length,r)+2});console.log(t.map((t,n)=>e.bold(t.padEnd(i[n]))).join(``));for(let e of n)console.log(e.map((e,t)=>String(e??``).padEnd(i[t])).join(``))}export{u as a,l as c,_ as d,d as f,x as i,r as l,y as n,v as o,p,m as r,b as s,f as t,g as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,f as t,o as n,r,u as i}from"./output-BqCeTtw4.mjs";import{y as a}from"./index.mjs";import{t as o}from"./solve-signer-CcAle-Dv.mjs";import{c as s,f as c,n as l,o as u,s as d,t as f}from"./workspace-C-JZvGpv.mjs";import{n as p,t as m}from"./solve-checker-gdxdE3g4.mjs";import{randomBytes as h,randomUUID as g}from"node:crypto";import*as _ from"node:path";import{toHex as v}from"viem";async function y(y,b){try{let{root:a,manifest:x}=await d(y,b.directory),S=await u(a),C=x.provenance?await s(a,x,S,{allowMissing:!0}):void 0,w=o(),T=i(`Running ${x.title} checker…`);b.json||T.start();let E;try{E=await m(a,x.checker)}finally{T.stop()}let D=l(E,C,x.provenance,void 0,{allowMissingSource:!0,requirePullRequest:!1}),O=v(h(32)),k=p(E.candidateRef,O),A={version:1,competition:x.slug,candidateRef:E.candidateRef,evidence:D.evidence,evidenceJson:E.evidenceJson,evidenceRefs:D.evidenceRefs,salt:O,candidateId:k,...C?{source:C}:{},deviceAddress:w.account.address,clientSubmissionId:g(),createdAt:new Date().toISOString()};await c(_.join(a,`.tangle-solve-run.json`),A),b.json?e({localRun:A}):(t(`Checker output recorded locally for operator evaluation`),n({Competition:x.slug,Candidate:E.candidateRef,"Device address":w.account.address,"Evidence refs":D.evidenceRefs.length}),r("Commit any changes, then run `tangle solve submit` from this directory."),x.provenance&&!C&&r(`Add your GitHub fork as 'origin' before submitting. The task repository is available as '${f}'.`))}catch(e){a(e)}}export{y as runCompetition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./deployment-t_Jhgj4Q.mjs";import{_ as t,a as n,b as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,o as f,p,r as m,s as h,t as g,u as _,v,y}from"./transactions-C3dKwqB0.mjs";import*as b from"node:path";import*as x from"node:os";import{execFile as S}from"node:child_process";import*as C from"node:fs/promises";import{promisify as w}from"node:util";import{encodeAbiParameters as T,keccak256 as E}from"viem";function D(e,t){return E(T(c,[e.trim(),t]))}function O(e){let t=/^submission=(\S+)/.exec(e);if(!t?.[1])throw Error(`COMMIT_CANDIDATE did not return a submission reference`);return t[1]}async function k(e,t,r,i,c){let l=c.resumeTransactions?.evaluation;if(l){let n=await e.publicClient.waitForTransactionReceipt({hash:l});if(a(n,l,`Evaluation`,{from:e.account.address,to:t.managerAddress}),!u(n,t,e.account,i))throw Error(`Saved evaluation transaction did not emit EvaluationAccepted for this candidate`);return l}let d=Date.now();for(;!o(d,p);){if(await h(e,t,i)){let n=_(await e.publicClient.getLogs({address:t.managerAddress,event:s,args:{serviceId:t.serviceId,competitionId:t.competitionId,researcher:e.account.address},fromBlock:r.blockNumber,toBlock:`latest`}),i);if(n)return n;throw Error(`Candidate is already accepted, but its EvaluationAccepted transaction is unavailable`)}let[o,l,,d,f]=await e.publicClient.readContract({address:t.managerAddress,abi:v,functionName:`pendingResults`,args:[t.serviceId,r.callId]});if(d&&o!==4)throw Error(`Manager pending result ${r.callId} has unexpected job ${o}`);if(d&&f)throw Error(`Manager executed the report without EvaluationAccepted`);if(d&&!f){if(l.toLowerCase()!==E(r.output).toLowerCase())throw Error(`Manager pending report output does not match the aggregate`);let o=await n(e,{address:t.managerAddress,abi:v,functionName:`executePendingResult`,args:[t.serviceId,r.callId,r.output]});await c.onTransaction?.(`evaluation`,o);let s=await e.publicClient.waitForTransactionReceipt({hash:o});if(a(s,o,`Evaluation`,{from:e.account.address,to:t.managerAddress}),!u(s,t,e.account,i))throw Error(`Evaluation transaction did not emit EvaluationAccepted for this candidate`);return o}await new Promise(e=>setTimeout(e,1e3))}throw Error(`Manager did not emit EvaluationAccepted within 120 seconds`)}async function A(o,s,c,u={}){if(e(o),!/^0x[0-9a-f]{64}$/i.test(c.salt))throw Error(`Reveal salt must be bytes32`);if(!c.artifactRef.trim())throw Error(`Candidate reference is required`);if(!c.evidenceJson.trim()||c.evidenceRefs.length===0)throw Error(`Checker evidence is required`);let h=await f(o,s),_=await g(h,o,u.onTransaction,u.resumeTransactions?.authorization),b,x=await h.publicClient.readContract({address:o.managerAddress,abi:v,functionName:`stakes`,args:[o.serviceId,o.competitionId,h.account.address]});x<o.minStakeWei&&(b=await n(h,{address:o.managerAddress,abi:v,functionName:`postStake`,args:[o.serviceId,o.competitionId],value:o.minStakeWei-x}),await u.onTransaction?.(`stake`,b),a(await h.publicClient.waitForTransactionReceipt({hash:b}),b,`Stake`,{from:h.account.address,to:o.managerAddress}));let S=D(c.artifactRef,c.salt),C=T(t,[o.competitionId,o.minStakeWei]),w=T(d,[o.competitionId,S]),E=T(r,[o.competitionId,S,c.artifactRef.trim(),c.salt]),A=await m(h,o,1,C,`joined`,u.onTransaction,`join`,u.resumeTransactions),j=await m(h,o,2,w,`committed`,u.onTransaction,`commit`,u.resumeTransactions),M=O(j.acknowledgement.detail),N=await m(h,o,3,E,`revealed`,u.onTransaction,`reveal`,u.resumeTransactions),P=await l(h,o,4,T(y,[o.competitionId,S,M,c.evidenceJson,JSON.stringify(c.evidenceRefs)]),u.onTransaction,`report`,u.resumeTransactions),F=await i(h,o,P.callId,P.blockNumber,p),I=await k(h,o,{callId:P.callId,output:F,blockNumber:P.blockNumber},S,u);return{address:h.account.address,..._?{authorization:_}:{},...b?{stake:b}:{},join:A.hash,commit:j.hash,reveal:N.hash,report:P.hash,evaluation:I,candidateId:S,submissionRef:M}}const j=w(S),M=`/usr/bin/bwrap`,N=[`/usr`,`/bin`,`/sbin`,`/lib`,`/lib64`];function P(e){return[...e].some(e=>{let t=e.charCodeAt(0);return t<32||t===127})}function F(e,t){if(!e||e.length>2048||P(e))throw Error(`${t} contains invalid control characters or is too long`)}function I(e,t){let n=t;for(;n<e.length&&/\s/.test(e[n]??``);)n+=1;return n}function L(e,t){if(e[t]!==`"`)throw Error(`Checker output must be valid JSON`);let n=t+1;for(;n<e.length;){let t=e[n];if(t===`\\`){n+=2;continue}if(t===`"`)return n+1;if((t?.charCodeAt(0)??0)<32)throw Error(`Checker output must be valid JSON`);n+=1}throw Error(`Checker output must be valid JSON`)}function R(e,t,n){let r=new Set,i=I(e,t+1);if(e[i]===`}`)return i+1;for(;i<e.length;){let t=L(e,i),a=JSON.parse(e.slice(i,t));if(r.has(a))throw Error(`Checker output must not contain duplicate object keys`);if(r.add(a),i=I(e,t),e[i]!==`:`)throw Error(`Checker output must be valid JSON`);let o=I(e,i+1),s=B(e,o);if(n?.(a,o,s),i=I(e,s),e[i]===`}`)return i+1;if(e[i]!==`,`)throw Error(`Checker output must be valid JSON`);i=I(e,i+1)}throw Error(`Checker output must be valid JSON`)}function z(e,t){let n=I(e,t+1);if(e[n]===`]`)return n+1;for(;n<e.length;){if(n=I(e,B(e,n)),e[n]===`]`)return n+1;if(e[n]!==`,`)throw Error(`Checker output must be valid JSON`);n=I(e,n+1)}throw Error(`Checker output must be valid JSON`)}function B(e,t){if(e[t]===`"`)return L(e,t);if(e[t]===`{`)return R(e,t);if(e[t]===`[`)return z(e,t);let n=t;for(;n<e.length&&!/[\s,\]}]/.test(e[n]??``);)n+=1;return n}function V(e){let t=e.trim();if(I(t,B(t,0))!==t.length)throw Error(`Checker output must be valid JSON`)}function H(e,t){let n=e.trim();if(n[0]!==`{`)return;let r;return R(n,0,(e,i,a)=>{e===t&&(r=n.slice(i,a).trim())}),r}function U(e){let t;try{t=JSON.parse(e)}catch{throw Error(`Checker output must be one JSON object`)}if(V(e),!t||typeof t!=`object`||Array.isArray(t))throw Error(`Checker output must be a JSON object`);let n=t,r=n.candidate_ref;if(typeof r!=`string`||!r.trim())throw Error(`Checker output must include candidate_ref`);let i=r.trim(),a=n.evidence_refs;if(!Array.isArray(a)||a.length===0||a.some(e=>typeof e!=`string`||!e.trim()))throw Error(`Checker output must include a non-empty evidence_refs array`);F(i,`candidate_ref`);for(let e of a)F(e.trim(),`evidence_refs`);if(!n.evidence_json||typeof n.evidence_json!=`object`||Array.isArray(n.evidence_json))throw Error(`Checker output must include an evidence_json object`);let o={...n.evidence_json},s=H(e,`evidence_json`);if(!s)throw Error(`Checker evidence_json source text is missing`);if(o.candidate_ref!==i)throw Error(`Checker evidence_json candidate_ref must match candidate_ref`);return{candidateRef:i,evidenceRefs:a.map(e=>e.trim()),evidence:o,evidenceJson:s}}async function W(e,t,n){let r=n.trim();if(r.startsWith(`{`)&&r.endsWith(`}`)||!t.result_file)return r;let i=await X(e),a=b.resolve(i,t.result_file),o=b.relative(i,a);if(o.startsWith(`..`)||b.isAbsolute(o))throw Error(`Checker result_file must stay inside the competition repository`);let s;try{s=await C.lstat(a)}catch{throw Error(`Checker result_file must be an existing regular file inside the competition repository`)}if(s.isSymbolicLink())throw Error(`Checker result_file must not be a symbolic link`);if(!s.isFile())throw Error(`Checker result_file must be an existing regular file inside the competition repository`);let c;try{c=await C.realpath(a)}catch{throw Error(`Checker result_file must resolve to a regular file inside the competition repository`)}let l=b.relative(i,c);if(l.startsWith(`..`)||b.isAbsolute(l))throw Error(`Checker result_file must stay inside the competition repository`);return(await C.readFile(c,`utf8`)).trim()}function G(e,t){let n=b.relative(e,t);return n===``||!n.startsWith(`..`)&&!b.isAbsolute(n)}function K(e){return N.some(t=>G(t,e))}async function q(e,t,n){let r=e.includes(`/`)?[b.resolve(t,e)]:(process.env.PATH??``).split(b.delimiter).filter(Boolean).map(t=>b.join(t,e));for(let i of r){let r;try{r=await C.realpath(i),await C.access(r,C.constants.X_OK)}catch{continue}if(!G(t,r)&&!K(r)&&r!==n)throw Error(`Checker executable '${e}' must resolve inside the competition repository or a trusted runtime directory`);return r}throw Error(`Checker executable '${e}' was not found`)}async function J(e){let t=[];for(let n of e)try{(await C.stat(n)).isDirectory()&&t.push(n)}catch{}return t}async function Y(e){let t=await C.realpath(x.homedir());if(e===b.parse(e).root||e===t)throw Error(`Solve checker repository must be a dedicated directory, not the filesystem or home root`)}async function X(e){let t=await C.realpath(e);return await Y(t),t}async function Z(e){let t=b.join(e,`.git`),n;try{n=await C.lstat(t)}catch{return}if(n.isSymbolicLink())throw Error(`Solve checker repository .git must not be a symbolic link`);if(!n.isDirectory()&&!n.isFile())return;let r;try{let t={...process.env};for(let e of[`GIT_DIR`,`GIT_WORK_TREE`,`GIT_INDEX_FILE`,`GIT_OBJECT_DIRECTORY`,`GIT_ALTERNATE_OBJECT_DIRECTORIES`,`GIT_COMMON_DIR`,`GIT_CONFIG_COUNT`,`GIT_CONFIG_PARAMETERS`])delete t[e];let n=await j(`/usr/bin/git`,[`-C`,e,`rev-parse`,`--verify`,`HEAD^{commit}`],{encoding:`utf8`,maxBuffer:1e5,env:{...t,GIT_CONFIG_GLOBAL:`/dev/null`,GIT_CONFIG_SYSTEM:`/dev/null`,GIT_CONFIG_NOSYSTEM:`1`,GIT_TERMINAL_PROMPT:`0`}}),i=String(n.stdout).trim();/^[0-9a-f]{40}$/i.test(i)&&(r=i.toLowerCase())}catch{}return{kind:n.isDirectory()?`directory`:`file`,...r?{commit:r}:{}}}async function Q(e,t,n){let r=await X(e);if(process.platform!==`linux`)throw Error(`Solve checkers require the Linux sandbox runtime (bubblewrap) with network isolation`);try{await C.access(M,C.constants.X_OK)}catch{throw Error(`Solve checkers require /usr/bin/bwrap; install bubblewrap or run the checker in a Tangle sandbox`)}let i=await q(t,r,await C.realpath(process.execPath)),a=await Z(r),o=(await J(N)).flatMap(e=>[`--ro-bind`,e,e]),s=G(r,i)?`/work/${b.relative(r,i)}`:K(i)?i:`/checker/node`;!G(r,i)&&!K(i)&&o.push(`--ro-bind`,i,`/checker/node`);let c=a?.kind===`directory`?[`--tmpfs`,`/work/.git`]:a?.kind===`file`?[`--ro-bind`,`/dev/null`,`/work/.git`]:[];return{executable:M,args:[`--die-with-parent`,`--new-session`,`--unshare-all`,`--clearenv`,...o,`--proc`,`/proc`,`--dev`,`/dev`,`--tmpfs`,`/tmp`,`--dir`,`/tmp/home`,`--bind`,r,`/work`,...c,`--chdir`,`/work`,`--setenv`,`HOME`,`/tmp/home`,...a?.commit?[`--setenv`,`TANGLE_SOLVE_COMMIT`,a.commit]:[],`--setenv`,`TMPDIR`,`/tmp`,`--setenv`,`PATH`,`/checker:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`,`--setenv`,`LANG`,`C.UTF-8`,`--setenv`,`PYTHONDONTWRITEBYTECODE`,`1`,`--setenv`,`XDG_CONFIG_HOME`,`/tmp/home/.config`,`--setenv`,`XDG_CACHE_HOME`,`/tmp/home/.cache`,`--setenv`,`XDG_DATA_HOME`,`/tmp/home/.local/share`,`--setenv`,`GIT_CONFIG_GLOBAL`,`/dev/null`,`--setenv`,`GIT_CONFIG_SYSTEM`,`/dev/null`,`--setenv`,`NPM_CONFIG_USERCONFIG`,`/dev/null`,s,...n]}}async function $(e,t){if(!t.command||t.command.includes(`/../`)||P(t.command))throw Error(`The competition checker command is invalid`);if(!Array.isArray(t.args))throw Error(`The competition checker arguments must be an array`);for(let e of t.args)F(e,`Checker argument`);let n=t.timeout_ms??15*6e4;if(!Number.isSafeInteger(n)||n<1e3||n>60*6e4)throw Error(`Checker timeout must be between one second and one hour`);let r=await X(e),i;try{let e=await Q(r,t.command,t.args);i=await j(e.executable,e.args,{cwd:r,timeout:n,maxBuffer:4194304,encoding:`utf8`})}catch(e){let t=e,n=t.stderr?.trim()||t.stdout?.trim()||t.message||`checker failed`;throw Error(`Pinned checker failed: ${n}`)}let a=String(i.stdout),o=String(i.stderr);return{...U(await W(r,t,a)),stdout:a,stderr:o}}export{D as n,A as r,$ as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,r as n}from"./credential-store-BglYxKnr.mjs";import{generatePrivateKey as r,privateKeyToAccount as i}from"viem/accounts";const a=`solve:device:secp256k1`,o=/^0x[0-9a-f]{64}$/i;function s(e){return e&&o.test(e)?e:void 0}function c(){let e=n(a),t=s(e.value);if(!(!t||e.source===`none`))return{account:i(t),source:e.source}}function l(){let t=c();if(t)return t;let n=r(),o=e(a,n);return{account:i(n),source:o}}function u(r){let o=s(n(a).value);if(!o||i(o).address!==r.account.address)throw Error(`The local Solve device key changed; it was not retired`);let c=`${a}:retired:${r.account.address.toLowerCase()}`;if(e(c,o),n(c).value!==o)throw Error(`The revoked device key could not be retired safely`);return t(a),c}export{c as n,u as r,l as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,f as t,o as n,u as r}from"./output-BqCeTtw4.mjs";import{y as i}from"./index.mjs";import{n as a}from"./solve-signer-CcAle-Dv.mjs";import{a as o,c as s,d as c,f as l,h as u,l as d,m as f,n as p,o as m,s as h,u as g}from"./workspace-C-JZvGpv.mjs";import{a as _,i as v,t as y}from"./api-COxVvwlJ.mjs";import{n as b,r as x,t as S}from"./solve-checker-gdxdE3g4.mjs";import*as C from"node:path";const w=/^0x[0-9a-f]{64}$/i;async function T(e){let t=await y({deviceAddress:e.deviceAddress,apiUrl:e.apiUrl,profile:e.profile}),n=await e.signer.signMessage({message:t.message});return{walletChallengeId:t.challengeId,walletSignature:n}}async function E(y,E){try{let{root:i,manifest:D}=await h(y,E.directory);v({profile:E.profile});let O=await m(i),k=await o(i);if(k.competition!==D.slug)throw Error(`.tangle-solve-run.json does not match this competition`);if(!w.test(k.salt)||!w.test(k.candidateId))throw Error("This run predates durable candidate identity. Run `tangle solve run` again");let A=D.provenance?await s(i,D,O):void 0;if(D.provenance&&k.source&&!d(k.source,A))throw Error("The saved run points to a different repository or revision. Keep your fork as 'origin' and run `tangle solve run` again before submitting");let j=a();if(!j)throw Error("No Solve device signer found. Run `tangle solve run` first");if(j.account.address.toLowerCase()!==k.deviceAddress.toLowerCase())throw Error("The local Solve device account changed after `tangle solve run`; run the checker again");let M=r(`Checking the committed candidate…`);E.json||M.start();let N;try{N=await S(i,D.checker)}finally{M.stop()}if(N.candidateRef!==k.candidateRef||N.evidenceJson!==k.evidenceJson)throw Error("The committed checker output changed after `tangle solve run`; run the checker again");if(b(N.candidateRef,k.salt).toLowerCase()!==k.candidateId.toLowerCase())throw Error(`The saved candidate identity does not match the checker output; run the checker again`);let P=u(E.prUrl);if(!D.provenance&&P)throw Error(`This competition does not accept GitHub pull request provenance`);if(P){if(!A)throw Error(`A provenance policy is required for a pull request`);await c({pullRequest:P,taskRepository:A.taskRepository,submissionRepository:A.submissionRepository,submissionRevision:O})}let F=p(N,A,D.provenance,P,{requirePullRequest:!0}),I={...k,...A?{source:A}:{},chainState:{status:`submitting`,transactions:{...k.chainState?.transactions??{}}}},L=C.join(i,`.tangle-solve-run.json`);await l(L,I);let R=r(`Submitting candidate to Tempo…`);E.json||R.start();let z;try{z=await x(f(D),j.account,{artifactRef:N.candidateRef,salt:k.salt,evidenceJson:N.evidenceJson,evidenceRefs:F.evidenceRefs},{resumeTransactions:I.chainState?.transactions,onTransaction:async(e,t)=>{I={...I,chainState:{status:`submitting`,transactions:{...I.chainState?.transactions??{},[e]:t}}},await l(L,I)}})}finally{R.stop()}I={...I,chainReceipt:z,chainState:{status:`accepted`,transactions:{...I.chainState?.transactions??{},...g(z)}}},await l(L,I);let B=await T({deviceAddress:z.address,signer:j.account,apiUrl:E.apiUrl,profile:E.profile}),V=await _({path:`/v1/submissions`,method:`POST`,apiUrl:E.apiUrl,profile:E.profile,body:{competition:D.slug,candidateRef:N.candidateRef,candidateId:z.candidateId,evidenceJson:N.evidenceJson,evidenceRefs:F.evidenceRefs,deviceAddress:z.address,reportTxHash:z.report,evaluationTxHash:z.evaluation,transactions:g(z),...D.provenance&&A?{source:{...A,...P?{pullRequest:P}:{}}}:{},clientSubmissionId:k.clientSubmissionId,...B,...E.model?{model:E.model}:{},...E.note?{note:E.note}:{}}});E.json?e({...V,transactions:g(z),candidateId:z.candidateId}):(t(`Submission accepted on Tempo`),n({Competition:D.slug,Candidate:z.candidateId,"Device address":z.address,"Report transaction":z.report,"Evaluation transaction":z.evaluation,"Submission ID":typeof V.id==`string`?V.id:V.submission?.id}))}catch(e){i(e)}}export{E as submitCompetition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e}from"./deployment-t_Jhgj4Q.mjs";import{createPublicClient as t,createWalletClient as n,decodeAbiParameters as r,decodeEventLog as i,http as a,keccak256 as o,parseAbi as s,parseAbiItem as c,parseAbiParameters as l,stringToHex as u}from"viem";import{tempoModerato as d}from"viem/chains";import{Actions as f,withRelay as p}from"viem/tempo";const m=12e4,h=c(`event JobSubmitted(uint64 indexed serviceId, uint64 indexed callId, uint8 jobIndex, address caller, bytes inputs)`),g=c(`event JobCompleted(uint64 indexed serviceId, uint64 indexed callId)`),_=c(`event JobResultSubmitted(uint64 indexed serviceId, uint64 indexed callId, address indexed operator, bytes result)`),v=c(`event AggregatedResultSubmitted(uint64 indexed serviceId, uint64 indexed callId, uint256 signerBitmap, bytes output)`),y=c(`event EvaluationAccepted(uint64 indexed serviceId, uint64 indexed competitionId, address indexed researcher, bytes32 candidateId, bytes32 submissionRefHash, bytes32 evaluationDigest, bytes32 metricsHash, bytes32 evidenceRefsHash)`),b=[...s([`function submitJob(uint64 serviceId, uint8 jobIndex, bytes inputs) payable returns (uint64 callId)`,`function getJobEventRate(uint64 blueprintId, uint8 jobIndex) view returns (uint256 rate)`,`function getServicePaymentAsset(uint64 serviceId) view returns (address)`,`function isPermittedCaller(uint64 serviceId, address caller) view returns (bool)`]),h,g,_,v],x=s([`function authorizeSelf(uint64 serviceId)`,`function revokeSelf(uint64 serviceId)`,`function isDeviceRevoked(address device) view returns (bool)`,`function postStake(uint64 serviceId, uint64 competitionId) payable`,`function stakes(uint64 serviceId, uint64 competitionId, address researcher) view returns (uint256)`,`function pendingResults(uint64 serviceId, uint64 jobCallId) view returns (uint8 job, bytes32 outputHash, uint256 signerBitmap, bool exists, bool executed)`,`function executePendingResult(uint64 serviceId, uint64 jobCallId, bytes output)`,`function acceptedCandidates(uint64 serviceId, uint64 competitionId, address researcher, bytes32 candidateId) view returns (bool)`]),S=s([`function allowance(address owner, address spender) view returns (uint256)`,`function approve(address spender, uint256 amount) returns (bool)`]),C=l(`uint64 competitionId, uint256 stakeWei`),w=l(`uint64 competitionId, bytes32 commitment`),T=l(`uint64 competitionId, bytes32 commitment, string artifactRef, bytes32 salt`),E=l(`string artifactRef, bytes32 salt`),D=l(`uint64 competitionId, bytes32 candidateId, string submissionRef, string evidenceJson, string evidenceRefsJson`),O=l(`string status, string detail`),k=/^0x[0-9a-f]{64}$/i;function A(e,t){if(e!==t)throw Error(`Tempo RPC returned chain ${e}; expected ${t}`)}function j(e,t,n){return{...e,feePayer:!0,nonceKey:t,nonce:n}}function M(e,t){if(e!==`success`)throw Error(`${t} transaction reverted`)}function N(e,t,n,r){if(!k.test(t))throw Error(`${n} transaction hash is invalid`);if(typeof e.transactionHash!=`string`||e.transactionHash.toLowerCase()!==t.toLowerCase())throw Error(`${n} receipt hash does not match the saved transaction`);if(M(e.status??``,n),typeof e.from!=`string`||e.from.toLowerCase()!==r.from.toLowerCase())throw Error(`${n} receipt sender does not match the Solve device`);if(typeof e.to!=`string`||e.to.toLowerCase()!==r.to.toLowerCase())throw Error(`${n} receipt destination does not match the expected contract`)}function P(e,t){return e>=t?[]:e>0n?[0n,t]:[t]}function F(e,t,n=Date.now()){return n>=e+t}function I(e,t){return e.filter(e=>e.args?.candidateId?.toLowerCase()===t.toLowerCase()).at(-1)?.transactionHash}function L(e,t,n,r,a){for(let o of e.logs)if(o.address.toLowerCase()===t.tangleAddress.toLowerCase())try{let e=i({abi:[h],eventName:`JobSubmitted`,data:o.data,topics:o.topics});if(e.args.serviceId===t.serviceId&&e.args.jobIndex===n&&e.args.caller.toLowerCase()===r.toLowerCase()&&(!a||e.args.inputs.toLowerCase()===a.toLowerCase()))return e.args.callId}catch{}throw Error(`Tangle did not emit job ${n} for ${r}`)}function R(e,t,n,r){for(let a of e.logs)if(a.address.toLowerCase()===t.managerAddress.toLowerCase())try{let e=i({abi:[y],eventName:`EvaluationAccepted`,data:a.data,topics:a.topics}).args;if(e.serviceId===t.serviceId&&e.competitionId===t.competitionId&&e.researcher.toLowerCase()===n.address.toLowerCase()&&e.candidateId.toLowerCase()===r.toLowerCase())return!0}catch{}return!1}function z(e){if(e.chainId!==d.id)throw Error(`Solve submissions require Tempo Moderato (chain ${d.id}); received ${e.chainId}`);if(!e.sponsorUrl)throw Error(`Solve submissions require a Tempo sponsor relay URL; unsponsored writes are disabled`);return{...d,name:e.chainName,nativeCurrency:{name:e.nativeSymbol,symbol:e.nativeSymbol,decimals:18},rpcUrls:{default:{http:[e.rpcUrl]}}}}async function B(r,i){e(r);let o=z(r),s=t({chain:o,transport:a(r.rpcUrl)});return A(await s.getChainId(),r.chainId),await V({publicClient:s},r),{publicClient:s,walletClient:n({account:i,chain:o,transport:p(a(r.rpcUrl),a(r.sponsorUrl))}),account:i}}async function V(e,t){let n=await e.publicClient.readContract({address:t.tangleAddress,abi:b,functionName:`getServicePaymentAsset`,args:[t.serviceId]});if(n.toLowerCase()!==t.paymentAsset.toLowerCase())throw Error(`Tempo service payment asset ${n} does not match the trusted Solve asset ${t.paymentAsset}`)}async function H(e,t,n){let[r,i]=await Promise.all([e.publicClient.readContract({address:t.tangleAddress,abi:b,functionName:`getJobEventRate`,args:[t.blueprintId,n]}),e.publicClient.readContract({address:t.tangleAddress,abi:b,functionName:`getServicePaymentAsset`,args:[t.serviceId]})]);if(i.toLowerCase()!==t.paymentAsset.toLowerCase())throw Error(`Tempo job payment asset ${i} does not match the trusted Solve asset ${t.paymentAsset}`);return{asset:i,amount:r,value:i===`0x0000000000000000000000000000000000000000`?r:0n}}async function U(e,t,n){return await e.publicClient.readContract({address:t,abi:S,functionName:`allowance`,args:[e.account.address,n.tangleAddress]})}async function W(e,t,n,i,a,o){let s=Date.now();for(;!F(s,o);){if((await e.publicClient.getLogs({address:t.tangleAddress,event:g,args:{serviceId:t.serviceId,callId:n},fromBlock:i,toBlock:`latest`})).length>0){let o=(await e.publicClient.getLogs({address:t.tangleAddress,event:_,args:{serviceId:t.serviceId,callId:n},fromBlock:i,toBlock:`latest`}))[0]?.args.result;if(!o)throw Error(`Tangle job ${n} completed without a result`);let[s,c]=r(O,o);if(s!==a)throw Error(`Tangle job ${n} ${s}: ${c}`);return{status:s,detail:c}}await new Promise(e=>setTimeout(e,1e3))}throw Error(`Tangle job ${n} did not complete within 120 seconds`)}async function G(e,t,n,r,i){let a=Date.now();for(;!F(a,i);){let i=(await e.publicClient.getLogs({address:t.tangleAddress,event:v,args:{serviceId:t.serviceId,callId:n},fromBlock:r,toBlock:`latest`}))[0]?.args.output;if(i)return i;await new Promise(e=>setTimeout(e,1e3))}throw Error(`Tangle job ${n} did not produce an aggregate within 120 seconds`)}async function K(e,t,n){return!!await e.publicClient.readContract({address:t.managerAddress,abi:x,functionName:`acceptedCandidates`,args:[t.serviceId,t.competitionId,e.account.address,n]})}const q=BigInt(o(u(`tangle.solve.v1`)));async function J(e,t){let n=await f.nonce.getNonce(e.publicClient,{account:e.account.address,nonceKey:q});if(n>BigInt(2**53-1))throw Error(`The Solve transaction nonce exceeds the safe range`);return e.walletClient.writeContract(j(t,q,Number(n)))}async function Y(e,t,n,r){if(!await e.publicClient.readContract({address:t.tangleAddress,abi:b,functionName:`isPermittedCaller`,args:[t.serviceId,e.account.address]}))try{let i=r??await J(e,{address:t.managerAddress,abi:x,functionName:`authorizeSelf`,args:[t.serviceId]});if(r||await n?.(`authorization`,i),N(await e.publicClient.waitForTransactionReceipt({hash:i}),i,`Authorization`,{from:e.account.address,to:t.managerAddress}),!await e.publicClient.readContract({address:t.tangleAddress,abi:b,functionName:`isPermittedCaller`,args:[t.serviceId,e.account.address]}))throw Error(`authorization transaction did not add the device`);return i}catch(e){let t=e instanceof Error?e.message:`unknown chain error`;throw Error(`The competition manager did not authorize this device. The deployed manager must expose authorizeSelf(uint64): ${t}`)}}async function X(e,t){let n=await J(e,{address:t.managerAddress,abi:x,functionName:`revokeSelf`,args:[t.serviceId]});return N(await e.publicClient.waitForTransactionReceipt({hash:n}),n,`Revocation`,{from:e.account.address,to:t.managerAddress}),n}async function Z(e,t,n,r,i=`allowance`,a={}){if(t.amount===0n||t.asset===`0x0000000000000000000000000000000000000000`)return;let o=await U(e,t.asset,n);for(let s of P(o,t.amount)){let o=s===0n?`${i}:reset`:`${i}:approval`,c=a[o];if(c){if(N(await e.publicClient.waitForTransactionReceipt({hash:c}),c,s===0n?`ERC-20 allowance reset`:`ERC-20 allowance approval`,{from:e.account.address,to:t.asset}),await U(e,t.asset,n)!==s)throw Error(`${s===0n?`ERC-20 allowance reset`:`ERC-20 allowance approval`} did not set the expected allowance`);continue}let l=await J(e,{address:t.asset,abi:S,functionName:`approve`,args:[n.tangleAddress,s]});await r?.(o,l),N(await e.publicClient.waitForTransactionReceipt({hash:l}),l,s===0n?`ERC-20 allowance reset`:`ERC-20 allowance approval`,{from:e.account.address,to:t.asset})}}async function Q(e,t,n,r,i,a=`job:${n}`,o={}){let s=await H(e,t,n);await Z(e,s,t,i,`allowance:${a}`,o);let c=o[a],l=c??await J(e,{address:t.tangleAddress,abi:b,functionName:`submitJob`,args:[t.serviceId,n,r],value:s.value});c||await i?.(a,l);let u=await e.publicClient.waitForTransactionReceipt({hash:l});return N(u,l,`Job ${n}`,{from:e.account.address,to:t.tangleAddress}),{hash:l,callId:L(u,t,n,e.account.address,r),blockNumber:u.blockNumber}}async function $(e,t,n,r,i,a,o=`job:${n}`,s={}){let c=await Q(e,t,n,r,a,o,s),l=await W(e,t,c.callId,c.blockNumber,i,m);return{...c,acknowledgement:l}}export{C as _,J as a,T as b,G as c,N as d,F as f,y as g,E as h,Q as i,R as l,w as m,X as n,B as o,m as p,$ as r,K as s,Y as t,I as u,x as v,b as x,D as y};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./deployment-t_Jhgj4Q.mjs";import{createHash as t}from"node:crypto";import*as n from"node:path";import{execFile as r}from"node:child_process";import*as i from"node:fs/promises";import{promisify as a}from"node:util";import{getAddress as o,isAddress as s}from"viem";const c=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;function l(e){return[...e].some(e=>{let t=e.charCodeAt(0);return t<32||t===127})}function u(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`${t} must be an object`);return e}function d(e,t,n=2048){if(typeof e!=`string`||!e.trim()||e.length>n)throw Error(`${t} is missing or invalid`);if(l(e))throw Error(`${t} contains control characters`);return e.trim()}function f(e,t){let n=d(e,t,64).toLowerCase();if(!c.test(n))throw Error(`${t} must be a 40 or 64 character Git revision`);return n}function p(e,t,n=!1){let r=typeof e==`number`&&Number.isSafeInteger(e)?String(e):d(e,t,80);if(!/^\d+$/.test(r)||!n&&r===`0`)throw Error(`${t} must be an unsigned integer`);return BigInt(r).toString()}function m(e,t){let n=d(e,t,2048),r=new URL(n);if(r.protocol!==`https:`&&!(r.protocol===`http:`&&(r.hostname===`localhost`||r.hostname===`127.0.0.1`)))throw Error(`${t} must use HTTPS outside local development`);return n.replace(/\/$/,``)}function h(e,t){let n=m(e,t).replace(/\.git$/,``),r=new URL(n),i=r.pathname.split(`/`).filter(Boolean);if(r.hostname!==`github.com`||r.username||r.password||r.search||r.hash||i.length!==2)throw Error(`${t} must be an HTTPS GitHub repository URL`);return`https://github.com/${i.join(`/`)}`}function g(e,t){let n=d(e,t,42);if(!s(n,{strict:!1}))throw Error(`${t} must be an EVM address`);return o(n)}function _(e,t){let n=p(e,t),r=Number(n);if(!Number.isSafeInteger(r)||r<=0)throw Error(`${t} is out of range`);return r}function v(...e){for(let t of e)if(typeof t==`string`&&t.trim())return t.trim()}function y(e){let t=e.trim().replace(/\.git$/,``);return t.startsWith(`git@github.com:`)?`https://github.com/${t.slice(15)}`:t.startsWith(`ssh://git@github.com/`)?`https://github.com/${t.slice(21)}`:t}function b(e){if(e===void 0)return;let t=d(e,`pull request URL`,2048);if(!/^https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+(?:\/[^\s]*)?$/i.test(t))throw Error(`pull request URL must point to a GitHub pull request`);return t}function x(e,t){if(!/^https:\/\/[^\s]+$/i.test(e)&&!/^\/(?!\/).*$/.test(e)&&!/^[a-z][a-z0-9+.-]*:[^\s]+$/i.test(e))throw Error(`${t} must be an HTTPS URL or an absolute repository path`);if(e.split(/[?#]/,1)[0].split(`/`).includes(`..`))throw Error(`${t} cannot contain parent-directory segments`);return e}function S(e,t){let n=u(t.check??e.check,`competition.participation.check`),r=d(n.command,`competition.participation.check.command`,512);if(!Array.isArray(n.args)||n.args.some(e=>typeof e!=`string`))throw Error(`competition.participation.check.args must be an array of strings`);let i=n.args.map(e=>d(e,`competition checker argument`,2048)),a=v(n.result_file,n.resultFile),o=n.timeout_ms??n.timeoutMs,s=o===void 0?void 0:_(o,`competition checker timeout`);return{command:r,args:i,...a?{result_file:a}:{},...s?{timeout_ms:s}:{}}}function C(e){if(e.provenance===void 0)return;let t=u(e.provenance,`competition.participation.provenance`);if(t.mode!==`github_pull_request`)throw Error(`competition.participation.provenance.mode is unsupported`);if(t.required!==void 0&&typeof t.required!=`boolean`)throw Error(`competition.participation.provenance.required must be a boolean`);return{mode:`github_pull_request`,required:t.required===!0}}function w(t){let n=u(t.chain??t.network??{},`competition.chain`),r=t.rewards&&typeof t.rewards==`object`&&!Array.isArray(t.rewards)?u(t.rewards,`competition.rewards`):{},i=r.minStake&&typeof r.minStake==`object`&&!Array.isArray(r.minStake)?u(r.minStake,`competition.rewards.minStake`).raw:void 0,a=v(n.minStakeWei,n.min_stake_wei,t.minStakeWei,t.min_stake_wei,i),o=n.chainId??n.chain_id??t.chainId??t.chain_id,s=v(n.chainName,n.chain_name,t.chainName,t.chain_name)??`Tempo`,c=v(n.nativeSymbol,n.native_symbol,t.nativeSymbol,t.native_symbol)??`TNT`,l=v(n.rpcUrl,n.rpc_url,t.rpcUrl,t.rpc_url,process.env.TANGLE_SOLVE_RPC_URL),d=v(n.sponsorUrl,n.sponsor_url,t.sponsorUrl,t.sponsor_url,process.env.TANGLE_SOLVE_SPONSOR_URL),f=v(n.tangleAddress,n.tangle_address,n.coreAddress,n.core_address,t.tangleAddress,t.tangle_address,t.coreAddress,t.core_address),h=v(n.managerAddress,n.manager_address,t.managerAddress,t.manager_address),y=v(n.paymentAsset,n.payment_asset,n.servicePaymentAsset,n.service_payment_asset,t.paymentAsset,t.payment_asset,t.servicePaymentAsset,t.service_payment_asset),b=v(n.blueprintId,n.blueprint_id,t.blueprintId,t.blueprint_id),x=v(n.serviceId,n.service_id,t.serviceId,t.service_id),S=v(n.competitionId,n.competition_id,t.competitionId,t.competition_id,t.id);if(!l||!d||!f||!h||!b||!x||!S||!a||o===void 0)throw Error(`Solve competition metadata must include complete Tempo chain configuration`);return{chainId:_(o,`chain.chainId`),chainName:s,nativeSymbol:c,rpcUrl:m(l,`chain.rpcUrl`),sponsorUrl:m(d,`chain.sponsorUrl`),tangleAddress:g(f,`chain.tangleAddress`),managerAddress:g(h,`chain.managerAddress`),paymentAsset:g(y??e.paymentAsset,`chain.paymentAsset`),blueprintId:p(b,`chain.blueprintId`),serviceId:p(x,`chain.serviceId`),competitionId:p(S,`chain.competitionId`,!0),minStakeWei:p(a,`chain.minStakeWei`,!0)}}function T(e){let t=u(e,`competition`),n=u(t.participation??t.task,`competition.task`),r={...t,participation:{...n,...n.repositoryRevision===void 0&&n.revision!==void 0?{repositoryRevision:n.revision}:{}}},i=r.participation,a=h(v(r.repository,r.repo_url,i.repository)??``,`competition.repository`),o=f(v(r.repositoryRevision,r.repository_revision,i.revision,i.repositoryRevision,i.repository_revision),`competition.repositoryRevision`),s=d(r.slug??r.id,`competition.slug`,128),c=d(r.name??r.title??s,`competition.name`,256),l=S(r,i),p=C(i);return{version:1,slug:s,title:c,repository:a,taskRevision:o,checker:l,chain:w(r),...p?{provenance:p}:{}}}function E(e){return{chainId:e.chain.chainId,chainName:e.chain.chainName,nativeSymbol:e.chain.nativeSymbol,rpcUrl:e.chain.rpcUrl,sponsorUrl:e.chain.sponsorUrl,tangleAddress:e.chain.tangleAddress,managerAddress:e.chain.managerAddress,paymentAsset:e.chain.paymentAsset,blueprintId:BigInt(e.chain.blueprintId),serviceId:BigInt(e.chain.serviceId),competitionId:BigInt(e.chain.competitionId),minStakeWei:BigInt(e.chain.minStakeWei)}}async function D(e){let t=u(JSON.parse(await i.readFile(n.join(e,`.tangle-solve.json`),`utf8`)),`.tangle-solve.json`);if(t.version!==1)throw Error(`.tangle-solve.json has an unsupported version`);let r=u(t.checker,`.tangle-solve.json.checker`),a=u(t.chain,`.tangle-solve.json.chain`);return T({slug:t.slug,name:t.title,repository:t.repository,repositoryRevision:t.taskRevision,participation:{check:r,provenance:t.provenance},chain:a,competitionId:a.competitionId})}const O=a(r),k=`.tangle-solve-run.json`,A=`.tangle-solve.json`,j=`tangle.solve.manifestSha256`,M=new Set([A,k]),N=`upstream`;async function P(e,t){let n=await O(`git`,[`-C`,e,...t],{encoding:`utf8`,maxBuffer:1e6});return String(n.stdout).trim()}async function F(e,t){let r=n.resolve(t??process.cwd()),i=await D(r);if(e&&e!==i.slug&&e!==i.chain.competitionId)throw Error(`This directory contains '${i.slug}', not '${e}'`);return{root:r,manifest:i}}async function I(e){let r=n.join(e,A),a;try{a=await i.lstat(r)}catch{throw Error(`${A} is missing`)}if(a.isSymbolicLink()||!a.isFile())throw Error(`${A} must be a regular file`);return t(`sha256`).update(await i.readFile(r)).digest(`hex`)}async function L(e){let t=await I(e);return await P(e,[`config`,`--local`,`--replace-all`,j,t]),t}async function R(e){let t;try{t=await P(e,[`config`,`--local`,`--get`,j])}catch{throw Error(`The local Git metadata has no ${j} pin; run tangle solve clone again`)}if(!/^[0-9a-f]{64}$/i.test(t))throw Error(`The local ${j} pin is invalid`);if(await I(e)!==t.toLowerCase())throw Error(`${A} changed after clone; run tangle solve clone again`)}async function z(e,t){try{return await P(e,[`ls-files`,`--error-unmatch`,`--`,t]),!0}catch{return!1}}async function B(e){await R(e);for(let t of M)if(await z(e,t))throw Error(`${t} must remain untracked and local to this Solve workspace`);let t=await O(`git`,[`-C`,e,`status`,`--porcelain=v1`,`--untracked-files=all`,`--ignored=matching`],{encoding:`utf8`,maxBuffer:1e6});if(String(t.stdout).split(/\r?\n/).filter(Boolean).filter(e=>{let t=e.slice(0,2),n=e.slice(3);return!((t===`??`||t===`!!`)&&M.has(n))}).length>0)throw Error(`Commit the candidate before running Solve. Only the local manifest and run record may remain uncommitted.`);return f(await P(e,[`rev-parse`,`HEAD`]),`submission revision`)}async function V(e,t,n,r={}){let i=await H(e,t,r);if(i)return{taskRepository:t.repository,taskRevision:t.taskRevision,submissionRepository:i,submissionRevision:n}}async function H(e,t,n={}){let r;try{r=y(await P(e,[`config`,`--get`,`remote.origin.pushurl`]))}catch{try{r=y(await P(e,[`config`,`--get`,`remote.origin.url`]))}catch{if(n.allowMissing)return;throw Error(`Add your GitHub fork as the 'origin' remote before submitting. The task repository is available as '${N}'.`)}}let i=h(r,`git remote.origin.url`);if(i.toLowerCase()===t.repository.toLowerCase()){if(n.allowMissing)return;throw Error(`The 'origin' remote is the task repository. Add your GitHub fork as 'origin'; keep the task repository as '${N}' before submitting.`)}return i}function U(e,t){return!e||!t?!1:e.taskRepository.toLowerCase()===t.taskRepository.toLowerCase()&&e.taskRevision.toLowerCase()===t.taskRevision.toLowerCase()&&e.submissionRepository.toLowerCase()===t.submissionRepository.toLowerCase()&&e.submissionRevision.toLowerCase()===t.submissionRevision.toLowerCase()}function W(e,t){return`${e}/commit/${t}`}function G(e,t,n,r,i={}){let a=e.evidenceRefs.map(e=>x(e.trim(),`checker evidence reference`));if(n){if(!t){if(i.allowMissingSource)return{evidence:e.evidence,evidenceRefs:a};throw Error(`Provenance policy requires a submission source`)}let o=b(r);if(n.required&&(i.requirePullRequest??!0)&&!o)throw Error(`This competition requires a GitHub pull request`);a.push(W(t.taskRepository,t.taskRevision),W(t.submissionRepository,t.submissionRevision),...o?[o]:[])}return{evidence:e.evidence,evidenceRefs:[...new Set(a)]}}async function K(e,t){let n=`${e}.${process.pid}.tmp`;await i.writeFile(n,`${JSON.stringify(t,null,2)}\n`,{mode:384}),await i.rename(n,e)}async function q(e){let t=JSON.parse(await i.readFile(n.join(e,k),`utf8`));if(t.version!==1||typeof t.competition!=`string`)throw Error(`${k} has an unsupported format`);return t}async function J(e){let t=b(e.pullRequest);if(!t)throw Error(`A pull request URL is required`);let n=new URL(t).pathname.split(`/`).filter(Boolean),r=await fetch(`https://api.github.com/repos/${n[0]}/${n[1]}/pulls/${n[3]}`,{headers:{Accept:`application/vnd.github+json`,"User-Agent":`tangle-solve-cli`},signal:AbortSignal.timeout(15e3)}),i=await r.json().catch(()=>null),a=e=>e.replace(/\/$/,``).toLowerCase();if(!r.ok||a(i?.base?.repo?.html_url??``)!==a(e.taskRepository)||i?.head?.sha?.toLowerCase()!==e.submissionRevision.toLowerCase()||a(i?.head?.repo?.html_url??``)!==a(e.submissionRepository))throw Error(`GitHub pull request must target the pinned task repository and contain the current committed submission`)}function Y(e){return{...e.authorization?{authorization:e.authorization}:{},...e.stake?{stake:e.stake}:{},join:e.join,commit:e.commit,reveal:e.reveal,report:e.report,evaluation:e.evaluation}}export{q as a,V as c,J as d,K as f,u as g,b as h,L as i,U as l,E as m,G as n,B as o,T as p,P as r,F as s,N as t,Y as u};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-cli",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.114",
|
|
4
4
|
"description": "CLI for Tangle Sandbox operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"tsx": "^4.23.15",
|
|
61
61
|
"typescript": "^6.0.3",
|
|
62
62
|
"vitest": "^4.1.12",
|
|
63
|
-
"@repo/shared": "0.0.0",
|
|
64
|
-
"@repo/knowledge-host": "0.0.0",
|
|
65
63
|
"@tangle-network/runtime-contracts": "0.20.0",
|
|
64
|
+
"@repo/knowledge-host": "0.0.0",
|
|
65
|
+
"@repo/shared": "0.0.0",
|
|
66
66
|
"@tangle-network/sdk-session-persistence": "0.7.0"
|
|
67
67
|
},
|
|
68
68
|
"publishConfig": {
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"author": "Tangle Network",
|
|
88
88
|
"license": "MIT",
|
|
89
89
|
"tangleRelease": {
|
|
90
|
-
"sourceSha": "
|
|
91
|
-
"mergedAt": "2026-11-
|
|
90
|
+
"sourceSha": "5d9c01624cc209174cf7210a1422ae80f8d48069",
|
|
91
|
+
"mergedAt": "2026-11-12T22:39:54-08:00"
|
|
92
92
|
},
|
|
93
93
|
"scripts": {
|
|
94
94
|
"build": "tsdown",
|
|
File without changes
|