diff --git a/plugins/zkool/README.md b/plugins/zkool/README.md new file mode 100644 index 0000000..8102064 --- /dev/null +++ b/plugins/zkool/README.md @@ -0,0 +1,20 @@ +# Zkool ZAP1 Memo Plugin + +Zkool supports memo plugins through its Plugin Manager. This package renders +ZAP1 structured memo strings such as: + +```text +ZAP1:01:075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b +``` + +It matches the `ZAP1` prefix, labels known type bytes, keeps the raw hash +visible, and links non-root entries to the ZAP1 proof endpoint. + +Install URL after this lands on `main`: + +```text +https://github.com/Frontier-Compute/zap1/raw/main/plugins/zkool/zap1-memo-plugin.zip +``` + +Source files are under `plugins/zkool/zap1-memo-plugin/`. The zip is flat +because Zkool expects `manifest.json` and `main.rhai` at archive root. diff --git a/plugins/zkool/zap1-memo-plugin.zip b/plugins/zkool/zap1-memo-plugin.zip new file mode 100644 index 0000000..bf83dfc Binary files /dev/null and b/plugins/zkool/zap1-memo-plugin.zip differ diff --git a/plugins/zkool/zap1-memo-plugin/main.rhai b/plugins/zkool/zap1-memo-plugin/main.rhai new file mode 100644 index 0000000..c7e407d --- /dev/null +++ b/plugins/zkool/zap1-memo-plugin/main.rhai @@ -0,0 +1,63 @@ +fn get_prefixes() { + return ["5a415031"]; +} + +fn hex_char(byte) { + if byte == 48 { return "0"; } + if byte == 49 { return "1"; } + if byte == 50 { return "2"; } + if byte == 51 { return "3"; } + if byte == 52 { return "4"; } + if byte == 53 { return "5"; } + if byte == 54 { return "6"; } + if byte == 55 { return "7"; } + if byte == 56 { return "8"; } + if byte == 57 { return "9"; } + if byte == 65 || byte == 97 { return "a"; } + if byte == 66 || byte == 98 { return "b"; } + if byte == 67 || byte == 99 { return "c"; } + if byte == 68 || byte == 100 { return "d"; } + if byte == 69 || byte == 101 { return "e"; } + if byte == 70 || byte == 102 { return "f"; } + return "?"; +} + +fn type_label(type_hex) { + if type_hex == "01" { return "PROGRAM_ENTRY"; } + if type_hex == "02" { return "OWNERSHIP_ATTEST"; } + if type_hex == "03" { return "CONTRACT_ANCHOR"; } + if type_hex == "04" { return "DEPLOYMENT"; } + if type_hex == "05" { return "HOSTING_PAYMENT"; } + if type_hex == "06" { return "SHIELD_RENEWAL"; } + if type_hex == "07" { return "TRANSFER"; } + if type_hex == "08" { return "EXIT"; } + if type_hex == "09" { return "MERKLE_ROOT"; } + if type_hex == "0a" { return "STAKING_DEPOSIT"; } + if type_hex == "0b" { return "STAKING_WITHDRAW"; } + if type_hex == "0c" { return "STAKING_REWARD"; } + if type_hex == "0d" { return "GOVERNANCE_PROPOSAL"; } + if type_hex == "0e" { return "GOVERNANCE_VOTE"; } + if type_hex == "0f" { return "GOVERNANCE_RESULT"; } + return "UNKNOWN"; +} + +fn process_memo() { + let type_hex = hex_char(memo::read_u8(5)) + hex_char(memo::read_u8(6)); + let hash = memo::read_string(8, 64); + let label = type_label(type_hex); + let headers = ["Field", "Value"]; + let rows = [ + [cell_string("Protocol"), cell_string("ZAP1")], + [cell_string("Type"), cell_string(type_hex)], + [cell_string("Label"), cell_string(label)], + [cell_string("Hash"), cell_string(hash)], + ]; + + if type_hex != "09" { + let url = "https://api.frontiercompute.cash/verify/" + hash; + url += "/proof.json"; + rows.push([cell_string("Proof"), cell_url(url)]); + } + + return [section("ZAP1 Memo", headers, rows)]; +} diff --git a/plugins/zkool/zap1-memo-plugin/manifest.json b/plugins/zkool/zap1-memo-plugin/manifest.json new file mode 100644 index 0000000..1541d1c --- /dev/null +++ b/plugins/zkool/zap1-memo-plugin/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "cash.frontiercompute.zap1-memo", + "name": "ZAP1 Memo Parser", + "version": "1.0.0", + "author": "Frontier Compute", + "description": "Parses ZAP1 structured attestation memos.", + "min_app_version": "6.20.0", + "types": ["memo"], + "entry_point": "main.rhai" +}