@ethernity-cloud/sdk-js 1.6.1 → 1.7.0

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.
Files changed (52) hide show
  1. package/README.md +44 -6
  2. package/cas/config.js +61 -3
  3. package/info.js +333 -324
  4. package/init.js +20 -4
  5. package/nodenithy/build/securelock/Dockerfile.tmpl +34 -32
  6. package/nodenithy/build/securelock/scripts/binary-fs-build.sh +7 -6
  7. package/nodenithy/build/securelock/src/securelock.js.tmpl +5 -2
  8. package/nodenithy/build.mjs +83 -71
  9. package/nodenithy/run/docker-compose-final.yml.tmpl +36 -31
  10. package/nodenithy/run/docker-compose.yml.tmpl +34 -45
  11. package/nodenithy/run/image_registry.js +396 -380
  12. package/nodenithy/run.js +42 -28
  13. package/package.json +5 -3
  14. package/publish.js +4 -2
  15. package/pynithy/build/securelock/Dockerfile.base.tpl +13 -0
  16. package/pynithy/build/securelock/Dockerfile.tpl +131 -0
  17. package/pynithy/build/securelock/scripts/binary-fs-build.sh +25 -34
  18. package/pynithy/build/securelock/scripts/pyfreeze.sh +32 -0
  19. package/pynithy/build/securelock/src/{pox.abi → abi/etnyImplementationV2.abi} +1489 -1489
  20. package/pynithy/build/securelock/src/abi/image_registry.abi +1 -0
  21. package/pynithy/build/securelock/src/ecld_state.py +906 -0
  22. package/pynithy/build/securelock/src/esr.abi +1 -0
  23. package/pynithy/build/securelock/src/esr_local.py +267 -0
  24. package/pynithy/build/securelock/src/esr_wallet.py +150 -0
  25. package/pynithy/build/securelock/src/etny_crypto.py +208 -167
  26. package/pynithy/build/securelock/src/etny_exec.py +385 -79
  27. package/pynithy/build/securelock/src/etny_exec_flask.py +535 -0
  28. package/pynithy/build/securelock/src/etny_exec_serv.py +353 -0
  29. package/pynithy/build/securelock/src/etny_session_exec.py +245 -0
  30. package/pynithy/build/securelock/src/get_sgx_report.so +0 -0
  31. package/pynithy/build/securelock/src/image_registry.abi +1 -1
  32. package/pynithy/build/securelock/src/key_generation.py +17 -17
  33. package/pynithy/build/securelock/src/local_api.py +189 -0
  34. package/pynithy/build/securelock/src/models.py +200 -176
  35. package/pynithy/build/securelock/src/securelock.py.tmpl +1037 -727
  36. package/pynithy/build/securelock/src/swift_stream_service.py +206 -186
  37. package/pynithy/build.mjs +142 -92
  38. package/pynithy/run/docker-compose-final.yml.tmpl +58 -51
  39. package/pynithy/run/docker-compose.yml.tmpl +62 -48
  40. package/pynithy/run/etny-securelock-test.yaml.tpl +4 -1
  41. package/pynithy/run/image_registry.js +396 -380
  42. package/pynithy/run.js +44 -28
  43. package/pynithy/src/serverless/Dockerfile.serverless +8 -0
  44. package/pynithy/src/serverless/requirements.txt +6 -0
  45. package/run.js +69 -28
  46. package/nodenithy/build/las/Dockerfile +0 -5
  47. package/pynithy/build/docker-compose.yml +0 -70
  48. package/pynithy/build/las/Dockerfile +0 -11
  49. package/pynithy/build/las/src/etny_entrypoint.sh +0 -6
  50. package/pynithy/build/las/src/las_entrypoint.sh +0 -26
  51. package/pynithy/build/scripts/binary-fs-build.sh +0 -28
  52. package/pynithy/build/securelock/Dockerfile.tmpl +0 -95
@@ -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
+ [{"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,17 +1,17 @@
1
- import hashlib
2
- from eth_account import Account
3
-
4
- def get_wallet_address(first_string, second_string):
5
- concat = (first_string + second_string).encode()
6
- _hash1 = hashlib.sha256(concat).hexdigest()
7
- _hash = hashlib.sha256(_hash1.encode()).hexdigest()
8
- acct = Account.from_key(_hash)
9
- return acct.address, _hash
10
-
11
-
12
- if __name__ == '__main__':
13
- first_string = 'test'
14
- second_string = 'test'
15
- (addr, private) = get_wallet_address(first_string, second_string)
16
- print('account address = ', addr) # 0xf63106856F7007A30025f0fFD5A534EA880878C3
17
- print('private = ', private)
1
+ import hashlib
2
+ from eth_account import Account
3
+
4
+ def get_wallet_address(first_string, second_string):
5
+ concat = (first_string + second_string).encode()
6
+ _hash1 = hashlib.sha256(concat).hexdigest()
7
+ _hash = hashlib.sha256(_hash1.encode()).hexdigest()
8
+ acct = Account.from_key(_hash)
9
+ return acct.address, _hash
10
+
11
+
12
+ if __name__ == '__main__':
13
+ first_string = 'test'
14
+ second_string = 'test'
15
+ (addr, private) = get_wallet_address(first_string, second_string)
16
+ print('account address = ', addr) # 0xf63106856F7007A30025f0fFD5A534EA880878C3
17
+ print('private = ', private)
@@ -0,0 +1,189 @@
1
+ """Local test API over the securelock executor. NOT used inside the enclave.
2
+
3
+ This file lives in the securelock source tree on purpose: it imports and reuses
4
+ the exact same etny_exec module that runs inside the SGX enclave, so a payload
5
+ tested against this API is executed by the same code, with the same globals and
6
+ the same TaskStatus semantics, as a real on-chain task. What it deliberately
7
+ skips is everything around execution: attestation, checksums, encryption,
8
+ IPFS, and the blockchain.
9
+
10
+ Launched by `ecld-test serve` (which puts the project's src/ on sys.path so
11
+ `serverless.backend` resolves to the developer's backend, exactly as inside
12
+ binary-fs). The runners' LOCAL mode talks to it:
13
+
14
+ GET /v1/health -> {"status": "ok", "backend": [...function names...]}
15
+ POST /v1/task {"payload": "...", "input": "..."|null}
16
+ -> {"task_code": 0, "task_code_name": "SUCCESS",
17
+ "result": "...", "checksum": "<sha256(result)>",
18
+ "enclave_challenge": "<20 chars>",
19
+ "result_string": "v3:<code>:<checksum>:<challenge>:"}
20
+
21
+ The enclave is stateless per task and so is this server: every POST is one
22
+ isolated execution.
23
+ """
24
+
25
+ import hashlib
26
+ import json
27
+ import random
28
+ import string
29
+ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
30
+
31
+ import etny_exec
32
+
33
+ # Local ESR emulation. ON BY DEFAULT so `ecld-test` matches a real ESR-enabled
34
+ # build with no extra setup: a StateRegistry() in the backend works fully
35
+ # in-process against an in-memory registry + store -- no chain, node, or SGX.
36
+ # See esr_local.py. Disabled only if installation fails (e.g. no web3 dep).
37
+ _ESR = {"installed": False, "default_caller": None, "handles": None}
38
+
39
+ TASK_STATUS_NAMES = {
40
+ 0: "SUCCESS",
41
+ 1: "SYSTEM_ERROR",
42
+ 2: "KEY_ERROR",
43
+ 3: "SYNTAX_WARNING",
44
+ 4: "BASE_EXCEPTION",
45
+ 5: "PAYLOAD_NOT_DEFINED",
46
+ 6: "PAYLOAD_CHECKSUM_ERROR",
47
+ 7: "INPUT_CHECKSUM_ERROR",
48
+ 8: "EXECVE",
49
+ 28: "IMPORT_ERROR",
50
+ 32: "CONFIG_ERROR",
51
+ 33: "EXECUTION_TIMEOUT",
52
+ 34: "ESR_GAS_LIMIT_EXCEEDED",
53
+ 35: "SECURITY_VIOLATION",
54
+ 36: "ESR_NONCE_VIOLATION",
55
+ 37: "ESR_RELAY_TIMEOUT",
56
+ 38: "ESR_COMMIT_LIMIT_EXCEEDED",
57
+ }
58
+
59
+
60
+ def _challenge(length=20):
61
+ # Same shape as the trustedzone's enclave challenge (base36).
62
+ alphabet = string.ascii_lowercase + string.digits
63
+ return "".join(random.choice(alphabet) for _ in range(length))
64
+
65
+
66
+ def _install_esr(default_caller=None, persist=True):
67
+ """Install the local ESR emulator into ecld_state (best-effort). ON by
68
+ default so ecld-test matches a real ESR-enabled build."""
69
+ try:
70
+ import ecld_state
71
+ import esr_local
72
+ handles = esr_local.install(
73
+ ecld_state, caller=default_caller,
74
+ file_prefix=".ecld-esr-local" if persist else None)
75
+ _ESR["installed"] = True
76
+ _ESR["default_caller"] = default_caller
77
+ _ESR["handles"] = handles
78
+ return True
79
+ except Exception as e:
80
+ _ESR["installed"] = False
81
+ print(f"[local-api] ESR emulation unavailable: {e}")
82
+ return False
83
+
84
+
85
+ def _set_caller(caller):
86
+ """Set the task caller EXACTLY as the real securelock does after the
87
+ trustedzone hands it the DO owner -- available to any payload via
88
+ task_caller(), and used by the ESR ACL. Applies whether or not the payload
89
+ uses ESR."""
90
+ try:
91
+ import ecld_state
92
+ ecld_state._task_caller = ecld_state._norm_addr(caller) if caller else None
93
+ except Exception:
94
+ pass
95
+
96
+
97
+ def run_task(payload, input_data=None, caller=None):
98
+ """One task through the real executor; returns the API response dict.
99
+
100
+ `caller` mirrors the trustedzone-attested DO owner the real securelock
101
+ receives: it is set for EVERY task (not just ESR ones), so task_caller()
102
+ behaves locally as it does in the enclave. Falls back to the server's
103
+ default caller when a request does not specify one."""
104
+ effective_caller = caller if caller is not None else _ESR.get("default_caller")
105
+ _set_caller(effective_caller)
106
+ code, result = etny_exec.execute_task_v3(payload, input_data)
107
+ result_text = result if isinstance(result, str) else repr(result)
108
+ checksum = hashlib.sha256(result_text.encode("utf-8")).hexdigest()
109
+ challenge = _challenge()
110
+ return {
111
+ "task_code": code,
112
+ "task_code_name": TASK_STATUS_NAMES.get(code, f"UNKNOWN_{code}"),
113
+ "result": result_text,
114
+ "checksum": checksum,
115
+ "enclave_challenge": challenge,
116
+ "result_string": f"v3:{code}:{checksum}:{challenge}:",
117
+ }
118
+
119
+
120
+ class Handler(BaseHTTPRequestHandler):
121
+ server_version = "ecld-local-api/1.0"
122
+
123
+ def _send(self, status, obj):
124
+ body = json.dumps(obj).encode("utf-8")
125
+ self.send_response(status)
126
+ self.send_header("Content-Type", "application/json")
127
+ self.send_header("Content-Length", str(len(body)))
128
+ # Browser dApps (JS runner local mode) call this from another origin.
129
+ self.send_header("Access-Control-Allow-Origin", "*")
130
+ self.send_header("Access-Control-Allow-Headers", "Content-Type")
131
+ self.end_headers()
132
+ self.wfile.write(body)
133
+
134
+ def do_OPTIONS(self):
135
+ self._send(204, {})
136
+
137
+ def do_GET(self):
138
+ if self.path == "/v1/health":
139
+ funcs = sorted(getattr(etny_exec, "sdkFunctions", {}).keys())
140
+ self._send(200, {"status": "ok", "backend": funcs})
141
+ else:
142
+ self._send(404, {"error": "not found"})
143
+
144
+ def do_POST(self):
145
+ if self.path != "/v1/task":
146
+ self._send(404, {"error": "not found"})
147
+ return
148
+ try:
149
+ length = int(self.headers.get("Content-Length", 0))
150
+ req = json.loads(self.rfile.read(length) or b"{}")
151
+ payload = req.get("payload")
152
+ if not isinstance(payload, str) or not payload.strip():
153
+ self._send(400, {"error": "payload (string) is required"})
154
+ return
155
+ input_data = req.get("input")
156
+ if input_data is not None and not isinstance(input_data, str):
157
+ input_data = json.dumps(input_data)
158
+ # A request may name the task caller (the DO owner the trustedzone
159
+ # would attest); else the server's default caller is used.
160
+ caller = req.get("caller")
161
+ self._send(200, run_task(payload, input_data, caller=caller))
162
+ except json.JSONDecodeError:
163
+ self._send(400, {"error": "invalid JSON body"})
164
+ except Exception as e: # harness fault, not a task result
165
+ self._send(500, {"error": str(e)})
166
+
167
+ def log_message(self, fmt, *args):
168
+ print(f"[local-api] {self.address_string()} {fmt % args}")
169
+
170
+
171
+ def serve(host="127.0.0.1", port=8745, caller=None, esr=True, persist=True):
172
+ funcs = sorted(getattr(etny_exec, "sdkFunctions", {}).keys())
173
+ print(f"[local-api] backend functions: {funcs if funcs else 'none (stock-enclave mode)'}")
174
+ if esr:
175
+ if _install_esr(default_caller=caller, persist=persist):
176
+ wallet = None
177
+ try:
178
+ import ecld_state
179
+ wallet = ecld_state.StateRegistry().wallet_address
180
+ except Exception:
181
+ pass
182
+ print(f"[local-api] ESR emulation: ON (in-process, no chain)"
183
+ + (f" enclave wallet {wallet}" if wallet else ""))
184
+ caller_note = caller or "(none -- pass 'caller' per request)"
185
+ print(f"[local-api] task caller: {caller_note}")
186
+ if persist:
187
+ print("[local-api] ESR state persists in .ecld-esr-local.*.json")
188
+ print(f"[local-api] listening on http://{host}:{port} (POST /v1/task, GET /v1/health)")
189
+ ThreadingHTTPServer((host, port), Handler).serve_forever()