Registration of job #188207 read at #5065796
E·19e216717b
Artifact retrieval for job #188207. An immutable observation by ✦peer-d62476 at 25 Oct 15:26 UTC: chain data, retrieval provenance and exact source spans are retained without executing source.
{
"evidence": {
"artifact_bytes": 474665,
"artifact_sha256": "cfe49b66de4d39a1cfdbe07c7a9ac1c9a554700700af8f455b27a2baa51507e9",
"cid_verified": false,
"files": [
{
"bytes": 1741531,
"name": "bundle.js",
"sha256": "e781cfe7c0df9d37837dbd450743ff9b0f64019ede5c87f9ff5dbeec30efaaae",
"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 qj=Object.create;var fE=Object.defineProperty;var $j=Object.getOwnPropertyDescriptor;var zj=Object.getOwnPropertyNames;var jj=Object.getPrototypeOf,Vj=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}},Xb=(e,t)=>{for(var n in t)fE(e,n,{get:t[n],enumerable:!0})},Gj=(e,t,n,r)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let i of zj(t))!Vj.call(e,i)&&i!==n&&fE(e,i,{get:()=>t[i],enumerable:!(r=$j(t,i))||r.enumerable});return e};var Nh=(e,t,n)=>(n=e!=null?qj(jj(e)):{},Gj(t||!e||!e.__esModule?fE(n,\"default\",{value:e,enumerable:!0}):n,e));var p3,f3=ae(()=>{p3=\"1.2.3\"});var qn,up=ae(()=>{f3();qn=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@${p3}`].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": "484844f77c6a22d7b0462d221d54d73f1c7e25cab3c734a4ae3b8d622d3f8580",
"text": "",
"truncated": true
}
],
"image_url": null,
"job": {
"job_id": "acurast:5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf:188207",
"observed_block": "0xe23de5a207a7e68eddbd2f027136b49c1d460859f328706ad7fdd317dcb9d87d",
"script_uri": "ipfs://QmWMdJo9ucZNaUfwbnXCLgKASMh43X8he2TtjJarunFqPp"
},
"kind": "cargo_zip"
},
"identity": {
"address": "5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf",
"address_hex": "0x706ff1ac5451a8123234c97e3ae8bd19c687992d501d26ea72216f03e5bcdf49",
"id": "acurast:5Ec8UUiMN3F4bd9TzZrYS378dSdCz3FfqaUMcpowHeHyKSpf:188207",
"origin_variant": "Acurast",
"sequence": "188207"
},
"outcome": "retrieved",
"registration_id": "r:o:19e216717b74876285d14794e3a88ef015440770423340f2a927397427d41c9c",
"retrieval": {
"cid_verified": false,
"downloaded_bytes": 474665,
"downloaded_sha256": "cfe49b66de4d39a1cfdbe07c7a9ac1c9a554700700af8f455b27a2baa51507e9",
"failures": [],
"gateway_index": 0,
"inspection_error": null,
"retrieved_at_ms": 1792941989666,
"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 #188207 read at #5065796
E·19e216717b
1741531 bytes · SHA-256 e781cfe7c0df9d37837dbd450743ff9b0f64019ede5c87f9ff5dbeec30efaaae
// 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 qj=Object.create;var fE=Object.defineProperty;var $j=Object.getOwnPropertyDescriptor;var zj=Object.getOwnPropertyNames;var jj=Object.getPrototypeOf,Vj=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}},Xb=(e,t)=>{for(var n in t)fE(e,n,{get:t[n],enumerable:!0})},Gj=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of zj(t))!Vj.call(e,i)&&i!==n&&fE(e,i,{get:()=>t[i],enumerable:!(r=$j(t,i))||r.enumerable});return e};var Nh=(e,t,n)=>(n=e!=null?qj(jj(e)):{},Gj(t||!e||!e.__esModule?fE(n,"default",{value:e,enumerable:!0}):n,e));var p3,f3=ae(()=>{p3="1.2.3"});var qn,up=ae(()=>{f3();qn=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@${p3}`].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 484844f77c6a22d7b0462d221d54d73f1c7e25cab3c734a4ae3b8d622d3f8580
Preview truncated.
The artifact script and block came from its linked finalized registration observation. Historical execution is a separate observation.
Available on peer-32d6ae.
No successful sync reported.
A sync timestamp does not confirm remote copies of this object.