From 3034fba59ede309e4f6a2b97a3b74a0217fa1228 Mon Sep 17 00:00:00 2001 From: artur Date: Fri, 5 Jul 2024 10:40:23 +0200 Subject: [PATCH] Add nip136 code packages kind 1036 --- 136.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 136.md diff --git a/136.md b/136.md new file mode 100644 index 00000000..efe81859 --- /dev/null +++ b/136.md @@ -0,0 +1,108 @@ +Code packages +============= + +This NIP handles distribution of code packages (akin to npm packages) in a decentralized way. + +Code package consists of a list of files in directories. A code package event of kind `1036` contains a list of hashes of files along with their relative paths, directories are not listed. File contents are to be stored on Blossom or NIP-96 or other kinds of servers that use `sha256` for addressing. + +The `content` field of the code package may contain human readable description of the package contents. Each file is an `f` tag containing sha256 file hash, relative file path within the package and a URL to download the file content. Other recommended meta tags are given as example below. + +Code package also contains `x` tag - the `package hash`, which is a combined hash of included relative paths and file hashes. This `package hash` serves as a content-based package address, to allow apps to fetch packages with the same package hash. Events referring to code package events should use package event id with a relay hint, and may include package hash in the reference - if original event is not accessible, package hash can be searched on relays as a fallback. + +Example package event: +``` +{ + "content":"", + "created_at":1718295088, + "id":"", + "kind":1036, + "pubkey":"", + "sig":"", + "tags":[ + ["title","Taste"], + ["summary","A Ghost theme"], + ["version","1.0.0"], + ["changes","Great improvements"], + ["license","MIT"], + ["x", ""], + [ + "f", + "7db7d6130b9b667001841b79ee67760619a80b9df305b8bfb872e22265313cf5","LICENSE", + "https://blossom.nostr.hu/7db7d6130b9b667001841b79ee67760619a80b9df305b8bfb872e22265313cf5" + ], + [ + "f", + "38117ebbd11b7571d6108a3fc642521c4f6f5c54c49dbcda5da0d15009c3013a", + "package.json", + "https://blossom.nostr.hu/38117ebbd11b7571d6108a3fc642521c4f6f5c54c49dbcda5da0d15009c3013a" + ], + [ + "f", + "c931b825e11cbc5149f41c21c83332fcf8c87d951065f2716f3b12dd875c414c", + "index.hbs", + "https://blossom.nostr.hu/c931b825e11cbc5149f41c21c83332fcf8c87d951065f2716f3b12dd875c414c" + ], + [ + "f", + "331c2869b4a7f8a9181089ecb158a987a92a5915cca95912a1a16b35898988ee", + "assets/built/screen.css", + "https://blossom.nostr.hu/331c2869b4a7f8a9181089ecb158a987a92a5915cca95912a1a16b35898988ee" + ], + [ + "f", + "ee737f159229961284f179a8d21024c599b07512825b049c900873fdc7e6df1a", + "assets/built/main.min.js", + "https://blossom.nostr.hu/ee737f159229961284f179a8d21024c599b07512825b049c900873fdc7e6df1a" + ], + ] +} +``` + +Pseudo-code to calculate package hash: +``` + const pkg: { + hash: string, // hex hash of a file + path: string // relative file path w/o leading / + }[] = [...]; + pkg.sort((a, b) => (a.hash > b.hash ? 1 : a.hash === b.hash ? 0 : -1)); + const packageHash = bytesToHex( + sha256(pkg.map((e) => e.hash + e.entry).join(",")) + ); +``` + +Test vector for a package hash: +``` + const pkg = [ + ["094cdc9a24ebf462c6c38be09ab3046396e21ae243a31b874ed6ee74bf3e4364","default.hbs"], + ["0a96d40dd8bac92d050ccdbd7f4b1d3fae8564892ae58584bfff090b27a0f862","partials/components/list-item.hbs"], + ["20482ce13e4e75c219c459b3a1c3ef0acb1d1f3d01aeda8c16931dd6f855aa8b","partials/components/article.hbs"], + ["25b4799d1e4a1da0875402c80fdf02da824e65535202000798e076f80fad0509","tag.hbs"], + ["28d78dc6cbf6569496b2a968f71a7bbd663fb0a9eb98d3c5268f9bfd2f66f1ba","assets/css/screen.css"], + ["331c2869b4a7f8a9181089ecb158a987a92a5915cca95912a1a16b35898988ee","assets/built/screen.css"], + ["341dce30d1dc1495181779af7ce3c27de68b12752c6184f8ed21939161df0ec4","partials/icons/facebook.hbs"], + ["38117ebbd11b7571d6108a3fc642521c4f6f5c54c49dbcda5da0d15009c3013a","package.json"], + ["3af99992cacb7e466f37a390d899f8323ac0fc4eafe8ca12f1cecb272c86ef64","assets/built/main.min.js.map"], + ["3be86ec65468322816a7c1468f88d6192a04affe02b30e83ea0bc50f7bb8dd02","partials/components/header-content.hbs"], + ["4256eafe8a3e80b78072518861c5872aacca3c8c019829a48c44f6e43b351070","partials/icons/search.hbs"], + ["509c6330788805349e0e8c90d97d6182b12038cc90de32657272fc3f88f1ec52","partials/components/list.hbs"], + ["55b72665ed314a9920e911a0808d6f631c525314ee233908e317ca60805cd0a9","post.hbs"], + ["6b561b27169e242b0656211e35b21210158713d566e5267aefc8ab92be699e41","gulpfile.js"], + ["7db7d6130b9b667001841b79ee67760619a80b9df305b8bfb872e22265313cf5","LICENSE"], + ["82e26e6c37d0bf92700fa3c9481be281758f2b79e4266cd8ed44138c9543512a","partials/components/author-header.hbs"], + ["96e8b7d2ac50f83c7535a63b3c54f5872ff7e13d2743d4c0cdaedcb60d155770","partials/components/cta.hbs"], + ["9c885f99ec47c0df2d9364888331be52f1e11dc77da28497950b8af1b0a3fd4c","assets/built/screen.css.map"], + ["9f48de3029455d4d58a9f6fb86175e7c4555a8c7744502b4cef5b9ceb5b51a1b","partials/components/navbar.hbs"], + ["a9e59ea2076c203ff5c68335cc1b16ac36f3e7bc26ed50bf376f29cd59fd15e8","partials/icons/twitter.hbs"], + ["b659c9d0d5730eb61bb72265872c4521d1e3964e72fc099fde2e819000c6c62c","author.hbs"], + ["c931b825e11cbc5149f41c21c83332fcf8c87d951065f2716f3b12dd875c414c","index.hbs"], + ["dbb322d0e284169192f1f6cfd08ddb6241b183d7e110c89285348a27becdd0a5","page.hbs"], + ["e819b4f518d24661e141a57be64fce163a828d987901c3ba0f529fc6f50dc4fc","partials/components/header.hbs"], + ["ee737f159229961284f179a8d21024c599b07512825b049c900873fdc7e6df1a","assets/built/main.min.js"], + ["f6072040f2d6845b43ef7b47c35313307610cde31b21ac70474d474f2c1faa39","partials/components/footer.hbs"], + ["fa4a19ebf8724e761e963146977ef99560eea04ea1fe3a9106836284bf7de762","assets/js/main.js"], + ["fac32039620932194df919c6f336b2e270f4a4210a8628bf4d5b0ffbcb091a8b","partials/pswp.hbs"], + ["ffdbdcade1a6dd508d10b463bd8a3b4ad16fa51ef352099979c5f0eaa8571218","partials/components/tag-header.hbs"] + ] + + const packageHash = "a70bb6d5b24c09a7f590ff70cd7dea3fc90fbb5f3fd152af8c86865cee51f6db"; +``` \ No newline at end of file