@ethernity-cloud/sdk-js 1.7.0 → 1.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -50
- package/cas/config.js +6 -6
- package/cas/resolver.js +49 -18
- package/cas/session_registry.js +72 -24
- package/info.js +1 -1
- package/init.js +17 -2
- package/localKubo.js +160 -0
- package/network.js +51 -0
- package/nodenithy/build/securelock/src/etny_crypto.js +20 -2
- package/nodenithy/build/securelock/src/models.js +3 -5
- package/nodenithy/build/securelock/src/securelock.js.tmpl +136 -70
- package/nodenithy/build.mjs +8 -7
- package/nodenithy/ipfs.mjs +37 -13
- package/nodenithy/run/image_registry.abi +1 -1
- package/nodenithy/run/image_registry.js +258 -68
- package/nodenithy/run/public_key_service.js +10 -3
- package/nodenithy/run/public_key_service.py +12 -6
- package/nodenithy/run.js +160 -88
- package/nodenithy/src/ec_helloworld_example.js +46 -42
- package/nodenithy/src/preStart.mjs +41 -51
- package/package.json +5 -2
- package/publish.js +20 -8
- package/pynithy/build/securelock/src/securelock.py.tmpl +21 -9
- package/pynithy/build.mjs +8 -7
- package/pynithy/ipfs.mjs +37 -13
- package/pynithy/run/image_registry.abi +1 -1
- package/pynithy/run/image_registry.js +258 -68
- package/pynithy/run/public_key_service.js +10 -3
- package/pynithy/run.js +160 -88
- package/pynithy/src/ec_helloworld_example.js +46 -42
- package/pynithy/src/preStart.mjs +41 -51
- package/revert.js +76 -0
- package/run.js +1 -39
- package/nodenithy/src/preStart.js +0 -45
package/publish.js
CHANGED
|
@@ -46,6 +46,10 @@ async function prompt(question) {
|
|
|
46
46
|
const { PROJECT_NAME, BLOCKCHAIN_NETWORK, PRIVATE_KEY, DEVELOPER_FEE, SERVICE_TYPE } = process.env;
|
|
47
47
|
const scriptPath = path.resolve(__dirname, 'nodenithy/run/image_registry.js');
|
|
48
48
|
process.env.NODE_NO_WARNINGS = 1
|
|
49
|
+
// image_registry.js reads the wallet's key from PRIVATE_KEY in its
|
|
50
|
+
// environment, never from its command line.
|
|
51
|
+
const registry = (args, privateKey) => execSync(`node ${scriptPath} ${args}`,
|
|
52
|
+
{ env: { ...process.env, PRIVATE_KEY: privateKey } }).toString().trim();
|
|
49
53
|
let result = '';
|
|
50
54
|
if (!PROJECT_NAME || !BLOCKCHAIN_NETWORK || !PRIVATE_KEY || !DEVELOPER_FEE) {
|
|
51
55
|
const hasWallet = await prompt('Do you have an existing wallet? (yes/no) (default value: no) ') || 'no';
|
|
@@ -57,12 +61,12 @@ async function prompt(question) {
|
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
let privateKey = await prompt('Enter your private key: ');
|
|
60
|
-
result =
|
|
64
|
+
result = registry('"" "" "" "validateAddress"', privateKey);
|
|
61
65
|
|
|
62
66
|
while (result !== 'OK') {
|
|
63
67
|
console.log(result);
|
|
64
68
|
privateKey = await prompt('Invalid private key. Please enter a valid private key: ');
|
|
65
|
-
result =
|
|
69
|
+
result = registry('"" "" "" "validateAddress"', privateKey);
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
console.log('Inputted Private key is valid.');
|
|
@@ -70,32 +74,40 @@ async function prompt(question) {
|
|
|
70
74
|
console.log()
|
|
71
75
|
console.log('Checking blockchain for required funds...');
|
|
72
76
|
|
|
73
|
-
result =
|
|
77
|
+
result = registry('"" "" "" "checkBalance"', privateKey);
|
|
74
78
|
|
|
75
79
|
console.log(`Available funds: ${result}`);
|
|
76
80
|
console.log()
|
|
77
81
|
const imageName = casConfig.nameOnNetwork(PROJECT_NAME, BLOCKCHAIN_NETWORK);
|
|
78
82
|
console.log(`Checking if project name ${imageName} is available on ${BLOCKCHAIN_NETWORK} network and ownership...`);
|
|
79
|
-
|
|
83
|
+
// Exits 1, with the owner, when another wallet owns the name.
|
|
84
|
+
try {
|
|
85
|
+
result = registry(`${BLOCKCHAIN_NETWORK} ${imageName} ${process.env.VERSION}`, privateKey);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.log((e.stdout || '').toString().trim());
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
80
90
|
console.log(result);
|
|
81
91
|
console.log()
|
|
82
92
|
|
|
83
|
-
|
|
93
|
+
// The publisher's fee, in percent of each task's base price: PoX adds it
|
|
94
|
+
// to what the dApp user pays and pays it to the image's reward address.
|
|
95
|
+
const taskPercentage = await prompt('Your fee as the publisher of this image, in % of each task\'s base price, 0 to 15 (default 0): ') || '0';
|
|
84
96
|
writeEnv('DEVELOPER_FEE', taskPercentage);
|
|
85
97
|
} else {
|
|
86
98
|
console.log('Using PROJECT_NAME, BLOCKCHAIN_NETWORK, PRIVATE_KEY, DEVELOPER_FEE from .env');
|
|
87
99
|
console.log('Checking blockchain for required funds...');
|
|
88
|
-
result =
|
|
100
|
+
result = registry('"" "" "" "checkBalance"', PRIVATE_KEY);
|
|
89
101
|
|
|
90
102
|
console.log(`Available funds: ${result}`);
|
|
91
103
|
console.log()
|
|
92
104
|
let privateKey = PRIVATE_KEY;
|
|
93
|
-
result =
|
|
105
|
+
result = registry('"" "" "" "validateAddress"', privateKey);
|
|
94
106
|
|
|
95
107
|
while (result !== 'OK') {
|
|
96
108
|
console.log(result);
|
|
97
109
|
privateKey = await prompt('Invalid private key. Please enter a valid private key: ');
|
|
98
|
-
result =
|
|
110
|
+
result = registry('"" "" "" "validateAddress"', privateKey);
|
|
99
111
|
}
|
|
100
112
|
writeEnv('PRIVATE_KEY', privateKey);
|
|
101
113
|
}
|
|
@@ -149,6 +149,16 @@ class EtnySecureLock:
|
|
|
149
149
|
logging.info("Generated key and cert in memory based on MR_ENCLAVE")
|
|
150
150
|
return private_key_pem, cert_pem
|
|
151
151
|
|
|
152
|
+
# The node-supplied bucket .env may only contribute the per-task order id.
|
|
153
|
+
# Everything else the securelock trusts is a per-network build constant
|
|
154
|
+
# (chain id, PoX contract, Image Registry, Web3 provider, ValidatorRegistry,
|
|
155
|
+
# bucket) set in __set_initializers, or a variable the CAS injects into the
|
|
156
|
+
# enclave process environment (ECAS_*, SCONE_*). Any key outside this set,
|
|
157
|
+
# and any key already present in the environment, is ignored.
|
|
158
|
+
NODE_ENV_ALLOWLIST = frozenset({
|
|
159
|
+
'ETNY_ORDER_ID',
|
|
160
|
+
})
|
|
161
|
+
|
|
152
162
|
@staticmethod
|
|
153
163
|
def read_env_str(env_str: str):
|
|
154
164
|
with io.StringIO(env_str) as f:
|
|
@@ -156,7 +166,13 @@ class EtnySecureLock:
|
|
|
156
166
|
if '=' not in line:
|
|
157
167
|
continue
|
|
158
168
|
key, value = line.split('=', 1)
|
|
159
|
-
|
|
169
|
+
key = key.strip()
|
|
170
|
+
if key not in EtnySecureLock.NODE_ENV_ALLOWLIST:
|
|
171
|
+
logging.info(f"Ignoring non-allowlisted .env key from the node bucket: {key}")
|
|
172
|
+
continue
|
|
173
|
+
if key in os.environ:
|
|
174
|
+
continue
|
|
175
|
+
os.environ[key] = re.sub(r'\n', '', value.strip())
|
|
160
176
|
def validate_client_payload(self):
|
|
161
177
|
payload_data = self.__get_file_content_and_decrypt(self.payload)
|
|
162
178
|
input_data = self.__get_file_content_and_decrypt(self.input)
|
|
@@ -588,14 +604,10 @@ class EtnySecureLock:
|
|
|
588
604
|
with open(path, 'r') as f:
|
|
589
605
|
return f.read()
|
|
590
606
|
def __load_env(self):
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if os.getenv('ETNY_WEB3_PROVIDER'):
|
|
596
|
-
self.web3_provider = os.getenv('ETNY_WEB3_PROVIDER').rstrip()
|
|
597
|
-
if os.getenv('IMAGE_REGISTRY_ADDRESS'):
|
|
598
|
-
self.image_registry_address = os.getenv('IMAGE_REGISTRY_ADDRESS').rstrip()
|
|
607
|
+
# The chain id, PoX contract, Image Registry and Web3 provider are the
|
|
608
|
+
# build constants of __set_initializers and are never read from the
|
|
609
|
+
# environment: the node supplies the environment, and an override would
|
|
610
|
+
# let it choose the registry the trustedzone's certificate comes from.
|
|
599
611
|
self.order_id = int(os.getenv('ETNY_ORDER_ID'))
|
|
600
612
|
|
|
601
613
|
def save_result(self):
|
package/pynithy/build.mjs
CHANGED
|
@@ -31,9 +31,9 @@ const writeEnv = (key, value) => {
|
|
|
31
31
|
// Kept in sync with etny-{pynithy,nodenithy}/v3/networks.yaml (the authoritative
|
|
32
32
|
// on-chain constants). Covers all supported networks for both dApp types.
|
|
33
33
|
export const ECRunner = {
|
|
34
|
-
// --- bloxberg (the testnet reads
|
|
35
|
-
'etny-pynithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '
|
|
36
|
-
'etny-nodenithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '
|
|
34
|
+
// --- bloxberg (the testnet reads ECImageRegistryV3, mainnet the original) ---
|
|
35
|
+
'etny-pynithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0xa372a6e1Eb7Fcf343AF6b91E809b900C55001CD1', 'https://bloxberg.ethernity.cloud', 8995],
|
|
36
|
+
'etny-nodenithy-testnet': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0xa372a6e1Eb7Fcf343AF6b91E809b900C55001CD1', 'https://bloxberg.ethernity.cloud', 8995],
|
|
37
37
|
'etny-pynithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
|
|
38
38
|
'etny-nodenithy': ['0x549A6E06BB2084100148D50F51CF77a3436C3Ae7', '0x15D73a742529C3fb11f3FA32EF7f0CC3870ACA31', 'https://bloxberg.ethernity.cloud', 8995],
|
|
39
39
|
// --- polygon mainnet ---
|
|
@@ -52,8 +52,8 @@ export const ECRunner = {
|
|
|
52
52
|
'ecld-pynithy-litvm-testnet': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441],
|
|
53
53
|
'ecld-nodenithy-litvm-testnet': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441],
|
|
54
54
|
// --- the -unsafe networks: the contracts of the network each is named after ---
|
|
55
|
-
'etny-pynithy-testnet-unsafe': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '
|
|
56
|
-
'etny-nodenithy-testnet-unsafe': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '
|
|
55
|
+
'etny-pynithy-testnet-unsafe': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0xa372a6e1Eb7Fcf343AF6b91E809b900C55001CD1', 'https://bloxberg.ethernity.cloud', 8995],
|
|
56
|
+
'etny-nodenithy-testnet-unsafe': ['0x02882F03097fE8cD31afbdFbB5D72a498B41112c', '0xa372a6e1Eb7Fcf343AF6b91E809b900C55001CD1', 'https://bloxberg.ethernity.cloud', 8995],
|
|
57
57
|
'ecld-pynithy-litvm-testnet-unsafe': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441],
|
|
58
58
|
'ecld-nodenithy-litvm-testnet-unsafe': ['0x29D3eC870565B6A1510232bd950A8Bc8336f0EB2', '0x55e0ad455Be85162b71a790f00Fc305680E3CE53', 'https://liteforge.rpc.caldera.xyz/infra-partner-http', 4441]
|
|
59
59
|
};
|
|
@@ -99,11 +99,12 @@ const runCommand = (command, canPass = false) => {
|
|
|
99
99
|
|
|
100
100
|
// Removes the containers this build and publish create, matched by exact name:
|
|
101
101
|
// `--filter name=` matches a substring, so name=las would also match the LAS of
|
|
102
|
-
// a CAS validator set on the same host.
|
|
102
|
+
// a CAS validator set on the same host. `-v` removes their anonymous volumes
|
|
103
|
+
// too: registry:2 keeps its pushed images in one, about 1.3 GB per build.
|
|
103
104
|
const removeContainer = (name) => {
|
|
104
105
|
const ids = shell.exec(`docker ps -a -q --filter "name=^/${name}$"`, { silent: true }).stdout.trim();
|
|
105
106
|
if (ids) {
|
|
106
|
-
runCommand(`docker rm -f ${ids.split('\n').join(' ')}`);
|
|
107
|
+
runCommand(`docker rm -f -v ${ids.split('\n').join(' ')}`);
|
|
107
108
|
}
|
|
108
109
|
};
|
|
109
110
|
|
package/pynithy/ipfs.mjs
CHANGED
|
@@ -223,12 +223,13 @@ const retryOnFailure = async (fn, label) => {
|
|
|
223
223
|
return null;
|
|
224
224
|
};
|
|
225
225
|
|
|
226
|
-
// Upload a single file: POST it to /api/v0/add and return its hash.
|
|
227
|
-
|
|
226
|
+
// Upload a single file: POST it to /api/v0/add and return its hash. With
|
|
227
|
+
// onlyHash the node computes the same hash and stores nothing.
|
|
228
|
+
const uploadFileToIPFSOnce = async (filePath, onlyHash = false) => {
|
|
228
229
|
const files = [filePath];
|
|
229
230
|
const dir = path.dirname(filePath);
|
|
230
231
|
const { body, boundary, length } = buildMultipartBody(files, dir);
|
|
231
|
-
const { statusCode, text } = await postAdd('', body, boundary, length, null);
|
|
232
|
+
const { statusCode, text } = await postAdd(onlyHash ? '?only-hash=true' : '', body, boundary, length, null);
|
|
232
233
|
if (statusCode !== 200) {
|
|
233
234
|
console.log(`Failed to upload to IPFS. Status code: ${statusCode}`);
|
|
234
235
|
return null;
|
|
@@ -260,13 +261,15 @@ const uploadFileToIPFS = async (filePath) => {
|
|
|
260
261
|
};
|
|
261
262
|
|
|
262
263
|
// Upload a whole directory with wrap-with-directory=true and return the root
|
|
263
|
-
// directory hash -- the exact behaviour of Python's upload_dir.
|
|
264
|
-
|
|
264
|
+
// directory hash -- the exact behaviour of Python's upload_dir. With onlyHash
|
|
265
|
+
// the node computes the same root hash and stores nothing.
|
|
266
|
+
const uploadDirOnce = async (dirPath, onlyHash = false) => {
|
|
265
267
|
const abs = path.resolve(dirPath);
|
|
266
268
|
const files = gatherFiles(abs);
|
|
267
269
|
const totalSize = files.reduce((acc, f) => acc + fs.statSync(f).size, 0);
|
|
268
270
|
const totalMb = Math.floor(totalSize / (1024 * 1024));
|
|
269
271
|
const { body, boundary, length } = buildMultipartBody(files, abs);
|
|
272
|
+
const step = onlyHash ? 'Hashing enclave for IPFS' : 'Uploading and pinning enclave to IPFS';
|
|
270
273
|
|
|
271
274
|
let lastShownMb = -1;
|
|
272
275
|
let frame = 0;
|
|
@@ -276,27 +279,28 @@ const uploadDirOnce = async (dirPath) => {
|
|
|
276
279
|
frame = (frame + 1) % SPINNER_FRAMES.length;
|
|
277
280
|
lastShownMb = mb;
|
|
278
281
|
process.stdout.write(
|
|
279
|
-
`\r\t${SPINNER_FRAMES[frame]}
|
|
282
|
+
`\r\t${SPINNER_FRAMES[frame]} ${step}... ${mb}MB/${totalMb}MB`
|
|
280
283
|
);
|
|
281
284
|
}
|
|
282
285
|
};
|
|
283
286
|
|
|
284
287
|
const query =
|
|
285
|
-
'?quieter=true&stream-channels=true&wrap-with-directory=true&progress=false&timeout=5m'
|
|
288
|
+
'?quieter=true&stream-channels=true&wrap-with-directory=true&progress=false&timeout=5m' +
|
|
289
|
+
(onlyHash ? '&only-hash=true' : '');
|
|
286
290
|
const { statusCode, text } = await postAdd(query, body, boundary, length, onProgress);
|
|
287
291
|
|
|
288
292
|
if (statusCode !== 200) {
|
|
289
|
-
process.stdout.write(`\r\t${FAIL}
|
|
293
|
+
process.stdout.write(`\r\t${FAIL}${step}\n`);
|
|
290
294
|
console.log(`Failed to upload to IPFS. Status code: ${statusCode}`);
|
|
291
295
|
return false;
|
|
292
296
|
}
|
|
293
297
|
const rootHash = parseRootHash(text);
|
|
294
298
|
if (!rootHash) {
|
|
295
|
-
process.stdout.write(`\r\t${FAIL}
|
|
299
|
+
process.stdout.write(`\r\t${FAIL}${step}\n`);
|
|
296
300
|
console.log('Failed to upload to IPFS. Could not determine root hash.');
|
|
297
301
|
return false;
|
|
298
302
|
}
|
|
299
|
-
process.stdout.write(`\r\t${CHECK}
|
|
303
|
+
process.stdout.write(`\r\t${CHECK}${step}\n`);
|
|
300
304
|
return rootHash;
|
|
301
305
|
};
|
|
302
306
|
|
|
@@ -322,6 +326,16 @@ const upload = async (p) => {
|
|
|
322
326
|
return null;
|
|
323
327
|
};
|
|
324
328
|
|
|
329
|
+
// The hash `upload(p)` gives, from the same add call with only-hash: the IPFS
|
|
330
|
+
// node neither stores nor announces anything.
|
|
331
|
+
const hashForIPFS = async (p) => {
|
|
332
|
+
const stat = fs.statSync(p);
|
|
333
|
+
if (stat.isFile()) return retryOnFailure(() => uploadFileToIPFSOnce(p, true), 'hash_file');
|
|
334
|
+
if (stat.isDirectory()) return retryOnFailure(() => uploadDirOnce(p, true), 'hash_dir');
|
|
335
|
+
console.log(`Path ${p} is neither a file nor a directory.`);
|
|
336
|
+
return null;
|
|
337
|
+
};
|
|
338
|
+
|
|
325
339
|
// ---------------------------------------------------------------------------
|
|
326
340
|
// Download helpers (kubo-rpc-client based; unchanged behaviour)
|
|
327
341
|
// ---------------------------------------------------------------------------
|
|
@@ -397,6 +411,7 @@ const getContentFromIPFS = async (hash, maxRetries = process.env.REACT_APP_IPFS_
|
|
|
397
411
|
export {
|
|
398
412
|
initialize,
|
|
399
413
|
upload,
|
|
414
|
+
hashForIPFS,
|
|
400
415
|
uploadFileToIPFS,
|
|
401
416
|
uploadFolderToIPFS,
|
|
402
417
|
getFromIPFS,
|
|
@@ -405,7 +420,7 @@ export {
|
|
|
405
420
|
};
|
|
406
421
|
|
|
407
422
|
// ---------------------------------------------------------------------------
|
|
408
|
-
// CLI
|
|
423
|
+
// CLI: --host --action upload/hash/download --filePath/--folderPath
|
|
409
424
|
// ---------------------------------------------------------------------------
|
|
410
425
|
|
|
411
426
|
program
|
|
@@ -413,7 +428,7 @@ program
|
|
|
413
428
|
.option('--hhash <hhash>', 'IPFS hash')
|
|
414
429
|
.option('--filePath <path>', 'Path to the file')
|
|
415
430
|
.option('--folderPath <path>', 'Path to the folder')
|
|
416
|
-
.option('--action <action>', 'Action to perform (upload, download)')
|
|
431
|
+
.option('--action <action>', 'Action to perform (upload, hash, download)')
|
|
417
432
|
.option('--token <token>', 'IPFS authorization token')
|
|
418
433
|
.option('--output <path>', 'Output path for download');
|
|
419
434
|
|
|
@@ -445,6 +460,15 @@ if (isMain) {
|
|
|
445
460
|
console.error('Please provide a filePath or folderPath for upload.');
|
|
446
461
|
process.exit(1);
|
|
447
462
|
}
|
|
463
|
+
} else if (options.action === 'hash') {
|
|
464
|
+
const target = options.filePath || options.folderPath;
|
|
465
|
+
if (!target) {
|
|
466
|
+
console.error('Please provide a filePath or folderPath to hash.');
|
|
467
|
+
process.exit(1);
|
|
468
|
+
}
|
|
469
|
+
const hhash = await hashForIPFS(target);
|
|
470
|
+
console.log(`${hhash}`);
|
|
471
|
+
process.exit(hhash ? 0 : 1);
|
|
448
472
|
} else if (options.action === 'download') {
|
|
449
473
|
if (options.filePath) {
|
|
450
474
|
await getFromIPFS(options.hhash, options.filePath);
|
|
@@ -456,7 +480,7 @@ if (isMain) {
|
|
|
456
480
|
console.error('Please provide a filePath or folderPath for download.');
|
|
457
481
|
}
|
|
458
482
|
} else {
|
|
459
|
-
console.error('Please provide a valid action (upload, download).');
|
|
483
|
+
console.error('Please provide a valid action (upload, hash, download).');
|
|
460
484
|
process.exit(1);
|
|
461
485
|
}
|
|
462
486
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"AllowedWalletAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"AllowedWalletRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"},{"indexed":false,"internalType":"string","name":"publicKey","type":"string"},{"indexed":false,"internalType":"string","name":"version","type":"string"}],"name":"ImageAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImagePublished","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImageRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImageValidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"TrustedZoneImageAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"TrustedZoneImageRemoved","type":"event"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"addAllowedWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"}],"name":"addImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"}],"name":"addTrustedZoneImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"newRewardAddress","type":"address"}],"name":"changeImageRewardAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"newRewardAddress","type":"address"}],"name":"changeTrustedZoneImageRewardAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"publishImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"removeAllowedWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"validateImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getImageSession","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"getLatestImageVersionPublicKey","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"getLatestTrustedZoneImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getRewardAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneImageSession","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneRewardAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"imageDetails","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bool","name":"validated","type":"bool"},{"internalType":"bool","name":"published","type":"bool"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"images","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"imageVersions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"imageVersionsHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"trustedZoneImageDetails","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bool","name":"validated","type":"bool"},{"internalType":"bool","name":"published","type":"bool"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"trustedZoneImageVersions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"trustedZoneVersionsHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
|
|
1
|
+
[{"inputs":[{"internalType":"string","name":"imageName","type":"string"}],"name":"imageNameOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"AllowedWalletAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"}],"name":"AllowedWalletRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"},{"indexed":false,"internalType":"string","name":"publicKey","type":"string"},{"indexed":false,"internalType":"string","name":"version","type":"string"}],"name":"ImageAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImagePublished","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImageRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"ImageValidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"TrustedZoneImageAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"}],"name":"TrustedZoneImageRemoved","type":"event"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"addAllowedWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"}],"name":"addImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"}],"name":"addTrustedZoneImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"newRewardAddress","type":"address"}],"name":"changeImageRewardAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"changeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"newRewardAddress","type":"address"}],"name":"changeTrustedZoneImageRewardAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"publishImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"removeAllowedWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"validateImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowedWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getImageSession","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"getLatestImageVersionPublicKey","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"getLatestTrustedZoneImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getRewardAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneImageCertPublicKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneImageSession","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"getTrustedZoneRewardAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"imageDetails","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bool","name":"validated","type":"bool"},{"internalType":"bool","name":"published","type":"bool"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"images","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"imageVersions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"imageVersionsHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"trustedZoneImageDetails","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"address","name":"rewardAddress","type":"address"},{"internalType":"bool","name":"validated","type":"bool"},{"internalType":"bool","name":"published","type":"bool"},{"internalType":"string","name":"certPublicKey","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"trustedZoneImageVersions","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"trustedZoneVersionsHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"},{"indexed":false,"internalType":"string","name":"imageName","type":"string"},{"indexed":false,"internalType":"string","name":"version","type":"string"}],"name":"ImageCertSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"},{"indexed":false,"internalType":"string","name":"imageName","type":"string"},{"indexed":false,"internalType":"string","name":"version","type":"string"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"string","name":"ipfsPeer","type":"string"}],"name":"ImageRegistered","type":"event"},{"inputs":[],"name":"pendingImages","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"string","name":"imageName","type":"string"},{"internalType":"string","name":"dockerComposeHash","type":"string"},{"internalType":"string","name":"session","type":"string"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"string","name":"ipfsPeer","type":"string"}],"name":"registerImage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"}],"name":"registrationPeer","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"string","name":"certPublicKey","type":"string"}],"name":"setImageCert","outputs":[],"stateMutability":"nonpayable","type":"function"}]
|