Registration of job #182232 read at #5082788
E·7de6e41397
Artifact retrieval for job #182232. An immutable observation by ✦peer-712d55 at 26 Oct 20:20 UTC: chain data, retrieval provenance and exact source spans are retained without executing source.
{
"evidence": {
"artifact_bytes": 474213,
"artifact_sha256": "4248025fd94f7f2263528b83e4b05ae68bd5a3991d953937dc90f0ee06dd234b",
"cid_verified": false,
"files": [
{
"bytes": 1740449,
"name": "bundle.js",
"sha256": "1d4c2ad4c304621d219f2c23818cd56f4f0dc94469131c4ccecf5bb10dc0a591",
"text": "// This file is compiled to devtools-snippet.js and injected at the beginning\n// of user scripts when enableDevtools is true. It overrides console methods to\n// forward logs to the Acurast DevTools API.\n//\n// Placeholder https://api.devtools.acurast.com is replaced at injection time.\n;\n(() => {\n const DEVTOOLS_API_URL = 'https://api.devtools.acurast.com';\n const originalConsole = {\n log: console.log,\n warn: console.warn,\n error: console.error,\n info: console.info,\n debug: console.debug,\n };\n // --- Auth: obtain a Bearer token from the devtools API ---\n let apiKey = null;\n const pendingLogs = []; // buffered payloads while awaiting auth\n const toHex = (str) => {\n let hex = '';\n for (let i = 0; i < str.length; i++) {\n hex += str.charCodeAt(i).toString(16).padStart(2, '0');\n }\n return hex;\n };\n const sendBuffered = () => {\n for (const body of pendingLogs.splice(0)) {\n httpPOST(`${DEVTOOLS_API_URL}/v1/logs`, body, { 'Content-Type': 'application/json', Authorization: 'Bearer ' + apiKey }, () => { }, (error) => {\n originalConsole.error('[devtools] buffered log post failed:', error);\n });\n }\n };\n try {\n // The full \"origin:owner:number\" deployment id. The API needs the owner to\n // find the job on chain: job storage is keyed by (origin, number) under a\n // one-way hasher, so a bare number cannot be resolved there.\n const rawId = _STD_.job.getId();\n const jobNumber = String(rawId.id);\n const origin = rawId.origin;\n const jobId = origin && origin.kind && origin.source\n ? origin.kind + ':' + origin.source + ':' + jobNumber\n : jobNumber;\n const processorAddress = _STD_.device.getAddress();\n const pubKeyHex = _STD_.job.getPublicKeys().ed25519;\n const timestamp = String(Math.floor(Date.now() / 1000));\n // Bound to the deployment so a captured signature cannot be reused against\n // another job.\n const message = pubKeyHex + ':' + jobId + ':' + timestamp;\n const messageHex = toHex(message);\n const signatureHex = _STD_.signers.ed25519.sign(messageHex);\n httpPOST(`${DEVTOOLS_API_URL}/v1/auth/api-key`, JSON.stringify({ jobId, processorAddress }), {\n 'Content-Type': 'application/json',\n 'X-Signature': signatureHex,\n 'X-PublicKey': pubKeyHex,\n 'X-Timestamp': timestamp,\n }, (response, _certificate) => {\n try {\n const parsed = JSON.parse(response);\n apiKey = parsed.apiKey;\n sendBuffered();\n }\n catch (_e) {\n originalConsole.error('[devtools] failed to parse auth response:', response);\n }\n }, (error) => {\n originalConsole.error('[devtools] auth failed:', error);\n });\n }\n catch (e) {\n originalConsole.error('[devtools] auth setup failed:', e?.message ?? String(e));\n }\n // --- Rate limiting ---\n const RATE_LIMIT_MAX = 20;\n const RATE_LIMIT_WINDOW_MS = 10000;\n let rateBucketStart = Date.now();\n let rateBucketCount = 0;\n let dropped = 0;\n const sendLog = (level, args) => {\n const now = Date.now();\n if (now - rateBucketStart >= RATE_LIMIT_WINDOW_MS) {\n if (dropped > 0) {\n enqueue([\n {\n type: 'warn',\n data: `[devtools] rate limit ended: ${dropped} log(s) were dropped`,\n timestamp: now,\n },\n ]);\n }\n rateBucketStart = now;\n rateBucketCount = 0;\n dropped = 0;\n }\n if (rateBucketCount >= RATE_LIMIT_MAX) {\n dropped++;\n return;\n }\n rateBucketCount++;\n try {\n const data = args.length === 1 ? args[0] : args;\n let serializable;\n try {\n JSON.stringify(data);\n serializable = data;\n }\n catch {\n serializable = String(data);\n }\n enqueue([{ type: level, data: serializable, timestamp: now }]);\n }\n catch (_e) {\n // Silently ignore serialization errors to avoid breaking user scripts\n }\n };\n const enqueue = (entries) => {\n const body = JSON.stringify(entries);\n if (apiKey) {\n httpPOST(`${DEVTOOLS_API_URL}/v1/logs`, body, { 'Content-Type': 'application/json', Authorization: 'Bearer ' + apiKey }, () => { }, (error) => {\n originalConsole.error('[devtools] log post failed:', error);\n });\n }\n else {\n pendingLogs.push(body);\n }\n };\n // --- File upload via /v1/files ---\n const uploadFile = (filename, content, mimeType, onSuccess, onError) => {\n if (!apiKey) {\n onError('[devtools] file upload failed: not authenticated yet');\n return;\n }\n // The processor's httpPOST JSON-parses the body regardless of Content-Type,\n // so we cannot send multipart/form-data through it. Use fetch + FormData\n // instead — fetch sets the Content-Type header (with boundary) automatically.\n const formData = new FormData();\n formData.append('file', new Blob([content], { type: mimeType }), filename);\n fetch(`${DEVTOOLS_API_URL}/v1/files`, {\n method: 'POST',\n headers: { Authorization: 'Bearer ' + apiKey },\n body: formData,\n })\n .then((res) => res.text().then((text) => ({ ok: res.ok, status: res.status, text })))\n .then(({ ok, status, text }) => {\n if (!ok) {\n onError('[devtools] file upload failed: HTTP ' + status + ' ' + text);\n return;\n }\n try {\n onSuccess(JSON.parse(text));\n }\n catch (_e) {\n onError('[devtools] failed to parse upload response: ' + text);\n }\n })\n .catch((err) => {\n onError('[devtools] file upload failed: ' + (err?.message ?? String(err)));\n });\n };\n globalThis._DEVTOOLS_ = { uploadFile };\n for (const level of Object.keys(originalConsole)) {\n ;\n console[level] = (...args) => {\n originalConsole[level](...args);\n sendLog(level, args);\n };\n }\n})();\nconst __import_meta_url=require('url').pathToFileURL(__filename).href;\n\"use strict\";var Nj=Object.create;var pE=Object.defineProperty;var Bj=Object.getOwnPropertyDescriptor;var Dj=Object.getOwnPropertyNames;var Lj=Object.getPrototypeOf,Uj=Object.prototype.hasOwnProperty;var ae=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Pe=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},Zb=(e,t)=>{for(var n in t)pE(e,n,{get:t[n],enumerable:!0})},Fj=(e,t,n,r)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let i of Dj(t))!Uj.call(e,i)&&i!==n&&pE(e,i,{get:()=>t[i],enumerable:!(r=Bj(t,i))||r.enumerable});return e};var Mh=(e,t,n)=>(n=e!=null?Nj(Lj(e)):{},Fj(t||!e||!e.__esModule?pE(n,\"default\",{value:e,enumerable:!0}):n,e));var d3,l3=ae(()=>{d3=\"1.2.3\"});var Hn,cp=ae(()=>{l3();Hn=class e extends Error{constructor(t,n={}){let r=n.cause instanceof e?n.cause.details:n.cause?.message?n.cause.message:n.details,i=n.cause instanceof e&&n.cause.docsPath||n.docsPath,o=[t||\"An error occurred.\",\"\",...n.metaMessages?[...n.metaMessages,\"\"]:[],...i?[`Docs: https://abitype.dev${i}`]:[],...r?[`Details: ${r}`]:[],`Version: abitype@${d3}`].join(`\n`);super(o),Object.defineProperty(this,\"details\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"docsPath\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"metaMessages\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,\"shortMessage\",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProper",
"truncated": true
},
{
"bytes": 77,
"name": "manifest.json",
"sha256": "981478369204b4991fc02966ebf88fc709c7bb9fade101070af735c952ad283c",
"text": "",
"truncated": true
}
],
"image_url": null,
"job": {
"job_id": "acurast:5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf:182232",
"observed_block": "0xe5c1731a22ed890d54996b5833a0c3e564875d357c50324a1095a34dc329e4e2",
"script_uri": "ipfs://Qme9GoisBuqubeX18cmwXRnhaPZksmzpH98nmRGmeYiS1e"
},
"kind": "cargo_zip"
},
"identity": {
"address": "5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf",
"address_hex": "0x706ff1ac5451a8123234c97e3ae8bd19c687992d501d26ea72216f03e5bcdf49",
"id": "acurast:5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf:182232",
"origin_variant": "Acurast",
"sequence": "182232"
},
"outcome": "retrieved",
"registration_id": "r:o:7de6e413978ce8ae8698dc36f73208437d37dbc34a8b8a1fcee4e96730acff35",
"retrieval": {
"cid_verified": false,
"downloaded_bytes": 474213,
"downloaded_sha256": "4248025fd94f7f2263528b83e4b05ae68bd5a3991d953937dc90f0ee06dd234b",
"failures": [],
"gateway_index": 0,
"inspection_error": null,
"retrieved_at_ms": 1793046018605,
"state": "retrieved",
"trust": "trusted gateway; UnixFS root not independently verified"
},
"type": "artifact"
}Configured RPC responses are not independently storage-proof verified. Reported outcomes retain their reported semantics. Only successfully covered history ranges support absence claims.
Registration of job #182232 read at #5082788
E·7de6e41397
1740449 bytes · SHA-256 1d4c2ad4c304621d219f2c23818cd56f4f0dc94469131c4ccecf5bb10dc0a591
// This file is compiled to devtools-snippet.js and injected at the beginning
// of user scripts when enableDevtools is true. It overrides console methods to
// forward logs to the Acurast DevTools API.
//
// Placeholder https://api.devtools.acurast.com is replaced at injection time.
;
(() => {
const DEVTOOLS_API_URL = 'https://api.devtools.acurast.com';
const originalConsole = {
log: console.log,
warn: console.warn,
error: console.error,
info: console.info,
debug: console.debug,
};
// --- Auth: obtain a Bearer token from the devtools API ---
let apiKey = null;
const pendingLogs = []; // buffered payloads while awaiting auth
const toHex = (str) => {
let hex = '';
for (let i = 0; i < str.length; i++) {
hex += str.charCodeAt(i).toString(16).padStart(2, '0');
}
return hex;
};
const sendBuffered = () => {
for (const body of pendingLogs.splice(0)) {
httpPOST(`${DEVTOOLS_API_URL}/v1/logs`, body, { 'Content-Type': 'application/json', Authorization: 'Bearer ' + apiKey }, () => { }, (error) => {
originalConsole.error('[devtools] buffered log post failed:', error);
});
}
};
try {
// The full "origin:owner:number" deployment id. The API needs the owner to
// find the job on chain: job storage is keyed by (origin, number) under a
// one-way hasher, so a bare number cannot be resolved there.
const rawId = _STD_.job.getId();
const jobNumber = String(rawId.id);
const origin = rawId.origin;
const jobId = origin && origin.kind && origin.source
? origin.kind + ':' + origin.source + ':' + jobNumber
: jobNumber;
const processorAddress = _STD_.device.getAddress();
const pubKeyHex = _STD_.job.getPublicKeys().ed25519;
const timestamp = String(Math.floor(Date.now() / 1000));
// Bound to the deployment so a captured signature cannot be reused against
// another job.
const message = pubKeyHex + ':' + jobId + ':' + timestamp;
const messageHex = toHex(message);
const signatureHex = _STD_.signers.ed25519.sign(messageHex);
httpPOST(`${DEVTOOLS_API_URL}/v1/auth/api-key`, JSON.stringify({ jobId, processorAddress }), {
'Content-Type': 'application/json',
'X-Signature': signatureHex,
'X-PublicKey': pubKeyHex,
'X-Timestamp': timestamp,
}, (response, _certificate) => {
try {
const parsed = JSON.parse(response);
apiKey = parsed.apiKey;
sendBuffered();
}
catch (_e) {
originalConsole.error('[devtools] failed to parse auth response:', response);
}
}, (error) => {
originalConsole.error('[devtools] auth failed:', error);
});
}
catch (e) {
originalConsole.error('[devtools] auth setup failed:', e?.message ?? String(e));
}
// --- Rate limiting ---
const RATE_LIMIT_MAX = 20;
const RATE_LIMIT_WINDOW_MS = 10000;
let rateBucketStart = Date.now();
let rateBucketCount = 0;
let dropped = 0;
const sendLog = (level, args) => {
const now = Date.now();
if (now - rateBucketStart >= RATE_LIMIT_WINDOW_MS) {
if (dropped > 0) {
enqueue([
{
type: 'warn',
data: `[devtools] rate limit ended: ${dropped} log(s) were dropped`,
timestamp: now,
},
]);
}
rateBucketStart = now;
rateBucketCount = 0;
dropped = 0;
}
if (rateBucketCount >= RATE_LIMIT_MAX) {
dropped++;
return;
}
rateBucketCount++;
try {
const data = args.length === 1 ? args[0] : args;
let serializable;
try {
JSON.stringify(data);
serializable = data;
}
catch {
serializable = String(data);
}
enqueue([{ type: level, data: serializable, timestamp: now }]);
}
catch (_e) {
// Silently ignore serialization errors to avoid breaking user scripts
}
};
const enqueue = (entries) => {
const body = JSON.stringify(entries);
if (apiKey) {
httpPOST(`${DEVTOOLS_API_URL}/v1/logs`, body, { 'Content-Type': 'application/json', Authorization: 'Bearer ' + apiKey }, () => { }, (error) => {
originalConsole.error('[devtools] log post failed:', error);
});
}
else {
pendingLogs.push(body);
}
};
// --- File upload via /v1/files ---
const uploadFile = (filename, content, mimeType, onSuccess, onError) => {
if (!apiKey) {
onError('[devtools] file upload failed: not authenticated yet');
return;
}
// The processor's httpPOST JSON-parses the body regardless of Content-Type,
// so we cannot send multipart/form-data through it. Use fetch + FormData
// instead — fetch sets the Content-Type header (with boundary) automatically.
const formData = new FormData();
formData.append('file', new Blob([content], { type: mimeType }), filename);
fetch(`${DEVTOOLS_API_URL}/v1/files`, {
method: 'POST',
headers: { Authorization: 'Bearer ' + apiKey },
body: formData,
})
.then((res) => res.text().then((text) => ({ ok: res.ok, status: res.status, text })))
.then(({ ok, status, text }) => {
if (!ok) {
onError('[devtools] file upload failed: HTTP ' + status + ' ' + text);
return;
}
try {
onSuccess(JSON.parse(text));
}
catch (_e) {
onError('[devtools] failed to parse upload response: ' + text);
}
})
.catch((err) => {
onError('[devtools] file upload failed: ' + (err?.message ?? String(err)));
});
};
globalThis._DEVTOOLS_ = { uploadFile };
for (const level of Object.keys(originalConsole)) {
;
console[level] = (...args) => {
originalConsole[level](...args);
sendLog(level, args);
};
}
})();
const __import_meta_url=require('url').pathToFileURL(__filename).href;
"use strict";var Nj=Object.create;var pE=Object.defineProperty;var Bj=Object.getOwnPropertyDescriptor;var Dj=Object.getOwnPropertyNames;var Lj=Object.getPrototypeOf,Uj=Object.prototype.hasOwnProperty;var ae=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var Pe=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(n){throw t=0,n}},Zb=(e,t)=>{for(var n in t)pE(e,n,{get:t[n],enumerable:!0})},Fj=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Dj(t))!Uj.call(e,i)&&i!==n&&pE(e,i,{get:()=>t[i],enumerable:!(r=Bj(t,i))||r.enumerable});return e};var Mh=(e,t,n)=>(n=e!=null?Nj(Lj(e)):{},Fj(t||!e||!e.__esModule?pE(n,"default",{value:e,enumerable:!0}):n,e));var d3,l3=ae(()=>{d3="1.2.3"});var Hn,cp=ae(()=>{l3();Hn=class e extends Error{constructor(t,n={}){let r=n.cause instanceof e?n.cause.details:n.cause?.message?n.cause.message:n.details,i=n.cause instanceof e&&n.cause.docsPath||n.docsPath,o=[t||"An error occurred.","",...n.metaMessages?[...n.metaMessages,""]:[],...i?[`Docs: https://abitype.dev${i}`]:[],...r?[`Details: ${r}`]:[],`Version: abitype@${d3}`].join(`
`);super(o),Object.defineProperty(this,"details",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"docsPath",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"metaMessages",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"shortMessage",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProper
Preview truncated.
77 bytes · SHA-256 981478369204b4991fc02966ebf88fc709c7bb9fade101070af735c952ad283c
Preview truncated.
The artifact script and block came from its linked finalized registration observation. Historical execution is a separate observation.
Available on peer-f0c48a.
No successful sync reported.
A sync timestamp does not confirm remote copies of this object.