{"id":"68eaa1e4cde654ba098625e83f1a6828d87849f98c756fd385a93e0d6e36c78a","pubkey":"78ce6faa72264387284e647ba6938995735ec8c7d5c5a65737e55130f026307d","created_at":1786497755,"kind":30817,"tags":[["d","82"],["title","Software Applications"],["alt","Nostr Implementation Possibility: Software Applications"],["k","32267"],["k","30063"],["k","3063"]],"content":"# NIP-82\n\n## Software Applications\n\n`draft` `optional`\n\nThis NIP defines kind 32267 to describe a software application, kind 30063 for a software release and kind 3063 for a software asset.\n\nA software asset is a file associated with a software release. Automatic installation and dependency resolution are client concerns outside this NIP.\n\n## Software Application\n\nAn application is a parameterizable replaceable event as a pubkey may maintain many different ones and update their description over time.\n\n```jsonc\n{\n  \"kind\": 32267,\n  // Full description of the application, markdown is allowed\n  \"content\": \"<description>\",\n  \"tags\": [\n    [\n      // REQUIRED\n      // Reverse-domain identifier (com.example.app) recommended, can be any string\n      \"d\",\n      \"<app-id>\",\n    ],\n    [\n      // REQUIRED\n      // App name\n      \"name\",\n      \"<human-readable project name>\",\n    ],\n    [\n      // OPTIONAL\n      // Summary, short description, Markdown not allowed\n      \"summary\",\n      \"<summary-text>\",\n    ],\n    [\n      // OPTIONAL\n      // Icon URL\n      \"icon\",\n      \"<icon-url>\",\n    ],\n    [\n      // OPTIONAL, MULTIPLE\n      // Image URL\n      \"image\",\n      \"<image-url>\",\n    ],\n    [\n      // OPTIONAL, MULTIPLE\n      // Tags used to describe the application\n      \"t\",\n      \"<tag>\",\n    ],\n    [\n      // OPTIONAL\n      // Website URL for the application\n      \"url\",\n      \"<website-url>\",\n    ],\n    [\n      // OPTIONAL\n      // Source code repository URL: https://github.com/example/android\n      // Must be able to `git clone <repo-url>`\n      \"repository\",\n      \"<repo-url>\",\n    ],\n    [\n      // OPTIONAL\n      // Pointer to NIP-34 repository\n      \"a\",\n      \"30617:<destination-pubkey>:<repo-id>\",\n      \"<relay-url>\",\n    ],\n    [\n      // OPTIONAL, MULTIPLE\n      // Platform identifiers for assets that have platform restrictions\n      // NOTE: See Appendix A. Only include platforms that have restrictions\n      // in the corresponding assets. Platform-agnostic software may omit\n      // this tag entirely.\n      \"f\",\n      \"<platform-identifier>\",\n    ],\n    [\n      // OPTIONAL\n      // SPDX license ID\n      \"license\",\n      \"<spdx-id>\",\n    ],\n  ],\n}\n```\n\nTag requirements are indicated in the tag definitions.\n\nApplications SHOULD use their application or bundle identifier (typically in reverse-domain notation) as the `d` tag. Note that application and asset identifiers are independent, an Android app may have `com.example.android` as ID while its macOS counterpart may use `com.example.mac`.\n\nFor `icon` and `image` tags any URL is valid but a Blossom [BUD-01](https://github.com/hzrd149/blossom/blob/master/buds/01.md#get-sha256---get-blob) endpoint is recommended.\n\n`f` tags SHOULD be included when assets have platform restrictions. See [Appendix A](#appendix-a-platform-identifiers) for identifiers and [Appendix C](#appendix-c-mime-types) for when `f` tags are required.\n\nLicense IDs are SPDX IDs as defined in https://spdx.org/licenses/.\n\n## Software Release\n\nA release is a parameterizable replaceable event, it is important for developers to be able to overwrite a bad release and update pointers to the right assets.\n\nIt also contains a release channel name.\n\n```jsonc\n{\n  \"kind\": 30063,\n  // Full release notes, Markdown allowed\n  \"content\": \"<release-notes>\",\n  \"tags\": [\n    [\n      // REQUIRED\n      // Pointer to the software application kind 32267\n      \"a\",\n      \"32267:<app-publisher-pubkey>:<app-id>\",\n      \"<relay-hint>\",\n    ],\n    [\n      // REQUIRED\n      // This MUST be the `<app-id>` in the `a` tag\n      \"i\",\n      \"<app-id>\",\n    ],\n    [\n      // REQUIRED\n      // Release version: 1.2.3, v0.1.2-rc1\n      \"version\",\n      \"<version>\",\n    ],\n    [\n      // REQUIRED\n      // MUST be the `i` and `version` tags joined by '@'\n      \"d\",\n      \"<identifier>@<version>\",\n    ],\n    [\n      // REQUIRED\n      // See Appendix B for channel IDs\n      \"c\",\n      \"<channel-id>\",\n    ],\n    [\n      // REQUIRED, MULTIPLE\n      // Asset event id (kind 3063)\n      \"e\",\n      \"<asset-event-id>\",\n      \"<relay-hint>\",\n    ],\n    [\n      // REQUIRED, MULTIPLE\n      // Aggregate platform identifiers: MUST be the deduplicated union\n      // of every `f` tag on the linked assets (kind 3063). See Appendix A.\n      \"f\",\n      \"<platform-identifier>\",\n    ],\n  ],\n}\n```\n\nThe `e` tags are pointers to all [Software Asset](#software-asset)s in this release. This event MUST be the authoritative source for assets belonging to a given version.\n\nThe `i` tag MUST be the `<app-id>` component of the kind 32267 coordinate in the `a` tag.\n\nWhen `f` tags are included, they MUST be the aggregate (deduplicated union) of all `f` tags on the linked kind 3063 events. Clients MAY use them for discovery and filtering without resolving every asset. Publishers SHOULD include them whenever any linked asset has platform tags, and keep them in sync when assets are added, removed, or retagged.\n\nThe event's `created_at` timestamp MUST be the release date.\n\nThe identifier `i` MUST be the exact same used in the application. The `d` tag is required and MUST be `<identifier>@<version>` (`i` and `version` tags joined by `@`).\n\nNote that a release version, typically a git tag, does not need to coincide with any of the linked asset versions.\n\n## Software Asset\n\nAn asset is a regular non-replaceable event, mainly used to cryptographically link a file through its SHA-256 hash. This kind is an extension of [kind 1063](94.md). See [Appendix C](#appendix-c-mime-types) for MIME type handling.\n\n```jsonc\n{\n  \"kind\": 3063,\n  // Empty content\n  \"content\": \"\",\n  \"tags\": [\n    // Tags derived from kind 1063\n    [\n      // REQUIRED\n      // Reverse-domain identifier: com.example.app\n      // NOTE: Here \"i\" stands for \"identifier\", not \"infohash\"\n      \"i\",\n      \"<app-id>\",\n    ],\n    [\n      // OPTIONAL\n      // URL of the asset, may be a Blossom URL\n      \"url\",\n      \"<asset-url>\",\n    ],\n    [\n      // OPTIONAL\n      // Filename for the asset\n      \"filename\",\n      \"<download-filename>\",\n    ],\n    [\n      // REQUIRED\n      // MIME type of the asset\n      // NOTE: This is the primary source of truth for the asset format.\n      // See Appendix C for MIME type handling.\n      \"m\",\n      \"<mime-type>\",\n    ],\n    [\n      // REQUIRED\n      // SHA-256 hash of the asset\n      \"x\",\n      \"<sha256-hash>\",\n    ],\n    [\n      // OPTIONAL\n      // Size of the asset in bytes\n      \"size\",\n      \"<size-bytes>\",\n    ],\n\n    // Software Asset-specific tags\n    [\n      // REQUIRED\n      // Version: 1.2.3, 0.1.2-rc1\n      \"version\",\n      \"<version>\",\n    ],\n    [\n      // OPTIONAL, MULTIPLE\n      // Platform restrictions (OS + architecture)\n      // NOTE: See Appendix A for identifiers.\n      //\n      // REQUIRED when MIME type does not fully determine the target platform,\n      // or to restrict compatibility to specific architectures.\n      \"f\",\n      \"<platform-id>\",\n    ],\n    [\n      // OPTIONAL\n      // Minimum platform version (minimum compatibility)\n      // NOTE: When the MIME type implies a runtime (e.g., VS Code for VSIX, Chrome for CRX),\n      // this refers to the runtime version. Otherwise, it refers to the OS version\n      // (e.g., Android API level, macOS version).\n      // See Appendix D for version comparison rules.\n      \"min_platform_version\",\n      \"<min-platform-version>\",\n    ],\n    [\n      // OPTIONAL\n      // Target platform version (version software was designed for)\n      // NOTE: Same semantics as min_platform_version.\n      \"target_platform_version\",\n      \"<target-platform-version>\",\n    ],\n    [\n      // OPTIONAL, MULTIPLE\n      // Supported Nostr NIP by this software\n      \"supported_nip\",\n      \"<nip-id-string>\",\n    ],\n    [\n      // OPTIONAL\n      // When we have sibling assets that need to differentiate, falls back to filename\n      // Example: \"offline\"\n      \"variant\",\n      \"<variant-name>\",\n    ],\n    [\n      // OPTIONAL\n      // Commit ID used to build the asset (same as NIP-34),\n      // needed for reproducible builds\n      \"commit\",\n      \"<commit-id>\",\n    ],\n    [\n      // OPTIONAL\n      // Minimum allowed version: defines a minimum version\n      // of this asset.\n      // See Appendix D for version comparison rules.\n      \"min_allowed_version\",\n      \"<version>\",\n    ],\n\n    // Version-code specific tags (for Android and others)\n    [\n      // Android: REQUIRED\n      \"version_code\",\n      \"<version-code-int>\",\n    ],\n    [\n      // OPTIONAL\n      // Minimum allowed version as integer\n      \"min_allowed_version_code\",\n      \"<version-code-int>\",\n    ],\n\n    // Android-specific tags (only for application/vnd.android.package-archive)\n    [\n      // REQUIRED for Android APKs, MULTIPLE\n      // APK certificate hash\n      \"apk_certificate_hash\",\n      \"<apk_certificate_hash>\",\n    ],\n\n    // Web content reference\n    [\n      // OPTIONAL\n      // URL of the original web content (e.g., PWA start URL)\n      \"r\",\n      \"<url>\",\n    ],\n  ],\n}\n```\n\nBoth asset identifier `i` and `version` tags MAY be different to the application and release identifier and version.\n\nWhen `url` is omitted, clients SHOULD locate the asset via its SHA-256 hash using a Blossom [BUD-01](https://github.com/hzrd149/blossom/blob/master/buds/01.md#get-sha256---get-blob) endpoint.\n\n## Appendix A: Platform identifiers\n\nPlatform is defined as the specific underlying system on which the application is executed, a combination of operating system and hardware architecture. We use the `f` tag for this purpose, with the following identifiers loosely based off `uname -sm`:\n\n| Identifier            | OS          | Architecture   |\n| --------------------- | ----------- | -------------- |\n| `android-arm64-v8a`   | Android     | ARMv8-A        |\n| `android-armeabi-v7a` | Android     | ARMv7-A        |\n| `android-x86`         | Android     | x86            |\n| `android-x86_64`      | Android     | x86-64         |\n| `darwin-arm64`        | macOS       | ARM64          |\n| `darwin-x86_64`       | macOS       | x86-64         |\n| `linux-aarch64`       | Linux       | ARM64          |\n| `linux-x86_64`        | Linux       | x86-64         |\n| `windows-aarch64`     | Windows     | ARM64          |\n| `windows-x86_64`      | Windows     | x86-64         |\n| `ios-arm64`           | iOS         | ARM64          |\n| `freebsd-x86_64`      | FreeBSD     | x86-64         |\n| `freebsd-aarch64`     | FreeBSD     | ARM64          |\n| `linux-armv7l`        | Linux       | ARMv7 (32-bit) |\n| `linux-riscv64`       | Linux       | RISC-V 64-bit  |\n| `wasm32`              | WebAssembly | WASM 32-bit    |\n| `wasm64`              | WebAssembly | WASM 64-bit    |\n| `wasi-wasm32`         | WASI        | WASM 32-bit    |\n| `wasi-wasm64`         | WASI        | WASM 64-bit    |\n\nThe `f` tag is used to **restrict** compatibility when the MIME type alone does not fully determine the target platform. See [Appendix C](#appendix-c-mime-types) for when `f` tags are required.\n\n## Appendix B: Channel IDs\n\nStandard channel identifiers:\n\n- `main` (Default)\n- `beta`\n- `nightly`\n- `dev`\n\nCustom channel identifiers MAY be used for organization-specific needs (e.g., `internal`, `canary`, `lts`).\n\n## Appendix C: MIME types\n\nAny valid MIME type MAY be used. The following non-exhaustive table lists formats with commonly understood platform or runtime handling.\n\n| MIME type                                       | Platform/Runtime    | Common Extension |\n| ----------------------------------------------- | ------------------- | ---------------- |\n| `application/vnd.android.package-archive`       | Android             | `.apk`           |\n| `application/vnd.apple.ipa`                     | iOS                 | `.ipa`           |\n| `application/x-apple-diskimage`                 | macOS               | `.dmg`           |\n| `application/vnd.apple.installer+xml`           | macOS               | `.pkg`           |\n| `application/x-msi`                             | Windows             | `.msi`           |\n| `application/vnd.appimage`                      | Linux               | `.AppImage`      |\n| `application/vnd.flatpak`                       | Linux (Flatpak)     | `.flatpak`       |\n| `application/vnd.oci.image.manifest.v1+json`    | OCI (Docker/Podman) | —                |\n| `application/x-executable`                      | Linux (ELF)         | —                |\n| `application/x-mach-binary`                     | macOS (Mach-O)      | —                |\n| `application/vnd.microsoft.portable-executable` | Windows (PE)        | `.exe`           |\n| `application/vsix`                              | VS Code             | `.vsix`          |\n| `application/x-chrome-extension`                | Chrome / Chromium   | `.crx`           |\n| `application/x-xpinstall`                       | Firefox             | `.xpi`           |\n| `application/wasm`                              | Browser / WASI      | `.wasm`          |\n| `application/webbundle`                         | Browser (PWA)       | `.wbn`, `.swbn`  |\n\nThe `f` tag is OPTIONAL. It records publisher-declared compatibility restrictions. Omitting it means that the publisher has declared no restriction beyond the MIME type; it does not guarantee compatibility with every device. Publishers SHOULD include explicit `f` tags for clarity, even for universal builds.\n\n### Native executables\n\nNative executables (`application/x-executable`, `application/x-mach-binary`, `application/vnd.microsoft.portable-executable`) SHOULD be statically linked. Self-contained formats like AppImage or Flatpak are preferred when additional dependencies are required. Any specific runtime requirements (e.g., C library variant, dynamic library dependencies) SHOULD be conveyed outside of this specification.\n\n**Examples:**\n\n```jsonc\n// Universal Android APK (all architectures)\n[\"m\", \"application/vnd.android.package-archive\"]\n\n// Android APK restricted to ARM64 only\n[\"m\", \"application/vnd.android.package-archive\"],\n[\"f\", \"android-arm64-v8a\"]\n\n// macOS universal binary\n[\"m\", \"application/x-apple-diskimage\"]\n\n// macOS ARM64 only\n[\"m\", \"application/x-apple-diskimage\"],\n[\"f\", \"darwin-arm64\"]\n```\n\n## Appendix D: Version comparison\n\nVersion strings are used in `version`, `min_platform_version`, `target_platform_version`, `min_allowed_version`, and related tags. Implementations MUST follow [Semantic Versioning 2.0.0](https://semver.org/) precedence rules for versions that conform to SemVer. For non-conforming versions, use the fallback rules below.\n\n### Parsing rules\n\n1. **Split** the version string into segments using `.` (dot), `-` (hyphen), and `_` (underscore) as delimiters.\n2. **Classify** each segment as either numeric or alphanumeric.\n3. **Compare** segments left-to-right using the rules below.\n\n### Comparison rules\n\n1. **Numeric segments** are compared as integers: `9 < 10 < 100`.\n2. **Alphanumeric segments** are compared lexicographically (case-insensitive).\n3. **Numeric vs alphanumeric**: numeric segments sort BEFORE alphanumeric segments.\n4. **Missing segments** are treated as less than present segments: `1.0 < 1.0.0 < 1.0.0.1`.\n\n### Pre-release identifiers\n\nThe following alphanumeric segments are common pre-release identifiers:\n\n| Identifier             |\n| ---------------------- |\n| `dev`, `develop`       |\n| `alpha`, `a`           |\n| `beta`, `b`            |\n| `rc`, `pre`, `preview` |\n\n**Examples of sort order:**\n\n```\n1.0.0-dev < 1.0.0-alpha < 1.0.0-alpha.2 < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-rc1 < 1.0.0 < 1.0.1\n```\n\n### Integer versions\n\nWhen comparing versions that are purely numeric integers (e.g., Android API levels, Chrome versions), compare them directly as integers:\n\n```\n119 < 120 < 121\n```\n\n### Recommendations for publishers\n\n- Use [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH`) where possible.\n- Avoid ambiguous pre-release identifiers.\n- For `version_code` and `min_allowed_version_code`, use monotonically increasing integers.\n\n## Appendix E: Attribution\n\nSigners MAY include other pubkeys as `p` tags and `zap` tags as per [NIP-57 - Appendix G](57.md) in any of the defined event kinds. This is useful when the signer is not the maintainer of the software, or in the case of multiple authors.\n","sig":"003d0c53cfec7b58104fe4475ddb4ad98128eb6dd1825616152ad7d0bc85c24e3485f1090dfd0b15e3474bf60dc0b990802dbb1e8fda981144c32d08c2c6ea2a"}